Mybatis - 인터페이스를 이용한 사용
- SQL Mapper(SQL 과 자바코드의 분리) 방식의 데이터베이스 연동 프레임워크
- 사용 방법은 xml(예전방식)을 이용하는 방법과 인터페이스(최근방식)를 이용하는 방법
- 대부분 xml을 이용하는 방식이 초창기 방식이고 json이나 코드로 설정 방식이 최근의 방식
1. Spring 프로젝트에서 MyBatis를 사용하기 위한 준비
- spring-jdbc, mybatis, mybatis-spring 라이브러리
- 사용하고자 하는 데이터베이스 연동 라이브러리
없어도 되는데 있어야 하는게 있다는 생각
데이터베이스 로그를 기록하는 것, lombok 같은 라이브러리는 필수 사항이 아니다.
워낙 많이 같이 사용을 하기 때문에 필수 사항인 것처럼 여겨지는 것이다.
2.인터페이스를 이용하는 방식
- 인터페이스를 생성하고 데이터베이스 구동 메소드의 원형을 선언하고 위에
@하고자 하는 SQL이름(실제 SQL)
을 추가해주면된다. Spring Bean Configuration
파일에 2개의 Bean을 생성- 첫번째
SqlSessionFactoryBean
을 생성하는데 여기에는dataSource
프로퍼티에 사용할 데이터베이스의DataSource
를 설정 - 두번째
MapperFactoryBean
을 생성하는데 앞에서 만든SqlSessionFactoryBean
이 필요하고 다른 하나는 인터페이스가 필요
- 첫번째
다른 클래스에서 인터페이스를 주입받아서 사용하면 된다.
3. Goods 테이블의 데이터이 CRUD 작업을 MyBatis를 이용하는 실습
1) 데이터베이스 정보
- 종류 : Oracle
- URL :
211.183.6.60:xe(SID)
만약에 ServiceName을 이용하는 경우에는/servicename
(oracle 11g이상 ) - UserName : user13
- Password : user13
문서의 형태로 제공
- DBeaver
SQL Server : 외부 접속이 안됨. 임베디드
Apache Hive : 하둡 , 하둡의 에코 시스템을 이용해서 디비를 사용, 하이브를 사용함. (카산드라 예전에 사용)
Mongo DB :
SAP - HANADB : 관계형 데이터베이스 , Oracle의 대항마, 현대기아, 한화
티맥스 - Tibero : 공공기관 데이터베이스
MySQL8+ : 카카오사용
- OS Authentication(인증) - 서버나 클라우드 환경 개발
Auto Commit 먼저 해제 - Manual로 변경하고 진행, Back_up 잘하자
2) 프로젝트 생성
- gitbub 에서 내려받기
3) Oracle과 MyBatis를 사용하기 위한 의존성 라이브러리 설정
- pom.xml 파일에 작성
- oracle, spring-jdbc, mybatis-spring, lombok
4) 소스코드를 작성할 src/main/java
디렉토리를 생성
1) java version을 1.8로 변경
- 프로젝트를 선택하고 마우스 오른쪽을 클릭해서 [Build Path]-[Configure Build Path]를 선택
- JRE System Library를 선택한 후 edit 버튼을 눌러서 변경
- 배포할 때 상대방 컴퓨터에 설치된 자바의 최소 버전 설정이기도 합니다.
// 아래 생성된 데이터베이스 테이블로 연결 할것이다.
CREATE TABLE goods(
code number(6) PRIMARY KEY,
name varchar2(50) NOT NULL,
manufacture varchar2(50),
price number(10)
);
INSERT INTO goods(code, name, manufacture, price)
values(1, '낙지', '목포', 8000);
INSERT INTO goods(code, name, manufacture, price)
values(2, '과메기', '포항', 20000);
INSERT INTO goods(code, name, manufacture, price)
values(3, '인삼', '금산', 200000);
COMMIT;
전체 데이터를 조회
SELECT * FROM goods;
code를 가지고 하나의 데이터를 조회
SELECT * FROM goods WHERE CODE=1;
데이터 삽입
INSERT INTO good(code, name, manufacture, price)
values(3, '배', '나주', 4500);
데이터 갱신
UPDATE goods SET name='쌀', MANUFACTURE='이천', PRICE=60000
WHERE code=3;
데이터 삭제
DELETE FROM goods
WHERE CODE=4;
1) goods 테이블의 데이터를 표현할 DTO 클래스를 생성
- Package :
db.mybatis.domain
, Class :Good
package db.mybatis.domain;
import lombok.Data;
@Data // lombok
public class Good {
// DB 테이블에 생성된걸 보고 작성
private int code ;
private String name ;
private String manufacture;
private int price ;
}
7) Dao 역할을 수행할 인터페이스를 생성
- Package :
db.mybatis.dao
, Class :GoodDoa
, interfaceclass로 생성
- 데이터 전체를 가져오는 구문
SELECT * FROM goods;
package db.mybatis.dao;
import java.util.List;
import org.apache.ibatis.annotations.Select;
import db.mybatis.domain.Good;
public interface GoodDao {
// goods 테이블의 전체 데이터를 가져오는 메소드
@Select("select * from goods") // SQL 구문 을 쓰면됨
public List<Good> allGood(); //
// public 리턴타입 이름(매개변수) ;
// 리턴타입 = 결과
// 이름 = 내가 정함
// select * from goods 구문이 변하는게 아니니까 매개변수는 없음.
// 전체데이터를 가져오는거니까 list 이고 Good 클래스라는 DTO를 만들었다.
}
열이 1개 = 기본자료형, String, Date
열이 여러개 - Map, DTO(사용자 정의 클래스)행이 여러개 일때는 위의 자료형의 List
행이 1개이면 위의 자료형 그대로SQL 구문들을 그대로 가져와서 변형시키는게 편할거 같다
- 데이터 한개만 가져오는 구문
SELECT * FROM goods WHERE CODE=1;
// code를 가지고 goods 테이블에서 데이터를 조회하는 메소드
// code는 기본키
@Select("select * from good where code = #{code}") // #{code} 부분은 바뀔 수 있는 부분이다.
public Good detailGood(int code);
// 데이터 한개만 가져오니까 list 가 필요없음
// 매개변수는 바뀔수 있는 값임.
- 데이터를 추가하는 구문
INSERT INTO goods(code, name, manufacture, price)
values(3, '배', '나주', 4500);
// 데이터를 추가하는 메소드
@Insert("INSERT INTO goods(code, name, manufacture, price)" + "values(#{code}, #{name}, #{manufacture}, #{price})")
// values 값들은 바뀔수 있는 부분이라 #{이름} 으로 변경함.
public int insertGood(Good good);
- 데이터를 수정하는 구문
UPDATE goods SET name='쌀', MANUFACTURE='이천', PRICE=60000
WHERE code=3;
// 데이터를 수정하는 메소드
@Update("UPDATE goods SET name=#{name}, MANUFACTURE=#{manufacture}, PRICE=#{price} WHERE code=#{code}")
public int updateGood(Good good);
- 데이터를 삭제하는 구문
DELETE FROM goods
WHERE CODE=4;
// 데이터를 삭제하는 메소드
@Delete("DELETE FROM goods WHERE CODE=#{code}")
public int deleteGood(int code);
8) spring 설정 파일을 생성하고 GoodDao 를 위한 설정을 작성
- src/main/resources 에서 spring bean cofiguration file - applicationController.xml 생성
java - Source(컴파일 하는 파일들)
resources - File(컴파일 않하는 파일들)어떤 파일이 어떤 용도로 만들어졌을 까 구분하기 위한것
실제 파일 경로가 바껴도 문제가 생기지 않음
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- DataSource -->
<!-- 스프링에서 데이터베이스를 사용할 때 접속 정보를 저장할 bean -->
<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="dataSource">
<!-- 데이터 베이스 종류 -->
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<!-- 데이터베이스 위치 : 데이터베이스 종류마다 작성법 다름 (검색필요) -->
<property name="url" value="jdbc:oracle:thin:@211.183.6.60:1521:xe"/>
<!-- 계정과 비밀번호 -->
<property name="username" value="user13" />
<property name="password" value="user13" />
</bean>
<!-- MyBaits를 인터페이스를 이용해서 사용할 때 필요한 Bean -->
<bean class="org.mybatis.spring.SqlSessionFactoryBean" id="sqlSessionFactory">
<property name="dataSource" ref="dataSource"/> <!-- 맨위에 id와 같아야된다. -->
</bean>
<bean class="org.mybatis.spring.mapper.MapperFactoryBean" id="goodDao">
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
<property name="mapperInterface" value="db.mybatis.dao.GoodDao"/> <!--value 값 위치 -->
</bean>
</beans>
1) GoodDao 인터페이스의 Bean을 자동으로 생성되도록 설정
- 인터페이스, 클래스 위에
@Component, @Controller, @Service, @Repository
어노테이션 중 하나를 추가 하고 spring 설정 파일에<context:annotation-config/>
,<context:coponenet-scan base-package="패키지경로"/>
10) main 메소드를 소유한 클래스를 만들고 GoodDao 객체를 사용
- 전체 데이터 불러오기
package db.mybatis;
import java.util.List;
import org.springframework.context.support.GenericXmlApplicationContext;
import db.mybatis.dao.GoodDao;
import db.mybatis.domain.Good;
public class MyBatisMain {
public static void main(String[] args) {
GenericXmlApplicationContext context =
new GenericXmlApplicationContext(
"classpath:applicationController.xml");
// id 없이 자료형만으로 bean을 찾아오기
GoodDao dao = context.getBean(GoodDao.class);
// 자료형.class 이름만 써줘도된다.
// 전체 데이터를 가져오는 메소드를 호출해서 확인
// List를 리턴하는 경우는 데이터가 없으면 List는 만들고 size가 0
// 리스트가 없으면 (문제는 없는데) 데이터가 없는거고, 터지면 에러난거다(문제발생)
List<Good> list = dao.allGood();
for(Good good : list) {
System.out.println(good);
}
- 데이터 1개를 리턴
package db.mybatis;
import java.util.List;
import org.springframework.context.support.GenericXmlApplicationContext;
import db.mybatis.dao.GoodDao;
import db.mybatis.domain.Good;
public class MyBatisMain {
public static void main(String[] args) {
GenericXmlApplicationContext context =
new GenericXmlApplicationContext(
"classpath:applicationController.xml");
GoodDao dao = context.getBean(GoodDao.class);
// code를 1개의 데이터를 리턴받는 메소드를 호출
// 1개의 행을 리턴하는 메소드는 리턴할 데이터가 있으면 데이터를 리턴하고 없으면 null을 리턴
Good good = dao.detailGood(1);
System.err.println(good);
- 데이터 삽입
package db.mybatis;
import java.util.List;
import org.springframework.context.support.GenericXmlApplicationContext;
import db.mybatis.dao.GoodDao;
import db.mybatis.domain.Good;
public class MyBatisMain {
public static void main(String[] args) {
GenericXmlApplicationContext context =
new GenericXmlApplicationContext(
"classpath:applicationController.xml");
GoodDao dao = context.getBean(GoodDao.class);
Good good = new Good();
good.setCode(10);
good.setName("딸기");
good.setManufacture("봉동");
good.setPrice(35000);
try {
int result = dao.insertGood(good);
if(result > 0) {
System.out.println("데이터 삽입성공");
}
}catch (Exception e) {
System.out.println("데이터 삽입 실패");
System.err.println(e.getMessage());
}
- 데이터 수정
package db.mybatis;
import java.util.List;
import org.springframework.context.support.GenericXmlApplicationContext;
import db.mybatis.dao.GoodDao;
import db.mybatis.domain.Good;
public class MyBatisMain {
public static void main(String[] args) {
GenericXmlApplicationContext context =
new GenericXmlApplicationContext(
"classpath:applicationController.xml");
GoodDao dao = context.getBean(GoodDao.class);
// if 문에 데이터가 없는 경우가 있으니 처리를 해야하는 구문 추가
Good good = new Good();
good.setCode(110);
good.setName("인삼");
good.setManufacture("논산");
good.setPrice(70000);
try {
int result = dao.updateGood(good);
if(result > 0) {
System.out.println("데이터 수정 성공");
}else {
System.out.println("수정할 데이터가 없음");
}
}catch (Exception e) {
System.out.println("데이터 수정 실패");
System.err.println(e.getMessage());
}
- 데이터 삭제
package db.mybatis;
import java.util.List;
import org.springframework.context.support.GenericXmlApplicationContext;
import db.mybatis.dao.GoodDao;
import db.mybatis.domain.Good;
public class MyBatisMain {
public static void main(String[] args) {
GenericXmlApplicationContext context =
new GenericXmlApplicationContext(
"classpath:applicationController.xml");
GoodDao dao = context.getBean(GoodDao.class);
try {
int result = dao.deleteGood(1);
if(result > 0) {
System.out.println("데이터 삭제 성공");
}else {
System.out.println("삭제 할 데이터가 없음");
}
}catch (Exception e) {
System.out.println("데이터 삭제 실패");
System.err.println(e.getMessage());
}
context.close();
}
}