자바 웹 개발 워크북 보고 따라함.
7.2 Mybatis 정리!!!!
7.2.1 mybatis 구동하기
1) MySqlProjectDao는 SqlSessionFactory에게 SQL을 실행할 객체를 요구합니다.
2) SqlSessionFactory는 SqlSession 객체를 생성하여 반환합니다.
3) MySqlProjectDao는 SqlSession 객체에게 SQL 실행을 요청합니다.
4) SqlSession 객체는 SQL이 저장된 맵퍼 파일에서 SQL을 찾습니다.
5) SqlSession은 JDBC 드라이버를 통해 DB에 질의를 실행합니다.
6) SqlSession은 DB로부터 가져온 데이터로 Project 목록을 생성하여 반환합니다.
7) MySqlProjectDao는 사용이 끝난 SqlSession을 닫습니다.
7.2.2 mybatis 프레임워크의 핵심 컴포넌트
프레임워크를 사용할 때는 그 프레임워크의 핵심을 담당하는 컴포넌트를 파악하는 것이 중요.
컴포넌트 |
설명 |
SqlSession |
실제SQL을 실행하는 객체. 이 객체는 SQL을 처리하기 위해 JDBC 드라이버를 사용함. |
SqlSessionFactory |
SqlSession 객체를 생성함. |
SqlSessionFactoryBuilder |
Mysql 설정 파일의 내용을 토대로 SqlSessionFactory를 생성함. |
Mybatis 설정 파일 |
Db 연결 정보, 트랜잭션 정보, mybatis 제어 정보 등의 설정 내용을 포함하고 있음. SqlSessionFactory를 만들 때 사용됨. |
Sql 맵퍼 파일 |
Sql 문을 담고 있는 파일. Sqlsession 객체가 참조함. |
7.2.3 DAO에서 SqlSessionFactory 사용
SqlSession을 사용하는 DAO 생성 ex) spms.dao.MySqlProjectDao
SqlSession의 주요 메서드
메서드 |
설명 |
selectList() |
SELECT 문을 실행. 값 객체(Value Object) 목록을 반환함. |
selectOne() |
SELECT 문을 실행. 하나의 값 객체를 반환함. |
insert() |
INSERT 문을 실행. 반환값은 입력한 데이터 개수. |
Update() |
UPDATE 문을 실행. 반환값은 변경한 데이터 개수. |
Delete() |
DELETE 문을 실행. 반환값은 삭제한 데이터 개수. |
SqlSession의 selectList() 호출 문법
List<E> selectList(String sqlId);
sqlId는 SQL 맵퍼의 네임스페이스 이름과 sql 문의 아이디를 결합하여 만든 문자열입니다.
SqlId = SQL 맵퍼의 네임스페이스 이름 + sql 문 ID
Ex) “spms.dao.ProjectDao.selectList” = “spms.dao.ProjectDao” + “selectList”
selectList()의 매개변수 값에서 ‘spms.dao.ProjectDao’는 sql 맵퍼의 네임스페이스 이름이고, selectList는 sql 문의 아이디입니다. 즉 sql 맵퍼 파일에서 selectList라는 아이디를 갖는 <select 태그를 가리키는 것이다.>
sql 맵퍼 파일 일부분
<mapper namespace="spms.dao.MemberDao">
만약 select 문을 실행하는 데 값이 필요하다면 다음과 같이 두 번째 매개변수로 값을 담은 객체를 넘기면 됩니다. 앞의 코드에서 insert()와 selectOne(), update(), delete()는 두 번째 매개변수로 객체를 넘겨주고 있습니다.
<E> List<E> selectList(String sql, Object var2);
7.3 SQL 맵퍼 파일
web07/src/spms/dao/MySqlProjectDao.xml
<mapper> 루트 엘리먼트
Sql 맵퍼 파일은 루트 엘리먼트 <mapper>를 작성하는 것으로 시작합니다. <mapper> 태그의 namespace 속성은 자바의 패키지처럼 sql 문을 묶는 용도로 사용합니다. 맵퍼 파일에 작성하는 모든 sql 문은 <mapper> 태그에 놓입니다.
<mapper namespace="spms.dao.MemberDao">
…
</mapper>
<select>, <insert>, <update>, <delete> 엘리먼트
Id 속성
SQL 문을 작성할 때 각각의 SQL문을 구분하기 위해 id 속성 사용
관리하기 쉽게 id 값을 SqlSession의 메서드 이름과 비슷하게 지음
resultType 속성
SELECT 문을 실행하면 결과가 생성되는데, 이 결과를 담을 객체를 지정하는 속성이 resultType입니다. resultType에는 다음과 같이 클래스 이름(패키지 이름 포함)이 옵니다.
<resultMap type="spms.vo.Member" id="memberResultMap">
만약 mybatis 설정 파일에 spms.vo.Member에 대한 별명이 정의 되어있다면 resultType의 값으로 그 별명을 사용할 수 있습니다.
<resultMap type="member" id="memberResultMap">
칼럼과 셋터 메서드
Mybatis는 select 결과를 저장하고자 resultType에 선언된 클래스의 인스턴스를 생성합니다. 그리고 각 칼럼에 대응하는 셋터 메서드를 찾아서 호출합니다. 이때 셋터 메서드는 대소문자 구분없이 set을 뺀 메서드의 이름과 칼럼 이름이 같으면 됩니다.
<resultMap> 엘리먼트
칼럼에 별명을 붙이는 대신 <resultMap>을 이용하면 칼럼 이름과 셋터 이름의 불일치 문제를 손쉽게 해결할 수 있습니다. 다음과 같이 <resultMap> 태그에 칼럼과 연결된 셋터 메서드를 정의합니다.
<resultMap> 태그의 type 값은 칼럼 데이터를 저장할 클래스 이름 또는 클래스의 별명입니다. 클래스에 대한 별명은 mybatis 설정 파일에 정의됩니다.
<result> 엘리먼트
<resultMap> 태그의 자식 태그로서 칼럼과 셋터 메서드의 연결을 정의합니다. <result> 태그를 살펴보면 column 속성에는 칼럼 이름을 지정하고, property 속성에는 객체의 프로퍼티 이름을 지정합니다. 셋터 메서드의 이름에서 set을 빼고, 첫 알파벳은 소문자로 바꾼 이름입니다.
javaType 속성
<result>에서 javaType을 사용하면, 칼럼의 값을 특정 자바 객체로 변환할 수 있습니다. CRE_DATE 칼럼에 대해 javaType을 java.sql.Date으로 설정하면, 칼럼 값을 꺼낼 때 그 객체로 변환됩니다.
이렇게 칼럼에 대해 호출될 셋터 메서드를 미리 지정해 두면, SQL 문을 작성할 때 매우 편리합니다. resultType 속성을 사용할 때는 SELECT 문의 각 칼럼에 대해 별명을 붙여야 했지만, resultMap을 사용하면 그럴 필요가 없어서 좋습니다.
<id> 엘리먼트
<id> 태그에서 지정한 프로퍼티는 객체 식별자료 사용됩니다. Select 문을 실행하면 레코드 값을 저장학 ㅣ위해 결과 객체가 생성되는데, select 문을 실행할 때마다 매번 결과 객체를 생성하면 성능이 나빠지기 때문에 캐싱해두고, 다음 select를 실행할 때 재사용합니다.
<id column="MNO" property="no" />
7.3.2 mybatis의 select 결과 캐싱
<select> 태그에 resultMap 적용
Select 결과에 대해 <resultMap>에 정의된 대로 자바 객체를 생성하고 싶다면, <select>의 resultMap 속성이 <resultMap> id를 지정합니다.
7.4 mybatis 설정 파일
/web07/src/spms/dao/mybatis-config.xml
<configuration> 루트 엘리먼트
Mybatis 설정 파일의 루트 엘리먼트는 configuration 입니다.
Configuration의 자식 엘리먼트 중에서 주요 엘리먼트들의 용도를 정리한 표입니다.
엘리먼트 |
용도 |
Properties |
프로퍼티 파일이 있는 경로 설정. <property>를 사용하여 개별 프로퍼티 정의 기능 |
Settings |
프레임워크의 실행 환경을 설정 |
typeAliases |
자바 클래스 이름(패키지 이름 포함)에 대한 별명 설정 |
typeHandlers |
컬럼의 값을 자바 객체로, 자바 객체를 컬럼의 값으로 변환해 주는 클래스를 설정 |
Environments |
프레임워크에서 사용할 DB 정보(트랜잭션 관리자, 데이터 소스)를 설정. |
Mappers |
SQL 맵퍼 파일들이 있는 경로 설정 |
<typeAliases> 엘리먼트
SQL 맵퍼 파일에서 매개변수 타입(parameterType)이나 결과 타입(resultType)을 지정할 때 긴 이름의 클래스명 대신 짧은 이름의 별명을 사용할 수 있습니다. typeAliases 엘리먼트는 SQL 맵퍼 파일에서 사용할 별명들을 설정합니다. 각 별명의 정의는 <typeAlias> 태그를 사용합니다.
SQL 맵퍼에서 별명 사용
다음은 typeAlias에서 정의한 별명을 사용하는 예
ð MySqlMemberDao.xml에서 사용
<environments> 엘리먼트
<environments> 태그는 db 환경 정보를 설정할 때 사용하는 태그입니다. 이 태그를 이용하면 여러 개의 DB 접속 정보를 설정할 수 있습니다. 설정된 DB 정보 중에서 하나를 선택할 때는 default 속성을 사용합니다.
Id 속성은 <environment>를 구분할 때 사용할 식별자 입니다.
<environment> 엘리먼트
Environment는 트랜잭션 관리 및 데이터 소스를 설정하는 태그입니다.
트랜잭션 관리 방식 설정
트랜잭션이란, 여러 개의 데이터 변경 작업(INSERT, UPDATE, DELETE)을 하나의 작업으로 묶은 것입니다. mybatis에서 트랜잭션을 관리하는 방식에는 두 가지가 있습니다.
트랜잭션 관리 유형 |
설명 |
JDBC |
직접 JDBC의 커밋, 롤백 기능을 사용하여 mybatis 자체에서 트랜잭션을 관리 |
MANAGED |
서버의 트랜잭션 관리 기능을 이용. 즉 Java EE 애플리케이션 서버(JBoss, WebLogic, WebSphere 등)나 서블릿 컨테이너(톰캣 서버 등)에서 트랜잭션을 관리 |
<transactionManager type="JDBC" />
데이터 소스 설정
Mybatis는 JDBC 표준 인터페이스인 javax.sql.DataSource 구현체를 이용하여 DB 커넥션을 다룹니다. mybatis에서 사용 가능한 데이터 소스 유형은 다음 세가지가 있습니다.
데이터 소스 유형 |
설명 |
UNPOOLED |
DB 커넥션을 요청할 때마다 매번 커넥션 객체를 생성한다. 높은 성능을 요구하지 않는 단순한 애플리케이션에 적합하다. |
POOLED |
미리 DB 커넥션 객체를 생성해 두고, 요청하면 즉시 반환한다. DB에 연결하는 과정. 즉 연결을 초기화하고 사용자를 인증하는 과정이 없기 때문에 속도가 빠르다. |
JNDI |
JAVA EE 애플리케이션 서버나 서블릿 컨테이너(예: 톰캣 서버)에서 제공하는 데이터 소스를 사용한다. |
데이터 소스를 설정하려면 <datasource> 엘리먼트를 사용해야 합니다.
<dataSource type="JNDI">
<property name="data_source" value="java:comp/env/jdbc/sample"/>
<mappers> 엘리먼트
<mappers> 태그는 SQL 맵퍼 파일들의 정보를 설정할 때 사용합니다. 각각의 SQL 맵퍼 파일의 정보는 <mapper> 태그로 정의합니다.
SQL 맵퍼 경로 설정
resource 속성 사용
Mybatis에서 JNDI 사용하기
톰캣 서버에서 제공하는 데이터 소스를 사용하도록 변경.
데이터 소스를 jndi로 설정한 경우, data_source속성을 지정해야 합니다.
톰캣 서버 재시작 후 웹 브라우저에서 list로 요청합니다.
spms/dao/MySqlMemberDao.java 전체
package spms.dao;
import java.util.List;
import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory;
import spms.annotation.Component;
import spms.vo.Member;
@Component("memberDao") // value 생략 가능; public class MySqlMemberDao implements MemberDao {
SqlSessionFactory sqlSessionFactory;
public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) { this.sqlSessionFactory = sqlSessionFactory; } //HashMap<String, Object> paramMap public List<Member> selectList() throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(); try { return sqlSession.selectList("spms.dao.MembertDao.selectList"); } finally { sqlSession.close(); } }
// rs = stmt.executeQuery("select mno, mname, email, cre_date from members order // by mno asc");
/* * while (rs.next()) { members.add( new Member() .setNo(rs.getInt("MNO")) * .setName(rs.getString("MNAME")) .setEmail(rs.getString("EMAIL")) * .setCreatedDate(rs.getDate("CRE_DATE"))); * * } */
public int delete(int no) throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(); try { int count = sqlSession.delete("spms.dao.MemberDao.insert", no); sqlSession.commit(); return count; } finally { sqlSession.close(); } // stmt = connection.prepareStatement("delete from members where mno=" + no); }
public Member selectOne(int no) throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession(); try { return sqlSession.selectOne("spms.dao.MemberDao.selectOne", no); } finally { sqlSession.close(); } }
/* * rs = stmt.executeQuery("SELECT MNO,EMAIL,MNAME,CRE_DATE FROM MEMBERS" + * " WHERE MNO=" + no); if (rs.next()) { return new Member() * .setNo(rs.getInt("MNO")) .setEmail(rs.getString("EMAIL")) * .setName(rs.getString("MNAME")) .setCreatedDate(rs.getDate("CRE_DATE")); */
public int update(Member member) throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession(); try { int count = sqlSession.update("spms.dao.MemberDao.update", member); sqlSession.commit(); return count; } finally { sqlSession.close(); } }
/* * stmt = connection. * prepareStatement("UPDATE MEMBERS SET EMAIL=?,MNAME=?,MOD_DATE=now() WHERE MNO=?" * ); stmt.setString(1, member.getEmail()); stmt.setString(2, member.getName()); * stmt.setInt(3, member.getNo()); */
public int insert(Member member) throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(); try { int count = sqlSession.insert("spms.dao.MemberDao.insert", member); sqlSession.commit(); return count; }finally { sqlSession.close(); }
/*stmt = connection.prepareStatement( "INSERT INTO MEMBERS(EMAIL, PWD, MNAME, CRE_DATE, MOD_DATE) VALUES(?,?,?,NOW(), NOW())"); stmt.setString(1, member.getEmail()); stmt.setString(2, member.getPassword()); stmt.setString(3, member.getName());*/
}
/* public Member exist(String email, String password) throws Exception { // 있으면 Member 객체 리턴, 없으면 null 리턴 return null;
}*/ } |
spms/dao/MysqlMemberDao.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="spms.dao.MemberDao"> <resultMap type="member" id="memberResultMap"> <id column="MNO" property="no" /> <result column="MNAME" property="name" /> <result column="EMAIL" property="email" /> <result column="PWD" property="password" /> <result column="CRE_DATE" property="createdDate" javaType="java.sql.Date"/> <result column="MOD_DATE" property="modifiedDate" javaType="java.sql.Date"/> </resultMap>
<select id="selectList" parameterType="map" resultMap="memberResultMap"> select MNO, MNAME, EMAIL, CRE_DATE, MOD_DATE FROM MEMBERS </select>
<insert id="insert" parameterType="member"> insert into PROJECTS(pname,content,sys_date,end_date,state,cre_date,tags) values (#{title},#{content},#{startDate},#{endDate},0,now(),#{tags}) </insert>
<select id="selectOne" parameterType="int" resultMap="memberResultMap"> SELECT MNO,EMAIL,MNAME,CRE_DATE FROM MEMBERS WHERE MNO=no </select>
<update id="update" parameterType="member"> UPDATE MEMBERS SET EMAIL=#{email}, MNAME=#{name}, MOD_DATE=#{modifiedDate} WHERE MNO=#{no} </update>
<delete id="delete" parameterType="int"> delete from members where mno=#{no} </delete> </mapper> |
spms/dao/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="spms/dao/db.properties" /> --> <settings> <setting name="logImpl" value="LOG4J"/> </settings>
<typeAliases> <typeAlias type="spms.vo.Project" alias="project" /> <typeAlias type="spms.vo.Member" alias="member" /> </typeAliases>
<environments default="development"> <environment id="development"> <transactionManager type="JDBC" /> <dataSource type="JNDI"> <property name="data_source" value="java:comp/env/jdbc/sample"/> <!-- <property name="driver" value="${driver}" /> <property name="url" value="${url}"/> <property name="username" value="${username}"/> <property name="password" value="${password}"/> -->
</dataSource> </environment> </environments>
<mappers> <mapper resource="spms/dao/MySqlProjectDao.xml"/> <mapper resource="spms/dao/MySqlMemberDao.xml"/> </mappers> </configuration> |
'JAVA > spring' 카테고리의 다른 글
Eclipse svn install to bring project (0) | 2020.07.08 |
---|---|
Mybatis Log Setting (0) | 2020.06.16 |
MVC Architecture (0) | 2020.02.24 |
Servlet JDBC (1) | 2020.01.20 |
Servlet Programming (0) | 2020.01.09 |
댓글