2013년 3월 24일 일요일

Spring 3.1 + EhCache 를 이용하여 캐시 사용하기

Spring 3.1 이상부터 Annotation을 이용하여, Cache 를 아주 쉽게 사용할 수 있습니다.
데이터를 처리하는 함수에서 @Cacheable 이라는 annotation을 사용하여, 반환되는 데이터를 캐시에 저장한다고 지정하기만 하면 됩니다.

Spring 3.1 Caching and @Cacheable 와 같은 좋은 예제가 많으니 그걸 참고하셔도 됩니다.

저도 비슷하게 함 예제를 만들어 봤습니다.
우선 캐시할 정보를 관리하는 UserRepository 라는 클래스를 구현했습니다. 보시다시피 @Repository 입니다.




처음 getUser() 메소드를 호출하게 되면,  User 인스턴스가 생성되어 반환되면서, 캐시에 자동 저장되고, 두번째 호출서부터는 캐시로부터 읽어드립니다.

정말 편하죠? Cache 와 관련된 코드가 설정만으로 끝낼 수 있다니^^ 물론 Cache 무효화나 key에 따라 다른 결과는 다른 키로 저장하기, 조건에 따라 캐싱하기 등등 더 많은 기능이 있습니다.

위와 같이 Cache 사용하기 위해서는 다음과 같이 Spring Configuration 을 정의합니다.


보시다시피, EhCacheCacheManager 를 제공하는 Bean이 실제 쓰이는 CacheManager 입니다.

테스트는 Spring Configuration을 지정하고, UserRepository.getUser() 를 같은 값으로 두 번 호출하여, 두 번째가 캐시에서 읽어오는지 확인하면 됩니다.
(UserRepository에 보면 log에 쓰는 부분이 있죠? 두 번째에는 나타나지 않으면 됩니다.)


자 테스트 코드는 위와 같고, 마지막으로 ehcache  설정은 다음과 같습니다.



이 것을 응용해서 다른 Cache Provider 에 대해서도 작업을 하실 수 있을 것입니다. 요즘 가장 성능 좋은 것으로 사용되는 Redis 를 활용해도 되겠지요^^

hibernate-ogm configuration for spring framework

요즘 hibernate-ogm 을 제품에 적용하기 위해 공부하고 있습니다만, 아직 많은 활용이 안되나 봅니다. 개발 자료가 별로 없어, 소스와 테스트 코드를 분석하면서 공부하고 있습니다만...

역시 제 나름대로 테스트 환경부터 만들어서 공부하는 습관이 도움이 되네요...
그래서 제가 만든 환경에 대해 설명하고, 이 것을 바탕으로 hibernate-ogm을 제품에 쉽게 적용할 수 있도록 해 보겠습니다.

hibernate-ogm 도 hibernate 와 유사하게 환경설정을 합니다. 다만, hibernate 3.x 대의 Configuration을 이용하여 SessionFactory를 build 하는 것과 유사하게 SessionFactory를 빌드합니다. 즉 hibernate 4.x대와는 다르게 설정하네요.

또 한가지 확실하지는 않지만,  Configuration에서 Package 추가는 잘 안되고, annotationClass 는 제대로 되는군요...
=> 제가 잘못알고 알고 있었네요. package 추가 시에는 scan을 해줘야 하는데 그것은 새로 구현을 해야 하는 거더군요^^

우선 모든 Datastore (NoSql이라 그런지 Database 라 하지 않고 Datastore 라고 하는군요) 에 공통되는 부분을 구현한 GridDatastoreConfigBase.java 파일을 보면



public SessionFactory sessionFactory() {...} 는 아주 익숙한 코드지요? 단지 Configuration class가 hibernate 것이 아닌 hibernate-ogm의 OgmConfiguration을 사용한다는 것만 다릅니다.

