원지의 개발
article thumbnail
728x90

MyBatis

  • 라이브러리이자 프레임워크 (Spring에 포함x)
  • 개발자가 지정한 SQL, 고급 매핑을 지원하는 프레임워크
  • 영속성 프레임워크: 파일을 영구적으로 저장해놓고 씀
  • DAO 계층을 대신 = DAO 필요 없음
  • DAO의 Interface의 구현클래스를 xml 파일이 대신
  • 복잡한 JDBC코드 걷어냄 = sql문만 남음
  • spring에서 사용하려면 MyBatis-Spring module 다운받아야 함

MyBatis 구조

전통적인  JDBC 프로그램 MyBatis
직접  Connection 생성 자동  Connection 생성
직접  Close() 처리 자동  Close() 처리
직접 PreparedStatement 생성 자동  PreparedStatement 처리
Pstmt의  setxxx() 직접  처리 #{name} 을  통한  ? 처리
Select의 경우 ResultSet 처리 리턴 타입으로 자동 ResultSet 처리
결론! MyBatis는 SQL문만 적어주면 됨

MyBatis 추가

  • 마이바티스 사용시 기본적으로 spring-jdbc 라이브러리가 있어야 함

0. root-context.xml

  • 마이바티스 핵심객체 - SQLSessionFactory 빈으로 선언
  • SQLSessionFactory: 전체적으로 필요한 것이 돌아가는 하나의 컨테이너 box
<!-- 데이터베이스 정보를 주입 -->
	<bean id="ds" class="com.zaxxer.hikari.HikariDataSource">
      <constructor-arg ref="hikari"/>
    </bean>

<위 설명>
<!-- 마이바티스 설정 sqlSessionFactory 빈으로 생성 -->
    <bean class="org.mybatis.spring.SqlSessionFactoryBean">
    	<!-- 데이터베이스 정보 전달 -->
    	<property name="dataSource" ref="ds" /> <!-- bean객체 주입 -->
    	<property name="configLocation" value="classpath:/mybatis-config/mybatis-config.xml" />
    </bean>

<아래 설명>
<!-- 마이바티스 관련 어노테이션을 찾아서 설정으로 등록 (모든 인터페이스를 등록)-->
<!-- TestMapper.java 인터페이스는 어노테이션 안해도 등록되긴함 -->
<!-- <mybatis-spring:scan base-package="com.simple.basic.mapper"/> -->
    <mybatis-spring:scan base-package="com.simple.*"/>
  • SqlSessionFactoryBean을 이용 SqlSessionFactory을 등록
  • 빈을 보면 MyBatis의 패키지가 아니라 스프링과 연동 작업을 처리하는 mybatis-spring 라이브러리의 클래스
  • property로 데이터베이스 정보 bean 객체 주입
  • mybatis-config 파일 잡아주기

 

  • MyBatis 동작할 때 Mapper를 인식할 수 있도록 root-context.xml에 추가적인 설명이 필요
  • 관련 어노테이션을 찾아서 등록
    지정된 패키지(com.simple.~)를 스캔해서 모든 MyBatis 관련 어노테이션을 찾아서 처리

namespace에서 mybatis-spring 체크

더보기

같은 내용

1. pom.xml

<!-- 마이바티스 -->
		<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
		<dependency>
		    <groupId>org.mybatis</groupId>
		    <artifactId>mybatis</artifactId>
		    <version>3.5.6</version>
		</dependency>
        
<!-- 마이바티스-스프링 -->
		<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
		<dependency>
		    <groupId>org.mybatis</groupId>
		    <artifactId>mybatis-spring</artifactId>
		    <version>2.0.6</version>
		</dependency>
  • MyBatis 모듈 하나 + MyBatis-spring 모듈 하나 : 두 개는 1+1

설정 추가 (옵션)

scr/main/resources ▷ mybatis-config ▷ mybatis-config.xml

