티스토리 뷰

안녕하세요. MIN-IT입니다.


이번시간은 Spring MVC프로젝트와 Mybatis를 이용하여 mysql을 다루는 시간을 갖겠습니다.


퍼가실 때 댓글을 남겨주세요!


http://min-it.tistory.com


저번 시간에 연결한 mysql과 mabatis설정을 하였고 설정한 mybatis로 테이블을 생성해보는 시간을 갖겠습니다.


http://min-it.tistory.com/5 (Spring + mysql 연결)

http://min-it.tistory.com/6 (Spring + mybatis 설정)



*간단히 MyBatis와 iBatis의 차이점

-iBatis는 Mybatis의 이전 버전으로 SQL문을 XML로 작성하며

SQL문을 사용하는 (DAO)클래스를 설계해서 SQL문을 호출하는 방식입니다.

-Mybatis는 애노테이션(@XXX)를 지원하고

인터페이스와 애노테이션을 통해서 SQL문을 설정하거나 처리할 수 있습니다.



Mybatis를 사용하면

1.애노테이션과 인터페이스만을 이용하여 SQL문 설정

2.XML만을 이용해서 SQL문 설정

3.애노테이션과 XML문을 같이 사용해서 SQL문 설정



저는 XML만을 이용해서 SQL문을 설정하고

별도의 DAO클래스를 만드는 실습을 진행하겠습니다.

(SQL문을 분리해서 처리하기때문에 SQL문의 수정이나 대처에

수월하여 유지보수가 좋습니다.)





워크벤치를 열어서 테이블을 하나 생성해봅시다.



test1이라는 스키마에 member라는 테이블을 만들었습니다.





한번더 Apply를 눌러주시면 테이블 생성이됩니다.



멤버테이블을 위한 클래스를 만들겠습니다.



public class MemberVO {
   
    private String user_id;
    private String user_pw;
    private String user_email;
   
    public String getUser_id() {
        return user_id;
    }
    public void setUser_id(String user_id) {
        this.user_id = user_id;
    }
    public String getUser_pw() {
        return user_pw;
    }
    public void setUser_pw(String user_pw) {
        this.user_pw = user_pw;
    }
    public String getUser_email() {
        return user_email;
    }
    public void setUser_email(String user_email) {
        this.user_email = user_email;
    }
    @Override
    public String toString() {
        return "MemberVO [user_id=" + user_id + ", user_pw=" + user_pw + ", user_email=" + user_email + "]";
    }
}




-주의하실점은 테이블의 컬럼명과 변수명이 일치하셔야됩니다.

(데이터베이스의 member테이블의 컬럼과 클래스의 변수명을 일치시켜 맵핑하려고 합니다. 이렇게 DB와 접근하는 클래스를 도메인 클래스(VO객체)라고 불립니다.)



다음은 DAO인터페이스를 만들겠습니다.

(DAO로 작성시 향후 DB가 변경되더라도

DAO만 변경해서 처리할 수 있는 장점이 있습니다.)



org.hello.dao라는 패키지를 만들고 new-Interface를 생성합니다.



생성후 다음과 같이 입력합니다.


package org.hello.dao;

import org.hello.domain.MemberVO;

public interface MemberDAO {
   
    public void insertMember(MemberVO vo);
   
}





DAO를 만들었으니 XML Mapper를 만들어 SQL문을 작성해 보겠습니다.

(SQL 문을 저장하는 부분을 Mybatis에서는 Mapper라 불린다.)


XML로 작성한 Mapper파일은 Java로 작성된 클래스와 경로를 분리해주세요.

(유지보수를 위해서)



src/main/resources폴더안에 mapper라는 패키지를 만들고

