본문 바로가기
카테고리 없음

MyBatis를 이용한 SpringBoot 애플리케이션 구현 1 - 게시판 목록 조회

by ^..^v 2020. 5. 29.
728x90
반응형

MySQL Workbench를 이용해서 테스트에 사용할 테이블을 생성합니다. 데이터베이스는 "도커로 MySQL 설치 및 실행"에서 생성한 것을 사용합니다.

CREATE TABLE board 
  ( 
     board_idx  INT (11) NOT NULL auto_increment comment '글 번호', 
     title      VARCHAR(300) NOT NULL comment '제목', 
     contents   TEXT NOT NULL comment '내용', 
     hit_cnt    SMALLINT(10) NOT NULL DEFAULT '0' comment '조회수', 
     creator_id VARCHAR (50) NOT NULL comment '작성자', 
     created_dt DATETIME NOT NULL comment '작성시간', 
     updater_id VARCHAR (50) NULL comment '수정자', 
     updated_dt DATETIME NULL comment '수정시간', 
     deleted_yn CHAR (1) NOT NULL DEFAULT 'N' comment '삭제 여부', 
     PRIMARY KEY (board_idx) 
  ); 
  
insert into board (title, contents, creator_id, created_dt, updated_dt) values ('title #1', 'contents #1', 'user001', now(), now());
insert into board (title, contents, creator_id, created_dt, updated_dt) values ('title #2', 'contents #2', 'user001', now(), now());
insert into board (title, contents, creator_id, created_dt, updated_dt) values ('title #3', 'contents #3', 'user002', now(), now());
insert into board (title, contents, creator_id, created_dt, updated_dt) values ('title #4', 'contents #4', 'user002', now(), now());

 

https://start.spring.io/ 사이트에서 생성한 프로젝트 파일을 이클립스에 추가합니다.

 

스프링 부트 애플리케이션을 실행합니다.

 

정상 동작 여부 확인을 위해 Hello Spring 메시지를 출력하는 컨트롤러 클래스를 추가합니다.

// /mybatisdemo/src/main/java/com/example/mybatisdemo/controller/HelloController.java

package com.example.mybatisdemo.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {

	// = @RequestMapping("/")
	// = @GetMapping("/")
	@RequestMapping(method = RequestMethod.GET, path = "/")
	public String hello() {
		return "Hello Spring";
	}
}

 

브라우저를 통해 결과를 확인합니다.

 

application.properties 설정 파일에 데이터베이스 연결 정보를 추가합니다. 

spring.datasource.hikari.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.hikari.jdbc-url=jdbc:mysql://localhost:3306/msa_db?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Seoul
spring.datasource.hikari.username=dev
spring.datasource.hikari.password=password
spring.datasource.hikari.connection-test-query=select 1

 

DatabaseConfiguration 클래스를 생성하고 DataSource를 생성하는 코드를 추가합니다.

// /mybatisdemo/src/main/java/com/example/mybatisdemo/config/DatabaseConfiguration.java

package com.example.mybatisdemo.config;

import javax.sql.DataSource;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Configuration
@PropertySource("classpath:/application.properties")
public class DatabaseConfiguration {

	@Bean
	@ConfigurationProperties(prefix = "spring.datasource.hikari")
	public HikariConfig hikariConfig() {
		return new HikariConfig();
	}

	@Bean
	public DataSource dataSource() throws Exception {
		DataSource dataSource = new HikariDataSource(hikariConfig());
		log.info("dataSource : {}", dataSource);
		return dataSource;
	}
}

 

콘솔창에 DataSource 정보 출력 여부를 확인합니다. 

 

DatabaseConfiguration 클래스에 MyBatis 설정 정보를 추가합니다. 

// /mybatisdemo/src/main/java/com/example/mybatisdemo/config/DatabaseConfiguration.java

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
				:
public class DatabaseConfiguration {

	@Autowired
	private ApplicationContext applicationContext;

	@Bean
	public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
		SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
		sqlSessionFactoryBean.setDataSource(dataSource);
		sqlSessionFactoryBean.setMapperLocations(applicationContext.getResources("classpath:/mapper/**/sql-*.xml"));
		return sqlSessionFactoryBean.getObject();
	}

	@Bean
	public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
		return new SqlSessionTemplate(sqlSessionFactory);
	}

				:
}

 

src/main/resources 디렉터리 아래에 쿼리맵을 저장할 mapper 디렉터리를 생성합니다.

 

맵퍼 인터페이스와 쿼리맵을 생성합니다.

// /mybatisdemo/src/main/java/com/example/mybatisdemo/mapper/BoardMapper.java

package com.example.mybatisdemo.mapper;

import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface BoardMapper {

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

<!-- /mybatisdemo/src/main/resources/mapper/sql-board.xml -->
<mapper namespace="mybatisdemo.BoardMapper">

</mapper>

 

게시판 목록 조회 RESTful API를 구현해 보도록 하겠습니다. 

클라이언트가 GET 방식의 /api/boards 주소로 요청하면 Controller를 통해서 Service가 호출되고, 서비스는 쿼리와 연결된 Mapper를 호출합니다. 쿼리 실행 결과는 DTO에 담겨서 반환되며, JSON 형태로 사용자에게 전달됩니다.

먼저 데이터를 담을 DTO 클래스를 생성해 보겠습니다. 

// /mybatisdemo/src/main/java/com/example/mybatisdemo/dto/BoardDto.java

package com.example.mybatisdemo.dto;

import lombok.Data;

@Data
public class BoardDto {
	private int boardIdx;
	private String title;
	private String contents;
	private int hitCnt;
	private String creatorId;
	private String createdDt;
	private String updaterId;
	private String updatedDt;
}

 

테이블의 컬럼명(snake expression)과 DTO 객체의 필드명(camel expression)을 자동 맵핑되도록 설정 정보를 추가합니다. 

				:
mybatis.configuration.map-underscore-to-camel-case=true
// /mybatisdemo/src/main/java/com/example/mybatisdemo/config/DatabaseConfiguration.java

package com.example.mybatisdemo.config;
			:

public class DatabaseConfiguration {
			:
	@Bean
	@ConfigurationProperties(prefix = "mybatis.configuration")
	public org.apache.ibatis.session.Configuration mybatisConfig() {
		return new org.apache.ibatis.session.Configuration();
	}

	@Bean
	public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
			:
		sqlSessionFactoryBean.setConfiguration(mybatisConfig());
		return sqlSessionFactoryBean.getObject();
	}
    
    		:
}        

 

