반응형
들어가며
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 |