Spring Boot์์ Mybatis ์ฌ์ฉ๋ฒ ์ ๋ฆฌ์ ๋๋ค :D
- ์ฌ์ฉ IDE : IntelliJ IDEA Ultimate
- ์ฌ์ฉ DB : MySQL
- ์ฌ์ฉ ์ธ์ด & SDK : Java & Amazon correto 11
- ์ ๋ฆฌ๋ณธ์ ๋๋ค ์ฐธ๊ณ ์ฉ์ผ๋ก๋ง ๋ด์ฃผ์ธ์ :D
์ด์ ๊ธ
ฮธ Spring Boot ์์ 1 (ํ์๊ด๋ฆฌ)
๐ Spring Boot ์์ 2 (ํ์๊ด๋ฆฌ)
๐ Spring Boot ์์ 3 (ํ์๊ด๋ฆฌ)
๐ Spring Boot ์์ 4 (ํ์๊ด๋ฆฌ)
๐ Spring Boot ํ์๊ด๋ฆฌ TEST ๋ชจ์
Spring Boot์์ mybatis ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ๋ํด ์ ๋ฆฌํด๋ณด๊ฒ ์ต๋๋ค.
Spring Framework์์ mybatis๋ฅผ ์ฐ์ง๋ง Spring Boot์์๋ ์ฌ์ฉํ ์ ์๊ณ ,
jpa๋ก ํ ์ ์๋ ๋ณต์กํ ์ฟผ๋ฆฌ๋ฌธ์ ๊ฒฝ์ฐ mybatis๋ฅผ ์ฌ์ฉํด ํด๊ฒฐํด์ผ ํ๊ธฐ ๋๋ฌธ์
์ด์ ๋ํด ์ค๋ช ์ ํ๋ คํฉ๋๋ค!
๊ธฐ์กด ํ์๊ด๋ฆฌ ์์ ์์ ์ถ๊ฐ๋ก ์์ฑํ๋ ๊ฒ์ด๋ฏ๋ก ์์ ๋ด์ฉ์ด ๊ถ๊ธํ๋ค๋ฉด ์ด์ ๊ธ์ ์ฐธ๊ณ ํด์ฃผ์ธ์ :D
mybatis๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์ dependency๊ฐ ํ์ํฉ๋๋ค.
ํ์๊ด๋ฆฌ ์์ ๋ฅผ ๋ง๋ค๋ฉด์ mybatis dependency๋ฅผ ์ถ๊ฐ๋ฅผ ์ํ๊ธฐ ๋๋ฌธ์
์ด๋ฅผ ์ถ๊ฐํด ์ฃผ๋ ์์ ์ ํด๋ด ์๋ค!!
build.gradle ํ์ผ์ ์ด์ด dependencies ๋ถ๋ถ์ ์ฃผ์ ์๋ ์ฝ๋ 2์ค ์ถ๊ฐ
๊ฐ jdbc์ mybatis๋ฅผ ์ฌ์ฉํ ์ ์๊ฒ ์ถ๊ฐํด์ฃผ๋ dependency
์ฝ๋ ์ถ๊ฐ ํ ํ๋ฉด ์ฐ์ธก ์๋จ์ ์ฝ๋ผ๋ฆฌ ์์ด์ฝ์ด ๋จ๋ฉด ๋๋ฌ์ gradle ์ค์ ์ ๋ฐ์ดํธ!
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-web'
// mybatis์ ๊ด๋ จ๋ dependency (jdbc, mybatis)
implementation 'org.springframework.boot:spring-boot-starter-data-jdbc'
implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.2.0'
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'mysql:mysql-connector-java'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
gradle ์ค์ ์ด ์๋ฃ๋์์ผ๋ฉด application.yml์ mybatis ๊ด๋ จ ์ค์ ์ ํด์ค์ผํฉ๋๋ค!
๊ณ์ ์ธ๊ธ์ ํ์ง๋ง ymlํ์ผ์ ๋ด์ฉ์ ์ธ ๋ ๋ค์ฌ์ฐ๊ธฐ๋ฅผ ๊ผญ ๋ง์ถฐ์ ์จ์ฃผ์ธ์!
๋ณด๊ธฐ์ ์ด์๊ฒ ๋ง๋ ๋ค๊ณ ๋ค์ฌ์ฐ๊ธฐ ๋ฌด์ฌํ๋ฉด ์ค๋ฅ๊ฐ ๋ฉ๋๋ค!!
๊ทธ๋ผ ์๋์ ์๋ ์ฝ๋๋ฅผ ymlํ์ผ์ ์ถ๊ฐํด๋ด ์๋ค :D
# mybatis ๊ด๋ จ ์ค์
mybatis:
# resources/mapper/ ์ ์๋ ๋ชจ๋ xml ํ์ผ
mapper-locations: mapper/*.xml
# alias ์ค์
# Spring Framework์ฒ๋ผ ์ด๋ฆ์ ์ฌ์ฉํ๊ธฐ ํธํ๊ฒ ๋ฐ๊ฟ์ฃผ๋๊ฒ ์๋๋ผ ๊ธธ์ด๋ฅผ ์ค์ฌ์ฃผ๋ ์ญํ .
# IntelluJ๋ ์๋์์ฑ์ ์ง์ํ๊ธฐ ๋๋ฌธ์ ๊ตณ์ด ์์จ๋ ๋จ.
# type-aliases-package: com.icia.member.dto
Mybatis ์ค์ ์ ์ ๋ถ ๋๋ง์ณค์ผ๋ Mybatis์ฉ Repository๋ฅผ ๋ง๋ค์ด ๋ด ์๋ค!
์ฃผ์ํ ์ ์ผ๋ก repository ํจํค์ง์ Interface Class๋ก ๋ง๋ค์ด์ผํฉ๋๋ค :D
๊ทธ๋ผ ๋ฐ๋ก ๋ง๋ค๋ฌ ๊ฐ์์ฃ !
@Mapper // Mapper์ฉ์ผ๋ก ์ธ Repository๋ผ๊ณ ์ ์ธํ๋ ์ด๋
ธํ
์ด์
public interface MemberMapperRepository {
}
mapper๊น์ง๋ง ๋ง๋ค๋ฉด Mybatis๋ฅผ ๋ณธ๊ฒฉ์ ์ผ๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค.
์๊น application.yml์์ ๊ฒฝ๋ก๋ฅผ resources/mapper/ ๋ก ๋ง๋ค์๊ธฐ ๋๋ฌธ์ ์ฌ๊ธฐ์ ๋ง๋ค์ด์ผ ํฉ๋๋ค.
๋ํ Spring Framework์์ ์ฌ์ฉํ๋ ๊ฒ๊ณผ ๋๊ฐ์ด ์ค์ ์ ํด์ค์ผํฉ๋๋ค.
๊ทธ๊ฒ๊น์ง ์ ๋ถ ํฌํจํด์ ์ฝ๋๋ฅผ ์ฌ๋ฆฌ๋ ์ฐธ๊ณ ํด์ฃผ์ธ์ :D
<?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 ์ค์ ์ ํ๋ ์ฝ๋ -->
<!-- Mapper๋ฅผ ์ฌ์ฉํ๋ Repository์ ์ ์ฒด ๊ฒฝ๋ก๋ฅผ ์ ์ด์ค์ผํจ. -->
<mapper namespace="com.icia.member.repository.MemberMapperRepository">
</mapper>
์ฌ๊ธฐ๊น์ง ์ ๋ฐ๋ผ์ค์ จ์ผ๋ฉด mybatis ๋ฅผ ์ฌ์ฉํ ์ค๋น๊ฐ ๋๋ฌ์ต๋๋ค!
๊ทธ๋ผ ๊ฐ๋จํ ๊ธฐ๋ฅ 2๊ฐ๋ฅผ ์ฌ์ฉํด๋ณด๋ฉฐ ์ด๋ป๊ฒ ๋ง๋ค์ด์ผํ๋์ง ์์๋ด ์๋ค :D
Mybatis๋ฅผ ์ด์ฉํ ๊ธฐ๋ฅ์ Test์ฝ๋๋ก๋ง ์คํํด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค!!
Mybatis ์ฌ์ฉ์ ์์ํ๊ธฐ ์ ์ ์ฃผ์์ฌํญ์ด ์์ต๋๋ค.
jpa์ ๋ฌ๋ฆฌ mybatis์์๋ DB์ ์ ์ฅ๋ ์ปฌ๋ผ์ด๋ฆ์ ๋ฐ.๋.์ ๋ง์ถฐ์ค์ผํฉ๋๋ค.
jpa๋ ์นด๋ฉ์ผ์ด์ค๋ก ์์ฑ ์(MemberId) ์๋์ผ๋ก ์ธ๋๋ฐ (member_id)๋ก ๋ฐ๊ฟ์ฃผ์ง๋ง,
mybatis๋ ์์ฑํ ๊ทธ๋๋ก ๋ฐ์ดํฐ๊ฐ ๊ฐ๊ธฐ ๋๋ฌธ์ ์ปฌ๋ผ๋ช ๊ณผ DTO์ ํ๋์ด๋ฆ์ด ๊ฐ์์ผํฉ๋๋ค.
์ด์ ๋ง์ถฐ์ DTO๋ฅผ ํ๋ ๋ ์์ฑํด์ค์๋ค :D
@Data
@NoArgsConstructor
@AllArgsConstructor
public class MemberMapperDTO {
private Long member_id;
private String member_email;
private String member_password;
private String member_name;
// ์๋ ์์ฑ์๋ ํ์๊ฐ์
๋ ํ์ํ ์ ๋ณด๋ง ๋ชจ์๋์ ์์ฑ์๋ก ๋ฏธ๋ฆฌ ๋ง๋ค์ด๋ก์๋ค :D
public MemberMapperDTO (String member_email, String member_password, String member_name) {
this.member_email = member_email;
this.member_password = member_password;
this.member_name = member_name;
}
}
Repository์์ mybatis๋ฅผ ์ฌ์ฉํด DB์ ์ฐ๊ฒฐํ๋ ๋ฐฉ๋ฒ์ 2๊ฐ์ง๊ฐ ์์ต๋๋ค.
Spring Framework์ฒ๋ผ mapper์ ์ฟผ๋ฆฌ๋ฌธ์ ๋ง๋๋ ๋ฐฉ๋ฒ์ด ์๊ณ ,
Repository์์ mapper๋ฅผ ํธ์ถํ์ง์๊ณ ์ฟผ๋ฆฌ๋ฅผ ์ํํ๋ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค.
๋๋ค ํ๋์ญํ ์ ๊ฐ๊ธฐ ๋๋ฌธ์ ๊ฐ์ด ์ค๋ช ํ๊ฒ ์ต๋๋ค :D
// ์๋ ์ฝ๋๋ฅผ Repository์ ์ถ๊ฐ
// mapper๋ฅผ ํธ์ถํ๋ ๋ฐฉ์
// ํ์๊ฐ์
void save1(MemberMapperDTO memberMapperDTO);
// mapper๋ฅผ ํธ์ถํ์ง ์๊ณ ์ฌ๊ธฐ์ ์ฟผ๋ฆฌ๊น์ง ์ํํ๋ ๋ฐฉ์
// ์๋๊ฐ์ด ์ฝ๋๋ฅผ ์์ฑํ๋ฉด mapper์ ๋ด์ฉ์ ์ถ๊ฐํ์ง ์์๋ ๋จ
// ์ฌ์ฉํ๊ณ ์ ํ๋ ์ฟผ๋ฆฌ ์ข
๋ฅ(insert, select ๋ฑ)์ ๋ง์ถฐ ์ด๋
ธํ
์ด์
์ ๋ถ์ฌ์ผํจ
@Insert("insert into member_table(member_email, member_password, member_name) values(#{member_email}, #{member_password}, #{member_name})")
void save2(MemberMapperDTO memberMapperDTO);
Repository์ ๋ฉ์๋๋ฅผ ์ถ๊ฐํ์ผ๋ mapper์ ํด๋น ์ฟผ๋ฆฌ๋ฅผ ์ํํ๋ ์ฟผ๋ฆฌ๋ฌธ์ ๋ง๋ค์ด๋ด ์๋ค!
Spring Framework์์ ์ฌ์ฉํ๋ ๋ฐฉ์๊ณผ ๋๊ฐ์ผ๋ ๋ฐ๋ก ์งํํ๊ฒ ์ต๋๋ค :D
์ฟผ๋ฆฌ๋ฌธ์<mapper> </mapper>
์์ ์์ฑ!
<!-- yml์์ alias๋ฅผ ์ค์ ํ๋ค๋ฉด ์๋ ์ฝ๋์ ๊ฐ์ด ์ธ ์ ์์. -->
<!-- <insert id="save" parameterType="MemberMapperDTO"> -->
<insert id="save1" parameterType="com.icia.member.dto.MemberMapperDTO">
insert into member_table(member_email, member_password, member_name)
values(#{member_email}, #{member_password}, #{member_name})
</insert>
mapper์ ํ์๊ฐ์ (ํ์์ ๋ณด ์ ์ฅ)ํ๋ ์ฟผ๋ฆฌ๋ฌธ์ ์์ฑํ์ผ๋ ์ด์ Test๋ฅผ ํด๋ด ์๋ค!
@Test
@Transactional
@Rollback
@DisplayName("mybatis ํ์๊ฐ์
ํ
์คํธ")
public void memberSaveTest1() {
mmr.save1(new MemberMapperDTO("mybatisํ์์ด๋ฉ์ผ", "mybatisํ์๋น๋ฐ๋ฒํธ", "mybatisํ์์ด๋ฆ"));
}
@Test
@Transactional
@Rollback
@DisplayName("mybatis ํ์๊ฐ์
ํ
์คํธ mapper X")
public void memberSaveTest2() {
mmr.save2(new MemberMapperDTO("mybatisํ์์ด๋ฉ์ผ", "mybatisํ์๋น๋ฐ๋ฒํธ", "mybatisํ์์ด๋ฆ"));
}
์ ํ ์คํธ ์ฝ๋๊ฐ ์ฑ๊ณต์ด ๋์๋ค๋ฉด ํด๋น ๋ฉ์๋๋ ์ฌ์ฉ์ด ๊ฐ๋ฅํ๋ค๋ ๊ฒ์ ๋๋ค.
๋ ํ ์คํธ ์ฝ๋ ๋ค ๊ฐ์ ์ฟผ๋ฆฌ๋ฅผ ์ํํ๋ ์์ ์ด๊ธฐ ๋๋ฌธ์ ๋ ์ค ํธํ์ ๋ฐฉ๋ฒ์ผ๋ก ์ฌ์ฉ์๋ฉด ๋ ๊ฒ๋๋ค :D
์ด๋ฒ์๋ Mybatis๋ก ๋ชฉ๋ก์กฐํ๊น์ง ํด๋ด ์๋ค!
๊ฐ ์ฌ์ฉ๋ฒ์ ๋ํ ์ค๋ช ์ ํ์๊ฐ์ ๋ถ๋ถ์์ ์ค๋ช ์ ํ์ผ๋ฏ๋ก ์ฌ๊ธฐ์๋ ์๋ตํ๊ฒ ์ต๋๋ค.
// ๋ชฉ๋ก ์ถ๋ ฅ
List<MemberMapperDTO> memberList1();
@Select("select * from member_table")
List<MemberMapperDTO> memberList2();
<select id="memberList1" resultType="com.icia.member.dto.MemberMapperDTO">
select * from member_table
</select>
@Test
@DisplayName("mybatis ๋ชฉ๋ก ์ถ๋ ฅ ํ
์คํธ")
public void mybatisMemberListTest1() {
List<MemberMapperDTO> memberDetailDTOList = mmr.memberList();
for (MemberMapperDTO m: memberDetailDTOList) {
System.out.println("m = " + m.toString());
}
}
@Test
@DisplayName("mybatis ๋ชฉ๋ก ์ถ๋ ฅ ํ
์คํธ mapper X")
public void mybatisMemberListTest2() {
List<MemberMapperDTO> memberDetailDTOList = mmr.memberList2();
for (MemberMapperDTO m: memberDetailDTOList) {
System.out.println("m = " + m.toString());
}
}
์ ํ ์คํธ ์ฝ๋ ์คํ ์ ์ฝ์์ฐฝ์ ํ์ ๋ชฉ๋ก์ด ์ ์ถ๋ ฅ ๋๋ฉด ์ฑ๊ณต์ ๋๋ค.
์ด๋ ๊ฒ ํ์๊ด๋ฆฌ ์์ ์ ๊ธฐ๋ฅ 2๊ฐ๋ฅผ ์๋ก ๋ค์ด Mybatis๋ก ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ ๋ํด ์ค๋ช ํ์ต๋๋ค.
๊ธฐ์กด Spring Framework์ ์ค์ ๋ฐฉ๋ฒ์ด ์กฐ๊ธ ๋ค๋ฅด์ง๋ง ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ๊ฑฐ์ ๋์ผํฉ๋๋ค!
๊ทธ๋ผ ๋ค์์๊ฐ์ Interceptor์ ๋ํด ์์๋ณด๋๋ก ํ๊ณ ๋ค์์ ๊ฑด๊ฐํ ๋ชจ์ต์ผ๋ก ๋ง๋์ :D
๋ง์ ๋์ ๋ฐ๊ณ ์์ต๋๋ค! ๊ฐ์ฌํฉ๋๋คใ ใ
์ ๊ทผ๋ฐ test ํ์ผ์ ์๋ mmr์ ์๋ฏธ๋ฅผ ์ ์ ์์๊น์?