memberMapper.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="org.hello.mapper.MemberMapper">

    <insert id="insertMember">
        insert into member(user_id,user_pw,user_email) values
                          (#{user_id},#{user_pw},#{user_email})
    </insert>

</mapper>







여기서 <insert id="insertMember">는


MemberDAO 인터페이스에서 작성한 메소드명과 일치시킵시다!

(헷갈릴 수 있으니까요!)





그리고 #{XXX},#{XXX},#{XXX} 이부분은 MemberVO(도메인클래스)의 변수들입니다.


MemberDAO를 보시면 insertMember(MemverVO vo)라고 적어놨습니다.


즉, insertMember를 호출할때 memberMapper.xml에서 MemberVO객체를 하겠다는 뜻입니다.


그래서 #{uer_id},#{user_pw}, #{user_email}을 사용할 수 있는 것입니다.




여기서 끝난 것이 아닙니다.

저희는 memberMapper.xml 파일을 만들었지만 Mybatis가 동작할때

XML mapper를 인식을 해야 정상동작 할 것입니다.


따라서 root-context.xml파일에서 mapper위치를 설정해주셔야합니다.




namespace는 클래스의 패키지와 비슷한 용도로 Mybatis에서 원하는 SQL문을 찾아서 실행할 때 동작합니다.



memberMapper.xml처럼 다른 맵퍼들을 생성할때 (xxx)Mapper.xml
만든다고 가정하면 root-context.xml에서 일일이 만들때마다 설정하지 않고

*Mapper.xml이라고 한번만 정의하면 모든 (xxx)Mapper.xml을

Mapper설정이 되겠죠??



root-context.xml파일에서 전에 만든 sqlSessionFactory빈을 수정하거나

복사 붙여넣기 하세요.


    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
             <property name="dataSource" ref="dataSource"></property>
            
                  <!-- mybatis-config.xml이 스프링 시작될때 같이 실행되도록 설정하기  -->
             <property name="configLocation" value="classpath:/mybatis-config.xml"></property>
            <property name="mapperLocations" value="classpath:mapper/**/*Mapper.xml"></property>
           
                        
     </bean>







DAO인터페이스와 Mapper가 작성되었으면

실제로 구현되도록 클래스를 만들어야합니다.


Mybatis에서는 DAO 인터페이스를 이용하는경우

SQLSessionTemplate을 사용해서 DAO를 구현하기 때문에

SqlSessionTemplate을 설정해줍니다.

(예전에 pom.xml을 통해 mybatis-spring 라이브러리를

다운받았는데 거기서 제공하는 것중 하나가

SqlSessionTemplate 클래스 입니다.

SqlSessionTemplate클래스는 연결 및 연결종료하거나

트랜잭션, 쓰레드 처리 등의 작업을 해주는 장점이 있어요.)



root-context.xml에서 다음과 같이 작성합니다.



    <!-- SQLSessionTemplate설정하기 DAO인터페이스를 만들었기때문에 Mybatis에서 DAO인터페이스를 구현하기위해서 필요한작업 -->

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







sqlSeesionTemplate설정이 끝났으면

DAO인터페이스에게 주입을 시켜줘야합니다.

따라서 memberDAOImp를 생성하여 다음과같이 주입을 시켜줍니다.



package org.hello.dao;

import javax.inject.Inject;
import org.apache.ibatis.session.SqlSession;
import org.hello.domain.MemberVO;
import org.springframework.stereotype.Repository;

@Repository //DAO라고 명시 (DAO를 스프링에서 인식시켜줌)
public class MemberDAOImp implements MemberDAO {

    @Inject // 의존관계를 자동으로 연결(JAVA에서 제공) ==@autowired (Spring에서 제공)
    private SqlSession sqlSession;
   
   
    private static final String namespace = "org.hello.mapper.MemberMapper";
                                            //memberMapper.xml의 namespace값
   
    @Override
    public void insertMember(MemberVO vo) {
        sqlSession.insert(namespace+".insertMember", vo);
    }
   
}



@Repository 애노테이션을 사용하여 DAO라고 명시를하여도

스프링에서 해당하는 패키지를 스캔하지 않는다면 제대로

스프링의 빈으로 등록되지 못하기 때문에 이를 방지하기 위해서

root-context.xml에서 다음과 같이 작성합니다.


    <context:component-scan base-package="org.hello.dao"></context:component-scan>





테스트를 통해 잘되었는지 확인해보겠습니다.

org.hello.web에 클래스파일을 생성하여
다음과 같이 입력합니다.



package org.hello.web;

import javax.inject.Inject;

import org.hello.dao.MemberDAO;
import org.hello.domain.MemberVO;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class TestDAO {
   
    @Inject
    private MemberDAO dao;
   
    @RequestMapping(value = "/testDAO", method = RequestMethod.GET)
    public void testDAO(){
        MemberVO vo = new MemberVO();
        vo.setUser_id("MIN-IT");
        vo.setUser_pw("1234");
        vo.setUser_email("min-it.tistory.com");
       
        dao.insertMember(vo);
    }
}








localhost:8081/testDAO를 입력하시면 404에러가 뜰 것입니다.

testDAO.jsp파일이 없어서 나는에러입니다.

workbench를 통해서 확인해봅시다.

(실패시 예외처리는 안만들었어요)





모르고 user_name을 안넣었지만 성공하였습니다.



*만약에  따라하시면

Mapped Statements collection does not contain value for~라고 에러가 뜨셨다면


1.

memberMapper.xml의 namespace 값과 MemberDAOImp클래스의 namespace값이 일치하는지 확인해주세요.

(또 다른 mapper.xml을 만들시 namespace값이 중복되면안되요!)


2.

MemberVO클래스안의 변수명과 mysql의 member테이블의 컬럼값과 일치하는 확인해주세요.


3.

3.root-context.xml에서 MXL mapper인식하는 설정부분을 경로를 제대로 작성했는지 확인해주세요


4.memberMapper.xml의 insert id="여기의값"

MemberDAOImp클래스의

sqlSession.insert(namespace+".insertMember", vo);

값이 일치하는지 확인해주세요


여기까지 확인하시면 아마 정상작동이 되실겁니다.




* 포스팅을 마치겠습니다.

궁금하거나 잘못된 부분이있다면 알려주시면 감사하겠습니다.*

을 마치겠습니다.

궁금하거나 잘못된 부분이있다면 알려주시면 감사하겠습니다.*



출처: http://min-it.tistory.com/6 [MIN-IT]








댓글