● 매퍼

XML 사용시 : SQL을 XML에 정의하는 매퍼 설정파일(context-mapper.xml)

어노테이션 사용시 : 인터페이스의 메소드마다 어노테이션을 정의한 매퍼 인터페이스

 

Mybatis의 특징

- 자원 생성 해제 필요 X

- 파라미터, 결과셋 설정 코드 X

- SQL문을 따로 관리(xml or 인터페이스)

- 구성요소 5가지 : 설정파일, 매퍼, 파라미터타입(parameterType), 결과타입(resultType), 결과매핑(resultMap)

- 파라미터, 결과 타입 : Map객체, Java 모델 클래스, 원시타입

 

속성명과 변수명이 다를때 맵핑하는 방법은 resultMap을 사용하거나 Alias를 사용함 (Alias 권장)

 

● #{} 와 ${}의 차이점

 - # : 문자면 '   '를 달아줌 (숫자의경우 '  '을 달지않음)

 - $ : 어떠한 경우도 '  '을 달지않음

 

 

mybatis-config.xml (mybatis 설정파일)

<?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>
    <typeAliases>
        <typeAlias type="mybatis.Comment" alias="Comment"/>	<!-- 자바빈에 별명 부여 -->
    </typeAliases>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC" />
            <dataSource type="POOLED">
                <property name="driver" value="oracle.jdbc.driver.OracleDriver"/>
                <property name="url" value="jdbc:oracle:thin:@localhost:1521:xe"/>
                <property name="username" value="scott"/>
                <property name="password" value="1111"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="mybatis/CommentMapper.xml"/>		<!-- 매퍼 등록 -->
        <mapper class="mybatis.anno.CommentMapper"/>
    </mappers>
</configuration>

 

● CommentMapper.xml (매퍼 설정파일)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org/DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
	
