프로그래밍/Spring

스프링 부트로 게시판 만들기2 - MyBatis, MySQL연동

abfc 2016. 10. 16.
반응형

관련글 : 프링 부트로 게시판 만들기1 - 프로젝트 생성


스프링 부트에서 데이터베이스 설정하기



스프링 부트에서 데이터베이스를 설정하기 위해서 라이브러리를 추가해야합니다. 처음 프로젝트를 생성할때도 가능하지만 저는 web만 선택하고 생성했기 때문에 관련 라이브러리를 먼저 추가하겠습니다.


프로젝트내에 있는 build.gradle 파일 아래에 보시면 dependencies가 있습니다. 그 아래에 추가로 작성해주세요. (기존에 dependency 되어 있는 라이브러리를 지우면 안돼요!)

1
2
compile('org.springframework.boot:spring-boot-starter-jdbc')
compile('mysql:mysql-connector-java')
cs




저장 후에 프로젝트 선택 우클릭 - Gradle(STS) - Enable Dependency Management 선택





선택 후 다시가서 Refresh Dependecies를 선택하면 콘솔창에 BUILD SUCCESSFUL 이 출력됩니다.(혹시 에러나면 오타를 확인해주세요.)





application.properties 파일 설정하기

STS의 Spring Starter Project를 이용해서 생성한 프로젝트는 기본적으로 src/main/resources폴더가 생성됩니다. 구조를 살펴보면

static : HTML, CSS, JavaScript, 이미지 파일들을 보관하는 경로

templates : Thymeleaf와 같은 템플릿의 경로(저는 JSP를 사용할거기 때문에 이 폴더는 사용하지 않습니다.)

application.properties : 어플리케이션 내의 설정 파일


이렇게 세가지가 자동으로 생성되어 있습니다. 스프링 부트는 기본적으로 XML을 이용하지 않고, 프로젝트의 설정을 하도록 생성이 되는데 문자열 등의 특별한 설정이 필요한 경우에 사용하는 것이 application.properties 파일입니다.




DataSource 설정

스프링 부트의 경우 DataSource를 처리하기 위해 1. @Bean을 이용한 DataSource설정, 2. application.properties를 이용한 데이터 설정. 이렇게 두 가지 방식이 있는데 저는 2번 방식을 사용하겠습니다.




mysql연동을 위해 application.properties파일에 다음과 같이 작성해주세요.

1
2
3
4
spring.datasource.driver-class-name= com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/데이터베이스명
spring.datasource.username=mySql아이디
spring.datasource.password=mySql
cs



연동이 잘 되었는지 테스트를 해봐야겠죠?

프로젝트 생성 시 만들어진 /src/test/java 아래에 com.board 패키지 아래에 프로젝트명+ApplicationTests 라는 이름의 파일이 자동으로 생성되어 있는데 이 파일을 이용해서 테스트를 해보겠습니다.





BoardApplicationTests.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package com.board;
 
import java.sql.Connection;
 
import javax.sql.DataSource;
 
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
 
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = BoardApplication.class)
@WebAppConfiguration
public class BoardApplicationTests {
    
    @Autowired
    private DataSource ds; //작성
 
    @Test
    public void contextLoads() {
    }
 
    @Test
    public void testConnection() throws Exception{ //작성
        System.out.println("ds : "+ds);
        
        Connection con = ds.getConnection(); //ds(DataSource)에서 Connection을 얻어내고
        
        System.out.println("con : "+con); //확인 후
        
        con.close(); //close
    }
}
 
cs





작성하고 저장한 후에 BoardApplicationTests 우클릭 - Run As - JUnit Test를 실행하면 콘솔창에 출력되는 걸 확인할 수 있습니다.

