반응형

들어가며

MyBatis?

  • 자바의 관계형 데이터베이스 프로그래밍을 좀 더 쉽게 할 수 있게 도와주는 SQL Mapper, Java Persistence Framework 중 하나
  • JDBC를 통해 데이터베이스에 엑세스하는 작업을 캡슐화한다
  • 일반 SQL 쿼리, 저장 프로시저 및 고급 매핑을 지원한다
  • 모든 JDBC 코드 및 매개 변수의 중복 작업을 제거한다
  • SQL 쿼리들을 XML 파일에 작성하여 코드와 SQL을 분리하여 관리한다

MyBatis 장점

  • 쉽고 빠르게 개발이 가능하여 생산성이 향상된다
  • SQL의 강점과 특징을 모두 활용할 수 있다
  • 복잡한 쿼리나 다이나믹하게 변경되는 쿼리 작성이 쉽다
  • 프로그램 코드와 SQL 쿼리의 분리로 코드의 간결성 및 유지보수성을 향상시킨다
  • 조회 결과를 사용자 정의 DTO, MAP에 쉽게 매핑하여 사용 가능하다
  • 데이터 캐싱 기능을 지원하여 성능을 향상 시킬 수 있다

MyBatis 단점

  • 테이블 필드 변경시 객체와 쿼리문 모두 관리해주어야 한다
  • 간단한 CRUD 쿼리도 직접 개발자가 작성해야 한다
  • 반복되는 쿼리가 많이 생길 수 있다
  • 특정 DB에 종속적으로 사용하기 쉽다

Spring MyBatis 설정

resources 설정

  • 해당 예제에서는 자바 패키지 안에 매퍼 인터페이스와 매퍼 xml 파일을 함께 관리
  • 아래 설정을 해주어야 빌드시 올바르게 패키징될 수 있음
  • pom.xml
    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
            </resource>
            <!-- Mapper -->
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
            </resource>
        </resources>
    </build>
    
  • build.gradle
    sourceSets {
        main {
            resources {
                srcDirs 'src/main/java'
            }
        }
    }
    

dependencies

  • pom.xml
    <dependencies>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>
    </dependencies>
    
  • build.gradle
    dependencies {
        ...
        implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.2.0'        
    }
    

SQLite일 경우 설정

  • dependency
    <dependency>
        <groupId>org.xerial</groupId>
        <artifactId>sqlite-jdbc</artifactId>
        <version>3.25.2</version>
    </dependency>
    
  • application.properties
    spring.datasource.driver-class-name=org.sqlite.JDBC
    spring.datasource.url=jdbc:sqlite:example.db
    spring.datasource.username=example123
    spring.datasource.password=example456
    
    mybatis.mapper-locations=classpath*:com/example/**/*.xml
    

MySQL일 경우 설정

  • dependency
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>6.0.6</version>
    </dependency>
    
  • application.properties
    spring.datasource.url=jdbc:mysql://docker.example.com:3306/example?characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false
    spring.datasource.username=ubuntu
    spring.datasource.password=123456
    spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
    

OracleDB일 경우 설정

  • dependency
    <dependency>
        <groupId>com.oracle.ojdbc</groupId>
        <artifactId>ojdbc10</artifactId>
        <version>19.3.0.0</version>
    </dependency>
    
  • application.properties
    spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver
    spring.datasource.url=jdbc:oracle:thin:@192.168.56.12:1521/xe
    spring.datasource.username=ubuntu
    spring.datasource.password=123456
    

ExampleMapper 인터페이스 추가

  • 경로 : ~/src/main/java/com/example/ExampleMapper.java
@Mapper
public interface ExampleMapper {
    int selectNumber(@Param("number") int number);
}

ExampleMapper.xml 파일 추가

  • 경로 : ~/src/main/java/com/example/ExampleMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.example.ExampleMapper">
    <select id="selectNumber" parameterType="int" resultType="int">
        SELECT #{number}
    </select>
