스프링 #2 마이바티스(MyBatis)

ednadev·2020년 8월 11일
1

Web 2. Spring Framework

목록 보기
4/13

퍼시스턴스 프레임워크
JDBC 코드와 수동으로 셋팅하는 파라미터와 결과 매핑을 제거한다.
Spring JDBC Framework 대신 한국에서 많이 사용한다.

MyBatis Products에서 MyBatis 3, Spring을 다운로드 받는다.

mybatis-3.5.5.zip은 말그대로 마이바티스! 최신버전을 다운로드한다.

mybatis-spring-1.3.2.zip은 마이바티스랑 DI를 연결할 때 필요하다.

DB 구축

CREATE TABLE users ( 
    user_id VARCHAR(10) PRIMARY KEY,
    user_name VARCHAR(10) NOT NULL,
    password VARCHAR(10) NOT NULL,
    age INT(3),
    grade INT(3),
    reg_date DATE  
);

INSERT INTO users VALUES('user01','홍길동','user01',10,1,'2019-10-11'); 
INSERT INTO users VALUES('user02','이순신','user02',20,2, '2019-10-12');
INSERT INTO users VALUES('user03','김유신','user03',30,3, '2019-10-09'); 
INSERT INTO users VALUES('mybatis01','홍길동iba','mybatis01',10,1,'2019-10-08');
INSERT INTO users VALUES('mybatis02','이순신iba','mybatis02',20,2, '2019-10-07');
INSERT INTO users VALUES('mybatis03','김유신iba','mybatis03',30,3,'2019-10-02');

VO 생성

public class User {
    private String userId, userName, password;
    private int age, grade;
    private Timestamp regDate = new Timestamp(new Date().getTime());
    
    public User() {}
    public User(String userId, String password) {
	this.userId = userId;
	this.password = password;
    }
    
    public User(String userId, String userName, String password, int age, int grade) {
	this.userId = userId;
	this.userName = userName;
	this.password = password;
	this.age = age;
	this.grade = grade;
    }

    //getter, setter
    
    //toString
}

MyBatis에서는 값을 Setter로 받는다. 기본 생성자만 있으면 된다.
VO에서 생성자를 아예 생성하지 않으면 기본 생성자가 자동으로 생성된다.

DB 서버 정보

dbconn.properties

jdbc.mysql.driver=com.mysql.cj.jdbc.Driver
jdbc.mysql.url=jdbc:mysql://127.0.0.1:3306/scott?characterEncoding=UTF-8&serverTimezone=UTC
jdbc.mysql.username=root
jdbc.mysql.password=1234

Mapper 작성

sql을 xml 기반으로 mapping

<?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="UserMapper">
    <!-- INSERT, UPDATE, DELETE, SELECT 작성 -->
</mapper>

INSERT, UPDATE, DELETE

