persistence 계층에서는 DB에 접근하여 SQL문을 실행하고, 데이터를 VO형태로 읽고 쓸 수 있는 DAO(Data Acess Object)을 구현하는 작업을 수행 합니다.

 

Mybatis 초기설정

 

DAO를 구현하기 위해 최초 1회 설정해야하는 DB와의 연동 작업을 수행합니다.

- DataSource 등록

 

mysql 서버에 연결할 때 필요한 정보를 가지고 있는 DataSource를 root_context.xml에 추가 합니다.

 

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
	    <property name="driverClassName" value="com.mysql.jdbc.Driver"></property> 
	    <property name="url" value="jdbc:mysql://127.0.0.1:3306/blog?serverTimezone=UTC"></property>
	    <property name="username" value="root"></property>
	    <property name="password" value="1234"></property>
	</bean>

 

- DataSource Test

 

DataSource 객체가 제대로 생성이 되었는지 테스트 합니다.

 

package kr.co.web;

import java.sql.Connection;

import javax.inject.Inject;
import javax.sql.DataSource;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

//Runner 클래스(테스트 메소드를 실행하는 클래스) 를 SpringJUnit4ClassRunner로 함
@RunWith(SpringJUnit4ClassRunner.class)
//location 속성 경로에 있는 xml 파일을 이용해서 스프링이 로딩됨
@ContextConfiguration("file:src/main/webapp/WEB-INF/spring/**/root-context.xml")

public class DataSourceTest {
	
	//DataSource의 객체를  new를 사용해 따로 생성해줄 필요없이 스프링이 생성해서 주입해줌
	@Inject
	private DataSource ds;
	
	@Test
	public void testConnection() throws Exception{
		try(Connection con = ds.getConnection()){
			System.out.println(con);
		}catch(Exception e) {
			e.printStackTrace();
		}
	}
}

 

 

 

- XML 네임스페이스 추가

 

root-context.xml의 NameSpaces를 다른 확장자도 사용할 수 있도록 추가합니다.

 

 

 

- mybatis-config.xml 추가

mybatis의 별도 설정을 담당하기 위한 파일로 mybatis-config.xml 파일을 src/main/resource에 추가

 

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

</configuration>

 

 

- root-context.xml에 SqlSessionFactory, SqlSessionTemplate 추가

 

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
	    <property name="dataSource" ref="dataSource"></property>
	    <property name="configLocation" value="classpath:/mybatis-config.xml"></property>
	    <property name="mapperLocations" value="classpath:mappers/**/*Mapper.xml"></property>
	</bean>
	
	<!-- sqlSessionTemplate -->
	<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"
	    destroy-method="clearCache">
	    <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"></constructor-arg>
	</bean>
	
	<!-- kr.co.web.persistence 패키지를 자동으로 인식 -->
	<context:component-scan base-package="kr.co.web.persistence">
	</context:component-scan>

 

 

- MyBatis Test

 

MyBatis와 Mysql이 제대로 연결 되었는지 테스트

 

package kr.co.web;

import javax.inject.Inject;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

//Runner 클래스(테스트 메소드를 실행하는 클래스) 를 SpringJUnit4ClassRunner로 함
@RunWith(SpringJUnit4ClassRunner.class)
//location 속성 경로에 있는 xml 파일을 이용해서 스프링이 로딩됨
@ContextConfiguration("file:src/main/webapp/WEB-INF/spring/**/root-context.xml")

public class MyBatisTest {
	
	//SqlSessionFactory 객체를 자동으로 생성
	@Inject
	private SqlSessionFactory sqlFactory;
	
	//SqlSessionFactory 객체가 제대로 만들어졌는지 Test
	@Test
	public void testFactory() {
		System.out.println(sqlFactory);
	}
	
	//MyBatis와 Mysql 서버가 제대로 연결되었는지 Test
	@Test
	public void testSession() throws Exception{
		try(SqlSession session = sqlFactory.openSession()){
			System.out.println(session);
		}catch(Exception e) {
			e.printStackTrace();
		}
	}
}

 

 

 

 

Board 테이블 생성

 

워크벤치에 board 테이블을 생성(워크벤츠 사용법은 어렵지 않기 떄문에 검색!)

 

CREATE TABLE board (
    board_number int NOT NULL AUTO_INCREMENT,
    title varchar(200) NOT NULL,
    contents text,
    name VARCHAR(30) NOT NULL,
    create_date timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
    view_count int DEFAULT 0,
    PRIMARY KEY (board_number)
    );

 

 

정상적으로 테이블이 생성되었습니다.

 

이제 SQL을 실행할 boardMapper.xml을 추가합니다.

 

<!-- /resource/mappers/boardMapper.xml -->

<?xml version="1.0" encoding="UTF-8"?>

<!-- DTD 선언 -->
<!DOCTYPE mapper
	PUBLIC "-//mybatis.org/DTD Mapper 3.0//EN"
	"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
	
