MYBATIS
๐ 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 ํน์ง
-
์ฌ์ด ์ ๊ทผ์ฑ๊ณผ ๊ฐ๊ฒฐํ ์ฝ๋
- ๊ฐ์ฅ ๊ฐ๋จํ persistence framework
- JDBC์ ๋ชจ๋ ๊ธฐ๋ฅ์ ์ ๊ณต
- ์๋์ ์ธ parameter ์ค์ ๊ณผ Query ๊ฒฐ๊ณผ์ ๋ํ mapping ๊ตฌ๋ฌธ์ ์ ๊ฑฐ
-
SQL๋ฌธ๊ณผ ํ๋ก๊ทธ๋๋ฐ ์ฝ๋์ ๋ถ๋ฆฌ
- SQL์ ๋ณ๊ฒฝ์ด ์์ ๋๋ง๋ค ์๋ฐ ์ฝ๋๋ฅผ ์์ ํ๊ฑฐ๋ ์ปดํ์ผ ํ์ง ์์๋ ๋จ
- ํ์ ํ ๋ DBA๊ฐ SQL์ ์ ๊ฒํ๊ธฐ ์ ์ฉํ๋ค.
-
๋ค์ํ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด๋ก ๊ตฌํ๊ฐ๋ฅ
- JAVA, C#, .NET, Ruby โฆ
MyBatis๋ DAO์ JDBC ์ฌ์ด์ ์์นํด์ ์๋ก๋ฅผ ๋งคํํด์ค๋ค.
๋ฐ์์ ์๊ธฐํ MyBatis-Spring๋ ๊ฐ์ ์์น์ ์กด์ฌํ๋ค. ( Repository (Mapper) - JDBC )
MYBATIS ๋์๊ณผ์
- MyBatis Config ํ์ผ์ ์ฝ์ด SqlSessionFactoryBuilder ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ค.
- SqlSessionFactoryBuilder ๊ฐ์ฒด๋ฅผ ์ด์ฉํด SqlSessionFactory ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ค.
- ์ฑ ์คํ ์ค์ CRUD ์ฒ๋ฆฌ๊ฐ ๋ค์ด์ค๋ฉด SqlSessionFactory๋ก SqlSession ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ค.
- SqlSession ๊ฐ์ฒด๋ฅผ ์ด์ฉํด DB ์์ฒญ์ ํ ํ ๊ฒฐ๊ณผ๊ฐ์ ๋ฐ์์จ๋ค.
MyBatis Config๋ XML๋ก ์์ฑํ๋ค. ํ์ผ์๋ 4๊ฐ์ง ์ ๋ณด๋ฅผ ์ค์ ํ๋ค.
๊ทธ๋ฆฌ๊ณ dtd ( ๋ฌธ์ ํ์ ์ ์ )๊ฐ ๋์ด์์ผ๋ฏ๋ก ์์๋๋ก ์ ์ด์ผ ํ๋ค.-
properties
ํ๋กํผํฐ ํ์ผ์ ์ ์ -
typeAliases
mapper.xml์์ ์ฌ์ฉํ alias ์ค์ ( ์งง์ ๋จ์ด๋ก ์ฌ์ฉํ๊ธฐ ์ํด ) -
environments
DB ์ ๋ณด๋ฅผ ์ค์ -
mapper
์ด๋ค XMl ํ์ผ์ด mapper ํ์ผ์ธ์ง ์ค์
-
properties
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;
}