iBATIS 3.0 Whiteboard

2008/02/18 00:51
컴파일타임에 알수 있는 것과 동적인 순간에 알수 있는것은 차이가 크다.

우리가 TDD를 하는 이유중의 하나도 가능한 빠른 시간에 코드를 런타임까지 만들어서 버그를 줄이는 것일 것이다. 런타임시에 버그를 줄일 수 있는 것은 코드품질과 밀접한 관계가 있다.

TDD를 통해서 빠르게 런타임 환경을 가져가는 것도 중요하지만, 자바와 같은 경우에는 새로 만든 코드들이 컴파일 타임에 모든 에러를 잡을 수 있으면 가장 좋을 것이라는 생각이다.

iBATIS는 국내에서 많이 사용되는 프레임워크 중의 하나이다. JDBC로 직접코딩하던 시절에 iBATIS와의 처음 만남은 아름다운 추억중의 하나였다. 여러가지 제약사항과 단점이 있긴 하지만, JDBC코딩보다는 중복이나 버그의 가능성을 줄여주는 것은 사실이다.

우리는 일반적으로 다음과 같이 구현을 한다. 써보신 분들은 너무나 자주 보던 syntax이고, 예제이다.
Employee employee = (Employee)sqlMapper.queryForList("getEmployee", 5);
//...and...
List employees = sqlMapper.queryForList("listAllEmployees");
이 코드를 보면서 불편함을 느낀점은 없는가? 문자열 인자로 인해서  refactoring을 하면, 이름이 rename이 되지 않아서 의미에 맞지 않은 이름으로 유지를 하거나 수작업을 통해서 변경을 했다. 특히 JDK5.0부터는 generic을 지원을 하는데, iBATIS는 지원을 하지 않아서 수많은 warning을 제거하기위해서 annotation을 사용을 했다.

3.0에서는 다음과 같이 표현이 가능하다.
Employee emp = empMapper.getEmployee(5);
//...and...
List<Employee> employees = empMapper.listAllEmployees();
casting과 문자열로 된 인자가 없어졌다. 런타임시 실행할 쿼리의 id를 문자열로 적어서 오타로 인한 오류들은 없어질 것이다. "xxx no statement xxxx"와 같은 예외는 iBATIS를 사용하는 사람이라면 지겹도록 봤을 것이다. 그리고, generic을 통해서 리턴되는 value의 타입의 명확성을 가져왔다.

인터페이스 자체가 모든 의도를 표현을 한것이다.
 
보통의 코드개발을 하다가 보면, iBATIS이 유연성만큼 필요한 경우도 드물다. 너무 유연성만 강조하면 코드개발도 힘들고, 유지보수시에도 귀찮아질수도 있다. 그 경우는 spring JDBC가 오히려 간편하고 나아보였는데, 3.0에서 annotation을 통한 쿼리설정은 그런 불편함을 느끼지 않아도 된다.
  @Select("SELECT #id(EMP_ID:NUMERIC), #firstName(FIRST_NAME:VARCHAR), #lastName(LAST_NAME:VARCHAR) " +
      "FROM EMPLOYEE")
  List<Employee> selectAllEmployees();


