티스토리 뷰

전체적인 스텝은 다음과 같다:

1. 새 Spring MVC 프로젝트 생성
2. web.xml: UTF-8 encoding filter 추가
3. Library dependency 추가(MySQL connector, Spring-jdbc, spring-test, MyBatis, MyBatis-Spring)
4. root-context.xml 파일에 data source, SqlSessionFactory, SqlSession bean 등록
5. mybatis-congfig.xml 파일 생성(MyBatis configuration file, XML)
6. board-mapper.xml 파일 생성(MyBatix mapper file, XML)
7. BoardVO class 생성(getters & setters)
8. BoardDAO class 생성(CRUD methods)
9. BoardService interface 생성
10. BoardServiceImpl class 생성
11. BoardController class 생성

1,2,7,9~11 단계는 이전에 spring annotation을 통해 프로젝트를 제작할 때와 내용이 같으니 참고하도록 하자.

carrot62.tistory.com/101

 

Spring CRUD project - Annotation 이용해서 만들기 실습

1. 참고용 소스를 준비한다 2. 새 Spring MVC project 생성 Spring Legacy Project -> Spring MVC project 프로젝트를 생성했다면 Java Build Path를 꼭 확인해보자: - Library: Tomcat 추가 + jre버전 변경/확인..

carrot62.tistory.com


이제 본격적으로 MyBatis를 이용한 CRUD 프로젝트를 제작해보자!!

시작하기 전 mybatis plugin 설치하고 간다.

1. 새 Spring MVC 프로젝트 생성

2. web.xml: UTF-8 encoding filter 추가

web.xml

<!-- utf-8 encoding을 위한 설정 추가 -->
<filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class> org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

3. Library dependency 추가(MySQL connector, Spring-jdbc, spring-test, MyBatis, MyBatis-Spring)

pom.xml 파일에 추가

<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
  <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.19</version>
  </dependency>
  <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
  <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>${org.springframework-version}</version>
  </dependency>
  <!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
  <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>${org.springframework-version}</version>
      <scope>test</scope>
  </dependency>
  <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
  <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.3</version>
  </dependency>
  <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
  <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>2.0.5</version>
  </dependency>

4. root-context.xml 파일에 data source, SqlSessionFactory, SqlSession bean 등록

root-context.xml

<bean id="dataSource"
    class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName"
        value="com.mysql.jdbc.Driver" />
    <property name="url"
        value="jdbc:mysql://로컬호스트/DB이름?useSSL=false" />
    <property name="username" value="DB사용자ID" />
    <property name="password" value="DB비밀번호" />
</bean>
<bean id="sqlSessionFactory"
    class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource"></property>
    <property name="configLocation" value="classpath:mybatis-config.xml"/>
    <property name="mapperLocations" value="classpath:mappers/*-mapper.xml"></property>
</bean>

<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate" destroy-method="clearCache">
    <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>

DB4free를 사용할 경우 host: db4free.net:3306

5. mybatis-congfig.xml 파일 생성(MyBatis configuration file, XML)

mybatis-congfig.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">
<configuration>
	<typeAliases>
		<typeAlias alias= "board" type="com.my.bat.board.BoardVO"/>
	</typeAliases>
</configuration>

6. board-mapper.xml 파일 생성(MyBatix mapper file, XML)

src/main/resources 아래에 mappers라는 폴더를 반드시 만들고, 새로만들기 -> "MyBatis XML Mapper" 를 선택해서 board-mapper.xml을 만들기

(반드시 mappers 라는 폴더 아래에 만들 것!)

mappers 옆 아이콘 모양이 폴더처럼 안 생겨서 헷갈릴 수도 있지만 src/main/resources 아래에 폴더를 만들면 저렇게 생긴 아이콘이 자동으로 나오니 저 아이콘과 같은 폴더를 찾지 않아도 된다.

mappers 이라는 source folder를 src/main/resources 폴더 경로 아래에 생성할 것!

