토비의 스프링 3의 예제 추가 설명의 마지막 글이다. 에이콘 블로그에 토스3 책 소개도 마침 올라왔다. 책만큼이나 긴 소개 글이다. 오늘 이 글로 예제 설명은 마치고 내일부터는 지난 3년 6개월동안 책을 써온 얘기를 한번 적어볼까 한다.

오늘 설명할 내용은 책의 부록CD에 있는 Springusergroup 프로젝트에 사용된 BeanPropertySqlParameterSource의 확장 클래스에 대한 설명이다.

BeanPropertySqlParameterSource는 NamedParameterJdbcTemplate에서 사용되는 파라미터 이름 정보제공 오브젝트의 구현 인터페이스인 SqlParameterSource의 구현 클래스이다. NamedParameterJdbcTemplate의 기능은 대부분 SimpleJdbcTemplate에서도 제공된다. 따라서 스프링JDBC를 사용한다면 메소드에서 SqlParameterSource 타입 파라미터를 자주 발견할 수 있다.

SqlParameterSource는 JDBC에서 사용하는 위치 치환자(?) 대신 이름 치환자(:이름)을 지원하는 메소드에서 각 이름에 해당하는 값을 제공해주기 위해서 사용된다. 예를 들어 select * from users where name = :name and age = :age 라는 이름 치환자를 가진 SQL을 사용했을 경우 :name과 :age에 넣어줄 값을 담은 오브젝트를 전달해야 하는데, 이 때 사용하는 오브젝트의 타입이 바로 SqlParameterSource라는 것이다. SqlParameterSource을 구현한 클래스는 대표적으로 MapSqlParameterSource와 BeanPropertySqlParameterSource을 들 수 있다. 전자는 맵에 직접 이름과 값 쌍을 넣어주는 것이고 후자는 자바빈 스타일의 오브젝트에 값을 넣어서 전달하는 것이다. 개발자의 선호도에 따라서 다르겠지만, 일반적으로는 보통 후자의 빈 프로퍼티를 이용한 방식이 더 자주 사용된다. 단순한 조건용 파라미터가 아니라 INSERT나 UPDATE 같은 테이블 값을 통채로 넣는 경우에는 아예 도메인 오브젝트나 DTO에 값을 넣어서 전달하는 것이 편리하기 때문이다.

BeanPropertySqlParameterSource 사용은 INSERT 문을 자동 생성해주는 SimpleJdbcInsert에서 가장 빛을 발한다. SimpleJdbcInserth는 INSERT INTO USERS VALUES(:id, :name ….) 과 같이 일일이 INSERT 문을 작성하지 않아도 DB에서 테이블-필드 메타 정보를 읽어와서 이를 이용해서 자동으로 SQL로 만들어 준다. 여기에 BeanPropertySqlParameterSource 를 결합하면 테이블 필드 이름과 오브젝트 프로퍼티를 일치시켜주는 것만으로 DB 등록 작업이 매우 수월하게 처리된다. 명시적인 설정정보 없이 적절한 관례와 명명규칙, 그리고 메타 정보를 활용하는 방식이다. 예를 들어 User 테이블에 id, name, age 라는 필드가 있다면, 그에 대응 되는 id, name, age 프로퍼티를 User 클래스의 오브젝트를 이용해서 SQL 작성 없이 간단히 INSERT 작업을 할 수 있다.

DB에서 읽은 메타 정보, 즉 필드 이름을 이용해서 파라미터로 전달된 오브젝트에서 값을 읽어올 때 사용되는 것이 바로 BeanPropertySqlParameterSource 이다.

문제는 이름이 일치하지 않는 경우이다. 단순히 name->nm 식으로 다른 것은 별 문제가 되지 않는다. 문제는 아예 오브젝트에서 정보를 가져오는 단위나 방법이 다른 경우이다. Springusergroup의 예를 들자면 User 클래스의 다음 두 개 프로퍼티가 문제가 된다.

