티스토리 뷰
[ 1. SqlSessionFactoryBuilder / SqlSessionFactory ] (*)
import static org.junit.jupiter.api.Assertions.assertNotNull;
import java.io.IOException;
import java.io.InputStream;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.TestInstance.Lifecycle;
import org.junit.jupiter.api.TestMethodOrder;
import org.junit.jupiter.api.Timeout;
import lombok.Cleanup;
import lombok.NoArgsConstructor;
import lombok.extern.log4j.Log4j2;
@Log4j2
@NoArgsConstructor
@TestInstance(Lifecycle.PER_CLASS)
// @TestMethodOrder로 테스트 메소드 실행순서를 어떻게 할 것인지 정하는데,
// 주로 OrderAnnotation을 지정하여 @Order로 순서를 지정하게 한다.
@TestMethodOrder(OrderAnnotation.class)
public class SqlSessionFactoryTests {
// sqlSessionFactory를 건설하는 건설사
private SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
private SqlSessionFactory sqlSessionFactory;
// ==============================================
// @BeforeAll는 사전처리로 단 1번만 수행된다.
@BeforeAll
void beforeAll() throws IOException {
log.trace("beforeAll() invoked.");
// mybatis의 설정파일 경로
String config = "mybatis-config.xml";
@Cleanup
InputStream is = Resources.getResourceAsStream(config);
// sqlSessionFactory 생성
this.sqlSessionFactory = this.sqlSessionFactoryBuilder.build(is);
assertNotNull(this.sqlSessionFactory);
log.info("\t + this.sqlSessionFactory : {}", this.sqlSessionFactory );
// sqlSessionFactoryBuilder 생성
// this.sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
// Objects.requireNonNull(this.sqlSessionFactoryBuilder);
// log.info("\t + this.sqlSessionFactoryBuilder : {}", this.sqlSessionFactoryBuilder);
} // beforeAll
// ==============================================
// @Disabled
@Test
@Order(1)
@DisplayName("1. getSqlSession")
@Timeout(value=3000, unit=TimeUnit.MILLISECONDS)
void getSqlSession() throws Exception {
log.trace("getSqlSession() invoked.");
// ==============================================
// sqlSessionFactory 객체로부터 SqlSession을 얻어내자!!
// sqlSession 객체를 다 사용하고 나면, 반드시 자원해제를 해줘야 한다.
// @Cleanup // 자원해제
SqlSession sqlSession = this.sqlSessionFactory.openSession();
Objects.requireNonNull(sqlSession);
log.info("\t + sqlSession : {}", sqlSession);
// SQL 문장 처리를 프레임워크에 의뢰
try ( sqlSession ){
;;
} // try - with - resources
// ==============================================
// SQL 연결을 얻어낸다.
// Connection conn = sqlSession.getConnection();
// assert conn != null;
// log.info("\t + conn : {}", conn);
// ==============================================
} // contextLoads
} // end class
[ 2. MyBatis 규격 - SqlSessionFactoryBuilder / SqlSessionFactory ] (*****)
[ 2 - 1. myBatis-config.xml : myBatis 환경설정 파일 만들기 ]
<?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>
<!-- 서비스 환경 -->
<environments default="production">
<environment id="development">
<transactionManager type="JDBC"/>
<!-- dataSource는 Connection pool 제공해 준다. -->
<dataSource type="UNPOOLED">
<!-- JDBC Driver spy 적용X ver. -->
<!-- <property name="driver" value="oracle.jdbc.OracleDriver"/> -->
<!-- <property name="url" value="jdbc:oracle:thin:@db000000_high?TNS_ADMIN=C:/opt/OracleCloudWallet/ATP"/> -->
<!-- JDBC Driver spy 적용 ver. -->
<property name="driver" value="net.sf.log4jdbc.sql.jdbcapi.DriverSpy"/>
<property name="url" value="jdbc:log4jdbc:oracle:thin:@db000000_high?TNS_ADMIN=C:/opt/OracleCloudWallet/ATP"/>
<property name="username" value="ADMIN"/>
<property name="password" value="Oracle000000"/>
<!-- <property name="defaultTransactionIsolationLevel" value="" /> -->
<!-- <property name="defaultNetworkTimeout" value="1000" /> -->
<property name="driver.encoding" value="utf8" />
</dataSource>
</environment>
<environment id="production">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<!-- JDBC Driver spy 적용X ver. -->
<!-- <property name="driver" value="oracle.jdbc.OracleDriver"/> -->
<!-- <property name="url" value="jdbc:oracle:thin:@db000000_high?TNS_ADMIN=C:/opt/OracleCloudWallet/ATP"/> -->
<!-- JDBC Driver spy 적용 ver. -->
<property name="driver" value="net.sf.log4jdbc.sql.jdbcapi.DriverSpy"/>
<property name="url" value="jdbc:log4jdbc:oracle:thin:@db000000_high?TNS_ADMIN=C:/opt/OracleCloudWallet/ATP"/>
<property name="username" value="ADMIN"/>
<property name="password" value="Oracle0000000"/>
<property name="poolMaximumActiveConnections" value="10" />
<property name="poolMaximumIdleConnections" value="3" />
<property name="poolTimeToWait" value="20000" />
<property name="poolPingQuery" value="SELECT 1 FROM dual" />
<property name="poolPingEnabled" value="true" />
<property name="poolPingConnectionsNotUsedFor" value="60000" />
<property name="driver.encoding" value="utf8" />
</dataSource>
</environment>
</environments>
<!-- 관리할 Mapper 파일 작성해 주기 (***) -->
<!-- Mapper 파일은 여러개일 수 있다. -->
<mappers>
<mapper resource="BoardMapper.xml" />
</mappers>
</configuration>
[ 2 - 2. BoardMapper.xml : sql문장을 지니고 있는 파일 설정 ]
<?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="BoardMapper">
<!-- CRUD의 기본적인 태그를 지니고 있다. -->
<!-- 태그의 id는 주로 실행시킨 메소드의 이름을 그대로 사용한다. (맘대로 작성해도 ok) -->
<!-- id의 값은 유니크해야 한다. -->
<!-- resulType은 반환될 구체타입을 지정해 주면 된다. : List타입을 반환하지만 실제로는 List<BoardVO>이기에 BoardVO의 FQCN을 지정해주면 된다. -->
<!-- 즉, List<E>를 반환한다면 resulType에 <E>를 지정해 주면 된다. -->
<select id="selectAllBoards" resultType="org.zerock.myapp.domain.BoardVO">
SELECT * FROM tbl_board
</select>
<!-- <insert id=""></insert> -->
<!-- <update id=""></update> -->
<!-- <delete id=""></delete> -->
</mapper>
[ 2 - 3. VO : 테이블에 맞게 VO 만들기 ]
package org.zerock.myapp.domain;
import java.sql.Timestamp;
import lombok.Value;
@Value // VO 객체는 Value, DTO는 @data
public class BoardVO {
// null도 포함되어야 하기 때문에 참조타입이어야 한다.
// 기본타입(ex. int)은 참조타입(ex. Integer)과 다르게 NULL을 받아들일 수 없다.
private Integer bno;
private String title;
private String content;
private String writer;
private Timestamp insert_ts;
private Timestamp update_ts;
// Timestamp는 오류가 날 수 있는데, 그렇다면 Date를 사용하자
// private Date INSERT_TS;
// private Date UPDATE_TS;
// private LocalDateTime INSERT_TS;
// private LocalDateTime UPDATE_TS;
} // end class
[ 2 - 4. SqlSessionTests.java : 실행하기 ]
import static org.junit.jupiter.api.Assertions.assertNotNull;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.TestInstance.Lifecycle;
import org.junit.jupiter.api.TestMethodOrder;
import org.junit.jupiter.api.Timeout;
import org.zerock.myapp.domain.BoardVO;
import lombok.Cleanup;
import lombok.NoArgsConstructor;
import lombok.extern.log4j.Log4j2;
@Log4j2
@NoArgsConstructor
@TestInstance(Lifecycle.PER_CLASS)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class SqlSessionTests {
private SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
private SqlSessionFactory sqlSessionFactory;
// ======================================================
// 1. 사전처리로 마이바틱스 설정을 기반으로 SqlSessionFactory 객체 생성 @BeforeAll
// ======================================================
@BeforeAll
void beforeAll() throws IOException {
log.trace("beforeAll() invoked.");
// 마이바틱스 설정 파일
String myBatisConfigXml = "mybatis-config.xml";
@Cleanup
InputStream is = Resources.getResourceAsStream(myBatisConfigXml);
Objects.requireNonNull(is);
this.sqlSessionFactory = builder.build(is);
} // beforeAll
// ======================================================
// 2. SQL을 실행할 메소드 생성 - selectAllBoards ( SELECT문 )
// ======================================================
// @Disabled
@Test
@Order(1)
@DisplayName("2. selectAllBoards")
@Timeout(value=10, unit=TimeUnit.SECONDS)
void selectAllBoards() {
log.trace("selectAllBoards() invoked.");
// SqlSessionFactory 객체에서 SqlSession 얻기
SqlSession sqlSession = this.sqlSessionFactory.openSession();
// ======================================================
// 2 - 1. SQL 문장 처리를 프레임워크에 의뢰
// ======================================================
try ( sqlSession; ) {
// ====================================
// 아래의 2가지가 많이 사용된다.
// 1. 반환되는 결과가 1개일때
// sqlSession.selectOne(sql);
// 2. 반환되는 결과가 0개 이상일때
// sqlSession.selectList(sql);
// ====================================
// ==================================================================
// String sql = "SELECT * FROM tbl_board"; <--- Mapper.xml로 이동
// 마이바틱스에서 실행시킬 sql문장은 Mapper.xml에서 보관한다.
// ==================================================================
// 마이바틱스가 요구하는 규칙 ( 수행시킬 SQL문장을 지정하는 방식 ) :
// 1) 각 SQL Mapper XML 파일 안의 namespace 속성마다 고유한 값을 가져야 한다.
// 2) 각 SQL Mapper XML 파일 안에 저장된 각 SQL 태그마다 고유한 id값을 가져야 한다.
// + 주로 id값은 일반적으로 SQL을 수행할 메소드의 이름과 동일하게 작성한다.
// + 하지만 필수요구사항은 아니기에 개발자가 원하는대로 id값을 작성해도 된다. ( 단, 고유해야 한다. )
// ==================================================================
// 이 규격을 지켜야 한다.
String namespace ="BoardMapper";
String sqlId = "selectAllBoards";
String sql = namespace + "." + sqlId; // Unique Identifier
List<BoardVO> list = sqlSession.selectList(sql);
assertNotNull(list);
// 마이바틱스에서 실행시킬 sql문장은 Mapper.xml에서 보관한다.
list.forEach(log::info);
} // try - with - resources
// ======================================================
} // selectAllBoards
} // end class
728x90
'KH 정보교육원 [ Java ]' 카테고리의 다른 글
KH 103일차 - myBatis마이바틱스 3 ( 검색조건 설정 / 히카리CP ) (*****) (0) | 2022.07.25 |
---|---|
KH 102일차 - myBatis ( 마이 바틱스 ) (*****) (0) | 2022.07.22 |
KH 100일차 - JSTL (***) (0) | 2022.07.20 |
KH 99일차 - EL / JSTL (*****) (0) | 2022.07.19 |
KH 98일차 - JSP ( 액션 태그 ) ( ***** ) (0) | 2022.07.18 |
댓글