<mapper namespace="CommentMapper">		<!-- 네임스페이스는 보통 이름과 동일하게 사용 -->
	<cache />
	<sql id="BaseColumns">
		comment_no AS commentNo,
		user_id AS userId,
		comment_content AS commentContent,
		reg_date AS regDate
	</sql>
	<select id="selectComment" parameterType="hashmap" resultType="Comment">
        SELECT
            <include refid="BaseColumns" />
        FROM tcomment
        <where>
            <if test="commentNo != null">
                comment_no = #{commentNo}		<!-- commentNo key값 or getCommentNo() -->
            </if>
        </where>
    </select>
    <insert id="insertComment" parameterType="Comment">
        INSERT INTO tcomment(comment_no, user_id, comment_content, reg_date)
            VALUES (#{commentNo}, #{userId}, #{commentContent}, #{regDate})
    </insert>
</mapper>

→ #{}를 사용할 때 parameterType이 hashmap일경우 key값, DTO일경우 getter를 의미함

 

● Repository 클래스(=DAO)

public class CommentSessionRepository {
    private final String namespace = "CommentMapper";	// <mapper namespace="CommentMapper"> 와 일치해야함
    
    private SqlSessionFactory getSqlSessionFactory() {
        String resource = "mybatis/mybatis-config.xml";		// Mybatis 설정파일
        InputStream inputStream;
        try {
            inputStream = Resources.getResourceAsStream(resource);
        } catch (IOException e) {
            throw new IllegalArgumentException(e);
        }
        
        return new SqlSessionFactoryBuilder().build(inputStream);
    }
    
    public List<Comment> selectComment(Map<String, Object> condition) {
	SqlSession sqlSession = getSqlSessionFactory().openSession();
	try {
            return sqlSession.selectList(namespace + ".selectComment", condition);	// CommentMapper.selectComment
	} finally {			// 결과가 여러개일경우 : selectList
            sqlSession.close();
	}
    }
    
    public Comment selectCommentByPrimaryKey(Long commentNo) {
	SqlSession sqlSession = getSqlSessionFactory().openSession();
	try {
            return sqlSession.selectOne(namespace + ".selectCommentByPrimaryKey", commentNo);	// CommentMapper.selectCommentByPrimaryKey
	} finally {			// 결과가 1개일경우 : selectOne
            sqlSession.close();
	}
    }
    
    public Integer insertComment(Comment comment) {
	SqlSession sqlSession = getSqlSessionFactory().openSession();
	    try {
             int result = sqlSession.insert(namespace + ".insertComment", comment);	// CommentMapper.insertComment
            if (result > 0) {
                sqlSession.commit();
            } else {
                sqlSession.rollback();
            }
            return result;
        } finally {
            sqlSession.close();
        }
    }

    public static void main(String[] args) {
        CommentSessionRepository c = new CommentSessionRepository();
        
        // selectComment
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("commentNo", 3L);
        System.out.println(c.selectComment(map));
        
        // insertComment
        Comment comment = new Comment();
        comment.setCommentNo(7L);
        comment.setCommentContent("sample_content");
        comment.setRegDate(new Date());
        comment.setUserId("sample user_Id");
        c.insertComment(comment);
    }
}

 

요소

● sql : 재사용 가능한 sql구문 정의 (id부여)

 - <include refid=""> 요소를 사용하여 SQL에 삽입

<sql id="BaseColumns">
    comment_no AS commentNo,
    user_id AS userId,
    comment_content AS commentContent,
    reg_date AS regDate
</sql>

 

● select

<select id="selectComment" parameterType="hashmap" resultType="mybatis.Comment">
    SELECT
        <include refid="BaseColumns" />
    FROM comment
</select>

 

● insert, update, delete

 - result가 없으므로 파라미터타입만 기입 (resultType, resultMap 필요 X)

<update id="insertComment" parameterType="Comment">
    UPDATE tcomment SET comment_content = #{commentContent} WHERE comment_no = #{commentNo}
</update>

 

● where : where절 사용

 - SQL구문에 WHERE를 추가, 게다가 구문이 AND 나 OR로 시작하면 그 구문을 지워줌 

 

● if

<where>
    <if test="commentNo != null">
        comment_no = #{commentNo}
    </if>
    <if test="userId != null">
        AND user_id = #{userId}
    </if>
</where>

 

● choose, when, otherwise : switch-case-default 구문

<select id="selectCommentByConditionChoose" parameterType="hashmap" resultType="Comment">
    SELECT comment_no AS commentNo, user_id AS userId, comment_content AS commentContent, reg_date AS regDate FROM tcomment
    <choose>
        <when test="commentNo != null">
            WHERE comment_no = #{commentNo}
        </when>
        <when test="userId != null">		<!-- 첫번째 when에 걸릴경우 실행되지 않음 -->
            WHERE user_id = #{userId}
        </when>
        <otherwise>				<!-- 첫번째 when에 걸릴경우 실행되지 않음 -->
            WHERE comment_no = 1 AND user_id = 'from'
        </otherwise>
    </choose>
</select>

 

● foreach : IN 구문에 많이 사용함

 - collection : 배열 or 컬렉션

 - item : each값

 - index : 인덱스

 - separator : 각 값의 구분자

 - open, close : 시작과 끝에 삽입할 문자

<select id="selectCommentByConditionForeach" parameterType="hashmap" resultType="Comment">
    SELECT comment_no AS commentNo, user_id AS userId, comment_content AS commentContent, reg_date AS regDate FROM tcomment
    <where>
        <if test="commentNos != null">
            comment_no IN
            <foreach collection="commentNos" item="commentNo" index="index" open="(" close=")" separator=", ">	<!-- (?, ?) -->
                #{commentNo}		<!-- item값 -->
            </foreach>
        </if>
    </where>
</select>

 

● selectKey : selectKey 구문이 먼저 실행되고 keyProperty에 결과를 넣은 후 그아래 SQL문이 실행됨

 - keyProperty : selectKey 구문의 결과가 셋팅될 프로퍼티

 - order : selectKey 구문의 순서 설정, SQL이 수행되기 전(BEFORE)인지 후(AFTER)인지

<insert id="insertCommentKey" parameterType="Comment">
	<selectKey keyProperty="commentNo" resultType="long" order="BEFORE">
		SELECT max(comment_no)+1 FROM tcomment
	</selectKey>
	INSERT INTO tcomment(comment_no, user_id, comment_content, reg_date)
		VALUES (#{commentNo}, #{userId}, #{commentContent}, #{regDate})
</insert>

+ Recent posts