4 ๋ถ„ ์†Œ์š”

๐Ÿ“š MYBATIS


๐Ÿ“š MYBATIS

MYBATIS ๋ž€

MyBatis๋Š” Java Object ( DAO )์™€ SQL๋ฌธ ์‚ฌ์ด์˜ ์ž๋™ Mapping ๊ธฐ๋Šฅ์„ ์ง€์›ํ•˜๋Š” Persistence Framework ์ด๋‹ค.
( ์ง€์†์„ฑ ํ”„๋ ˆ์ž„ ์›Œํฌ : ์ž๋ฃŒ๋ฅผ DB์— ์ €์žฅํ•˜๋Š” ๊ณผ์ •์„ ๋„์™€์ฃผ๊ณ  ์ž๋™ํ™”ํ•˜๋Š” ๋งค๊ฐœ SW) , SQL Mapper๋ผ๊ณ ๋„ ๋ถˆ๋ฆฐ๋‹ค.


SQL๋ฌธ์„ ๋ณ„๋„์˜ ํŒŒ์ผ๋กœ ๋ถ„๋ฆฌํ•ด์„œ ๊ด€๋ฆฌํ•œ๋‹ค.

Object (DAO) - SQL๋ฌธ ์‚ฌ์ด์˜ parameter mapping ์ž‘์—…์„ ์ž๋™์œผ๋กœ ํ•ด์ค€๋‹ค.

MyBatis๋Š” Hibernate๋‚˜ JPA์™€ ๊ฐ™์€ ์ƒˆ๋กœ์šด DB ํ”„๋กœ๊ทธ๋ž˜๋ฐ ํŒจ๋Ÿฌ๋‹ค์ž„์„ ์ตํ˜€์•ผ ํ•˜๋Š” ๋ถ€๋‹ด ์—†์ด ๊ฐœ๋ฐœ์ž๊ฐ€ ์ต์ˆ™ํ•œ SQL์„ ๊ทธ๋Œ€๋กœ ์ด์šฉํ•˜๋ฉด์„œ JDBC ์ฝ”๋“œ ์ž‘์„ฑ์˜ ๋ถˆํŽธํ•จ์„ ์ œ๊ฑฐํ•ด์ฃผ๊ณ  ๋„๋ฉ”์ธ ๊ฐ์ฒด๋‚˜ VO ๊ฐ์ฒด๋ฅผ ์ค‘์‹ฌ์œผ๋กœ ๊ฐœ๋ฐœ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ด์ค€๋‹ค.

MYBATIS ํŠน์ง•



MyBatis๋Š” DAO์™€ JDBC ์‚ฌ์ด์— ์œ„์น˜ํ•ด์„œ ์„œ๋กœ๋ฅผ ๋งคํ•‘ํ•ด์ค€๋‹ค.
๋ฐ‘์—์„œ ์–˜๊ธฐํ•  MyBatis-Spring๋„ ๊ฐ™์€ ์œ„์น˜์— ์กด์žฌํ•œ๋‹ค. ( Repository (Mapper) - JDBC )

MYBATIS ๋™์ž‘๊ณผ์ •


  1. MyBatis Config ํŒŒ์ผ์„ ์ฝ์–ด SqlSessionFactoryBuilder ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.
  2. SqlSessionFactoryBuilder ๊ฐ์ฒด๋ฅผ ์ด์šฉํ•ด SqlSessionFactory ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.
  3. ์•ฑ ์‹คํ–‰ ์ค‘์— CRUD ์ฒ˜๋ฆฌ๊ฐ€ ๋“ค์–ด์˜ค๋ฉด SqlSessionFactory๋กœ SqlSession ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.
  4. SqlSession ๊ฐ์ฒด๋ฅผ ์ด์šฉํ•ด DB ์š”์ฒญ์„ ํ•œ ํ›„ ๊ฒฐ๊ณผ๊ฐ’์„ ๋ฐ›์•„์˜จ๋‹ค.
    MyBatis Config๋Š” XML๋กœ ์ž‘์„ฑํ•œ๋‹ค. ํŒŒ์ผ์—๋Š” 4๊ฐ€์ง€ ์ •๋ณด๋ฅผ ์„ค์ •ํ•œ๋‹ค.
    ๊ทธ๋ฆฌ๊ณ  dtd ( ๋ฌธ์„œ ํ˜•์‹ ์ •์˜ )๊ฐ€ ๋˜์–ด์žˆ์œผ๋ฏ€๋กœ ์ˆœ์„œ๋Œ€๋กœ ์ ์–ด์•ผ ํ•œ๋‹ค.
    • properties
      ํ”„๋กœํผํ‹ฐ ํŒŒ์ผ์„ ์ •์˜
    • typeAliases
      mapper.xml์—์„œ ์‚ฌ์šฉํ•  alias ์„ค์ • ( ์งง์€ ๋‹จ์–ด๋กœ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด )
    • environments
      DB ์ •๋ณด๋ฅผ ์„ค์ •
    • mapper
      ์–ด๋–ค XMl ํŒŒ์ผ์ด mapper ํŒŒ์ผ์ธ์ง€ ์„ค์ •