<?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">
  
  <!-- 마이바티스 부연 설정 - ScoreVO를 단축명으로 사용 -->
  <configuration>
  	<typeAliases>
  		<typeAlias type="com.simple.command.ScoreVO" alias="ScoreVO"/>
  		<typeAlias type="com.simple.command.BoardVO" alias="BoardVO"/>
  	</typeAliases>
  	
  </configuration>
  • DOCTYPE - config로 설정

Root-context.xml

    <!-- 마이바티스 설정 sqlSessionFactory 빈으로 생성 -->
    <bean class="org.mybatis.spring.SqlSessionFactoryBean">
    	<!-- 데이터베이스 정보 전달 -->
    	<property name="dataSource" ref="ds" /> <!-- bean객체 주입 -->
    	<property name="configLocation" value="classpath:/mybatis-config/mybatis-config.xml" />
    </bean>
    
    <mybatis-spring:scan base-package="com.simple.*"/>

Spring 연결

  • serviceImpl에서 Mapper 인터페이스를 불러서 사용
  • service인터페이스와 Mapper인터페이스는 동일한 구조

ScoreMapper 인터페이스

package com.simple.score.mapper;

import java.util.ArrayList;
import org.apache.ibatis.annotations.Mapper;
import com.simple.command.ScoreVO;

// ScoreDAO를 myBatis로 바꾸려고
@Mapper //mybatis-scan 하게 하려고 root-context.xml 변경
public interface ScoreMapper {
	public void regist(ScoreVO vo); //서비스 영역에서 만든것과 거의 완전 동일하게 만듦
	public ArrayList<ScoreVO> getList();
	public void delete(int num);
}
  • @Mapper 어노테이션 붙이기
  • 나머지는 ScoreDAO와 같음

ScoreMapper.xml

