본문 바로가기
Programming/>> Spring

[Java] spring+mybatis+mysql 연동

by 니키ᕕ( ᐛ )ᕗ 2014. 8. 17.

 mybatis를 쓰면 좋은 점은 statement를 일일이 할 필요 없다는 것 그리고 column명과 vo 클래스를 디스패치시켜줄 코드를 짤 필요가 없다는 것. 마지막으로 국내에서 엄청 많이 쓴다는 거..? 초기 설정만 해주면 쿼리문만 입력해주면 되니 사용하기도 편리하다.


1. 라이브러리


 spring에서 mysql과 연결을 위해 mybatis를 사용하려면 maven에서 몇가지 라이브러리를 받아야 한다. 

1. commons-dbcp

2. mybatis

3. mybatis-spring

4. spring jdbc

5. mysql-connector

jdbc와 dbcp에 대한 내용은 이쪽에서 보면 설명이 더 정확할 것 같다.



2. 패키지

 MVC에서는 controller-service-dao(mybatis에서는 mapper)-model-mapper의 구조로 되어 있는데 controller는 프로젝트 생성 때 지정이 됐으므로 service와 mapper패키지를 만들어준다. 그리고 mybatis는 DB 테이블로부터 받아온 데이터를 담을 수 있는 vo가 필요하므로 vo패키지도 생성한다.



3. 테스트 유닛


 아직은 controller를 건드리지 않고 프로젝트가 mybaits를 통해 mysql과 연결이 되는 지를 볼 것이기 때문에 junit 테스트를 사용한다. spring이 test는 기본으로 가지고 있지 않아서 이것도 maven에서 라이브러리를 추가해야한다. spring test로 검색하면 나온다.


4. 테이블 생성


 user정보가 들어갈 테이블을 생성한다. 기본적으로 user_id는 이메일 주소로 할 것이다. 포인트는 나중에 트랜잭션 관련해서 써보려고 넣어봤다. user_regdate는 insert문이 실행되는 시점, 가입시점이다.

create table tbl_user(
	user_id varchar(100) primary key,
	user_pwd varchar(50),
	user_name varchar(50),
	user_point int default 0,
	user_regdate timestamp default current_timestamp
);


 테스트를 위해 한 개의 레코드를 등록한다

insert into tbl_user (user_id, user_pwd, user_name) values('abcd@naver.com', '1234', '사용자');



5. root-context.xml 수정


 왜 root-context.xml에 이 내용이 들어가야하는지는 찾아봐도 잘 안나온다. 애초에 root-context.xml의 용도를 명확하게 알려주는 곳이 없다 ㅠㅠ 이 부분은 검색하면 많이 나오니 간단하게 넘어가겠다.





	
		
		
		
		
	
	
	
		
		
	
	
	
		
	


	
		
	



 datasource는 DB정보, org.mybatis.spring.mapper.MapperScannerConfigurer클래스는 mapper패키지내의 xml로 구성된 apper를 스캔한다.

component-scan은 @Component 어노테이션이 적용된 클래스를 검색하여 빈으로 등록하게 한다. mapper 이외에도 나중에 component로서 쓸 클래스를 스캔한다.



6. UserVO 생성


 tbl_user 테이블로부터 받아온 데이터를 저장할 클래스를 vo패키지 안에 만든다. 코드가 길어져서 다 안넣었는데 변수마다 get/set 메소드를 다 추가시켜줘야 한다.

package com.vo;

public class UserVO {
	String user_id;
	String user_name;
	String user_pwd;
	String user_regdate;
	int user_point;
}



7. HomeMapper 생성

 interface로 mapper를 생성하고, user테이블에서 user_id와 user_name을 가져오는 쿼리와 메소드를 작성한다. 지금은 단순한데 만약에 쿼리문의 where절 부분을 동적으로 하려면 xml에서 설정해야한다. 그리고 xml과 interface mapper중, 같은 이름을 가진 메소드가 있다면 xml의 쿼리문이 우선적으로 작용한다. 이유는 나도 모른다! 그렇다더라! xml이랑은 영 친하지 않아서 가까이 하고 싶지 않은데 spring때문에 어쩔 수 없다 ㅠㅠ

package com.mapper;

import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Component;

import com.vo.UserVO;

@Component
public interface HomeMapper {

	@Select("SELECT user_id, user_name FROM tbl_user")
	public UserVO getUserList();
	
}

 각 메소드 위에 붙는 쿼리별?어노테이션?과 쿼리문은 통일시켜줘야한다. 처음에 insert로 하려고 하다가 select로 바꿨는데 어노테이션을 그대로 insert로 깜빡하고 냅뒀더니 바인딩 예외가 떠서 한참 고생했다... 오타와의 전쟁..ㅠㅠ



7. HomeService/HomeServiceImpl 생성


 두 개나 만드는 것이 번거로운 일이긴 하지만 인터페이스라는 것이 메소드 이름을 통일시키는 용도이기 때문에 어쩔 수 없는 것 같다(참고1참고2


 HomeService

1
2
3
4
5
6
7
package com.service;
 
import com.vo.UserVO;
 
public interface HomeService {
    public UserVO getUserList();
}


 HomeServiceImpl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com..service;
 
import javax.inject.Inject;
 
import org.springframework.stereotype.Service;
 
import com.mapper.HomeMapper;
import com.vo.UserVO;
 
@Service
public class HomeServiceImpl implements HomeService {
 
    @Inject
    HomeMapper mapper;
     
    @Override
    public UserVO getUserList() {
        return mapper.getUserList();
    }
 
}

service에서 component스캔으로 bean에 등록된 mapper를 참조해야 하므로 Inject 어노테이션을 통해 service에서 Homemapper를 활용하게 한다. (inject 관련 참조)


8. 레알 테스트 하기 src/test/java/에 TestDB 생성


 컨트롤러 대신에 일단 junit으로 테스트를 한다. 앞으로 모든 DB와 연결하는 작업은 junit테스트로 미리 검사하고 컨트롤러에 적용할 예정이다.


package com.test;

import javax.inject.Inject;

import org.junit.Test;

import com.mapper.HomeMapper;
import com.service.HomeService;
import com.vo.UserVO;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"file:src/main/**/*-context.xml"})
public class TestDB {
	@Inject
	HomeService service;
	@Inject
	HomeMapper mapper;
	
	@Test
	public void getUserListTest() {
		try {
			UserVO vo = service.getUserList();
			System.out.println(vo);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
}


 test에서 참조해야할 bean은 service, mapper 둘 다 필요하므로 inject 시켜준다. @Test가 붙은 메소드는 junit이 테스트 단위로 여기기 때문에 junit 실행시에 항상 테스트가 작동한다. 그리고 @ContextConfiguration에서 junit이 참조해야할 설정 파일 경로를 지시한다. 요걸 안하면 root-context에서 설정한게 말짱 도루묵이 되버린다.



그럼 테스트를 돌려보자...



클래스 파일을 통째로 test를 돌려도 되고 원하는 메소드만 test도 가능하다




junit 테스트는 성공했고 콘솔에 DB데이터가 제대로 불러오진 것을 볼 수가 있다 



연동은 이걸로 끝!!!!!!!



댓글