[MyBatis] 3. 마이바티스 CRUD

KIM KYUBIN·2022년 10월 12일
0

MyBatis

목록 보기
3/3

마이바티스 프로그래밍 - 이동국 저

3.1 데이터 구조 파악

3.1.1 데이터베이스 테이블 구조 파악

  • 데이터베이스에서 테이블의 구조를 표현하는 방법으로는 ERD를 주로 사용

3.1.2 자바 모델 클래스

  • 자바 애플리케이션에서는 테이블에 들어있는 데이터를 가져와서 사용하거나 조작을 하기 위해 그 데이터를 담는 객체를 만든다.
    -> 자바 모델 클래스로 정의해서 사용

  • 테이블별로 모델 클래스는 한 개씩 생성하며, 테이블의 칼럼들은 모델 클래스에서 필드로 만든다.

  • 마이바티스에서 사용할 모델 클래스를 만들 때 주의 사항

    • 캐시 사용 여부에 따라 다른 곳에 캐시를 사용할 경우 Serializable 이어야 한다.
  • 데이터베이스는 전통적으로 칼럼의 이름을 만들 때 _를 사용하지만, 자바에서는 CamelCase를 주로 사용


3.2 마이바티스 파라미터 표기법

#{commentNo}

  • 자바 빈일 경우 변수명 또는 getter/setter 메소드에서 get/set을 뺀 나머지 문자를 소문자로 시작해서 적어 주면 된다.

  • Map 객체일 때는 key 값을 적어 주면 설정해준다.

  • 파라미터의 값이 한 개인 원시 타입의 경우 안에 아무 값이나 적어줘도 알아서 설정해준다.

  • 마이바티스가 처리하는 과정에서 JDBC 코드와 같은 형태로 변환한다.
    -> 결과적으로 JDBCPreparedStatement를 사용하게 되고 매핑 구문에 적용했던 마이바티스 파라미터 표기법은 PreparedStatement? 표현식으로 바뀐다.

  • ${ } 표기법은 #{ } 표기법과는 달리 PreparedStatement? 표기법으로 변환하는 과정을 생략한다.
    -> SQL Injection 공격에 노출될 수 있기 때문에 사용을 피해야 한다.


3.3 데이터 조회

3.3.1 데이터를 조회하는 매핑 구문으로 분리

  • 매핑 구문 : JDBC 코드처럼 자바 코드에 선언하지 않고 별도 XML이나 애노테이션에 선언한 SQL
<!--1 start-->
<?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 end-->
<!--2 start-->
<mapper namespace="ldg.mybatis.repository.mapper.CommentMapper">
<!--2 end-->
	<!--3 start-->
	<select id="selectCommentByPrimaryKey" parameterType="long" resultType="ldg.mybatis.model.Comment">
		SELECT
			comment_no AS commentNo,
			user_id AS userId,
			comment_content AS commentContent,
			reg_date AS regDate
		FROM COMMENT
		WHERE comment_no = #{commentNo}
	</select>
	<!--3 end-->
</mapper>

1️⃣ XML과 DOCTYPE 선언

  • 첫 번째 줄 : 이 문서가 XML임을 나타낸다.

  • 두 번째 줄부터 : 이 XML 문서가 사용하는 엘리먼트와 엘리먼트 간의 구조를 정의하는 DTD 선언

2️⃣ 매퍼 네임스페이스

  • 매핑 구문들의 그룹

  • 여러 개의 매퍼에서 매핑 구문 아이디가 겹치더라도 네임스페이스와 함께 매핑 구문 아이디를 사용하기 때문에 아이디가 겹치지 않게 잘 분류할 수 있다.

  • 대개는 테이블명으로 네임스페이스를 정하고 매핑 구문 아이디는 SQL의 맥락에 따라 명명

3️⃣ 매핑 구문

  • id : 자바 코드에서 SQL을 선택할 때의 연결고리 역할

  • parameterType : 조회 조건에서 사용할 값을 가진 파라미터의 타입

  • resultType : 결과 데이터의 타입

3.3.2 매핑 구문을 사용하는 마이바티스 코드 생성

public class CommentSessionRepository {
    public Comment selectCommentByPrimaryKey(Long commentNo) {
        // 1 start
        SqlSession sqlSession = getSqlSessionFactory().openSession();
        // 1 end
        try {
            // 2 start
            return (Comment)sqlSession.selectOne("ldg.mybatis.repository.mapper.CommentMapper.selectCommentByPrimaryKey", commentNo);
            // 2 end
        } finally {
            // 3 start
            sqlSession.close();
            // 3 end
        }
    }
}

1️⃣ 마이바티스 객체 생성

  • SqlSessionFactory 객체가 없다면 만들고, 있다면 기존 객체를 사용

  • 마이바티스의 매핑 구문을 호출해서 사용하려면 SqlSession 객체가 필요하며, 각 데이터베이스 작업별로 SqlSession 객체를 사용하면 된다.

  • JDBC 코드에서 데이터베이스 연결 객체를 생성하는 것과 동일

2️⃣ 데이터 조회

  • selectOne 메소드에 첫 번째 파라미터로 매핑 구문을 지정하면 해당되는 SQL을 실행하게 마이바티스가 처리
    -> 네임스페이스.매핑 구분 ID

3️⃣ 데이터베이스 자원 해제

  • JDBC와 달리 한꺼번에 데이터베이스 자원 객체를 해제한다.

3.3.3 마이바티스 코드를 사용한 데이터 조회

public class CommentSessionRepositoryTest {
	public static void main(String[] args) {
    	Long commentNo = 1L;
        CommentSessionRepository commentSessionRepository = new CommentSessionRepository();
        Comment comment = commentSessionRepository.selectCommentByPrimaryKey(commentNo);
    }
}

3.4 데이터 입력

3.4.1 데이터를 입력하는 매핑 구문으로 분리

<mapper namespace="ldg.mybatis.repository.mapper.CommentMapper">
	<insert id="insertComment" parameterType="ldg.mybatis.model.Comment">
		INSERT INTO COMMENT(comment_no, user_id, comment_content, reg_date)
      	VALUES (#{commentNo}, #{userId}, #{commentContent}, #{regDate})
	</insert>
</mapper>
  • resultType 속성을 지정하지 않은 이유는 PreparedStatement 객체가 제공하는 executeUpdate 메소드의 반환 값이 입력한 데이터 레코드 수이기 때문

3.4.2 매핑 구문을 사용하는 마이바티스 코드 생성

public Integer insertComment(Comment comment) {
	SqlSession sqlSession = getSqlSessionFactory().openSession();
    
	try {
		int result = sqlSession.insert("ldg.mybatis.repository.mapper.CommentMapper.insertComment", comment);
        
        if(result > 0) {
        	sqlSession.commit();
        }
        
        return result;
	} finally {
		sqlSession.close();
	}
}
profile
상상을 현실로 만들기 위해 노력하는 개발자

0개의 댓글