게시판 목록 조회 쿼리를 쿼리맵에 추가합니다.

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

<!-- /mybatisdemo/src/main/resources/mapper/sql-board.xml -->
<mapper namespace="com.example.mybatisdemo.mapper.BoardMapper">

	<!-- 게시판 목록 조회 -->
	<select id="selectBoardList" resultType="com.example.mybatisdemo.dto.BoardDto">
		select board_idx, title, hit_cnt, creator_id, date_format(created_dt, '%Y.%m.%d %H:%i:%s') as created_dt, 
		       updater_id, date_format(updated_dt, '%Y.%m.%d %H:%i:%s') as updated_dt, deleted_yn
		  from board
		 where deleted_yn = 'N'
		 order by board_idx desc
	</select>
	
</mapper>

 

맵퍼 인터페이스에 게시판 목록 조회 맵퍼 메서드를 추가합니다.

// /mybatisdemo/src/main/java/com/example/mybatisdemo/mapper/BoardMapper.java

package com.example.mybatisdemo.mapper;

import java.util.List;

import org.apache.ibatis.annotations.Mapper;

import com.example.mybatisdemo.dto.BoardDto;

@Mapper
public interface BoardMapper {

	// 게시판 목록 조회
	List<BoardDto> selectBoardList() throws Exception;
}

 

게시판 관련 서비스 인터페이스와 클래스를 추가합니다.

// /mybatisdemo/src/main/java/com/example/mybatisdemo/service/BoardService.java

package com.example.mybatisdemo.service;

import java.util.List;

import com.example.mybatisdemo.dto.BoardDto;

public interface BoardService {

	// 게시판 목록 조회
	List<BoardDto> selectBoardList() throws Exception;

}

// /mybatisdemo/src/main/java/com/example/mybatisdemo/service/BoardServiceImpl.java

package com.example.mybatisdemo.service;

import java.util.List;

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

import com.example.mybatisdemo.dto.BoardDto;
import com.example.mybatisdemo.mapper.BoardMapper;

@Service
public class BoardServiceImpl implements BoardService {

	@Autowired
	private BoardMapper boardMapper;

	@Override
	public List<BoardDto> selectBoardList() throws Exception {
		return boardMapper.selectBoardList();
	}

}

 

게시판 관련 사용자 요청과 서비스를 연결할 컨트롤러 클래스를 생성합니다.

// /mybatisdemo/src/main/java/com/example/mybatisdemo/controller/BoardApiController.java

package com.example.mybatisdemo.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.example.mybatisdemo.dto.BoardDto;
import com.example.mybatisdemo.service.BoardService;

@RequestMapping(path = "/api")
@RestController
public class BoardApiController {

	@Autowired
	private BoardService boardService;

	@GetMapping("/boards")
	public List<BoardDto> selectBoardList() throws Exception {
		return boardService.selectBoardList();
	}
}

 

브라우저를 통해서 게시판 목록 조회 결과를 확인합니다.

 

조회 결과를 View를 통해서 클라이언트(사용자)에게 반환하는 기능을 추가해 보겠습니다.

사용자에게 보여질 View를 생성합니다. 여기서는 템플릿 엔진으로 mustache를 사용합니다.

<!-- /mybatisdemo/src/main/resources/templates/board/boardList.mustache -->

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>게시판 목록 조회</title>
<link rel="stylesheet"
	href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
</head>
<body>
	<div class="container">
		<h2>게시판 목록</h2>
		<!-- 목록 출력 -->
		<table class="table table-horizontal table-bordered">
			<thead class="thead-strong">
				<tr>
					<th>게시글 번호</th>
					<th>제목</th>
					<th>조회수</th>
					<th>최종수정일</th>
				</tr>
			</thead>
			<tbody>
				{{#resultList}}
				<tr>
					<td>{{boardIdx}}</td>
					<td>{{title}}</td>
					<td>{{hitCnt}}</td>
					<td>{{updatedDt}}</td>
				</tr>
				{{/resultList}}
			</tbody>
		</table>
	</div>

	<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
	<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
</body>
</html>

 

게시판 조회 결과를 뷰를 통해서 반환하는 컨트롤러를 추가합니다.

// /mybatisdemo/src/main/java/com/example/mybatisdemo/controller/BoardController.java

package com.example.mybatisdemo.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import com.example.mybatisdemo.dto.BoardDto;
import com.example.mybatisdemo.service.BoardService;

@Controller
public class BoardController {

	@Autowired
	private BoardService boardService;

	@RequestMapping("/boardList.do")
	public ModelAndView boardList() throws Exception {
		ModelAndView mv = new ModelAndView("/board/boardList");
		List<BoardDto> boardList = boardService.selectBoardList();
		mv.addObject("resultList", boardList);
		return mv;
	}
}

 

브라우저를 통해서 게시판 목록 조회 결과를 확인합니다.

728x90
반응형

댓글