<insert id="addUser" parameterType="user">
    INSERT INTO users(user_id, user_name, password, age, grade, reg_date)
    VALUES(#{userId}, #{userName}, #{password}, #{age}, #{grade}, #{regDate})
</insert>
	
<update id="updateUser" parameterType="user">
    UPDATE users
    SET user_name=#{userName}
    WHERE user_id=#{userId}
</update>
	
<delete id="removeUser" parameterType="string">
    DELETE FROM users
    WHERE user_id=#{value}
</delete>

SELECT

<select id="getUserList" resultType="user">
    SELECT
        user_id as userId,
	user_name as userName,
	password, age, grade,
	reg_date as regDate
    FROM users
</select>
<select id="getUser" resultType="user" parameterType="string">
    SELECT
	user_id as userId,
	user_name as userName,
	password, age, grade,
	reg_date as regDate
    FROM users
    WHERE user_id LIKE '%${value}%'
</select>
<select id="findUserId" resultType="user" parameterType="user">
    SELECT * FROM users
    WHERE user_id = #{userId} AND password = #{password}
</select>
  1. 파라미터 타입이 vo면 getter를 사용한다.
    파라미터 타입이 vo가 아니라면 value를 사용한다.

  2. 클래스의 alias를 사용 : string, int, list

ResultMap

SELECT 쿼리문에서만 사용

<resultMap type="user" id="userSelectRM">
    <result property="userId" column="user_id"/>
    <result property="userName" column="user_name"/>
    <result property="regDate" column="reg_date"/>
</resultMap>
<select id="getUserList" resultMap="userSelectRM">
    SELECT * FROM users
</select>

동적 쿼리 (Dynamic Query)

SELECT문에서 where절 조건을 어떻게 주느냐에 따라
서로 다른 select문이 만들어지는 쿼리

<select id="getUserList" parameterType="user" resultMap="userSelectRM">
    SELECT * FROM users
    <where>
	<if test="userName != null">
	    user_name LIKE #{userName}
	</if>
	<if test="age != null">
	    OR age LIKE #{age}
	</if>
    </where>
    ORDER BY user_id DESC
</select>

SQL 구문 재사용 : sql, include

<sql id="select-users">
    SELECT * FROM users
</sql>
<sql id="orderby-userid-desc">
    ORDER BY user_id DESC
</sql>
	
<select id="getUserList" parameterType="user" resultMap="userSelectRM">
    <include refid="select-users"/>
    <where>
        <if test="userName != null">
	    user_name LIKE #{userName}
	</if>
	<if test="age != null">
	    OR age LIKE #{age}
	</if>
    </where>
    <include refid="orderby-userid-desc"/>
</select>
<select id="getUser" resultMap="userSelectRM" parameterType="string">
    <include refid="select-users"/>
    WHERE user_id LIKE '%${value}%'
</select>

SqlMapConfig.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>
    <!-- wiring 및 설정 -->
</configuration>

Wiring : dbconn.properties

DB 서버 정보(driver, url, username, password)

<properties resource="config/dbconn.properties"/>

settings

<settings>
    <setting name="jdbcTypeForNull" value="NULL"/>
</settings>

Oracle인 경우 null값을 허용하지 않기에 반드시 옵션을 추가해야 실행
settings 태그의 위치와 NULL 값을 대문자로 입력해야 한다.

<settings>
    <setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>

Wiring : VO

<typeAliases>
    <typeAlias type="com.mybatis.domain.User" alias="user"/>
</typeAliases>

DB 서버 정보 등록

<environments default="development">
    <environment id="development">
	<transactionManager type="JDBC"/>
 	<dataSource type="UNPOOLED">
 	    <property name="driver" value="${jdbc.mysql.driver}"/>
 	    <property name="url" value="${jdbc.mysql.url}"/>
 	    <property name="username" value="${jdbc.mysql.username}"/>
 	    <property name="password" value="${jdbc.mysql.password}"/>
 	</dataSource>
    </environment>
</environments>

environments - environment - dataSource type
UNPOOLED : DriverManager 방식
POOLED : JNDI = DataSource 방식 - main에서 못 돌린다

마이바티스 단위테스트 할때만 사용되므로 필수적인 것은 아니다.

Wiring : SQL 쿼리문

<mappers>
    <mapper resource="mapper/mybatis-userservice-mapping.xml"/>
</mappers>

TEST

//1. SqlMapConfig.xml을 읽어들인다.
Reader r = Resources.getResourceAsReader("config/SqlMapConfig.xml");

//2. SqlSessionFactory를 리턴받는다.
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(r);

//3. SqlSession를 리턴받는다.
SqlSession session = factory.openSession();

MyBatis 라이브러리를 사용하려면

  1. SqlSessionFactoryBuilder
  2. SqlSessionFactory
  3. SqlSession

selectList

List<User> list = session.selectList("UserMapper.getUserList");
for(User user : list) System.out.println(user);

List<User> list = session.selectList("UserMapper.getUser", "user");
for(User user : list) System.out.println(user);

selectOne

User user = session.selectOne("UserMapper.findUserId", new User("user01", "user01"));
System.out.println(user);

insert

User user = new User("user04", "주몽", "user04", 40, 4);

session.insert("UserMapper.addUser", user);
session.commit();

update

user.setUserName("장보고");

session.update("UserMapper.updateUser", user);
session.commit();

delete

session.delete("UserMapper.removeUser", "user04");
session.commit();

관심 있을 만한 포스트

0개의 댓글