아래의 getDatabaseName(), getMappedPackageNames(), getMappedEntities() 메소드는 각자 Datastore와 제품에 따라 재정의하면 됩니다.
그 밑에 getHibernateProperties() 와 getHibernateOgmProperties() 는 각각 Hibernate 설정과 Hibernate-Ogm 설정을 추가할 수 있습니다. 이 부분도 재정의를 통해 추가하시면 됩니다.

그럼 MongoDB를 사용하는 환경설정은? 위의 GridDataStoreConfigBase를 상속하여 몇가지 메소드를 재정의만 하면 됩니다.


MongoDB 만의 설정을 보면 database 명을 설정해줘야 하고, 엔티티의 저장 방식을 설정해주게
됩니다. AssociationStorage enum 값의 설명을 보면 ...


입니다. Entity 들을 전역 컬렉션에 저장, 지정한 컬렉션에 저장, 엔티티별로 저장과 같이 3가지 방식이 있습니다.

뭐 Lazy Initialization을 많이 사용하려면 엔티티별로 저장하고, 일반적으로는 컬렉션에 저장하는게 좋으리라 생각됩니다.

자 그럼 실제 테스트 시에 사용할 Configuration을 보면은


과 같습니다. DB명을 지정하고, 매핑된 엔티티를 지정해 주는 것으로 끝납니다^^
이제부터는 위의 Configuration을 이용하여 테스트 코드를 작성하여 테스트를 수행하면됩니다

hibernate-ogm은 현재까지 NoSQL을 단순 저장소로 밖에 활용 못한 것을 Object Grid 방식으로 사용할 수 있도록 한 차원 업그래이드된 방법을 제공합니다.
이를 통해 앞으로는 RDBMS 뿐 아니라 NoSQL도 특정 제품에 구애받지 않고 사용할 수 있었으면 합니다.



2013년 3월 19일 화요일

hibernate-validator 사용 시

Business Application 개발 시, DDD를 적용하는 것은 거의 표준이고, Domain Model 을 전 Layer에 걸쳐 사용하는 것이 대세입니다.
hibernate 를 사용하는 경우는 hibernate-validator, hibernate-search 등을 같이 사용하게 되면, 상당히 많은 부분에서 업무 로직 등을 손쉽게 구현할 수 있습니다.

특히 hibernate-validator 는 Model의 속성 값의 제약 조건을 annotation을 이용하여 손쉽게 정의할 수 있습니다.

@NotEmpty
public String getName() { ... }

이라 하면,  엔티티의 name 속성 값은 빈 문자열이면 안된다는 뜻입니다. DB에 insert, update 시에 위의 검사 조건으로 자동 검사가 가능합니다.

자세한 내용은

Hibernate Validator Reference 4.3.1 Html Single
Hibernate Validator Reference Pdf

을 보시는게 ...

기본 제공되는 부가 제약 조건으로는

@AssertFalse, @AssertTrue, @DecimalMax, @DecimalMin, @Digits(integer=,fraction=), @Future, @Max, @Min, @NotNull, @Null, @Past, @Pattern(regex=,flag=), @Size(min=,max=), @Valid
가 있습니다.


부가 제약 조건으로는

@CreditCardNumber, @Email, @Length(min=, max), @ModChceck, @NotBlank,  @NotEmpty, @Range(min,max), @SafeHtml, @ScriptAssert, @URL 등이 있습니다.

위의 Validation이 굳이 필요한가? DB에도 Constraint 를 정의할 수 있는데? 라고 한다면...

Validation은 다음과 같은 단계에 모두 필요합니다.
1. Presentation Layer 에서 입력 작업 시
2. Business Layer 또는 Service Layer 에서 Entity 작업 시
3. Data Access Layer 에서 DB에 insert, update 시

에 하게 되면 굳이 DB에서 작업이 필요없습니다.
그리고 DB는 되도록 부가 작업을 안하게 하는 것이 성능 상 더 좋습니다.

또 향후 저장소를 RDBMS가 아닌 NoSQL을 사용하고자 할 경우에는 hibernate-ogm 을 사용하게 되면 다른 것은 하나도 바꿀 필요 없고, 환경설정만 변경하면 됩니다^^