Hayden's Archive

[Spring/MyBatis] MyBatis 라이브러리를 통한 DB Access와 CRUD 코드 본문

Study/DB

[Spring/MyBatis] MyBatis 라이브러리를 통한 DB Access와 CRUD 코드

_hayden 2020. 8. 4. 15:06

* Summary

 

SqlSession 

 * query statement 
 * INSERT INTO ------------- insert() 
 * DELETE FROM ------------- delete() 
 * UPDATE table ------------ update() 
 * SELECT all -------------- List selectList() 
 * SELECT one -------------- Object selectOne() 

 


DB 테이블 - mysawon 

 


VO - MySawon.java

package com.encore.mybatis.vo;
/*
 * Framework에서는 반드시 기본 생성자를 넣어야 한다.(생성자 아무것도 안 넣었을 경우에는 알아서 만들어짐)
 * MyBatis에서는 값의 주입을 Setter로 하고, 받아올 때는 Getter로 받아옴
 */
public class MySawon {
	private int num, age; //num은 auto_increment
	private String id, pwd, name, hiredate;
	
	public int getNum() {
		return num;
	}
	public void setNum(int num) {
		this.num = num;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getPwd() {
		return pwd;
	}
	public void setPwd(String pwd) {
		this.pwd = pwd;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getHiredate() {
		return hiredate;
	}
	public void setHiredate(String hiredate) {
		this.hiredate = hiredate;
	}
	
	@Override
	public String toString() {
		return "MySawon [num=" + num + ", age=" + age + ", id=" + id + ", pwd=" + pwd + ", name=" + name + ", hiredate="
				+ hiredate + "]";
	}
}

 

DB 테이블 설계하고 VO 작성하고 나서 MyBatis 설정 문서부터 만든다.

SQLMapConfig.xml 이 핵심이 되는 MyBatis 설정문서임.

 

 


* 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 Framework

<?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>

값은 값대로 따로 모듈화시키고 모듈화된 값을 끌어다쓴다. 
DB 서버에 대한 값을 외부로 메타데이터화 시켰는데, 그 값을 끌어오지 않고 직접 적어주면 비효율적. 
수정이 필요할 경우 모듈화된 외부 파일만 건드리게 해야 함.

따라서 SQLMapConfig.xml 파일에 dbconn.properties의 key를 EL기법으로 넣어줌.

 


mysawon_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>

 

 


* 단위 테스트

 

< mysawon_mapping.xml 의 sawonAdd >

Scanner를 통해서 값을 입력(화면을 대신한다). mysawon 테이블에 사원 정보 추가.
입력받은 값을 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()+" 님 정보 입력 실패!!!");
		}
	}

}

 


< mysawon_mapping.xml 의 sawonList >

mysawon 테이블에 있는 모든 사원의 정보를 출력하는 코드

 

 STEP 1 ) 

SimpleMyBatisAppTest2.java

package com.encore.mybatis.test;

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

public class SimpleMyBatisAppTest2 {

	public static void main(String[] args) {
		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();
			
			List<MySawon> list = session.selectList("mysawonMapper.sawonList");
			
			for(MySawon vo : list) {
				System.out.println(vo.getId()+", "+vo.getName()+", "+vo.getHiredate());
			}
			session.close(); 
			
		}catch(Exception e) {
			System.out.println("불러오기 실패!!!");
		}
	}
}

 

 

 STEP 2 ) 

FactoryService.java

SqlSessionFactory 하나 받아오는 로직을 따로 분리

package com.encore.mybatis.test;

import java.io.Reader;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class FactoryService {
	private static SqlSessionFactory factory;
	
	static { //static 초기화 블록
		try {
			Reader r = Resources.getResourceAsReader("config/SqlMapConfig.xml");
			factory = new SqlSessionFactoryBuilder().build(r);
			
		}catch(Exception e){
			//e.printStackTrace();
		}
	}//static
	
	public static SqlSessionFactory getFactory() {
		return factory;
	}
}

 

SimpleMyBatisAppTest3.java

FactoryService.java를 통해 SqlSessionFactory를 리턴받는다.

package com.encore.mybatis.test;

import java.util.List;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;

import com.encore.mybatis.vo.MySawon;

public class SimpleMyBatisAppTest3 {

	public static void main(String[] args) {
		
		SqlSessionFactory factory = FactoryService.getFactory();
		SqlSession session = factory.openSession();

		List<MySawon> list = session.selectList("mysawonMapper.sawonList");

		for(MySawon vo : list) {
			System.out.println(vo.getId()+", "+vo.getName()+", "+vo.getHiredate());
		}
		session.close(); 
	}
}