<mapper namespace="BoardMapper">

	<!-- 데이터 삽입 -->
	<insert id="create">
		insert into board (title, contents, name)
		values( #{title}, #{contents}, #{name})
	</insert>
	
	<!-- 행 검색 -->
	<select id="read" resultType="kr.co.web.domain.BoardVO">
		select *
		from board
		where board_number = #{board_number}
	</select>
    
	<!-- 행 수정 -->
	<update id="update">
		update board
		set title = #{title}, contents = #{contents}
		where board_number = #{board_number}
	</update>
    
	<!-- 행 삭제 -->
	<delete id="delete">
		delete from board where board_number = #{board_number}
	</delete>
    
	<!-- board 전체 행 조회 -->
	<select id="listAll" resultType="kr.co.web.domain.BoardVO">
		select *
		from board
		order by board_number desc, regdate desc
	</select>
    
	<!-- bno 최대 구하기 -->
	<select id="getMaxBno" resultType="Integer">
		select max(board_number) from board
	</select>	
    
</mapper>

 

resultType 

- resultType을 사용하게 되면 결과 값을 BoardVO의 setter에 값을 넣어주고, 이용자는 getter를 통해 해당 데이터를 이용할 수 있다.

 

 

BoardVO 구현

 

DB를 이용할 때 데이터를 넣고 데이터를 가져와서 사용하기 위해 데이터를 담을 공간인 BoardVO를 작성합니다.

 

package kr.co.web.domain;

import java.util.Date;

public class BoardVO {
	private Integer board_number;
	private String title;
	private String contents;
	private String name;
	private Date create_date;
	private int view_count;
	
	public Integer getBoard_number() {
		return board_number;
	}
	
	public void setBoard_number(Integer board_number) {
		this.board_number = board_number;
	}
	
	public String getTitle() {
		return title;
	}
	
	public void setTitle(String title) {
		this.title = title;
	}
	
	public String getContents() {
		return contents;
	}
	
	public void setContents(String contents) {
		this.contents = contents;
	}
	
	public String getName() {
		return name;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	public Date getCreate_date() {
		return create_date;
	}
	
	public void setCreate_date(Date create_date) {
		this.create_date = create_date;
	}
	
	public int getView_count() {
		return view_count;
	}
	
	public void setView_count(int view_count) {
		this.view_count = view_count;
	}
	
	@Override
	public String toString() {
		return "BoardVO [board_number=" + board_number + ", title=" + title + ", contents=" + contents + ", name=" + name + ", create_date="
				+ create_date + ", view_count=" + view_count + "]";
	}
}

 

 

DAO 인터페이스 작성

 

 

좀전에 만들었던 BoardMapper.xml에 SQL문을 실제로 실행하기 위해 

BoardDAO.java 인터페이스를 kr.co.web.persistence에 작성합니다.

 

package kr.co.web.persistence;

import java.util.List;

import kr.co.web.domain.BoardVO;

public interface BoardDAO {

	public void create(BoardVO board) throws Exception;
	
	public BoardVO read(Integer board_number) throws Exception;
	
	public void update(BoardVO board) throws Exception;
	
	public void delete(Integer board_number) throws Exception;
	
	public List<BoardVO> listAll() throws Exception;
	
	public Integer getMaxBoard_number() throws Exception;
}

 

이제 BoardDAO 인터페이스의 메소드를 구현합니다.

 

package kr.co.web.persistence;

import java.util.List;

import javax.inject.Inject;

import org.apache.ibatis.session.SqlSession;

import kr.co.web.domain.BoardVO;

@Repository
public class BoardDAOImpl implements BoardDAO{

	// SQL문을 실행하는 메소드를 가지고 있는 SqlSession을 구현한 SqlSessionTemplate을 찾아서 객체를 자동으로 생성
	@Inject
	private SqlSession session;
	
	private static String NS = "BoardMapper";
	private static String CREATE = NS + ".create";
	private static String READ = NS + ".read";
	private static String UPDATE = NS + ".update";
	private static String DELETE = NS + ".delete";
	private static String LISTALL = NS + ".listAll";
	private static String GETMAXBOARD_NUMBER = NS + ".getMaxBno";
	
	@Override
	public void create(BoardVO board) throws Exception {
		session.insert(CREATE, board);
		// 글을 작성할 때 입력한 값을 boardVO에 넣어주기 위해 파라미터값을 board로 함
	}
	
	@Override
	public BoardVO read(Integer board_number) throws Exception {
		return session.selectOne(READ, board_number);
		// 글을 읽기 위해 mapper에 where절에 게시글번호가 필요하기 때문에 board_number로 설정하고 boardVO를 리턴값으로 설정
	}
	
	@Override
	public void update(BoardVO board) throws Exception {
		session.update(UPDATE, board);
	}
	
	@Override
	public void delete(Integer board_number) throws Exception {
		session.delete(DELETE, board_number);
	}
	
	@Override
	public List<BoardVO> listAll() throws Exception {
		return session.selectList(LISTALL);
	}
	
	@Override
	public Integer getMaxBoard_number() throws Exception {
		return session.selectOne(GETMAXBOARD_NUMBER);
	}
}

 

 

typeAliases 적용

 

BoardMapper.xml에 있는 쿼리문에서 resultType을 패키지명과 같이 작성하였는데

MyBatis의 설정 파일인 mybatis-config.xml을 이용하여 typeAliases를 사용하면

resultType에 패키지명을 붙이지 않아도 됩니다.

 

<?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>
	
	<typeAliases>
		<package name="kr.co.web.domain" />
	</typeAliases>
	
</configuration>

 

+ Recent posts