1
2
ds : org.apache.tomcat.jdbc.pool.DataSource@5e742e4{ConnectionPool[defaul...생략....
con : ProxyConnection[PooledConnection[com.mysql.jdbc.JDBC4Connection@4b2a30d]]
cs





MyBatis 설정하기

스프링 부트는 MyBatis를 기본 설정에 추가시키지 않았기 때문에 MyBatis를 이용하기 위해서는 필요한 라이브러리와 객체의 설정이 필요합니다.


위에서 jdbc와 mySQL 라이브러리를 추가해줬을때처럼 build.gradle파일에 추가해주세요.

1
2
3
compile("org.mybatis.spring.boot:mybatis-spring-boot-starter:1.1.1")
compile("org.mybatis:mybatis-spring")
compile("org.mybatis:mybatis")
cs


저장 후에 귀찮으니 프로젝트 선택 우클릭 - Gradle(STS) -  Refresh All을 선택





SqlSessionFactory 설정

스프링 부트는 기본적으로 XML설정을 피하는 형태로 작성하는 경우가 많습니다. MyBatis 역시 어노테이션이나 Java 코드를 이용해서 Mapper인터페이스를 인식하도록 할건데요. 가장 간단한 방법인 @MapperScan 어노테이션을 이용하겠습니다.

MyBatis를 사용하기 위해서 BoardApplication 파일에 SqlSessionFactory에 대한 설정을 추가해줍니다.



BoardApplication.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package com.board;
 
import javax.sql.DataSource;
 
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
 
@SpringBootApplication
public class BoardApplication {
 
    public static void main(String[] args) {
        SpringApplication.run(BoardApplication.class, args);
    }
    
    /**
     * SqlSessionFactory 설정
     */
    @Bean
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource)throws Exception{
        SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
            sessionFactory.setDataSource(dataSource);
            return sessionFactory.getObject();
    }
    
}
 
cs



클래스 선언부에 있는 @MapperScan 어노테이션의 value 속성으로는 문자열의 배열을 이용할 수 있는데 Mapper 인터페이스들이 들어있는 패키지를 인식시켜주면 됩니다. @Bean 어노테이션은 스프링에 필요한 객체를 생성할 때 사용하고, sqlSessionFactory() 메서드는 리턴 타입으로 MyBatis의 SqlSessionFactory를 반환해줍니다.

 그리고 스프링 부트는 실행 시 DataSource객체를 메서드의 실행 시 주입해서 결과를 만들고 그 결과를 스프링 내 빈으로 사용하게 됩니다.

이전에 테스트를 위해 사용했던 BoardApplicationTests 파일을 이용하여 테스트를 통해 정상적으로 스프링에 등록이 되었는지 확인해보겠습니다.



BoardApplicationTests.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package com.board;
 
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
 
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = BoardApplication.class)
@WebAppConfiguration
public class BoardApplicationTests {
    
    @Autowired
    private SqlSessionFactory sqlSession; //작성
 
    @Test
    public void contextLoads() {
    }
    
    @Test
    public void testSqlSession() throws Exception{//작성
        
        System.out.println("sqlSession : "+sqlSession);
        
    }
 
}
 
cs





저장 후 BoardApplicationTests 우클릭 - Run As - JUnit Test

콘솔창에 객체가 올바르게 생성되었는지 확인합니다.

1
sqlSession : org.apache.ibatis.session.defaults.DefaultSqlSessionFactory@770b3be0
cs




Mapper 인터페이스 작성

위에서 SqlSessionFactory가 성공적으로 생성되었다면 도메인 객체와 인터페이스 Mapper를 만들어보도록 하겠습니다.



테이블 생성

