Hayden's Archive
[Spring/MyBatis] MyBatis 라이브러리를 통한 DB Access와 CRUD 코드 본문
* 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();
}
}