스프링
MyBatis
코딩 화이팅
2023. 4. 19. 14:48
- SQL 매핑 프레임워크
- SQL문과 저장프로시저 등의 매핑을 지원하는 퍼시스턴스 프레임워크
- JDBC로 처리하는 상당 부분의 코드와 파라미터 설정 및 결과 처리를 대신해준다.
- Map인터페이스 그리고 자바 POJO를 설정 데이터베이스와 매핑해서 사용할 수 있다.
- XML과 Annoatation 설정을 통해 사용할 수 있다.
Mybatis 구성
환경 설정 파일
- MyBatis 전반에 걸친 세팅
- DB접속 정보 모델 클래스 정보, 매핑정보
Mapper
사용할 SQL문 정의
Mapped Statement
- SqlSession빌드 및 사용
- SQL문 실행
Input/Output
- SQL 실행 시 필요한 데이터
- SQL 실행결과
SqlSessionFactory
- 모든 마이바티스 애플리케이션은 SqlSessionFactory 인스턴스를 사용한다.
- SqlSessionFactory는 SqlSession을 만든다.
SqlSession
데이터베이스에 대해 SQL 명령어를 실행하기 위한 메서드를 포함한다.
MyBatis 설정하기(XML 파일 구조)
밑에 순서대로 설정해줘야됨(굵은 글씨는 필수적 설정)
- configuration
- properties
- settings
- typeAliases
- typeHandlers
- objectFactory
- plugins
- environments
- environment
- transactionManager
- dataSource
- environment
- databaseIdProvider
- mappers
MyBatis 설정하기
mybatis-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${driver}" />
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mapper/boardMapper.xml" />
</mappers>
</configuration>
properties를 사용하여 외부에서 데이터 불러오기
db.proerties
url=jdbc:mysql://localhost:3306/ssafy_board?serverTimezone=UTC
driver=com.mysql.cj.jdbc.Driver
username=ssafy
password=ssafy
====================================================================
mybatis-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 여기서 가져와라잉 -->
<properties resource="config/db.properties"/>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${driver}" />
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mapper/boardMapper.xml" />
</mappers>
</configuration>
mybatis 설정 파일 가져오기
MyAppSqlConfig.java
package com.ssafy.board.config;
import java.io.IOException;
import java.io.Reader;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class MyAppSqlConfig {
private static SqlSession session;
static {
//MyBatis 설정파일을 가져오겠다.
try {
String resource = "config/mybatis-config.xml";
Reader reader = Resources.getResourceAsReader(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
//공장도 다 세웠다.
//세션 팩토리르 이용해서 세션을 얻어오겠다.
session = sqlSessionFactory.openSession(true); //true라는 옵션을 주면 자동으로 커밋이된다.
System.out.println("세션 생성 성공");
} catch (IOException e) {
System.out.println("세션 생성 실패");
}
}
//private한 session을 다른 클래스에서도 사용하기 위해서
public static SqlSession getSession() {
return session;
}
}
연결해보기
MyAppSqlConfig.java
package com.ssafy.board.config;
import java.io.IOException;
import java.io.Reader;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class MyAppSqlConfig {
private static SqlSession session;
static {
//MyBatis 설정파일을 가져오겠다.
try {
String resource = "config/mybatis-config.xml";
Reader reader = Resources.getResourceAsReader(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
//공장도 다 세웠다.
//세션 팩토리르 이용해서 세션을 얻어오겠다.
session = sqlSessionFactory.openSession(true); //true라는 옵션을 주면 자동으로 커밋이된다.
System.out.println("세션 생성 성공");
} catch (IOException e) {
System.out.println("세션 생성 실패");
}
}
public static SqlSession getSession() {
return session;
}
}
====================================================================
boardMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ssafy.board.model.dao.BoardDao">
</mapper>
====================================================================
package com.ssafy.board.test;
import com.ssafy.board.config.MyAppSqlConfig;
import com.ssafy.board.model.dao.BoardDao;
import com.ssafy.board.model.dto.Board;
public class Test {
public static void main(String[] args) {
BoardDao dao = MyAppSqlConfig.getSession().getMapper(BoardDao.class);
}
}
//
세션 생성 성공
MySql과 연결하여 리스트 불러오기
MySql
DROP DATABASE IF EXISTS ssafy_board;
CREATE DATABASE ssafy_board DEFAULT CHARACTER SET utf8mb4;
USE ssafy_board;
CREATE TABLE board (
id INT AUTO_INCREMENT,
writer VARCHAR(20) NOT NULL,
title VARCHAR(50) NOT NULL,
content TEXT,
view_cnt INT DEFAULT 0,
reg_date TIMESTAMP DEFAULT now(),
PRIMARY KEY(id)
);
INSERT INTO board(title, writer, content)
VALUES ("BackEnd 너두 마슷허","양씨","너도 할 수 있어"),
("누르지마시오", "따봉맨", "아무내용없음"),
("대답잘하는 법", "송소연", "채팅 잘치면됨 네(필쑤)");
SELECT * FROM board;
commit;
java
BoardDao.java
package com.ssafy.board.model.dao;
import java.util.List;
import com.ssafy.board.model.dto.Board;
public interface BoardDao {
// 전체 게시글을 몽땅 들고 오쎄용
public List<Board> selectAll();
// ID에 해당하는 게시글 하나 가져오기
public Board selectOne(int id);
// 게시글 등록
public void insertBoard(Board board);
// 게시글 삭제
public void deleteBoard(int id);
// 게시글 수정
public void updateBoard(Board board);
// 조회수 증가
public void updateViewCnt(int id);
}
=====================================================================
boardMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ssafy.board.model.dao.BoardDao">
<!-- 전체글 조회 -->
<select id="selectAll" resultType="Board">
<!-- resultType안에는 넘겨 받은 거 받을 바구니를 써야됨 -->
SELECT id, content, writer, title, view_cnt as viewCnt, date_format(reg_date, '%y-%m-%d %H:%i:%s') as regDate
FROM board;
</select>
</mapper>
=====================================================================
mybatis-confin.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 여기서 가져와라잉 -->
<properties resource="config/db.properties"/>
<!-- typeAliases를 사용하여 간단한 아이디를 지정하여 쉽게 불러줄 수 있다. -->
<typeAliases>
<typeAlias type="com.ssafy.board.model.dto.Board" alias="Board"/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${driver}" />
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mapper/boardMapper.xml" />
</mappers>
</configuration>
=====================================================================
package com.ssafy.board.test;
import com.ssafy.board.config.MyAppSqlConfig;
import com.ssafy.board.model.dao.BoardDao;
import com.ssafy.board.model.dto.Board;
public class Test {
public static void main(String[] args) {
BoardDao dao = MyAppSqlConfig.getSession().getMapper(BoardDao.class);
for (Board b : dao.selectAll()) {
System.out.println(b);
}
}
}
//
세션 생성 성공
Board [id=1, title=BackEnd 너두 마슷허, writer=양씨, content=너도 할 수 있어, regDate=23-04-19 13:38:05, viewCnt=0]
Board [id=2, title=누르지마시오, writer=따봉맨, content=아무내용없음, regDate=23-04-19 13:38:05, viewCnt=0]
Board [id=3, title=대답잘하는 법, writer=송소연, content=채팅 잘치면됨 네(필쑤), regDate=23-04-19 13:38:05, viewCnt=0]
MySql과 연결하여 글 하나 불러오기
나머지 코드는 위와 동일
boardMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ssafy.board.model.dao.BoardDao">
<resultMap type="Board" id="boardMap">
<result column="id" property="id"/>
<result column="writer" property="writer"/>
<result column="title" property="title"/>
<result column="content" property="content"/>
<result column="view_cnt" property="viewCnt"/>
<result column="reg_date" property="regDate"/>
</resultMap>
<!-- 상세글 조회 -->
<select id="selectOne" parameterType="int" resultMap="boardMap">
위에 전체글 조회처럼 resultType="Board"라고 써도 되고
위에 <resultMap>을 지정해줘서 resultMap에 아이디를 써서
view_cnt as viewCnt, date_format(reg_date, '%y-%m-%d %H:%i:%s') as regDate
위의 이 부분을 as를 빼고 작성해줄 수 있다.
parameterType부분에 위의 인터페이스에서의 파라미터 안에 int를 넣어줘야한다.
SELECT id, content, writer, title, view_cnt, date_format(reg_date, '%y-%m-%d') as reg_date
FROM board
WHERE id = #{id};
들어가는 반환값의 id인 값을->WHERE
</select>
</mapper>
==================================================================
Test.java
package com.ssafy.board.test;
import com.ssafy.board.config.MyAppSqlConfig;
import com.ssafy.board.model.dao.BoardDao;
import com.ssafy.board.model.dto.Board;
public class Test {
public static void main(String[] args) {
BoardDao dao = MyAppSqlConfig.getSession().getMapper(BoardDao.class);
System.out.println(dao.selectOne(1));
}
}
//
세션 생성 성공
Board [id=1, title=BackEnd 너두 마슷허, writer=양씨, content=너도 할 수 있어, regDate=23-04-19, viewCnt=0]
글 작성
나머지 코드는 위와 동일
boardMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ssafy.board.model.dao.BoardDao">
<resultMap type="Board" id="boardMap">
<result column="id" property="id"/>
<result column="writer" property="writer"/>
<result column="title" property="title"/>
<result column="content" property="content"/>
<result column="view_cnt" property="viewCnt"/>
<result column="reg_date" property="regDate"/>
</resultMap>
<!-- 게시글 등록 -->
<insert id="insertBoard" parameterType="Board">
INSERT INTO board (title, writer, content)
VALUES (#{title}, #{writer}, #{content})
</insert>
</mapper>
=====================================================================
Test.java
package com.ssafy.board.test;
import com.ssafy.board.config.MyAppSqlConfig;
import com.ssafy.board.model.dao.BoardDao;
import com.ssafy.board.model.dto.Board;
public class Test {
public static void main(String[] args) {
BoardDao dao = MyAppSqlConfig.getSession().getMapper(BoardDao.class);
Board board = new Board("이거 되나요요요요 ??", "이종민", "select * ....");
dao.insertBoard(board);
for (Board b : dao.selectAll()) {
System.out.println(b);
}
}
}
//
세션 생성 성공
Board [id=1, title=BackEnd 너두 마슷허, writer=양씨, content=너도 할 수 있어, regDate=23-04-19 13:38:05, viewCnt=0]
Board [id=2, title=누르지마시오, writer=따봉맨, content=아무내용없음, regDate=23-04-19 13:38:05, viewCnt=0]
Board [id=3, title=대답잘하는 법, writer=송소연, content=채팅 잘치면됨 네(필쑤), regDate=23-04-19 13:38:05, viewCnt=0]
Board [id=4, title=이거 되나요요요요 ??, writer=이종민, content=select * ...., regDate=23-04-19 14:20:47, viewCnt=0]
글 삭제
나머지 코드는 위와 동일
boardMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ssafy.board.model.dao.BoardDao">
<resultMap type="Board" id="boardMap">
<result column="id" property="id"/>
<result column="writer" property="writer"/>
<result column="title" property="title"/>
<result column="content" property="content"/>
<result column="view_cnt" property="viewCnt"/>
<result column="reg_date" property="regDate"/>
</resultMap>
<!-- 게시글 삭제 -->
<delete id="deleteBoard" parameterType="int">
DELETE FROM board
WHERE id = #{id}
</delete>
</mapper>
====================================================================
Test.java
package com.ssafy.board.test;
import com.ssafy.board.config.MyAppSqlConfig;
import com.ssafy.board.model.dao.BoardDao;
import com.ssafy.board.model.dto.Board;
public class Test {
public static void main(String[] args) {
BoardDao dao = MyAppSqlConfig.getSession().getMapper(BoardDao.class);
dao.deleteBoard(1);
for (Board b : dao.selectAll()) {
System.out.println(b);
}
}
}
//
세션 생성 성공
Board [id=2, title=누르지마시오, writer=따봉맨, content=아무내용없음, regDate=23-04-19 13:38:05, viewCnt=0]
Board [id=3, title=대답잘하는 법, writer=송소연, content=채팅 잘치면됨 네(필쑤), regDate=23-04-19 13:38:05, viewCnt=0]
Board [id=4, title=이거 되나요요요요 ??, writer=이종민, content=select * ...., regDate=23-04-19 14:20:47, viewCnt=0]
조회수 늘리기
나머지 코드는 위와 동일
boardMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ssafy.board.model.dao.BoardDao">
<resultMap type="Board" id="boardMap">
<result column="id" property="id"/>
<result column="writer" property="writer"/>
<result column="title" property="title"/>
<result column="content" property="content"/>
<result column="view_cnt" property="viewCnt"/>
<result column="reg_date" property="regDate"/>
</resultMap>
<!-- 조회수 증가 -->
<update id="updateViewCnt" parameterType="int">
UPDATE board
SET view_cnt = view_cnt+1
WHERE id = #{id}
</update>
</mapper>
==================================================================
Test.java
package com.ssafy.board.test;
import com.ssafy.board.config.MyAppSqlConfig;
import com.ssafy.board.model.dao.BoardDao;
import com.ssafy.board.model.dto.Board;
public class Test {
public static void main(String[] args) {
BoardDao dao = MyAppSqlConfig.getSession().getMapper(BoardDao.class);
dao.updateViewCnt(4);
for (Board b : dao.selectAll()) {
System.out.println(b);
}
}
}
//
세션 생성 성공
Board [id=2, title=누르지마시오, writer=따봉맨, content=아무내용없음, regDate=23-04-19 13:38:05, viewCnt=0]
Board [id=3, title=대답잘하는 법, writer=송소연, content=채팅 잘치면됨 네(필쑤), regDate=23-04-19 13:38:05, viewCnt=0]
Board [id=4, title=이거 되나요요요요 ??, writer=이종민, content=select * ...., regDate=23-04-19 14:20:47, viewCnt=2]
실행할수록 조회수가 하나씩 늘어남
게시글 수정
나머지 코드는 위와 동일
boardMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ssafy.board.model.dao.BoardDao">
<resultMap type="Board" id="boardMap">
<result column="id" property="id"/>
<result column="writer" property="writer"/>
<result column="title" property="title"/>
<result column="content" property="content"/>
<result column="view_cnt" property="viewCnt"/>
<result column="reg_date" property="regDate"/>
</resultMap>
<!-- 게시글 수정 -->
<!-- 지금 게시글 날짜는 등록 날짜만 존재한다. 나중에 수정날짜도 같이 관리하게 된다면의 상황을보자ㅏ... -->
<update id="updateBoard" parameterType="Board">
UPDATE board
SET title = #{title}, content=#{content}, reg_date = now()
reg_date를 now()하며 수정한 시간까지 초기화해줄 수 있다.
WHERE id=#{id}
</update>
</mapper>
===================================================================
Test.java
package com.ssafy.board.test;
import com.ssafy.board.config.MyAppSqlConfig;
import com.ssafy.board.model.dao.BoardDao;
import com.ssafy.board.model.dto.Board;
public class Test {
public static void main(String[] args) {
BoardDao dao = MyAppSqlConfig.getSession().getMapper(BoardDao.class);
Board bb = dao.selectOne(3);
bb.setTitle("대답잘하는법 공유해드림");
bb.setContent("채팅 뿐만아니라 열정도 있어야함.");
dao.updateBoard(bb);
for (Board b : dao.selectAll()) {
System.out.println(b);
}
}
}
//
세션 생성 성공
Board [id=2, title=누르지마시오, writer=따봉맨, content=아무내용없음, regDate=23-04-19 13:38:05, viewCnt=0]
Board [id=3, title=대답잘하는법 공유해드림, writer=송소연, content=채팅 뿐만아니라 열정도 있어야함., regDate=23-04-19 14:41:35, viewCnt=0]
Board [id=4, title=이거 되나요요요요 ??, writer=이종민, content=select * ...., regDate=23-04-19 14:20:47, viewCnt=2]