<?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="Board">
	<insert id="insertBoard">
		insert into BOARD (category, title, writer, content)
		values
		(#{category}, #{title}, #{writer}, #{content})
	</insert>
	<update id="updateBoard">
		update BOARD
		set title=#{title}, content=#{content}, writer=#{writer}, category=#{category}
		where seq=#{seq}
	</update>
	<delete id="deleteBoard">
		delete from BOARD where seq=#{seq}
	</delete>
	<select id="getBoard" resultType="board">
		select * from BOARD where seq=#{seq}
	</select>
	<select id="getBoardList" resultType="board">
		select * from BOARD order by seq desc
	</select>
</mapper>

7. BoardVO class 생성(getters & setters)

com.myapp.company.board 아래에 BoardVO class 생성해서 변수를 적고 getters 와 setters 받아오기
(여기서 myapp.company는 본인이 설정한 패키지에 맞게 적을 것, 무조건 똑같이 안해도 된다)

private int seq;
private String category;
private String title;
private String writer;
private String content;
private Date regdate;
private int cnt;

8. BoardDAO class 생성(CRUD methods)

BoardVO를 반드시 먼저 생성하고 나서 DAO를 만들도록 한다.
board-mapper.xml 을 참고해서 작성하면 된다.

package com.my.bat.dao;

import java.util.List;

import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.my.bat.board.BoardVO;

@Repository
public class BoardDAO {

	@Autowired
	SqlSession sqlSession;
	
	public int insertBoard(BoardVO vo) {
		int result = sqlSession.insert("Board.insertBoard", vo);
		return result;
	}
	
	public int updateBoard(BoardVO vo) {
		int result = sqlSession.update("Board.updateBoard", vo);
		return result;
	}
	
	public int deleteBoard(int seq) {
		int result = sqlSession.delete("Board.deleteBoard", seq);
		return result;
	}
	
	public BoardVO getBoard(int seq) {
		BoardVO result = sqlSession.selectOne("Board.getBoard", seq);
		return result;
	}
	
	public List<BoardVO> getBoardList() {
		List<BoardVO> result = sqlSession.selectList("Board.getBoardList");
		return result;
	}
	
}

9. BoardService interface 생성

폴더 구조 참고

src/main/java 에서 com.sp.anot (본인이 만든 패키지 기본 폴더) 아래에 BoardService.java 이라는 interface 파일을 만든다

package com.sp.anot;

import java.util.List;

import com.sp.anot.board.BoardVO;

public interface BoardService {
	public int insertBoard(BoardVO vo);
	public int deleteBoard(int seq);
	public int updateBoard(BoardVO vo);
	public BoardVO getBoard(int seq);
	public List<BoardVO> getBoardList();
	
}

10. BoardServiceImpl class 생성

BoardServiceImpl.java

package com.my.bat;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.my.bat.board.BoardVO;
import com.my.bat.dao.BoardDAO;

@Service
public class BoardServiceImpl implements BoardService{
	
	@Autowired
	BoardDAO boardDAO;
	
	@Override
	public int insertBoard(BoardVO vo) {
		return boardDAO.insertBoard(vo);
	}
	
	@Override
	public int deleteBoard(int seq) {
		return boardDAO.deleteBoard(seq);
	}
	
	@Override	
	public int updateBoard(BoardVO vo){
		return boardDAO.updateBoard(vo);
	}
	
	@Override
	public BoardVO getBoard(int seq){
		return boardDAO.getBoard(seq);
	}
	
	@Override
	public List<BoardVO> getBoardList(){
		return boardDAO.getBoardList();
	}

}

11. BoardController class 생성

package com.my.bat;

import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.my.bat.board.BoardVO;

@Controller
@RequestMapping(value="/board")
public class BoardController {
	@Autowired
	BoardService boardService;
	
	@RequestMapping(value = "/list", method = RequestMethod.GET)
	public String boardlist(Model model) {
		model.addAttribute("list", boardService.getBoardList());
		return "list";
	}
	
	@RequestMapping(value = "/add", method = RequestMethod.GET)
	public String addPost() {
		return "addpostform";
	}
	
	@RequestMapping(value="/addok", method=RequestMethod.POST)
	public String addPostOk(BoardVO vo) {
		if(boardService.insertBoard(vo) == 0)
			System.out.println("데이터 추가 실패 ");
		else
			System.out.println("데이터 추가 성공!!!");
		return "redirect:list";
	}
	
	@RequestMapping(value = "/editform/{id}", method = RequestMethod.GET)
	public String editPost(@PathVariable("id") int id, Model model) {
		BoardVO boardVO = boardService.getBoard(id);
		model.addAttribute("u", boardVO);
		return "editform";
	}
	
	@RequestMapping(value = "/editok", method = RequestMethod.POST)
	public String editPostOk(BoardVO vo) {
		if(boardService.updateBoard(vo) == 0)
			System.out.println("데이터 수정 실패 ");
		else
			System.out.println("데이터 수정 성공!!!");
		return "redirect:list";
	}
	
	@RequestMapping(value = "/deleteok/{id}", method = RequestMethod.GET)
	public String deletePostOk(@PathVariable("id") int id)  {
		if(boardService.deleteBoard(id) == 0)
			System.out.println("데이터 삭제 실패 ");
		else
			System.out.println("데이터 삭제 성공!!!");
		return "redirect:../list";
	}
	
		
}

 

여기까지 하고 테스트 해보면

 


[일어날 수 있는 에러]

오타를 주의하도록! content 필드 이름을 context로 잘못 적어서 다음과 같은 에러가 났었다. 에러 메시지를 침착하게 읽어보고 mybatis의 경우에는 sql 쿼리문들이 board-mapper.xml 파일에 들어가기 때문에 이 부분을 다시 확인해보도록 하자!

더보기

Request processing failed; nested exception is org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'context' in 'class com.my.bat.board.BoardVO'

이번에도 오타가 있어서 제대로 작동이 안됐었다.

 

이 부분을 seq desc 로 잘못 적어서 쿼리문의 결과로 하나 아상의 값을 불러오면서 에러가 났었다.
이런 상황에서는 board-mapper.xml 파일을 확인해봐야 한다.