DataAccessUtils는 유틸 클래스로서 DAO 구현을 위해 사용할 수 있으며 모든 데이터 액세스 기술에 유용하다.
총 9개의 메서드가 있는데, 각 메서드의 내부 구현은 다음과 같다. 내부 구현을 통해 메서드의 목적을 잘 드러내고 있는 것 같아 구체적인 설명 없이 내부 구현을 기록하기로 했다.
1. intResult
public static int intResult(@Nullable Collection<?> results)
throws IncorrectResultSizeDataAccessException, TypeMismatchDataAccessException {
return objectResult(results, Number.class).intValue();
}
2. longResult
public static long longResult(@Nullable Collection<?> results)
throws IncorrectResultSizeDataAccessException, TypeMismatchDataAccessException {
return objectResult(results, Number.class).longValue();
}
3. nullableSingleResult
@Nullable
public static <T> T nullableSingleResult(@Nullable Collection<T> results) throws IncorrectResultSizeDataAccessException {
// This is identical to the requiredSingleResult implementation but differs in the
// semantics of the incoming Collection (which we currently can't formally express)
if (CollectionUtils.isEmpty(results)) {
throw new EmptyResultDataAccessException(1);
}
if (results.size() > 1) {
throw new IncorrectResultSizeDataAccessException(1, results.size());
}
return results.iterator().next();
}
4. objectResult
@SuppressWarnings("unchecked")
public static <T> T objectResult(@Nullable Collection<?> results, @Nullable Class<T> requiredType)
throws IncorrectResultSizeDataAccessException, TypeMismatchDataAccessException {
Object result = requiredUniqueResult(results);
if (requiredType != null && !requiredType.isInstance(result)) {
if (String.class == requiredType) {
result = result.toString();
}
else if (Number.class.isAssignableFrom(requiredType) && result instanceof Number) {
try {
result = NumberUtils.convertNumberToTargetClass(((Number) result), (Class<? extends Number>) requiredType);
}
catch (IllegalArgumentException ex) {
throw new TypeMismatchDataAccessException(ex.getMessage());
}
}
else {
throw new TypeMismatchDataAccessException(
"Result object is of type [" + result.getClass().getName() +
"] and could not be converted to required type [" + requiredType.getName() + "]");
}
}
return (T) result;
}
5. requiredUniqueResult
public static <T> T requiredUniqueResult(@Nullable Collection<T> results) throws IncorrectResultSizeDataAccessException {
if (CollectionUtils.isEmpty(results)) {
throw new EmptyResultDataAccessException(1);
}
if (!CollectionUtils.hasUniqueObject(results)) {
throw new IncorrectResultSizeDataAccessException(1, results.size());
}
return results.iterator().next();
}
6. uniqueResult
파라미터로 들어온 컬렉션에서 unique한 객체를 리턴한다.
@Nullable
public static <T> T uniqueResult(@Nullable Collection<T> results) throws IncorrectResultSizeDataAccessException {
if (CollectionUtils.isEmpty(results)) {
return null;
}
if (!CollectionUtils.hasUniqueObject(results)) {
throw new IncorrectResultSizeDataAccessException(1, results.size());
}
return results.iterator().next();
}
7. requiredSingleResult
조회문 (select) 쿼리를 수행할 때, 결과가 1개 존재한다면 그 값을 리턴하고, 존재하지 않으면 EmptyResultDataAccessException을, 1개보다 많다면 IncorrectResultSizeDataAccessException을 던진다.
public static <T> T requiredSingleResult(@Nullable Collection<T> results) throws IncorrectResultSizeDataAccessException {
if (CollectionUtils.isEmpty(results)) {
throw new EmptyResultDataAccessException(1);
}
if (results.size() > 1) {
throw new IncorrectResultSizeDataAccessException(1, results.size());
}
return results.iterator().next();
}
8. singleResult
(참고) @Nullable 어노테이션은 파라미터와 리턴 값에 널이 들어오는 것을 허용한다는 의미이다.
조회문 (select) 쿼리를 수행할 때, 결과가 1개 존재한다면 그 값을 리턴하고, 존재하지 않으면 null을, 1개보다 많다면 IncorrectResultSizeDataAccessException을 던진다.
@Nullable
public static <T> T singleResult(@Nullable Collection<T> results) throws IncorrectResultSizeDataAccessException {
if (CollectionUtils.isEmpty(results)) {
return null;
}
if (results.size() > 1) {
throw new IncorrectResultSizeDataAccessException(1, results.size());
}
return results.iterator().next();
}
9. translateIfNecessary
적절한 경우 번역 된 예외를 반환하고, 그렇지 않으면 주어진 예외를 있는 그대로 반환한다.
public static RuntimeException translateIfNecessary(
RuntimeException rawException, PersistenceExceptionTranslator pet) {
Assert.notNull(pet, "PersistenceExceptionTranslator must not be null");
DataAccessException dae = pet.translateExceptionIfPossible(rawException);
return (dae != null ? dae : rawException);
}