mybatis-config.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="dbinfo.properties"/>

	<typeAliases>
		<typeAlias type="com.test.guestbook.model.MemberDto" alias="member" />
		<typeAlias type="com.test.guestbook.model.GuestBookDto" alias="guestbook" />
		<typeAlias type="com.test.guestbook.model.FileInfoDto" alias="fileinfo" />
	</typeAliases>
	
	<environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
            <!-- value ๊ฐ’๋“ค์€ ์œ„์—์„œ ๊ฐ€์ ธ์˜จ dbinfo.properties์— ์žˆ๋‹ค -->
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${dbid}"/>
                <property name="password" value="${dbpwd}"/>
            </dataSource>
        </environment>
    </environments>
    
    <mappers>
		<mapper resource="guestbook.xml" />
		<mapper resource="member.xml" />
	</mappers>
	
</configuration>


dbinfo.properties

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/testweb?serverTimezone=UTC&useUniCode=yes&characterEncoding=UTF-8
dbid=root
dbpwd=1234


mapper์—์„œ ์ •์˜ํ•œ member.xml ๋งคํผ ํŒŒ์ผ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

member.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"> 

<!-- 1. ์–ด๋””์„œ ์‚ฌ์šฉํ•  ๊ฒƒ์ธ๊ฐ€ ๋ช…์‹œ ( guestbook์—๋„ register๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ๋‹ค ) -->
<mapper namespace="com.test.guestbook.model.dao.MemberDao">

