type
status
date
slug
summary
tags
category
icon
password
두번째 미션이 주어졌다.
KakaoAPI에서 검색한 도서 정보를 가져와 DB에 저장 후 목록을 출력하는 내용이다
단순 JDBC로 구현할려다가 간만에 SqlMapper 가 써보고 싶어져서 mybatis를 찾게 되었다.
문서탐방을 하면서 알게 된 건데, 생각이상으로 많이 발전되어 있었다.
 
notion image
요약하면 Mybatis도 Generator, DSL 등의 지원으로 QueryDSL 처럼 Type-Safe 한 코드를 작성할 수 있게 되었다.
mybatis에서 예제코드도 제공해준다

준비

build.gradle

Gradle 프로젝트로 수행할 것이라 Mybatis 위주로 불러왔다. Generator 가 있어서 jakarta 도 가져왔다.

generatorConfig.xml

Querydsl이 gradle 세팅 후 build 를 통해 자동으로 생성하듯이 Mybatis도 지원한다. 예제 자료는 XML이라. Gradle로 스크립트 짜서 XML 파일을 실행하도록 구현할 수 있어 보인다.

MyBatisGeneratorExecutor

예제 코드를 참고해서 작성해봤다. 이코드를 실행하면 jOOQ 처럼 자동으로 DB에 접근하여 generatorConfig.xml 에서 지정한 테이블을 확인 후 자동으로 자바 코드를 생성해준다.
생성되는 파일은 아래와 같다
  • Table
  • TableDynamicSqlSupport
  • TableMapper
notion image
엔티티? 라고 해야 하나. 저거를 record 타입으로 별도로 관리하려 했는데, 코드가 실행이 안되었다. 로그를 살펴보니 Mybatis가 내부적으로 getter/setter를 사용했었다. 스샷 찍어둘껄...껄껄
notion image
DynamicSqlSupport는 우리가 ORM에서 자주보던 QClass역할(jOOQ에서는 JClass)과 비슷하다 . 칼럼 지정할때 쓰인다.
notion image
Mapper 는 인터페이스 형태로 제공되며, 우리가 주로 사용될 쿼리문들이 자동으로 생성된다. Mybatis3에서 쓰던 @Select, @Update 와 같은 애너테이션도 지원해서 TableMapperCustom 이런식으로 인터페이스 만들어서 상속받으면 된다.
이런기능이 있었다니... DBA분들이 잘 설계해놓은 db를 토대로 리뉴얼 해야 할 때 도움이 되지 않을까 싶다.

DAO

Mybatis 와 동일하게 SqlSessionFactory 를 이용해서 구현할 수 있다. 아래 코드처럼 프로그램 시작시 쿼리문을 주입해서 쓸 수 있다. 가장 눈에 띄는 것은 뭐... 요런거? type-safe 하게 작성할 수 있게 되었다는 점이다.
Mybatis 가 전통성이 있다보니 윈도우 함수, 서브 쿼리 등 풍부하게 지원한다. Querydsl 에서는 위의 기능에 제한이 있어 SqlQueryFactorySQLExpressions 를 이용해야 한다. 그렇다. 위의 클래스는 JPAQueryFactory가 아니다.
때문에 네이티브 쿼리나 JdbcTemplate, blaze-persistence 를 사용해야 한다.
Querydsl 기여자분이 blazebit 에서 활동하시는 것 같았다.
querydsl 이 2021년 이후 패치가 멈춘 이유가 이건가?
쿼리가 잘 수행되었다.
notion image

마치며

뭐... 이렇게 Mybatis로도 이정도 까지 할수 있게 되었다! 라고 말은 하긴 했는데, 개발자 준비하시는 분들은 sql Mapper 이야기를 꺼내면
에에엥?? 아직도 그런거 쓰세요? ORM이 편한데...😱
오래된 데다가 XML 써야 되잖아요.🤔
라고 대화한 것을 들은 적이 있었다.
하지만 우리가 개발에 투입되는 곳은 신규 플랫폼을 개발하지 않는 이상 기 서비스를 유지보수, 기능 추가 등 부분적으로 진행될 것이고 DB도 이전 DBA가 잘 설계해놓은 것을 활용할 가능성이 크다. 필자도 xml은 선호하지 않는다.
ORM은 만능이 아니다. 필요에 따라 ORM, SQL Mapper 둘다 쓸 일이 있다고 생각한다.
근데... jOOQ 로 다 할 수 있지 않나?
RESTful APIFlyway
Loading...