[project] mybatis 설정

Walter Mitty·2023년 1월 16일
1

| DB 테이블 - product

select * from product;

|Vo - ProductVo.java

package com.myomi.product;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;

@Setter @Getter
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class ProductVo {
	private int num;
	private String sellerId;
	private String category;
	private String name;
	private int originPrice;
	private int percentage;
	private int week;
	private int status;
	private String detail;
	private int reviewCnt;
	private int stars;
	private int fee;
}

테이블 설계하고 Vo 작성한 후 MyBatis 설정문서부터 만든다.
(SQLMapConfig.xml가 핵심이 되는 MyBatis 설정문서라고하는데 나는 좀 다르게 만들어서 내일 비교예정!)

| properties - dbconn.properties

  • properties 파일에는 상수에 대한 정보를 넣는데 Map 방식으로 넣는다. 자바 진영에서 매우 중요하다.
  • dbconn.properties = DB 서버와 관련하여 상수값에 대한 정보를 메타데이터화한다.

어디까지나 예시인코드!

### dbconn.properties file....dbServer Information Storing
jdbc.mysql.driver=com.mysql.cj.jdbc.Driver
jdbc.mysql.url=jdbc:mysql://127.0.0.1:3306/scott?characterEncoding=UTF-8&serverTimezone=UTC
jdbc.mysql.username=root //당연하게도 자기 유저네임이랑
jdbc.mysql.password=1234 //패스워드 넣어야함.

| DTD(Document Type Definition)

문서의 첫줄에 <!DOCTYPE>으로 시작하는 문법을 말한다.

  • MyBatis 설정문서의 DTD선언부
<!DOCTYPE configuration
 PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
 "http://mybatis.org/dtd/mybatis-3-config.dtd"> 

위 코드를 보면 configuration이 Root Tag에 해당한다. <configuration> </configuration>

SqlMapConfig.xml

DB 서버 정보, Vo 정보, SQL 쿼리문 정보를 다 쥐고 있다.
Persistence Freamwork

<?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>
 	<!-- 1. properties 파일 연결 -->
 	<!-- Wiring 시킨다. 클래스가 해징하듯이 파일들을 자동으로 연결시킴 -->
 	<properties resource="config/dbconn.properties"/>
    
    	<!-- Oracle인 경우 null값을 허용하지 않기에 반드시 옵션을 추가해야 실행될 수 있다
	settings 태그의 위치 주의. value에 NULL 값을 대문자로 입력해야 한다.
	MySQL인 경우에는 상관없다.-->
	<settings>
		<setting name="jdbcTypeForNull" value="NULL"/>
	</settings>
 	
	<!-- 2. vo 연결 및 alias 지정 -->
 	<!-- FQCN이 기니까 alias로 쓴다 -->
 	<!-- 복수로 끝나는 태그는 안에 단수로 끝나는 태그가 있다. -->
 	<typeAliases>
 		<typeAlias type="com.encore.mybatis.vo.MySawon" alias="mySawon"/>
 	</typeAliases>
 	
	<!-- 3. DB 서버 정보 -->
 	<!-- default와 id에 어떤 값이든 넣어도 되는데 같은 값으로 넣어줘야 한다. -->
 	<environments default="development">
 		<environment id="development">
 			<transactionManager type="JDBC"/>
 			<!-- type=UNPOOLED ==> DriverManager 방식 -->
 			<!-- type=POOLED ==> DataSource 방식 -->
 			<!-- type=JNDI ==> NamingService... POOLED와 같다 -->
 			<dataSource type="UNPOOLED">
 				<!-- Setter -->
 				<property name="driver" value="${jdbc.mysql.driver}"/>
 				<property name="url" value="${jdbc.mysql.url}"/>
 				<property name="username" value="${jdbc.mysql.username}"/>
 				<property name="password" value="${jdbc.mysql.password}"/>
 			</dataSource>
 		</environment>
 	</environments>
 	
 	<!-- SQL Mapping -->
 	<mappers>
 		<mapper resource="mapper/mysawon_mapping.xml"/>
 	</mappers>
 </configuration>

이건 내코드

<?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>
	<settings>
	<!-- Camel Case, Snake Case로만 다를 경우 
        	resultMap을 안 써도 이 코드 쓰면 알아서 바꿔줌 -->
		<setting name="mapUnderscoreToCamelCase" value="true"/>
		<setting name="jdbcTypeForNull" value="NULL" />
    </settings>
    <!-- 2. vo 연결 및 alias 지정 -->
    <typeAliases>
		<typeAlias alias="Product" type="com.myomi.product.ProductVo"/>
	</typeAliases>
	<!-- 3. DB 서버 정보 -->
	<environments default="development">
		<environment id="development">
			<transactionManager type="JDBC" />
			<dataSource type="POOLED">
				<property name="driver"
					value="oracle.jdbc.driver.OracleDriver" />
				<property name="url"
					value="jdbc:oracle:thin:@localhost:1521:xe" />
				<property name="username" value="유저명" />
				<property name="password" value="비밀번호" />
			</dataSource>
		</environment>
	</environments>
	<mappers>
		<mapper resource="com/myomi/product/product-mapper.xml" />
	</mappers>