<!-- 2. id๋Š” ๋ฉ”์„œ๋“œ์˜ ์ด๋ฆ„ , 3. parameterType์€  config์—์„œ alias ํ•ด์ค€ ํŒŒ์ผ ( Dto ์—ฐ๊ฒฐ ) -->
<!-- 4. query ๋ฌธ์„ ๋งŒ๋“ค์–ด ์ค€๋‹ค. ์˜ˆ์ „PreparedStatement ์— ๋“ค์–ด๊ฐˆ ๊ฐ’๋“ค์€  #{} ๋กœ ๋Œ€์ฒดํ•˜๊ณ  , getter. setter์˜ property๋กœ ์„ค์ •ํ•˜๋ฉด ๋œ๋‹ค
		values ๊ฐ’๋“ค์€ getter๊ฐ€ ๋œ๋‹ค.	
		-->
	<insert id="registerMember" parameterType="member">
	insert into test_member (userid, username, userpwd, email, joindate)
	<!-- dto๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” property -->
	values(#{userId}, #{userName}, #{userPwd}, #{email}, now())
	</insert>

<!-- java๊ฐ€ ์ œ๊ณตํ•ด์ฃผ๋Š” wrapper class๋Š” ๋งจ์ฒซ๊ธ€์ž๋ฅผ ์†Œ๋ฌธ์ž๋กœ ๋ฐ”๊พธ๋ฉด ๋œ๋‹ค -->
<!-- ์–ป์–ด์˜จ๊ฑฐ ์žˆ์œผ๋ฉด ์ „๋‹ฌ - resultType -->
<!-- select ์˜†์— ๊ฐ’๋“ค์€ setter ๊ฐ€ ๋œ๋‹ค. -->
	<select id="login" parameterType="map" resultType="member">
	<!-- ์ด๋ฆ„์ด ๋‹ค๋ฅด๋ฉด as ์ค˜์•ผํ•œ๋‹ค ( form, dto, db ) -->
	select username, userid, email
	from test_member
	<!-- map์˜ key ๊ฐ’ -->
	where userid = #{userId} and userpwd = #{userPwd}
	</select>

</mapper>


๋‹ค์Œ์€ SqlSessionFactoryBuilder ์™€ SqlSessionFactory ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์ฝ”๋“œ์ด๋‹ค.

์œ„์˜ MyBatis ์„ค์ • ํŒŒ์ผ์„ ์ฝ์–ด SqlSessionFactoryBuilder ๋ฅผ ์ƒ์„ฑํ•œ ํ›„ ์ด๊ฒƒ์œผ๋กœ SqlSessionFactory ๋ฅผ ์ƒ์„ฑํ•˜์—ฌ SqlSession ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ด ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค.
SqlMapConfig.java

public class SqlMapConfig {
	
	private static SqlSessionFactory factory;

	// ํŒฉํ† ๋ฆฌ ์ƒ์„ฑ 
	static {
		try {
			String resource = "mybatis-config.xml";
			Reader reader = Resources.getResourceAsReader(resource);
			factory = new SqlSessionFactoryBuilder().build(reader);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	// sql ์„ธ์…˜์„ ๋งŒ๋“ค์–ด ๋‚ธ๋‹ค
	public static SqlSession getSqlSession() {
		return factory.openSession();
	}
	
}


์‹ค์ œ SqlSession ๋ฉ”์„œ๋“œ๋ฅผ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ mapper id ์™€ mapper ํŒŒ๋ผ๋ฏธํ„ฐ ๋ฅผ ๋„˜๊ธด๋‹ค.
MemberDaoImpl.java

@Repository
public class MemberDaoImpl implements MemberDao {

	private final String NAMESPACE = "com.test.guestbook.model.dao.MemberDao.";

// mapper.xml ์—์„œ id๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค. 
	@Override
	public void registerMember(MemberDto memberDto) throws SQLException {
		// sqlmapconfig์— ์žˆ๋˜ ๊ฑฐ ์‚ฌ์šฉ
		try (SqlSession sqlSession = SqlMapConfig.getSqlSession()) {
			sqlSession.insert(NAMESPACE + "registerMember", memberDto);
			sqlSession.commit();
		}
	}

	@Override
	public MemberDto login(Map<String, String> map) throws SQLException {
		try (SqlSession sqlSession = SqlMapConfig.getSqlSession()) {
			return sqlSession.selectOne(NAMESPACE + "login", map);
		}
	}
}

MyBatis - Spring ๋ž€

MyBatis-Spring์€ MyBatis๋ฅผ Spring Framework์— ๋…น์—ฌ๋‚ด ์ข€ ๋” ์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•˜๊ณ ์žํ•˜๋Š” ์—ฐ๋™ ๋ชจ๋“ˆ์ด๋‹ค.

MyBatis-Spring์—์„œ๋Š” Spring Framework์˜ Bean ์œผ๋กœ SqlSessionFactoryBean๊ณผ SqlSession์„ ๋“ฑ๋กํ•œ๋‹ค.
SqlSessionTemplate ๋Š” SqlSession์˜ ๊ตฌํ˜„์ฒด ์ด๋‹ค.


root-context.xml

<!-- ๋ฐ‘์— ๊ณผ์ •์€ SqlMapConfig.java์—์„œ ์ง„ํ–‰๋˜๋˜ ๊ณผ์ •
	๋จผ์ € mybatis-config.xml์„ ๋ฐ›์•„์™€ factory๋ฅผ ๋งŒ๋“ค๊ณ  ๊ทธ factory๋ฅผ ์ด์šฉํ•ด sql ์„ธ์…˜์„ ๋งŒ๋“ค์–ด ๋‚ธ๋‹ค.
	mybatis-config.xml ์—์„œ๋Š” db ์—ฐ๊ฒฐ๊ณผ ์“ธ ํŒŒ์ผ ์„ค์ •, alias ๋“ฑ์„ ์ง„ํ–‰ํ•œ๋‹ค.
	๊ทธ๊ฒƒ์„ ๋‹ค ๋ฐ‘์— ๊ตฌํ˜„ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ธฐ์กด SqlMapConfig.java์™€ mybatis-config.xml๋Š” ์—†์–ด๋„ ๋œ๋‹ค.
 	-->

	<!-- mybatis-config.xml ์—์„œ enviornments ๋ถ€๋ถ„ -->
	<bean id="ds" class="org.springframework.jndi.JndiObjectFactoryBean">
		<property name="jndiName" value="java:comp/env/jdbc/ssafy"></property>
	</bean>


	<!-- mybatis -->
	<!-- SqlMapConfig.java ๋ถ€๋ถ„ ์ƒ์„ฑ -->
	<!-- factory ๋งŒ๋“ค์–ด์ฃผ๊ธฐ -->
	<bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
		<!-- ์œ„์— ์„ ์–ธํ•œ ds ์ฐธ์กฐ -->
		<property name="dataSource" ref="ds" />
		<!-- mybatis-config.xml ์—์„œ mappers ๋ถ€๋ถ„ -->
		<!-- mapper๋ผ๋Š” ํด๋” ๋ฐ‘์— ๋ชจ๋“  xml์„ ์ฝ์–ด ์˜ค๊ฒ ๋‹ค 	mapper๊ฐ€ ์–ด๋”จ๋Š๋ƒ~	-->
		<property name="mapperLocations" value="classpath:mapper/*.xml" />
		
		<!-- mybatis-config.xml ์—์„œ typeAliases ๋ถ€๋ถ„ -->
		<!-- config๊ฐ€ ์–ด๋”จ๋Š๋ƒ~  -->
		<!-- ํด๋” ๊ฒฝ๋กœ ์ง€์ •ํ•ด์„œ ์—ฐ๊ฒฐ -->
		<!-- <property name="configLocation" value="classpath:mybatis-config.xml"/> -->
		<!-- ์—ฌ๊ธฐ์„œ package ์„ ์–ธ -> mybatis-config.xml๊ฐ€ ์—†์–ด๋„๋œ๋‹ค -->
		<property name="typeAliasesPackage" value="com.ssafy.guestbook.model"/>
	</bean>
	
	<!-- SqlMapConfig.java ๋ถ€๋ถ„ ์ƒ์„ฑ -->
	<!-- default ๊ฐ’์ด ์—†์–ด์„œ ๋ฐ˜๋“œ์‹œ ์ƒ์„ฑ์ž๋ฅผ ๊ฐ€์ ธ๊ฐ€์•ผํ•œ๋‹ค -->
	<!-- factory๋ฅผ ๊ฐ€์ง€๊ณ  SqlSession์„ ๋งŒ๋“ค์–ด๋ผ -->
	<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
		<constructor-arg ref="sqlSessionFactoryBean"/>
	</bean>


mapper ์„ค์ • ํŒŒ์ผ

member.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.test.guestbook.model.mapper.MemberMapper">

	<insert id="registerMember" parameterType="MemberDto">
		insert into ssafy_member (userid, username, userpwd, email, joindate)
		values (#{userId}, #{userName}, #{userPwd}, #{email}, now())
	</insert>

	<select id="login" parameterType="map" resultType="MemberDto">
		select username, userid, email
		from ssafy_member
		where userid = #{userId} and userpwd = #{userPwd}
	</select>
	
</mapper>


์ด์ œ ์ค€๋น„๋ฅผ ๋‹ค ๋งˆ์น˜๊ณ  mapper interface์— ๊ฐ์ฒด๋ฅผ ๊ตณ์ด ๊ตฌํ˜„ ์•ˆํ•˜๊ณ  ๋งŒ๋“ค์–ด์ฃผ๋Š” ์ด์œ ๋Š” ํ•ด๋‹น interface๊ฐ€ ๋งคํ•‘๋˜๋Š” mapper.xml์„ ์•Œ์•„์„œ ์ฐพ์•„์ค€๋‹ค.

MemberMapper.java

public interface MemberMapper {

	int idCheck(String id) throws Exception;
	void registerMember(MemberDto memberDto) throws Exception;
	MemberDto login(Map<String, String> map) throws Exception;
}