변화되는 프로세스
이전 레거시방식에서는 사용자의 요청을 처리하기 위해
jsp(화면단) > Controller(서블릿클래스) > Service(클래스) > Dao(클래스) > mapper(xml) 의 로직을 거쳤다.
Mybatis를 사용했을때도 기본 로직은 동일하나 조금씩 변화되는 코드들이 있다.
Controller에서 달라지는 부분
- sql문이 전달받을 수 있는 객체는 1개이기 때문에(페이징용 제외) 데이터가 단 2개라 하더라도 한곳에 담아야 한다.
이런 경우 vo클래스를 만들수도 있지만 보다 간결하게 HashMap을 활용할수도 있다.
>>mapper단에서는 #{키값}으로 뽑으면 된다.
//Vo객체 대신 활용할 수 있는 HashMap
HashMap<String, String> map = new HashMap<>();
map.put("condition", condition);
map.put("keyword", keyword);
Service에서 달라지는 부분
- 이전 JDBC 방식에서는 Dao의 기본생성자에 Properties객체와 sql문이 작성된 mapper.xml 파일을 연결시키는 구문을 작성했었다.
>>Service단에서는 매번 새로이 new Dao()를 생성 했어야만 했다. - Mybatis방식에서는 SqlSession객체를 만드는 행위에 mapper.xml을 연결시키는 과정이 녹아있다.
>> Dao객체를 전역변수로 선언해놓을 수 있다! - SqlSession 객체는 Connection 객체의 역할을 대신할 뿐 만 아니라 자체적으로 가지고 있는 commit(), rollback(), close() 메소드를 활용할 수 있다.
Template를 static import하여 객체 생성 메소드를 바로 사용할 수 있도록 한다. - Sql객체가 생성될때 mybatis-config가 읽어들여지고, mapper파일이 읽어들여다.
//Service를 Interface로 설계한 후 구현하는 연습을 해본다.
public class MemberServiceImpl implements MemberService {
//실시간으로 생성할 필요가 없어 전역변수로 선언해놓는다.
private MemberDao mDao = new MemberDao();
@Override
public int insertMember(Member m) {
SqlSession sqlSession = getSqlSession();
int result = mDao.insertMember(sqlSession, m);
if(result>0) {
sqlSession.commit(); //자체적으로 메소드를 가지고 있다.
}else {
sqlSession.rollback();
}
sqlSession.close();
return result;
}
...
}
Dao에서 달라지는 부분
- 전달받은 SqlSession 객체가 가지고 있는 sql 전용 메소드를 통해서 sql문을 완성시키고 결과를 객체로 돌려 받는다.
[표현법] SqlSession객체.sql에따른메소드("sql문지정"[, 전달할 객체, Rowbounds]) - 메소드의 종류
객체.insert(...) : insert문 전용 메소드
객체.update(...) : update문 전용 메소드
객체.delete(...) : delete문 전용 메소드
객체.selectOne(...) : 1개행만 돌려받는 쿼리문일 경우 사용한다.
객체.selectList(...) :
-여러행을 돌려받는 쿼리문일 경우 사용한다.
-유일하게 매개변수 3개짜리가 있다.
-리턴은 List이기때문에 (ArrayList)를 앞에 붙여 다운캐스팅 해주어야한다. - 매개변수의 순서
- 첫번째 매개변수 : " 매퍼파일의별칭 . sql문의 id "
- 두번째 매개변수 : 해당 sql문을 완성시킬 객체
만약 완성형태의 sql문일경우 생략할 수 있다.
세번째 매개변수를 써야한다면 null을 입력한다. - 세번째 매개변수 : RowBounds객체
selectList 메소드에서 활용할 수 있다.
public int insertMember(SqlSession sqlSession, Member m) {
return sqlSession.insert("memberMapper.insertMember", m);
}
sql을 저장할 mapper.xml
Mybatis에서 mapper.xml는 중요한 역할을 한다.
mapper.xml을 만들고 등록하는 과정을 알아본다.
sql을 위한 xml파일 만들기
- 생성위치 : resources(소스폴더)/mappers/member-mapper.xml
- <!DOCTYPE>
: 문서형식을 선언하는 태그로 mybatis전용 구문이 있다.
공식사이트에서 복붙해온다. - <mapper>
: 해당 파일의 정체성은 mapper이다. mapper태그로 전체 내용을 감싸준다.
- namespace 속성:
mapper파일의 id를 지정한다. (필수)
id는 mapper파일을 mybatis-config에 등록할때 쓰인다. - <select> <insert> <update> <delete>
: sql문들은 자신의 키워드에 맞는 태그를 기술한 후 content부에 sql문을 작성하면 된다.
- 이전 JDBC방식에서 ?로 미완성된 sql문을 작성했다면, Mybatis방식에서는 객체를 전달받는다는것을 전제로 sql문을 완성시킨다.
값을 넣을 때는 다음과 같은 두가지 방법이 있다.
- #{필드명or변수명or키값}
- 해당 위치에 ?가 생기며 파싱되며, PreparedStatement를 생성하게 된다.
>>재활용(캐싱)되기 때문에 효율적이다.
- ' '가 붙으며 쿼리가 수행되나 오라클은 숫자-문자간에 자동형변환이 지원되기때문에 문제되지 않는다 - ${필드명or변수명or키값}
- 값이 넣어진채로 쿼리문이 수행된다(파라미터의 값이 바뀔때마다 쿼리문 파싱을 진행해야한다는 단점)
- 작은따옴표가 붙지 않아 테이블이름이나 컬럼이름을 동적으로 결정할 때 활용할 수 있다.
- SQL Injection에 취약하다는 보안적 단점이 있다.
(입력값으로 서버의 데이터베이스를 공격하는 것)
- id 속성 :
각각의 sql문을 식별할 수 있는 아이디를 지정해준다.
관례대로 해당 sql문이 쓰일 메소드명과 일치시켜준다.
- parameterType 속성 :
statement에 사용되기 위해 전달받을 객체나 자료형의 풀클래스명 혹은 별칭 기술한다.
** 기본자료형이나 자바내장객체의 경우 MyBatis에서 지정해놓은 별칭을 쓰면 된다.
( 공식사이트 - [매퍼설정] - typeAliases부분에서 다양한 별칭을 확인할 수 있다.)
마이바티스가 자동계산 가능하므로 생략 가능 - #{필드명or변수명or키값}
- <select>의 결과타입 속성 :
- Mybatis는 매핑(조회된 칼럼값 뽑아서 자바객체에 담는 것)이 자동으로 진행된다.
이때 어떤 타입으로 돌려줄건지 resultType 혹은 resultMap 속성으로 기재해주어야 한다.
- resultType 속성 : 자바의 타입(풀클래스명or별칭)을 입력한다.
vo객체의 경우 컬럼명과 필드명이 일치할 경우만 사용할 수 있다.
단, select문의 칼럼에 필드명과 일치하도록 별칭을 넣었다면 컬럼명과 필드명이 달라도 사용 할 수 있다.
- resultMap 속성 : 매핑시킬 resultMap의 id를 입력한다. - <resultMap>
-컬럼명과 필드명이 일치하지 않는 경우 어떤컬럼의 값을 어떤 필드에 입력시킬건지 매칭을 시켜준다.
-보통 mapper상단에 기재한다.
[표현법]
<resultMap id="식별자" type="vo객체풀클래스명or별">
<id colume="db칼럼명" property="vo필드명" />
<result column="db칼럼명" property="vo필드명" />
....
</resultMap>
- primaryKey는 id 태그를 쓸 수 있음.(심화활용에 쓰임)
- column은 대소문자를 가리지 않으나 property는 대소문자를 구분한다.
- column은 출력되는 컬럼 그 자체를 인식하므로 r.create_date 등과 같이 테이블별칭을 붙여준 경우라도 create_date로 입력해야한다.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="memberMapper">
<!-- resultMap을 지정하는 예시 -->
<resultMap id="memberResultSet" type="com.br.mybatis.member.model.vo.Member">
<result column="user_no" property="userNo" />
...
<result column="status" property="status" />
</resultMap>
...
<!-- 다양한 sql문들을 입력하는 예시 -->
<insert id="insertMember" parameterType="com.br.mybatis.member.model.vo.Member">
insert
into member
...
</insert>
<select id="loginMember" parameterType="Member" resultMap="memberResultSet">
select *
from member
...
</select>
...
</mapper>
mapper.xml등록하기
- Dao에서 sql을 찾을 수 있도록 mapper.xml을 등록해주어야 한다.
- 등록할 위치는 resources(소스폴더)/config/mybatis-config.xml의
<mappers>태그 안에 등록한다.
<mappers>
<mapper resource="/mappers/member-mapper.xml" />
<mapper resource="/mappers/board-mapper.xml" />
...
</mappers>

'Framework > MyBatis' 카테고리의 다른 글
| <selectKey> : insert + select를 한번에 (0) | 2023.04.20 |
|---|---|
| 스프링에서 직접 트랜잭션 제어하기 : @Transactional (0) | 2023.04.19 |
| [03] SQL문 응용태그 : 동적 SQL, <association>, <collection> (0) | 2023.02.15 |
| [02] 페이징처리 : RowBounds (0) | 2023.02.14 |
| [00] 프레임워크 개념 / mybatis 준비 / Filter 활용 (0) | 2023.02.13 |
댓글