Data Persistence Framework
- 데이터의 영속성(지속성; 등록,조회,변경,삭제)을 대신 처리해주는 프레임워크.
Mybatis 도입
1) Mybatis 라이브러리 파일을 프로젝트에 등록하기
- mvnrepository.com 또는 search.maven.org에서 mybatis를 검색하여 라이브러리 정보 알아낸다.
- build.gradle 파일에 의존 라이브러리 정보를 추가한다.
- 'gradle eclipse' 실행하여 라이브러리를 다운로드 받고, 이클립스 설정 파일에 등록한다.
- 이클립스 프로젝트를 리프래시하여 변경된 설정 파일의 정보를 반영한다.
2) Mybatis 설정 파일 준비
- mybatis.org 사이트에서 문서 페이지를 참조한다.
- Mybatis 설정 파일(예: mybatis-config.xml)을 생성한다.
- 문서 페이지를 참조하여 설정 파일의 내용을 변경한다.
1. mybatis 설정 파일을 읽을 InputStream 도구를 준비한다.
=> 다음과 같이 mybatis 설정 파일의 경로를 직접 지정하면
애플리케이션 배포 경로가 바뀔 때 마다
소스를 변경하고 다시 컴파일 해야 하는 문제가 있다.
InputStream mybatisConfigInputStream = new FileInputStream(
"./bin/main/com/eomcs/mybatis/ex01/a/mybatis-config.xml");
=> 이런 문제를 해결하기 위해 Mybatis는 도우미 객체를 제공한다.
=> Resources 클래스의 메서드를 이용하면
자바 클래스가 있는 패키지 폴더의 mybatis 설정 파일을 바로 지정할 수 있다.
2. SqlSessionFactory를 만들어 줄 빌더 객체 준비
3. SqlSession 객체를 만들어 줄 팩토리 객체 준비
4. SQL을 실행시키는 객체 준비
SqlSession 사용법 - SQL 문을 실행하는 메서드
SqlSession 객체를 이용하여 SQL 맵퍼 파일에 작성한 SQL 문을 실행하는 방법
=> select 문장
- sqlSession.selectList() : 목록 리턴
- sqlSession.selectOne() : 한 개의 결과 리턴
=> insert 문장
- sqlSession.insert()
=> update 문장
- sqlSession.update()
=> delete 문장
- sqlSession.delete()
SqlSession.selectList() 사용법 - select 문 실행하기
selectList()
=> 여러 개의 결과 값을 리턴하는 select를 실행할 때 사용한다.
=> select 실행으로 생성된 각 row의 값은 resultType에 지정한 클래스의 인스턴스에 저장된다.
=> 그리고 그 인스턴스는 List 구현체에 담겨 리턴된다.
=> 결과가 없으면 size 가 0인 List 객체를 리턴한다.
실행 결과가 기대와 같지 않은 이유?
=> mybatis에서 결과 값을 Board 객체에 담을 때 일부 컬럼의 값을 담지 못했기 때문이다.
왜 일부 컬럼의 값을 Board에 담지 못했는가?
=> mybatis에서 결과의 컬럼 값을 자바 객체에 담을 때
컬럼 이름과 같은 이름을 가진 프로퍼티(셋터 메서드)를 찾는다.
=> 컬럼 이름과 일치하는 프로퍼티가 없다면,
셋터 메서드를 호출할 수 없기 때문에
해당 컬럼의 값이 자바 객체에 저장되지 못한다.
Mybatis에서 select 결과를 자바 인스턴스에 담을 때 규칙
=> 컬럼 이름과 같은 프로퍼티를 찾아서 값을 담는다.
=> 자바에서 '프로퍼티'란?
세터/게터를 가리키는 용어다.
예) setNo()/getNo()
=> 프로퍼티 이름?
세터/게터 이름에서 set/get 이름을 제거한 후, 나머지 이름이다.
단 첫 알파벳은 소문자이다.
예) setNo()/getNo() => no
예) setCreatedDate()/getCreatedDate() => createdDate
=> 주의!
필드 이름이 프로퍼티 이름이 아니다!
결론!
- Board 클래스의 프로퍼티 이름을 보면
no, title, content, registeredDate, viewCount 가 있다.
- 이 프로퍼티 중에서 컬럼 이름과 같은 프로퍼티는 title 뿐이다.
- Mybatis는 컬럼 이름과 같은 이름을 가진
프로퍼티(title,contents)에 대해서만 결과 값을 넣어 준다.
- 그래서 Board 객체를 출력해보면 title 값만 정상적으로 출력된다.
해결책?
=> 컬럼 이름과 프로퍼티 명을 같게 하면 되지 않겠는가?
- DB의 이름짓는 규칙과 자바의 이름 짓는 규칙은 다르다.
- DBMS 마다 또 이름 짓는 규칙이 다른다.
- 그래서 자바에서 프로퍼티 이름을 지을 때 특정 DBMS에 종속되게 지어서는 안된다.
- 자바는 자바의 명명 규칙을 따르고, DB는 DBMS의 명명 규칙을 따르면 된다.
=> 그러면 어떻게 하자는 것인가?
- select 할 때 컬럼의 별명을 자바 프로퍼티 이름과 같게 하라!
SqlSession.selectList() 사용법 - <resultMap>을 통해 자바 객체의 프로퍼티 이름과 일치시키기
<mapper namespace="BoardMapper">
<!-- 컬럼명과 자바 객체의 프로퍼티 명을 미리 연결한다.
type: 자바 객체의 클래스명 또는 별명
id: 연결 정보를 가리키는 식별자. SQL 문을 설정할 때 사용한다.
-->
<resultMap type="Board" id="BoardMap">
<!-- 컬럼명과 자바 객체의 프로퍼티명을 연결한다.
column="테이블 컬럼명"
property="자바 객체의 프로퍼티명"
시작태그와 끝태그 사이에 추가 내용이 없다면 끝태그를 생략하고
대신에 시작태그의 끝에 /를 붙인다.
PK 컬럼을 지정할 때는 id 엘리먼트를 사용하고,
일반 컬럼을 지정할 때는 result 엘리먼트를 사용하라! -->
<id column="board_id" property="no"/>
<!-- 의미 => board_id 컬럼 값은 Board.setNo()을 호출해서 넣으라는 의미 -->
<!-- 컬럼 이름과 자바 객체의 프로퍼티 이름이 같을 경우 생략해도 된다. -->
<!--
<result column="title" property="title"/>
-->
<result column="contents" property="content"/>
<result column="created_date" property="registeredDate"/>
<result column="view_count" property="viewCount"/>
</resultMap>
<!-- 위에서 정의한 연결 정보를 사용하고 싶다면,
resultMap="컬럼과 프로퍼티의 연결을 정의한 resultMap 아이디" 를 설정하라!
참고!
resultType="클래스명 또는 별명"
-->
<select id="selectBoard" resultMap="BoardMap">
select
board_id, <!-- BoardMap의 연결정보를 참조하기 때문에 별명을 주지 않아도 된다. -->
title,
contents,
created_date,
view_count
from x_board
</select>
</mapper>
SqlSession.selectOne() 사용법 - 결과 값을 Map 객체로 받기
<mapper namespace="BoardMapper">
<!-- select 결과를 Map 객체에 받을 수 있다.
- 각각의 레코드 값은 각각의 Map 객체에 보관된다.
- 그리고 List에 Map 객체 목록이 보관된다.
-->
<select id="selectBoard" resultType="map">
select
board_id,
title,
contents,
created_date,
view_count
from x_board
</select>
</mapper>
Map 객체로 받으려면 SQL 매퍼에서 다음과 같이 resultType을 설정해야 한다.
<select id="selectBoard3" resultType="map" parameterType="int">
select
board_id,
title,
contents,
created_date,
view_count
from x_board
where board_id=#{no}
</select>
- 컬럼 이름(이나 별명)으로 컬럼 값을 저장하기 때문에
map 객체에 컬럼 값을 꺼낼 때 컬럼 이름(이나 별명)을 사용해야 한다.
SQL 문에 삽입할 파라미터 전달하기 - 한 개의 int 값 넘기기
in-parameter에 int 값 넘기기
=> SQL을 실행할 때 파라미터 값을 전달하려면
두 번째 파라미터로 전달해야 한다.
예) selectOne(sql, in-parameter 값)
=> in-parameter 값의 타입은 Object이다.
자바 원시 타입의 값을 지정하면 자동으로 오토 박싱되어 mybatis에 전달된다.
=> 여러 개의 값을 전달해야 한다면,
도메인 객체나 Map 객체에 담아 전달하라!
SQL 문에 삽입할 파라미터 전달하기 - XML Entity를 사용할 때
XML 파서가 혼동을 일으킬 수 있는(XML 파싱 오류 발생) 문자를 사용할 때
- 그 문자 대신 XML Entity를 사용하라.
" => "
' => '
& => &
< => <
> => >
SQL 문에 삽입할 파라미터 전달하기 - CDATA 섹션을 사용할 때 : <[!CDATA[ SQL 문 []]>
CDATA 섹션
- XML 파서(parser)에게 해당 블록의 내용물이 단순 텍스트임을 알려주는 명령이다.
- 문법
<![CDATA[ 내용물 ]]>
- 내용물 안에 XML 파서가 혼동을 일으킬 문자가 많을 때 사용하기 적합하다.
SQL 문에 삽입할 파라미터 전달하기 - Map을 이용하여 여러 개의 값 넘기기
selectList(),selectOne(),insert(),update(),delete()
- selectList(SQL ID)
- selectList(SQL ID, 파라미터)
- 위와 같이 SQL을 실행할 때 오직 한 개의 파라미터만 넘길 수 있다.
- 여러 개의 파라미터를 넘기고 싶다면 객체에 담아서 넘겨라!
'DB' 카테고리의 다른 글
Mybatis에서 DAO 구현체를 자동으로 생성하기 (0) | 2021.10.23 |
---|---|
Mybatis - useGeneratedKeys (0) | 2021.10.22 |
DBMS에 SQL문 보내기 : select,update,delete, FK 가 참조하는 데이터 지우는 방법, insert 한 후 auto increment PK 값 리턴 받기 (0) | 2021.10.20 |
데이터 관리를 DBMS에게 맡기기 : JDBC API 사용 (0) | 2021.10.19 |
Join, 서브쿼리, 그룹으로 묶기 (0) | 2021.10.11 |