ConstructorResults와 PropertyResults를 지원한다.
그토록 원하던 ConstructorResults였지만, 다음과 같은 내용이 적혀있다...-.-
  • Result and Parameter mappings to fields, constructor parameters and JavaBeans properties. - Yet again, C# will rule with regard to constructor parameters, because they can be named. Java will be limited to ordinal constructor parameter mappings.

     @ResultClass (Company.class)
      @ConstructorResults({
          @Result(property="id", column="C.COMP_ID"),
          @Result(property="name", column="C.NAME")
          })
      @PropertyResults({
          @Result(property="departments.id", column="D.DEPT_ID"),
          @Result(property="departments.name", column="D.NAME"),
          @Result(property="departments.employee.id", column="E.EMP_ID"),
          @Result(property="departments.employee.firstName", column="E.FIRST_NAME"),
          @Result(property="departments.employee.lastName", column="E.LAST_NAME")
          })
      @Collections ({
          @Collection(type=Department.class, property="departments", groupBy="id"),
          @Collection(type=Employee.class, property="departments.employees", groupBy="departments.id")
          })
      @Select("SELECT #id, #name, " +
              "#departments.id, #departments.name, " +
              "#departments.employees.id, #departments.employees.firstName, " +
              "#departments.employees.lastName " +
              "FROM COMPANY C, DEPARTMENT D, EMPLOYEE E " +
              "WHERE D.DEPT_ID = E.DEPT_ID " +
              "AND C.COMP_ID = D.COMP_ID")
      List<Company> selectAllCompaniesWithJoin();

    iBATIS를 이용해서 자바에서 immutable domain 클래스로 result를  TypeHandler, TypeHandlerCallback를 이용해서 할수 있는 방법은 있을거 같다.

    더 자세한 내용은 아래 링크를 확인하면 된다.
    http://opensource.atlassian.com/confluence/oss/display/IBATIS/iBATIS+3.0+Whiteboard
    http://opensource.atlassian.com/confluence/oss/display/IBATIS/iBATIS+3.0+Whiteboard+-+Korean

    iBATIS3.0 에서 신경을 쓴 부분은 다음과 같다. 코드를 만들면서 생각해볼만한 주제는 굵은 글씨로 표시를 해봤다,

    Themes for iBATIS 3.0

    • Test driven development
    • Code cleanliness over performance
    • Simple design over flexible design
    • One JAR file
    • No required 3rd party dependencies
    • Better plug-in support
    • Third party plug-ins are hosted elsewhere (sub-project on SF or CodePlex) http://sourceforge.net/projects/ibatiscontrib/
  • 자바빈 규약에 맞추어서 다음과 같은 프러퍼티에 값을 셋팅을 하고 싶다.
    post.postOptions.openType

    iBATIS는 어떻게 작동을 할까? PostOptions객체를 만들어서 populate를 한 다음 Post에 setPostOptions을 이용해서 VO를 셋팅한다.

    난 post.postOptions으로 만들어진 객체를 찾은 후에 postOptions에서 setter를 찾아서 populate를 하길 원했는데..흑흑

    내가 원했던 코드
    class Post{
       private final PostOptions postOptions = new PostOptions();

      public PostOptions getPostOptions()
        
      }
    }


    iBATIS 덕택에 수정한 코드

    class Post{
       private PostOptions postOptions;

      public void setPostOptions(){
     
      }
      public PostOptions getPostOptions()
        
      }
    }

    물론 이렇게 해도 된다.

    class Post{
       private final PostOptions postOptions = new PostOptions ();

      public void setPostOptions(){
          postOptions.setXXX(XXX);
         postOptions.setXXX(XXX);
         postOptions.setXXX(XXX);
      }
      public PostOptions getPostOptions()
        
      }
    }

    BeanUtils클래스나 spring의 프러퍼티를 접근하는 API를 이용해서 좀더 깔끔하게 만들 수는 있지만, 여전히 종속적인 코드가 들어간다.

    결론을 얘기하자면, PostOptions에 대한 get을 만들고, Post에 대한 PostOptions객체를 immutable하게 만들려는 나의 생각은 setPostOptions(PostOptions postOptions)와 함께 날라가 버렸다.

    프레임워크를 사용을 하다가 보면, 의도하지 하게 내부 프러퍼티에 대한 접근을 오픈을 해야 하는 경우가 종종 있다. spring을 사용을 하다가 보면 만은 setter메소드가 필요하게 된다. default접근자로 해결을 해야 할 것도 어쩔 수 없이 public으로 하는 경우도 종종 있다.

    내가 2년정도 즐겨 써온 DAO쪽 프레임워크와 SqlMap이라는 기술을 사용한 iBATIS에 대한 이야기들을 잘 모아둔 링크이다. 예전에 처음 쓸때는 여러가지 테스트를 많이 하면서 어렵게(?) 사용을 했는데, 국내에도 사용자가 많아질수록 한글화된 문서와 외국의 좋은 문서들의 링크를 좀더 쉽게 발견할 수 있는 것은 좋은 일임에 틀림이 없다.  

    안영회님 애많이 쓰셨습니다..^^

    iBatis 참고 문헌 모음 - 안영회님
    http://blog.empas.com/ahnyounghoe/13229273
    난 1.X 끝자락에서 이 오픈소스에 대해서 알게 되어서, 정확한 유래라던가, history를 몰랐는데, 아래 링크를 보면 재미있는 이야기들이 있다. 항상 느끼는 거지만, 기술은 항상 경쟁하면서 발전한다!!

    C와 자바를 넘어서서 개발자들에게 폭넓게 이용할 수 있는 다음 언어는 무엇이 될까?

    iBATIS의 유래에 대해서
    http://pxforever.egloos.com/1022231
    <select remapResults="true" ....
    어쩌구 저쩌구...


    http://openframework.or.kr/JSPWiki/Wiki.jsp?page=Kwon37xiiBATISDEBUG

    iBatis는 일단 쿼리를 실행하고 나면 그 쿼리 ID에 대해 결과를 저장하는 컬럼들 정보를 캐싱하고 있다가, 다음번 쿼리때 그 컬럼 정보들을 재사용한다. 헌데, 나같은 경우 현재 컬럼 자체를 를 이용해 동적으로 생성하기 때문에 동일한 ID의 쿼리라도 실제 쿼리 결과로 돌아오는 컬럼들이 항상 다르다.

    위와 같이 remapResults="true" 을 사용하면 컬럼 정보를 쿼리 할 때마다 가져와서 문제가 해결된다.

    iBATIS Abator config

    2006/03/17 19:51
    iBATIS Abator config
    http://www.mail-archive.com/user-java@ibatis.apache.org/msg02689.html


    iBATIS Home
    http://ibatis.apache.org

    수작업으로 하던 클래스나 iBATIS관련 클래스들은 자동으로 만들어주는 이클립스 플러그인이다. 관련문서 적어서 DTD를 보고 추론을 해서 쓰거나 위에 있는 링크에 간단한 설명이 있다.

    좀더 설정을 통해서 컴팩트한 코드를 만들수 있으면 좋겠는데, 그건 안되는듯 하네....
    버젼이 좀더 올라가면서 사용자정의로 코드가 더 유연하게 생성이 되면 좋겠다는 생각을 한다.
    하기는 수작업으로 하는 때도 있었으니 만족을 해야 하는건가...^^

    BLOG main image
    OOP and Java by ologist

    공지사항

    카테고리

    All (649)
    private!! (106)
    WEB & IT (140)
    Developer (400)