1
2
3
4
5
6
7
create table board_pro(
bno int not null auto_increment primary key//글번호
subject varchar(50not null//제목
content text not null//내용
writer varchar(50not null//작성자
reg_date datetime not null//작성날
hit int); //조회수
cs



도메인 클래스 작성

src/main/java아래에 com.board.domain패키지 생성 후 BoardVO 클래스를 생성합니다.



BoardVO.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package com.board.domain;
 
import java.util.Date;
 
public class BoardVO {
 
    private int bno;
    private String subject;
    private String content;
    private String writer;
    private Date reg_date;
    private int hit;
 
    public int getBno() {
        return bno;
    }
 
    public void setBno(int bno) {
        this.bno = bno;
    }
 
    public String getSubject() {
        return subject;
    }
 
    public void setSubject(String subject) {
        this.subject = subject;
    }
 
    public String getContent() {
        return content;
    }
 
    public void setContent(String content) {
        this.content = content;
    }
 
    public String getWriter() {
        return writer;
    }
 
    public void setWriter(String writer) {
        this.writer = writer;
    }
 
    public Date getReg_date() {
        return reg_date;
    }
 
    public void setReg_date(Date reg_date) {
        this.reg_date = reg_date;
    }
 
    public int getHit() {
        return hit;
    }
 
    public void setHit(int hit) {
        this.hit = hit;
    }
 
}
 
cs





Mapper 인터페이스 작성

com.board.mapper 패키지 생성/ BoardMapper 인터페이스 생성



BoardMapper.java

1
2
3
4
5
6
7
8
9
10
11
12
package com.board.mapper;
 
import org.apache.ibatis.annotations.Param;
 
import com.board.domain.BoardVO;
 
public interface BoardMapper {
 
    public void boardInsert(BoardVO board)throws Exception;
 
}
 
cs





src/main/resources에 mappers 폴더를 생성합니다.


mappers에 boardMapper.xml 파일을 생성하고 작성합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?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.board.mapper.BoardMapper">
 
    <insert id="boardInsert" parameterType="com.board.domain.BoardVO">
        insert into board_pro
            values
        (#{bno},#{subject},#{content},#{writer},now(),0)
    </insert>
 
</mapper>
cs





작성된 XML Mapper를 인식하기 위해서 BoardApplication 실행 파일에 설정된 SqlSessionFactory의 설정을 변경해주어야 합니다. (직접 작성하는 경우에 import 꼭 확인해주세요)


BoardApplication.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package com.board;
 
import javax.sql.DataSource;
 
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
 
@SpringBootApplication
@MapperScan(value = {"com.board.mapper"})
public class BoardApplication {
 
    public static void main(String[] args) {
        SpringApplication.run(BoardApplication.class, args);
    }
    
    /**
     * SqlSessionFactory 설정
     */
    @Bean
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource)throws Exception{
        SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
            sessionFactory.setDataSource(dataSource);
            
            Resource[] res = new PathMatchingResourcePatternResolver().getResources("classpath:mappers/*Mapper.xml");
            
            sessionFactory.setMapperLocations(res);
            
            return sessionFactory.getObject();
    }
    
}
 
cs





XML Mapper가 정상적으로 동작하는지 테스트를 해보기 위해 BoardApplicationTestes 파일에 다음과 같이 작성합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package com.board;
 
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
 
import com.board.domain.BoardVO;
import com.board.mapper.BoardMapper;
 
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = BoardApplication.class)
@WebAppConfiguration
public class BoardApplicationTests {
    
    @Autowired
    private BoardMapper mapper;
    
    @Test
    public void contextLoads() {
    }
    
    @Test
    public void testMapper() throws Exception{//작성
        
        BoardVO vo = new BoardVO();
        
        vo.setSubject("제목입니다.");
        vo.setContent("내용입니다.");
        vo.setWriter("작성자입니다.");
        
        mapper.boardInsert(vo);
        
    }
 
}
 
cs





저장 후 테스트를 해보면 board_pro테이블에 데이터가 저장되어있는 걸 확인할 수 있습니다.


간단하게 controller를 작성해서 화면에 출력해볼까요? 게시판 리스트를 불러오는 mapper인터페이스와 쿼리문 먼저 작성합니다.



BoardMapper.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.board.mapper;
 
 
import java.util.List;
 
import com.board.domain.BoardVO;
 
public interface BoardMapper {
 
    //글작성
    public void boardInsert(BoardVO vo)throws Exception;
    
    //글목록
    public List<BoardVO>boardList()throws Exception; //추가
    
}
 
cs




boardMapper.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?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.board.mapper.BoardMapper">
 
    <insert id="boardInsert" parameterType="com.board.domain.BoardVO">
        insert into board_pro
            values
        (#{bno},#{subject},#{content},#{writer},now(),0)
    </insert>
    
    <select id="boardList" resultType="com.board.domain.BoardVO">
        select * from board_pro
    </select>
 
</mapper>
cs




com.board.controller에 BoardListController 클래스를 생성한 뒤 작성해주세요.


BoardListController.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.board.controller;
 
import java.util.List;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
 
import com.board.domain.BoardVO;
import com.board.mapper.BoardMapper;
 
@RestController
public class BoardListController {
 
    @Autowired
    private BoardMapper boardMapper;
    
    @RequestMapping("/board")
    public List<BoardVO> board() throws Exception{
        List<BoardVO> board = boardMapper.boardList();
        return board;
    }
}
 
cs





다 작성하였으면 저장 후 프로젝트를 실행하고 http://localhost:8080/board 를 요청합니다.



잘 나오나요? 

기존 프로젝트의 경우 1) 테이블 생성 및 도메인 클래스 작성 2) DAO 인터페이스 정의 3) XML 매퍼 작성 4) DAO 인터페이스 구현 순서로 작성했지만,

스프링 부트를 이용하는 경우에는 1) 테이블 생성 및 도메인 클래스 작성 2) 인터페이스 Mapper의 작성 및 어노테이션 처리로 끝나기 때문에 기존 프로젝트에 비하면 정말 너무나 간단하게 MyBatis를 연동하고 MySQL을 사용할 수 있ㅓ 기존에 비해 개발 시간을 단축할 수 있겠네요.


다음 포스팅에서는 스프링부트에서 JSP를 사용해보도록 하겠습니다.





**

혹시나 콘솔창에

SQLErrorCodes loaded: [DB2, Derby, H2, HSQL, Informix, MS-SQL, MySQL, Oracle, PostgreSQL, Sybase, Hana]

이러한 에러가 뜨는 분들은 오타가 없는지 꼭 확인해보시고 build.gradle 파일로 주입시켰던 MySQL, MyBatis 라이브러리가 Web App Libraries에 제대로 다운받아 졌는지 꼭 확인해보세요. 저는 오타였습니다^^;









반응형

댓글

💲 추천 글