Spring

DataAccessUtils

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);
}

 

참고 자료

- docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/dao/support/DataAccessUtils.html