</configuration>

DB 서버에 대한 값을 외부로 메타데이터화 시켰는데 그 값을 끌어오지 않고 직접 적어주면 비효율적이다. 수정이 필요한 경우에는 모듈화된 외부 파일만 건드리게 해야한다.
따라서, SQLMapConfig.xml 파일에 dbconn.properties의 key를 EL 기법으로 넣어준다.

| product-mapping.xml

SQL 쿼리문을 넣는다.
SQL을 xml 기반으로 Mapping 한다.

  • 값을 getter로 가져올 때는 #{}를 사용한다.
    • 이렇게 가져온 값을 가지고 DB로가서 CRUD!

예시

<?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="mysawonMapper">
 
 	<!-- SqlMapConfig.xml에서 alias로 정한 VO 객체 mySawon을 parameterType에 넣어준다 -->
 	<!-- Getter는 형태가 #{} / #{id}는 vo.getId를 xml식으로 표현한 것 -->
 	<!-- curDate() -> mySQL 함수. 현재 연-월-일 -->
 	<insert id="sawonAdd" parameterType="mySawon">
 		INSERT
 		INTO mysawon(id, pwd, name, age, hiredate) 
 		VALUES(#{id}, #{pwd}, #{name}, #{age}, curDate())
 	</insert>
    
 	<!-- 전부 다 불러올 거라서 parameterType 안 줌 -->
 	<!-- resultType을 List로 받을 건데 List의 제네릭을 넣음 -->
 	<select id="sawonList" resultType="mySawon">
 		SELECT
 		num, id, name, age, hiredate
 		FROM mysawon
 		ORDER BY num DESC
 	</select>
 </mapper>

내 코드!
컬럼명 옆에 AS 로 별칭을 붙여준 이유는 camelCase 때문에 붙여줬다.

<?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" >
<!-- SQL definition -->
<mapper namespace="ProdMapper">
	<select id="getProdList" resultType="product">
		SELECT
 		num AS num, 
 		seller_id AS sellerId, 
 		category AS category, 
 		name AS name, 
 		origin_price AS originPrice, 
 		percentage AS percentage,
 		week AS week,
 		status AS status,
 		detail AS detail,
 		review_cnt AS reviewCnt,
 		stars AS stars,
 		fee AS fee
 		FROM product
 		<!-- ORDER BY num; -->
	</select>
</mapper>

단위테스트

  • Scanner 클래스를 통해 값을 받아서 product 정보 추가해보기
    입력받은 값을 MyBatis 라이브러리를 사용해서 DB에 Access해보자

| SimpleMyBatisAppTest.java

예제

package com.encore.mybatis.test;

import java.io.Reader;
import java.util.Scanner;

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 com.encore.mybatis.vo.MySawon;

public class SimpleMyBatisAppTest {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		MySawon vo = new MySawon();
		
		System.out.println("아이디 : ");
		vo.setId(sc.next());
		
		System.out.println("비밀번호 : ");
		vo.setPwd(sc.next());
		
		System.out.println("이름 : ");
		vo.setName(sc.next());
		
		System.out.println("나이 : ");
		vo.setAge(sc.nextInt());
		
		//MyBatis 라이브러리 사용...
		try {
			//1. SQLMapConfig.xml을 읽어들인다.
			Reader r = Resources.getResourceAsReader("config/SqlMapConfig.xml");
			
			//2. SqlSessionFactory를 리턴받는다.
			SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(r);
			
			//3. SqlSession을 리턴받는다.
			SqlSession session = factory.openSession();
			
			//4. session에 쿼리문을 실행하는 모든 기능이 다 들어있다...
			// insert(), delete(), update(), selectList()-다 가져올 때, selectOne()-하나만 가져올 때
			session.insert("mysawonMapper.sawonAdd", vo);
			session.commit(); //DML(추가/수정/삭제)일 때 반드시 해줄 것.
			session.close(); //spring DI Framework일 때는 들어가 있다..
            
			System.out.println(vo.getName()+" 님 정보 입력 성공!!!");
		}catch(Exception e) {
			System.out.println(vo.getName()+" 님 정보 입력 실패!!!");
		}
	}

}

내코드(나는 insert가 아니라 select라 읽어오는 로직만..!)

package com.myomi.common;

import java.io.IOException;
import java.io.Reader;
import java.util.List;

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 com.myomi.product.ProductVo;

public class MyBatisTestApp01 {

	public static void main(String[] args) throws IOException {

		Reader reader=Resources.getResourceAsReader("com/myomi/product/product-config.xml");
		SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(reader);		
		SqlSession session=factory.openSession();
        
		List<ProductVo> list=session.selectList("ProdMapper.getProdList");
		
		//0. getUserList :: 모든 user 정보
		System.out.println(":: 0. all Product(SELECT)  ? ");
		
		for (int i =0 ;  i < list.size() ; i++) {
			System.out.println( "<"+ ( i +1 )+"> 번째 회원.."+ list.get(i).toString() );
		}
	}

}

참고자료

0개의 댓글