최근 Mybatis 레퍼런스를 보다가 스프링 부트에서 Java Config로 할 수 있는 방법을 보았다. 기존에 xml파일을 통해 맵핑시키는 방법은 소스코드와 쿼리를 분리시키기 위함으로 알고있는데 뭔가 요즘 추세가 xml파일로 Config를 따로 뽑아내는 대신 Java Annotation으로 Config를 대체하는 것 같은 추세인거 같다. 예제가 되는 mapper.xml은 다음과 같다.
<selectid="selectMessagesBeforeMessageId"parameterType="hashMap"resultType="message"resultMap="messageMap"> SELECT * FROM ( SELECT * FROM Message WHERE channel_id = #{channel} AND id <![CDATA[ < ]]> IFNULL(#{messageId}, ( (SELECT MAX(id) FROM Message WHERE channel_id = #{channel}) + 1 )) ORDER BY id DESC LIMIT 10) SortedMessages ORDER BY id ASC </select> </mapper>
1 2 3 4 5
<mappernamespace="com.navercorp.bootcamp.repository.UserMapper"> <insertid="insertUser"> INSERT INTO User (id, username, img_url, email) VALUE( #{userId}, #{userName}, #{url}, #{email}) </insert> </mapper>
@Results({ @Result(property = "messageId", column = "id"), @Result(property = "context", column = "content"), @Result(property = "type", column = "type"), @Result(property = "timeStamp", column = "timeStamp"), @Result(property = "sender", column = "sender_id"), @Result(property = "channel", column = "channel_id"), }) @Select("SELECT * FROM (" + "SELECT * FROM Message WHERE channel_id = #{channel} AND id < IFNULL(#{messageId}, (" + "(SELECT MAX(id) FROM Message WHERE channel_id = #{channel}) + 1" + ")) ORDER BY id DESC LIMIT 10) SortedMessages ORDER BY id ASC") List<Message> selectMessagesBeforeMessageId(Map map); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
@Mapper publicinterfaceUserMapper {
@Results({ @Result(property = "userId", column = "id"), @Result(property = "userName", column = "username"), @Result(property = "url", column = "img_Url"), @Result(property = "email", column = "email"), }) @Select("SELECT * FROM User WHERE id = #{userId}") User getUser(String userId);
@Insert("INSERT INTO User (id, username, img_url, email) VALUE( #{userId}, #{userName}, #{url}, #{email})") voidinsertUser(User user); }
오브젝트의 멤버 인스턴스와 컬럼명이 일치하지 않는 문제는 @ResultMap이나 @Result Annotation으로 해결할 수 있는데 @ResultMap을 사용할 경우 ResultMap에 해당하는 xml파일을 아직까지는 작성해 줘야한다. Java Config로 넘어오면서 xml에서는 쿼리를 분석해서 구분을 해줬는데 아직 인텔리제이에서는 Java Config에 이런 기능을 하는 플러그인은 없는것 같다. 또 다른 하나는 xml에서는 특수문자를 입력하기 위해 <![CDATA[ ${특수문자} ]]> 를 추가해야 했는데 Java Config에서는 특수문자를 사용할 수 있다.
그리고 @Results Annotation으로 만든 ResultMap을 재사용할 수 있는데 id를 붙혀주면 이를 다른 메소드에서 재사용 가능하다. 가령 다음과 같다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
@Mapper publicinterfaceUserMapper {
@Results(id = "userResult", { @Result(property = "userId", column = "id"), @Result(property = "userName", column = "username"), @Result(property = "url", column = "img_Url"), @Result(property = "email", column = "email"), }) @Select("SELECT * FROM User WHERE id = #{userId}") User getUser(String userId); @ResultMap("userResult") @Select("blah blah some my query...") List<User> getAllUsers();
@Insert("INSERT INTO User (id, username, img_url, email) VALUE( #{userId}, #{userName}, #{url}, #{email})") voidinsertUser(User user); }