엄범

 

Mybatis가 쿼리를 처리하는 방식?


스프링에서는 DB 커넥션을 어떻게 처리하는가?
  • 쿼리 하나 날릴 때 마다 Connection을 맺고 끊는건 비효율적이므로,
  • Connection Pool을 구성하여 Connection을 생성해두고, DB를 사용해야 할 때 Pool에서 커넥션을 빌려 쓰고 반납하게 되어 있다.
  • Spring에서 제공하는 Connection Pool 인터페이스가 바로 `` DataSource``
    • 각 driver vendor들은 자사 규격에 맞게 `` DataSource`` 인터페이스를 구현해서 제공하고 있음!(커넥션 풀 구현체)
      • ojdbc의 `` OracleDataSource``
      • jdbc의 `` ~~DataSource``
    • 각 벤더가 만들어 제공하는게 맞는게, Connection object를 만들어서 가지고 있어야 하는데 이를 만들기 위한 규격을 제공하는게 driver vendor들이 하는 일이고, 그 규격에 맞게 커넥터를 만드는건 자기들이 제일 잘할거니까...
  • 참고하면 도움이 되는 커넥션 풀과 구현체에 대한 설명 : Commons DBCP 이해하기

 

Mybatis에서 xml 기반으로 쿼리 작성 시 어떻게 resolve되는가?
  • `` DataSource``에서 커넥션을 가져와서 쿼리를 수행하거나, prepared statement를 세팅한다거나, 세션을 유지한다거나 하는 동작을 대행해주는 것이 Mybatis
  • Spring-Mybatis에서는 `` SqlSessionFactoryBean``을 사용하는데, 이 Bean에 DataSource, ConfigLocation, MapperLocation 등을 설정하게 된다.
    • mybatis-spring-boot-starter를 사용하면 config.xml설정은 application.yml에서 할 수 있고, mapper xml은 지정 위치에서 자동으로 파싱한다.
    • 그래서 아래와 같은 설정을 생략할 수 있어 여러모로 설정이 간결해짐

```java

factoryBean.setDataSource(dataSource);
factoryBean.setConfigLocation(applicationContext.getResource("classpath:mybatis/config.xml"));
factoryBean.setMapperLocations(applicationContext.getResources("classpath*:mybatis/mappers/**/*.xml"));

```

  • MapperLocation에 지정된 위치에 있는 xml을 파싱하게 되고, 그 안의 mapper namespace를 따라가 그 인터페이스를 확장한 Bean을 생성해준다!

```xml

<mapper namespace="com.example.ex.mapper.TestMapper"> 이면,

interface TestMapper를 확장해서 Bean으로 만들어 준다.

이 때 @Mapper 애너테이션은 그냥 장식임! xml 보고 resolve하는거라서 안붙여도 상관 없다.

```

 

Mybatis에서 애너테이션 기반으로 쿼리 작성 시 어떻게 resolve 되는가?
  • `` @Mapper`` 애너테이션을 달면 `` @MapperScan``을 통해 스프링 빈으로 만들어준다.
  • 이 때 쿼리 구문을 넘기기 위해서 `` @Select()``와 같은 애너테이션을 사용함
  • 자바에서는 줄바꿈 스트링이 지원되지 않기 때문에 ``java "" + "" +``로 연결해야 해서 아주 지저분하다
  • 그러나 코틀린은 ``kt """`` 문자열이 지원되기 때문에, 이런 방식이 오히려 깔끔한 것 같다.
    • 가독성도 괜찮고 Mapper interface의 메서드와 실제 query가 xml로 분리되어서 따라가기 귀찮은 점과 관리포인트가 늘어난다는 점도 해소되고..

 

Mybatis 설정 / 시작하기


 

mybatis-spring-boot-starter

 

mybatis get sequence after insert

 

mybatis에서 enum을 query 파라미터로 쓸 때, lang3을 사용하면 예외가 발생한다

```xml

<if test="@org.apache.commons.lang3.StringUtils@isNotEmpty(userCode)">

--- error 발생

Caused by: java.lang.IllegalArgumentException: Unable to convert type com.naver.dbill.common.enums.UserCode of AB to type of java.lang.CharSequence

```

  • 애초에 enum을 StringUtils로 비교한다는 것 자체가 type이 안맞기 때문임.
  • lang3이 아닌 lang.StringUtils를 쓰면 예외 없이 동작은 하는데, 타입 체크를 안하기 때문. lang은 안쓰는 것이 좋다.
  • enum은 ``java userCode != null``로 비교해주면 된다.