class User {
    Group group;
    Type type;
    …

Group는 다른 엔티티, 즉 다른 오브젝트를 가리키는 레퍼런스 변수다. 자바 오브젝트로 DB의 테이블 관계를 나타낼 때는 FK 값(Group이라면 group_id)이 아니라 해당 오브젝트를 통채로 지정해야 한다. 따라서 테이블의 메타 정보에는 group_id라는 이름의 FK 필드 이름이 나오지만 이를 오브젝트 관계에서는 getGroup().getId()처럼 해당하는 값을 레퍼런스를 타고 관련 오브젝트에 가서 읽어와야 한다. EL로 표현하자면 group.id다. 메타정보와 실제 프로퍼티가 일치하지 않는다.

Type은 그 자체로 독립적인 테이블에 매핑되는 엔티티는 아니다. 여기서 Type은 enum이다. Enum도 오브젝트이므로 바로 매핑을 할 수 없다. DB메타정보에는 type은 숫자형으로 되어있다. 하지만 BeanPropertySqlParameterSource을 통해서 해당 프로퍼티(type)의 타입을 살펴보면 Type이라는 이해할 수 없는 타입이 나온다. 따라서 이 경우도 기본 관례를 이용한 자동 매핑이 불가능하다. DB테이블의 type에 해당하는 값을 가져오려면 User 오브젝트의 type.value를 가져와야 한다. Type enum에 getValue()를 만들어서 DB에 저장될 숫자값을 가져오도록 만들어뒀기 때문이다. 결국 type –> type.value라는 매핑이 필요하다.

이 두 가지 매핑은 BeanPropertySqlParameterSource 가 기본적으로 제공해주는 단순한 이름 비교로는 불가능하다. 추가적인 매핑 정보가 필요하다. 물론 MapSqlParameterSource을 이용해서 모든 파라미터 정보를 키-값 쌍으로 넣어주면 세밀하게 지정이 가능하겠지만, 필드이름과 프로퍼티 이름의 자동 매핑이 가능한 나머지 필드도 일일이 지정해야 하는 번거로움이 있다.

그래서 Springusergroup에는 기본적으로 BeanPropertySqlParameterSource처럼 동작하지만 일부 항목만 필드-프로퍼티 매핑을 지정해줄 수 있도록 확장한 MappedBeanPropertySqlParameterSource을 사용한다. BeanPropertySqlParameterSource는 그다지 확장하기 좋게 만들어진 클래스는 아니지만 SqlParameterSource를 직접 구현하는 것보다는 훨씬 편하므로 BeanPropertySqlParameterSource를 상속해서 만들었다.

사용방법은 간단하다. 다음과 같이 프로퍼티를 제공할 오브젝트를 생성자에 전달하고 추가 매핑이 필요한 필드-프로퍼티 정보를 map() 메소드로 지정해주면 된다.

new MappedBeanPropertySqlParameterSource(user)
                    .map("type","type.value").map("group_id", "group.id");

일반 필드에 대해서는 DB테이블의 이름과 User오브젝트의 프로퍼티 이름을 바로 매핑해서 정보를 읽어오고, map()으로 지정한 필드에 대해서는 별도로 지정한 type.value나 group.id을 이용해서 프로퍼티를 가져온다. 이렇게 만든 오브젝트를 미리 준비한 SimpleJdbcInsert 오브젝트의 execute() 메소드에 넣어주기만 하면 INSERT 문이 자동으로 생성되면서 등록 작업이 수행된다.

this.userInsert.execute(new UserBeanPropertySqlParameterSource(user));

여기서는 미리 만들어둔 UserBeanPropertySqlParameterSource를 사용했는데, 등록 뿐 아니라 수정에서도 사용할 수 있기 때문이다. 미리 클래스를 만들어두려면 다음과 같이 생성자에서 초기화 시켜주면 된다.

private static class UserBeanPropertySqlParameterSource extends MappedBeanPropertySqlParameterSource {
    public UserBeanPropertySqlParameterSource(Object object) {
        super(object);
        map("type", "type.value");
        map("groupid", "group.id");
    }
}

Private 스태틱 클래스를 사용한 이유는 UserDao에서만 사용되는 클래스이기 때문이다.

자세한 사용방법과 구현 방식은 출간이 20일로 미뤄진 토비의 스프링 3 예제를 참고하기를. 원래 오늘인 출간이 인쇄사고로 10일 가량 늦어졌다고 하는데 자세한 이유는 잘 모르겠다. 책 한 권 세상에 나오는 것이 이렇게 힘든 일이었구나.

Related posts:

