오늘은 Springboot와 Mybatis를 연동하는 방법에 대해 알아보도록 하겠다.
- SpringBoot (JAVA 11, Maven)
- Thymeleaf
- MySQL
- Spring Initializr 링크
https://start.spring.io
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.6.1</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.example</groupId>
	<artifactId>mybatisStudy</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>mybatisStudy</name>
	<description>for my mybatis study</description>
	<properties>
		<java.version>11</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jdbc</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>2.2.0</version>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>
	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<configuration>
					<excludes>
						<exclude>
							<groupId>org.projectlombok</groupId>
							<artifactId>lombok</artifactId>
						</exclude>
					</excludes>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>전체 application.properties
# mysql config
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/mytestdb?serverTimezone=UTC&characterEncoding=UTF-8
spring.datasource.username={본인DB's username}
spring.datasource.password={본인DB's password}
# mybatis config
mybatis.type-aliases-package=com.example.mybatisStudy.vo
mybatis.mapper-locations=mybatis/mapper/**/*.xml소스 분석
spring.datasource.driver-class-name=com.mysql.cj.jdbc.DriverJDBC 드라이버 클래스의 이름 지정 (위 클래스는 MySQL JDBC 드라이버 클래스)
spring.datasource.url=jdbc:mysql://localhost:3306/{본인db명}?serverTimezone=UTC&characterEncoding=UTF-8본인 DB의 IP와 스키마 이름 지정 (나머지는 그대로 사용하고 {본인db명} 부분만 본인 db로 변경)
spring.datasource.username={본인DB's username}
spring.datasource.password={본인DB's password}본인 DB의 username과 password 기입
mybatis.type-aliases-package={mapper resultType}DB의 조회 결과 데이터를 담을 클래스 package 지정 (=resultType)
mybatis.mapper-locations={mapper 경로}mapper가 위치한 경로 설정
Controller
package com.example.mybatisStudy.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import com.example.mybatisStudy.service.MemberService;
import com.example.mybatisStudy.vo.MemberVo;
@Controller
@RequestMapping("/")
public class MemberController {
	
	@Autowired
	private MemberService memberService;
	
	@RequestMapping(value="/index")
	public String index(Model model) {
		
		List<MemberVo> memberList = memberService.getAllMember();
		System.out.println("size: " + memberList.size());
		
		
		model.addAttribute("memberList",memberList);
		return "index";
	}
}List<MemberVo> memberList = memberService.getAllMember();-> MemberVo 객체 리스트를 List형태로 불러온다.
model.addAttribute("memberList",membetList);-> Thymeleaf를 통해 memberList 데이터를 가져와 뿌려주기 위해 Model 사용
Service
// Service.java
package com.example.mybatisStudy.service;
import java.util.List;
import com.example.mybatisStudy.vo.MemberVo;
public interface MemberService {
	public List<MemberVo> getAllMember();
}// ServiceImpl.java
package com.example.mybatisStudy.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.example.mybatisStudy.repository.MemberRepository;
import com.example.mybatisStudy.service.MemberService;
import com.example.mybatisStudy.vo.MemberVo;
@Service
public class MemberServiceImpl implements MemberService{
	
	@Autowired
	private MemberRepository memberRepository;
	
	@Override
	public List<MemberVo> getAllMember(){
		return memberRepository.getAllMember();
	}
}현재 프로젝트는 Mybatis 연동을 위한 단순 기능만을 제공하므로 Service단은 다른 로직 없이 바로 Dao로 넘긴다.
@Override
public List<MemberVo> getAllMember(){
	return memberRepository.getAllMember();
}Repository
package com.example.mybatisStudy.repository;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import com.example.mybatisStudy.vo.MemberVo;
@Mapper
public interface MemberRepository {
	List<MemberVo> getAllMember();
}@Mapper
public interface MemberRepository {
	List<MemberVo> getAllMember();
}기존 Spring MVC는 SqlSession, SqlSessionFactory와 같은 클래스를 통해 설정하고 Dao단에서 selectOne과 같은 함수를 call하여 처리했다.
SpringBoot의 @Mapper를 사용하게 되면 application.properties에서 설정한 경로를 바탕으로 알아서 쿼리 xml 파일과 매핑해주기 때문에 위의 일련의 과정을 생략할 수 있다.
- Vo
package com.example.mybatisStudy.vo;
public class MemberVo {
	private String user_no;
	private String user_nm;
	private String user_id;
	
	
	public String getUser_no() {
		return user_no;
	}
	public void setUser_no(String user_no) {
		this.user_no = user_no;
	}
	public String getUser_nm() {
		return user_nm;
	}
	public void setUser_nm(String user_nm) {
		this.user_nm = user_nm;
	}
	public String getUser_id() {
		return user_id;
	}
	public void setUser_id(String user_id) {
		this.user_id = user_id;
	}
}lombok을 사용해서 코드를 간결히 처리할 수도 있지만 이번 프로젝트는 lombok 사용이 주요 목표가 아니니 getter/setter를 각각 만들어주었다.
- Mybatis 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.mybatisStudy.repository.MemberRepository">
	<select id="getAllMember" resultType="MemberVo">
		SELECT user_no, user_nm, user_id FROM MEMBER_INFO
	</select>
</mapper><?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">위 부분은 Mybatis를 사용하기 위한 기본 설정부분으로 똑같이 기입해주면 된다.
<mapper namespace="com.example.mybatisStudy.dao.MemberDao">
	<select id="getAllMember" resultType="MemberVo">
		SELECT user_no, user_nm, user_id FROM MEMBER_INFO
	</select>
</mapper>namespace부분은 @Mapper와 매핑시키기 위한 경로를 기입하는 부분으로
본인이 @Mapper 어노테이션으로 Mapper를 만들어놓은 경로를 입력해주면 된다.
resultType은 원래 전체 패키지경로를 입력해줘야하지만 앞서 application.properties에서
mybatis.type-aliases-package=com.example.mybatisStudy.vo위와 같이 상위 패키지명을 기입해줬기 때문에 해당 경로 하위 객체명만 기입해주면 된다.
<!DOCTYPE html>
<html>
<head lang="en" xmlns:th="http://thymeleaf.org">
<meta charset="UTF-8">
<style>
	table {
		font-family: arial, sans-serif;
		border-collapse: collapse;
		width: 100%;
	}
	
	td, th{
		border: 1px solid black;
		text-align: left;
	}
	
	tr:nth-child(even){
		background-color:#dddddd;
	}
</style>
<title>Insert title here</title>
	</head>
<body>
	<h1>회원 리스트</h1>
	
	<table>
		<thead>
			<tr>
				<th>회원번호</th>
				<th>아이디</th>
				<th>이름</th>
			</tr>
		</thead>
		
		<tbody>
			<tr th:each="member : ${memberList}">
			 	<td><span th:text="${member.user_no}"></span></td>
				<td><span th:text="${member.user_id}"></span></td>
				<td><span th:text="${member.user_nm}"></span></td>
			</tr>
		</tbody>
	</table>
</body>
</html><tbody>
	<tr th:each="member : ${memberList}">
	 	<td><span th:text="${member.user_no}"></span></td>
		<td><span th:text="${member.user_id}"></span></td>
		<td><span th:text="${member.user_nm}"></span></td>
	</tr>
</tbody>Thymeleaf를 사용하게 되면 Back단에서 Model 객체를 통해 넘긴 값을 바로 받아서 사용할 수 있다.
th:each문을 통해 해당 객체 리스트를 받아오고 th:text를 통해 객체 내부 값을 출력하도록 만든다.
Thymeleaf는 이번 주제와 상관없는 부분이기 때문에 이에 대한 문법은 추후, 따로 작성해보도록 하겠다.


프로그래밍 설계도 있을까요?