- SqlSession 사용
SqlSession 객체는 SQL을 실행하는 도구이다. 이 객체가 있어야만 SQL문을 실행할 수 있다. 이 객체는 직접 생성할 수는 없고 SqlSessionFactory 객체를 통해서만 얻을 수 있다.
//SqlSession : SQL 실행하는 도구, sqlSessionFactory 객체 통해서만 얻을 수 있다
SqlSession sqlSession = sqlSessionFactory.openSession();
SqlSession 객체를 사용한 예를 보면, 회원 목록을 얻고자 SqlSession 객체의 selectList() 메서드를 호출하고 있다. selectList() 메서드는 여러 개의 결과를 반환하는 SELECT문을 실행할 때 호출한다.
//SqlSession : SQL 실행하는 도구, sqlSessionFactory 객체 통해서만 얻을 수 있다
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
//selectList() : 여러 개의 결과 반환하는 SELECT문 실행시 호출
return sqlSession.selectList("spms.dao.ProjectDao.selectList");
} finally {
//close() : SQL문 실행할 때 사용한 자원 해제
sqlSession.close();
}
SqlSession 객체 또한 DB 커넥션처럼 사용을 완료한 후에는 닫아야 한다. SqlSession 객체의 close() 메서드를 호출하면 SQL문을 실행할 때 사용한 자원을 해제한다.
- SqlSession의 주요 메서드
SqlSession 객체는 SQL문을 실행할 때 사용할 수 있는 메서드들을 갖추고 있다. 다음 표는 SqlSession 객체의 주요 메서드를 정리한 것이다.
메서드 | 설명 |
selectList() | SELECT문을 실행. 값 객체(Value Object) 목록을 반환함. |
selectOne() | SELECT문을 실행. 하나의 값 객체를 반환함. |
insert() | INSERT문을 실행. 반환값은 입력한 데이터 개수. |
update() | UPDATE문을 실행. 반환값은 변경한 데이터 개수. |
delete() | DELETE문을 실행. 반환값은 삭제한 데이터 개수. |
- SqlSession의 selectList() 호출 문법
SqlSession 객체의 메서드 중에서 selectList() 메서드에 대해 알아본다. selectList() 메서드는 SELECT문을 실행할 때 호출하는 메서드이다. 호출 규칙은 다음과 같다.
List<E> selectList(String sqlId)
selectList() 메서드를 호출할 때 넘기는 매개변수 값은 SQL 아이디이다. sqlId는 SQL 맵퍼의 네임스페이스 이름과 SQL문의 아이디를 결합하여 만든 문자열이다.
sqlId = SQL 맵퍼의 네임스페이스 이름 + SQL 문 ID
예) "spms.dao.ProjectDao.selectList" = "spms.dao.ProjectDao" + "selectList"
MySqlProjectDao 클래스에서 selectList() 메서드의 호출 부분을 살펴본다.
//SqlSession : SQL 실행하는 도구, sqlSessionFactory 객체 통해서만 얻을 수 있다
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
//selectList() : 여러 개의 결과 반환하는 SELECT문 실행시 호출
return sqlSession.selectList("spms.dao.ProjectDao.selectList");
} finally {
//close() : SQL문 실행할 때 사용한 자원 해제
sqlSession.close();
}
selectList() 메서드의 매개변수 값에서 'spms.dao.ProjectDao'는 SQL 맵퍼의 네임스페이스 이름이고, 'selectList'는 SQL문의 아이디이다. 즉 SQL 맵퍼 파일에서 'selectList'라는 아이디를 갖는 <select> 태그를 가리키는 것이다.
- SQL 맵퍼 파일의 일부분
<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>
...
만약 SELECT문을 실행하는데 값이 필요하다면 다음과 같이 두 번째 매개변수로 값을 담은 객체를 넘기면 된다. 앞의 코드에서 insert() 메서드와 selectOne(), update(), delete() 메서드는 두 번째 매개변수로 객체를 넘겨주고 있다.
List<E> selectList(String sqlId, Object parameter)
- SqlSession의 insert()와 매개변수 값 전달
프로젝트 정보를 입력하기 위해서는 SqlSession 객체의 insert() 메서드를 호출할 때 두 번째 매개변수로 프로젝트 정보를 담은 값 객체를 넘겨야 한다.
public int insert(Project project) throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
//자동 커밋(Auto-commit)을 수행하는 sqlSession 객체 반환
//SqlSession sqlSession = sqlSessionFactory.openSession(true);
try {
//insert() : 두 번째 매개변수로 프로젝트 정보 담은 값 객체 전달
int count = sqlSession.insert("spms.dao.ProjectDao.insert", project);
...
이렇게 전달된 'project' 객체는 다음과 같이 SQL 맵퍼 파일의 insert문을 실행할 때 사용된다.
- SQL 맵퍼 파일의 일부분
<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>
#{프로퍼티명} 자리에 project 객체의 프로퍼티 값이 놓인다. 객체의 프로퍼티란? 인스턴스 변수를 말하는 것이 아니다. 겟터/셋터를 가리키는 용어이다. 프로퍼티 이름은 겟터/셋터 메서드의 이름에서 추출한다. 다음 그림은 겟터/셋터 메서드와 프로퍼티의 관계를 보여주고 있다(그림 1).
앞의 SQL 문에서 #{title} 자리에는 project 객체의 getTitle() 메서드 반환값이 놓이고, #{content}에는 getContent() 메서드 반환값이 놓인다. #{startDate}는 getStartDate() 메서드, #{endDate}는 getEndDate() 메서드, 마지막으로 #{tags}에는 getTags() 메서드 반환값이 놓인다.
sqlSession.insert() 메서드를 호출할 때 두 번째 매개변수의 값은 이렇게 SQL문을 실행할 때 사용된다. update() 메서드와 selectOne(), delete(), selectList() 메서드 또한 마찬가지이다.
- SqlSession의 selectOne()과 delete()에 Integer 객체 전달
selectOne() 메서드와 delete() 메서드를 호출할 때 프로젝트 번호(no)를 매개변수 값으로 전달하였다. 물론 int와 같은 기본 데이터 형은 객체가 아니므로 매개변수로 사용할 수 없다. 그런데도 다음과 같이 매개변수로 전달해도 컴파일 오류가 발생하지 않는다. 그 이유는 컴파일 시 Integer 객체로 자동 포장(Auto-boxing)되기 때문이다. 즉 new Integer(no) 코드로 변환된다.
public Project selectOne(int no) throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
//selectOne() : 두 번째 매개변수로 int 값 전달(컴파일 시 Integer 객체로 자동 포장(Auto-boxing) : new Integer(no))
return sqlSession.selectOne("spms.dao.ProjectDao.selectOne", no);
...
}
public int delete(int no) throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
//delete() : 두 번째 매개변수로 int 값 전달(컴파일 시 Integer 객체로 자동 포장(Auto-boxing) : new Integer(no))
int count = sqlSession.delete("spms.dao.ProjectDao.delete", no);
...
}
Integer 클래스에는 프로퍼티를 의미하는 겟터 메서드가 없어서 이렇게 기본 타입의 객체(보통 랩퍼(wrapper) 객체라 부름)로부터 값을 꺼낼 때는 아무 이름이나 사용해도 된다. 다음 코드에서는 Integer 객체의 값을 꺼내고자 'value'라는 이름을 사용했다.
- SQL 맵퍼 파일의 일부분
<delete id="delete" parameterType="int">
DELETE FROM PROJECTS
WHERE PNO = #{value}
</delete>
앞에서 설명한 대로 기본 타입 객체일 경우 아무 이름이나 사용해도 된다. #{no}라고 해도 되고, #{okok}라고 해도 된다.
- commit()과 rollback() 메서드
DBMS는 INSERT, UPDATE, DELETE문을 실행하면 그 작업 결과를 임시 데이터베이스에 보관한다. 클라이언트 요청이 있어야만 임시 데이터베이스의 작업물을 운영 데이터베이스에 반영한다(그림 2).
commit() 메서드는 임시 데이터베이스에 보관된 작업 결과를 운영 데이터베이스에 적용하라고 요청할 때 사용하는 메서드이다. 예제 코드에서 insert(), update(), delete() 메서드를 호출하는 부분을 보면 commit() 메서드를 사용하고 있다.
//insert() : 두 번째 매개변수로 프로젝트 정보 담은 값 객체 전달
int count = sqlSession.insert("spms.dao.ProjectDao.insert", project);
//임시 데이터베이스에 보관된 작업 결과를 운영 데이터베이스에 적용
sqlSession.commit();
...
//update() : 두 번째 매개변수로 프로젝트 정보 담은 값 객체 전달
int count = sqlSession.update("spms.dao.ProjectDao.update", project);
//임시 데이터베이스에 보관된 작업 결과를 운영 데이터베이스에 적용
sqlSession.commit();;
...
//delete() : 두 번째 매개변수로 int 값 전달(컴파일 시 Integer 객체로 자동 포장(Auto-boxing) : new Integer(no))
int count = sqlSession.delete("spms.dao.ProjectDao.delete", no);
//임시 데이터베이스에 보관된 작업 결과를 운영 데이터베이스에 적용
sqlSession.commit();
...
SELECT문은 값을 변경하는 것이 아니므로 commit() 메서드를 호출할 필요가 없다.
rollback() 메서드는 임시 데이터베이스의 작업 결과를 운영 데이터베이스에 반영하지 않고 취소할 때 호출한다.
- 자동 커밋
INSERT, UPDATE, DELETE를 실행할 때 자동으로 커밋하고 싶다면, SqlSession 객체를 생성할 때 다음과 같이 지정한다.
//자동 커밋(Auto-commit)을 수행하는 sqlSession 객체 반환
SqlSession sqlSession = sqlSessionFactory.openSession(true);
openSession() 메서드의 매개변수 값을 true로 지정하면 자동 커밋(Auto-commit)을 수행하는 SqlSession 객체를 반환한다. 자동 커밋으로 설정해 놓고 쓰면 편리하지만 트랜잭션을 다룰 수 없다. 트랜잭션에 대해서는 추후 진행되는 강의에서 자세히 설명한다.
참고도서 : https://freelec.co.kr/book/1674/
[열혈강의] 자바 웹 개발 워크북
[열혈강의] 자바 웹 개발 워크북
freelec.co.kr
'교재 실습 > 자바 웹 개발 워크북' 카테고리의 다른 글
106. mybatis 적용 (4) (0) | 2022.08.31 |
---|---|
105. mybatis 적용 (3) (1) | 2022.08.30 |
103. mybatis 적용 (1) (0) | 2022.08.28 |
102. mybatis 소개 (2) | 2022.08.27 |
101. 퍼시스턴스 프레임워크의 도입 도입부 및 환경설정 (0) | 2022.08.25 |
댓글