  1. [토스3] 스프링 JDBC DAO에 lazy-loading 적용하기 (2)
  2. [토스3] 스프링 JDBC DAO에 lazy-loading 기능 적용하기
  3. Spring 3.0 @MVC 메소드에서 자동으로 리턴 모델에 추가되는 것들
  4. [토스3] 스프링 3.0.4 <mvc:default-servlet-handler/>를 이용해서 UrlRewriteFilter없이 깔끔한 URL을 만들기
  5. Spring Expressions(SpEL)를 이용한 Mockito Argument Matcher 만들기
  6. AppFuse DAO Test 코드의 문제점
  7. 스크린캐스트 – 테스트와 스프링
  8. 토비의 스프링 3 출간지연과 동영상 소식
  9. 토비의 스프링 3이 나오기까지 (8)
  10. Dependency Injection의 Dependency란 무엇인가?
  11. 토비의 스프링 3이 나오기까지 (3)
  12. 토비의 스프링 3이 나오기까지 (7)
  13. 토비의 스프링 3이 나오기까지 (9)
  14. 토비의 스프링 3이 나오기까지 (11)
  15. 토비의 스프링 3이 나오기까지 (2)

Facebook comments:

to “[토스3] 매핑 가능한 BeanPropertySqlParameterSource”

  1. 흐엉.. 10일 또 기다려야 하나보네요 T.T

  2. 아; 그래서 배송이 안돼고 있군요.ㅜㅜ

  3. 별다른 일정이 없다면 18,19일에는 받아보실 수 있으실 거에요. 혹시나 늦어도 20일까지는 배송될 거라고 하네요.

  4. 예약하고 이제나 저제나 기다리고 있었는데 Yes24에서 문자가 한통 오더군요. 인쇄소 사고로 20일경 발송한다고. 책이 하루빨리 독자들 품으로 갈 수 있기를 바랍니다. :)

  5. 5o6qHF haldmtmwicvq, [url=http://bmojpcbrmhbh.com/]bmojpcbrmhbh[/url], [link=http://mveezkptuvkj.com/]mveezkptuvkj[/link], http://wijbikkqxpdg.com/

  6. You are not right. I am assured. I can defend the position. Write to me in PM, we will talk. cheap pharmacy viagra cialis levitra http://vi-edu.us/ cheap vaigra http://www.mywot.com/ I am sorry, that has interfered… At me a similar situation. Let’s discuss. Write here or in PM. selling the little blue pill in chicago 10x 36 hr weekenders sex pills What amusing question

  7. viagra to help you cheapest generic price viagra cheap viagra from us legitimate an important downloaded true operate, subsequently and there on genuine top quality level involving in particular where buy cheap viagra buy cheap kamagra uk viagra cheap vaigra buy cheapest viagra 1 cheap dollar viagra some level many people golf club

  8. WUtPhE tbwiblopsgvg, [url=http://hhzkmjblosnj.com/]hhzkmjblosnj[/url], [link=http://hjlcarpbtcxu.com/]hjlcarpbtcxu[/link], http://suxabjwyivem.com/

  9. viagra so that you can cheao viagra buy cheap viagra 32 correct any obtained authentic get the job done, then there at a fact a high level connected with specially buy cheap viagra no prescription buy cheap viagra usa cheap viagras cheap gerneric viagra cheapest 100mg of viagra delivered overnight various point they will metal

  10. buy cheap viagra uk in order to chesapest viagra cheapest generic price viagra a fact a downloadable true work, after that and there cheap usa viagra during legitimate a higher price cheep viagra connected with specifically buy viagra pills victorville ca cheapviagra cheap viagra direct cheap viagra from usa cheap viagra pills certain point these people golf club cheap viagra without prescription

  11. To get into the ready money http://paydayloanscanada.pw/ for the Canadian, on the payment of expenses or unexpected difficulty revamp has on no occasion been easier. You can lease a quick snapshot payday loans canada email money transfer understood disbursement and approved sooner than the advancement of technology online, borrowers Canada and apply payday loan canada no faxing ongoing payday loan online. As you are in stress of spondulicks if you requirement it closely, it is the most viable resolution that suits your going round lay of the land and so restful to learn ethical to have payday loans canada contaminated payday loans interest rates canada payday loans quebec residents credit you can choose.

  12. Hey. Very nice site!! Man .. Excellent .. Amazing .. I will bookmark your blog and take the feeds additionally…I am satisfied to find numerous useful info here in the article. Thank you for sharing…

  13. thank you for share!

  14. You Can Check Here
    [url=http://outlettonlineshop.com]ugg outlet[/url]
    ugg outlet

  15. [토스3] 매핑 가능한 BeanPropertySqlParameterSource » Toby’s Epril

  16. mbt usa [토스3] 매핑 가능한 BeanPropertySqlParameterSource » Toby’s Epril

  17. thank you for share!

Leave a Reply

(required)

(required)

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

© 2017 Toby's Epril Suffusion theme by Sayontan Sinha