</mapper>

Test 클래스에서 실행

@SpringBootTest
public class ExampleMapperTest {
    @Autowired
    private ExampleMapper exampleMapper;

    @Test
    public void selectNumber() {
        int number = exampleMapper.selectNumber(1);

        System.out.println(number);
    }
}

기타

collection

  • 1:N 조건의 하위 필드값을 쿼리로 재조회해 세팅해주는 방식
<mapper namespace="com.example.springexample.test1.mapper.VoteMapper">
    <resultMap id="vote" type="com.example.springexample.test1.model.Vote">
        <result property="voteSeq" column="voteSeq"/>
        <result property="voteType" column="voteType"/>
        <result property="voteTitle" column="voteTitle"/>
        <collection property="voteItems" column="voteSeq" select="selectVoteItems"/>
    </resultMap>

    <select id="selectVote" resultMap="vote">
        SELECT voteSeq
             , voteType
             , voteTitle
          FROM vote
         WHERE voteSeq = #{voteSeq}
    </select>

    <select id="selectVoteItems" resultType="com.example.springexample.test1.model.VoteItem">
        SELECT voteSeq
             , voteItemSeq
             , voteItemTitle
          FROM voteItem
         WHERE voteSeq = #{voteSeq}
    </select>
</mapper>

jdbcTemplate

  • MyBatis와는 상관 없지만 Test Case나 간단하게 쿼리 수행해야할 때 사용하면 좋을듯 하여 정리
@Slf4j
@SpringBootTest
public class VoteTest {
    @Autowired
    private NamedParameterJdbcTemplate jdbcTemplate;

    @Test
    public void insertDummyData() {
        for (int voteSeq = 1; voteSeq <= 100; voteSeq++) {
            jdbcTemplate.update("INSERT INTO vote (voteTitle) VALUES (:voteTitle)", Map.of(
                "voteTitle", "투표-" + voteSeq
            ));

            for (int voteItemSeq = 1; voteItemSeq <= 3; voteItemSeq++) {
                jdbcTemplate.update("INSERT INTO voteItem (voteSeq, voteItemTitle) VALUES (:voteSeq, :voteItemTitle)", Map.of(
                    "voteSeq", voteSeq,
                    "voteItemTitle", "투표항목-" + voteSeq + "-" + voteItemSeq
                ));
            }
        }

        log.info("count : {}", jdbcTemplate.queryForObject("SELECT COUNT(*) FROM vote", new HashMap<>(), Long.class));

        log.info("voteList : {}", jdbcTemplate.query("SELECT voteSeq, voteTitle FROM vote", (resultSet, i) -> Map.of(
            "voteSeq", resultSet.getInt("voteSeq"),
            "voteTitle", resultSet.getString("voteTitle")
        )));
    }
}

properties 데이터를 Mapper에서 활용하기

  • ~/src/main/resources/test.properties
    test.image.url=http://test.image.com
    
  • ~/src/main/resources/mybatis.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
    
    <configuration>
        <properties resource="test.properties" />
    </configuration>
    
  • ~/src/main/resources/application.properties
    mybatis.config-location=classpath:mybatis.xml
    
  • TestMapper
    @Repository
    public interface TestMapper {
        String selectTest();
    }
    
  • TestMapper.xml
    <mapper namespace="TestMapper">
        <select id="selectTest" resultType="java.lang.String">
            SELECT '${test.image.url}'
        </select>
    </mapper>
    

참고

반응형

'Development > Spring' 카테고리의 다른 글

[Spring] Spring Cloud Eureka  (0) 2020.12.27
[Spring] Spring Cloud Config  (0) 2020.12.27
[Spring] ORM (with JPA, Hibernate)  (0) 2020.12.27
[Spring] WebSocket(stomp)  (0) 2020.12.27
[Spring] Dependency Injection  (0) 2020.12.27

+ Recent posts