<?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="com.simple.score.mapper.ScoreMapper">
  
  	<insert id="regist">
  		insert into score(name, kor, eng)
  		values(#{name}, #{kor}, #{eng})
  	</insert>
  	
  	<select id="getList" resultType="ScoreVO">
  		select * from score order by num desc
  	</select>
  	
  	<delete id="delete">
  		delete from score where num = #{num}
  	</delete>
  
  </mapper>
  • DOCTYPE - mapper로 설정
  • 데이터베이스 테이블에 대한 SQL 쿼리와 Java 객체 간의 매핑을 정의

Mapper XML

  • Namespace - 인터페이스 경로와 동일하게 작성
  • Id - 인터페이스 추상메서드와 동일하게 작성
  • resultType - 추상메서드의 리턴타입과 동일하게 작성

Mapper XML 속성 [ 중요 ]

두개 이상 맵핑 처리

  • 단일값은 그냥 전달 가능

@Param

  • VO클래스 자동 맵핑
  • HashMap 자동 맵핑 (변환하는데이터에 바로 적용이 힘들어 부득이한 경우 아니면 잘 사용X)
  • @Param 이름 지정을 사용해서 맵핑

동적쿼리 지원: 검색에서 사용 (나중)

1. if

2. choose(when, overwise)

3. foreach

테스트

1. JDBCTest.java

TestMapper.xml

<?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="com.simple.basic.mapper.TestMapper"> <!-- 내가 실행시킬 풀 경로 -->

	<!-- id는 인터페이스의 메서드명 resultType=반환타입  -->
	<select id="getTime" resultType="string">
		select now()
	</select>
	
	<!-- ; 은 없습니다 -->
	<!-- 한 행에 대한 처리를 할 데이터 타입 (풀경로) -->
	<select id="getScore" resultType="ScoreVO">
		select * from score
	</select>
	
	<!-- 매개변수 - 단일값 -->
	<select id="getOne" resultType="ScoreVO">
		select * from score where num = #{a}
	</select>
	
	<!-- insert -->
	<!-- parameterType - 매개변수의 타입(생략가능) -->
	<insert id="insertOne" parameterType="String">
		insert into score(name) values(#{name})
	</insert>
	
	<insert id="insertTwo" parameterType="com.simple.command.ScoreVO"> <!-- 여기는 풀 경로 적어준 것 -->
		insert into score(name, kor, eng)
		values(#{name}, #{kor}, #{eng})
	</insert>
	
	<insert id="insertThree"> <!-- 여기서는 파라미터타입 생략했음 -->
		insert into score(name, kor, eng)
		values(#{name}, #{kor}, #{eng})
	</insert>
	
	<select id="selectMap" resultType="map" parameterType="int">
		select * from score where num = #{num}
	</select>
	
	<select id="selectTwo" resultType="map">
		score * from score
	</select>
	
	<!-- alias 설정이 있다면 parameter, result타입에 단축명으로 사용 가능합니다. -->
	<update id="updateOne" parameterType="ScoreVO">
		update score
		set name = #{name},
			kor = #{kor},
			eng = #{eng}
		where num = #{num}
	</update>
	
	<insert id="insertFour">
		insert into score(name, kor) values(#{변수명1}, #{변수명2})
	</insert>
	
</mapper>

2. JDBCMybatis.java

package com.simple.basic;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.simple.basic.mapper.TestMapper;
import com.simple.command.ScoreVO;

@RunWith(SpringJUnit4ClassRunner.class) //junit으로 테스트환경을 구성
@ContextConfiguration("file:src/main/webapp/WEB-INF/config/root-context.xml") //동작시킬 스프링 설정 파일 - 전체 풀 경로
public class JDBCMybatis {
	
//	@Autowired
//	SqlSessionFactoryBean sqlSessionFactory;
//	
//	@Test
//	public void testCode01() {
//		//마이바티스 핵심 객체
//		System.out.println(sqlSessionFactory);
//	}
	
	@Autowired
	TestMapper testMapper;
	
//	@Test
//	public void testCode02() {
//		String time = testMapper.getTime();
//		System.out.println(time);
//	}
	
	//select 태그의 resultType
//	@Test
//	public void testCode03() {
//		ArrayList<ScoreVO> list = testMapper.getScore();
//		System.out.println(list.toString());
//	}
	
	//매개변수 - 단일값
//	@Test
//	public void testCode04() {
//		ScoreVO vo = testMapper.getOne(7);
//		System.out.println(vo.toString());
//	}
	
	//insert - 단일값
//	@Test
//	public void testCode05() {
//		int result = testMapper.insertOne("이순신");
//		System.out.println("성공실패:" + result);
//	}
	
	//insert - 다중값 (vo) - setter가 파라미터가 됩니다.
//	@Test
//	public void testCode06() {
//		ScoreVO vo = new ScoreVO(0, "테스트", "60", "50");
//		int result = testMapper.insertTwo(vo);
//		System.out.println("성공실패:" + result);
//	}
	
	//insert - 다중값 (Map) : 키값이 중요, key값이 파라미터가 됩니다.
//	@Test
//	public void testCode07() {
//		Map<String, String> map = new HashMap<>();
//		map.put("name", "앨리스"); 
//		map.put("kor", "100");
//		map.put("eng", "10");
//		
//		int result = testMapper.insertThree(map);
//		System.out.println("성공실패:" + result);
//	}
	
	//select - map타입의 반환
//	@Test
//	public void testCode08() {
//		Map<String, Object> map = testMapper.selectMap(6);
//		System.out.println(map.toString());
//	}
	
	//select - map타입의 반환: 맵 타입을 사용하는 것은 부득이한 경우에만 사용합니다.
//	@Test
//	public void testCode09() {
//		ArrayList<Map<String, Object>> list = testMapper.selectTwo();
//		System.out.println(list.toString());
//	}
	
	//update
//	@Test
//	public void testCode10() {
//		ScoreVO vo = new ScoreVO(6, "변경", "100", "100");
//		boolean result = testMapper.updateOne(vo);
//		System.out.println("성공실패:" + result);
//	}
	
	//insert구문 @Param - 매개변수
	@Test
	public void testCode11() {
		testMapper.insertFour("파람테스트", 100);
	}
	
}
  • TestMapper.java, TestMapper.xml은 같음

오늘 하루

더보기

기억에 남는 부분

 

어려운 부분

 

문제 해결 부분

 

728x90
profile

원지의 개발

@원지다

250x250