Java Web Development Workbook Chapter. 07
JDBC API를 직접 호출할 필요없이, 데이터베이스에 접근하여 CRUD 진행, 개발자 대신에 프레임워크가 JDBC API 호출
Persistence: 데이터의 지속성, 애플리케이션을 종료하고 다시 실행해도 이전에 저장한 데이터를 다시 로드하는 기술 Persistence Framework: 데이터의 저장, 조회, 변경, 삭제를 다루는 클래스 / 설정 파일 집합
프레임워크에서 제공하는 API와 전용 객체 질의어를 통해 데이터를 다룸. 객체 질의어를 사용함으로써, SQL 문장을 몰라도 됨. (DBMS에 맞추어 SQL 문장을 생성)
Hibernate 는 HQL 이라는 객체 질의어 제공
MyBatis는 SQL Mapper를 제공, 개발과 유지보수가 쉽도록 SQL 문장을 코드와 분리. -> 데이터베이스 프로그래밍을 간결화
stmt = connection.prepareStatement(
"update projects set " +
" pname = ?," +
" contents = ?," +
" state = ?" +
" where pno = ?"
);
stmt.setString(1, project.getTitle());
...
... // SQL 문을 다루는 문장이 없음
update projects set
pname=#{title},
content=#{content},
state=#{state},
where pno=#{no}
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.3.1</version>
</dependency>
Component | Description |
---|---|
SqlSession | 실제 SQL을 실행하는 객체, SQL을 처리하기 위해 JDBC 드라이버 사용 |
SqlSessionFactory | SqlSession 객체 생성 |
SqlSessionFactoryBuilder | mybatis 설정 파일의 내용을 토대로 SqlSessionFactory 생성 |
mybatis 설정 파일 | DB 연결정보, 트랜잭션 정보, mybatis 제어 정보등의 설정 포함, SqlSessionFactory 생성시 사용 |
SQL Mapper 파일 | SQL 문을 담고 있는 파일, SqlSession 객체가 참조 |
SqlSession: SQL 문장을 실행하는 도구
Component | Description |
---|---|
selectList | select 문을 실행, 값 객체 (Value Object) 목록을 반환 |
selectOne | select 문을 실행, 하나의 값 객체를 반환 |
insert | insert 문을 실행, 반환값은 입력한 데이터 개수 |
update | update 문을 실행, 반환값은 변경한 데이터 개수 |
delete | delete 문을 실행, 반환값은 삭제한 데이터 개수 |
List<E> selectList(String sqlId)
List<E> selectList(String sqlId, Object parameter)
...
sqlSession.selectList("spms.dao.ProjectDao.selectList")
...
<mapper namespace="spms.dao.ProjectDao">
<select id="selectList" resultMap="projectResultMap">
select pno, pname, sta_date, end_date, state
from projects
order by pno desc
</select>
...
sqlSession.insert("spms.dao.ProjectDao.insert", project);
<insert id="insert" parameterType="project">
insert into projects(pname, content, sta_date, end_date, state, cre_date, tags)
values (#{title}, #{content}, #{startDate}, #{endDate}, 0, now(), #{tags})
</insert>
객체의 프로퍼티: 인스턴스 변수를 말하는 것이 아닌, getter / setter를 가리키는 용어. 프로퍼티 이름은 getter / setter 메소드의 이름에서 추출
sqlSession.selectOne("spms.dao.ProjectDao.selectOne", no);
...
sqlSession.delete("spms.dao.ProjectDao.delete", no);
<delete id="delete" parameterType="int">
delete from projects
where pno=#{value}
</delete>
DBMS는 insert / update / delete 문을 실행할 때 그 작업 결과를 임시 데이터베이스에 보관 -> 클라이언트의 요청이 있을 때 운영 데이터베이스에 반영
SqlSession sqlSession = SqlSessionFactory.openSession(true);
<mapper namespace="spms.dao.ProjectDao">
...
</mapper>
각 select / insert / update / delete 문을 각 태그에 맞추어 사용
<select id="selectList" ... >
...
</select>
select 문을 실행하면, 결과가 생성되는데 이 결과를 담을 객체를 지정하는 속성
<select id="selectList" resultType="spms.vo.Project" >
만약 mybatis 설정 파일에 다음과 같이 alias가 설정되어 있다면 그 alias에 정의된 이름을 사용 가능
<typeAliases>
<typeAlias type="spms.vo.Project" alias="project" />
</typeAliases>
<select id="selectList" resultType="project" />
Mybatis는 select 결과를 저장하고자, resultType 에 선언된 클래스의 인스턴스를 생성한다. 그리고 각 컬럼에 대응하는 setter 메소드를 찾아 호출하여 컬럼 값을 인스턴스의 필드에 저장한다.
위에서 해당하는 setter가 없으면 그 컬럼 값은 저장되지 않는데 다음 두 가지 방법으로 해결
<select id="selectList" resultType="project" >
select
PNO as no,
PNAME as title,
...
<resultMap type="project" id="projectResultMap">
<id column="PNO" property="no" />
<result column="PNAME" property="title" />
<result column="STA_DATE" property="startDate" javaType="java.sql.Date" />
...
</resultMap>
MyBatis는 결과 레코드에 대해 객체 캐싱을 제공. 결과 객체를 풀 (pool) 에 보관해두었다가, 다시 질의가 들어오면 객체 풀에 저장된 객체 중에서 id 에 지정된 컬럼의 값과 일치하는 객체를 찾음
select 결과에 대해 <resultMap> 에 정의된 대로 자바 객체를 생성하고 싶다면, 다음과 같이 resultMap 속성에 id 지정
<select id="selectList" resultMap="projectResultMap">
...