일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- select문
- 클래스
- BufferedReader
- Linux
- order by
- StringBuilder
- 알고리즘
- 데이터 조회
- select
- html
- JavaScript
- 형변환
- 메서드
- where
- scanner
- sql문
- DML
- 스프링
- 입출력
- github
- 자바
- MySQL
- SQL
- Java
- 정보처리기사
- 자바스크립트
- String클래스
- 개발자
- 리눅스
- mybatis
- 정보처리기사필기요약
- 프로그래밍
- 프론트엔드
- 프로그래머스 sql 고득점 kit
- Git
- 백준
- 예외처리
- 프로그래머스 SQL
- 백엔드
- 웹개발
- Today
- Total
ToBe끝판왕
[ 프로젝트 ] Mybatis 프레임워크 게시판 적용 (1) 본문
Mybatis 프레임워크 적용
▶ Mybatis 구조 파악하기
• 기존 프로젝트 내 게시판 디렉터리 구조이다.
< 기존 프로젝트 게시판 디렉터리 구조 >
src
├── controller
│ └── CommController.java
├── model
│ ├── BoardTO.java
│ ├── BoardDAO.java
│ └── BoardListTO.java
└── webapp
└── WEB-INF
└── views
└── community
└── .jsp 파일들
• 게시판에 Mybatis를 적용시켜 디렉터리 구조를 아래와 같이 만들 것이다.
< Mybatis 프레임워크 적용 디렉터리 구조 >
src
├── community
│ ├── controller
│ │ └── CommController.java
│ ├── mapper
│ │ └── CommMapper.java
│ ├── model
│ │ └── BoardTO.java
│ │ └── PagingVO.java
│ └── service
│ ├── impl
│ │ └── CommServiceImpl.java
│ └── CommService.java
└── resources
└── mybatis
└── commMapper.xml
• 디렉터리 구조를 파악해보면
CommMapper.java / CommServiceImpl.java / CommService.java / commMapper.xml 4개의 파일을 만들어야 한다.
▶ pom.xml 에 스프링 부트 myBatis dependency를 추가한다.
<!-- mybatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
▶ application.properties 에서 mapper.xml 위치 관련 설정을 한다.
mybatis.mapper-locations: mybatis/*.xml
# mybatis.type-aliases-package=com.camper.mapper
=> 물론 데이터베이스로 사용한 AWS RDS 연결설정도 필요하다.
▶ mapper.xml 파일 만들기
• Mybatis 사용목적 중 하나는 DAO로부터 SQL문을 분리하는 것이다.
• 분리된 SQL문은 SQL mapper 파일에 작성하며 DAO에서 SqlSession 객체가 SQL mapper 파일을
참조하게 된다.
• SQL mapper 파일은 XML이기 때문에 XML 선언을 먼저 해준다.
<?xml version="1.0" encoding="UTF-8"?>
• 태그 규칙을 정의한 DTD 선언을 한다.
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
• Root Element - <mapper>
- SQL mapper 파일은 루트 엘리먼트 <mapper>을 작성하는 것으로 시작한다.
- <mapper>의 namespace 속성은 자바의 패키지처럼 여러 개의 SQL문을 묶는 용도로 사용된다.
- mapper 파일에 작성하는 모든 SQL문은 <mapper> 하위에 놓여야 한다.
<mapper namespace="com.camper.mapper.CommMapper">
• SQL 문 작성 - <select> , <insert> , <update> , <delete>
< select / insert / update / delete id = " " parameterType=" " resultType/resultyMap= " " >
속성 | 설명 |
id | 각 SQL문을 구분한다. |
resultyType | SELECT문 실행 결과를 담을 객체 패키지 이름을 포함한 클래스 이름 or 객체 alias 지정 ( alias는 Mybais 설정파일에 설정한다. ) |
resultMap | SELECT문 실행 결과를 담을 객체를 resultMap으로 지정 <resultMap> 따로 선언해줘야 한다. resultType , resultMap 중 하나를 택해서 설정한다. |
parameterType | 이 속성에 지정한 객체의 프로퍼티값이 SQL문의 입력 파라미터에 지정된다. |
- resultType 속성 : myBatis는 SELECT 결과를 저장하기 위해 resultType에 지정된 클래스의 인스턴스를 생성한다.
그리고 각 칼럼에 대응하는 Setter를 호출한다.
칼럼에 맞는 Setter가 없으면 그 칼럼의 값은 객체에 저장되지 않는다.
이름이 달라서 값이 저장되지 않는 문제를 해결하기 위해선, SELECT문의 각 칼럼에 as로 alias를
붙이면 된다.
- resultMap 속성 : resultType를 사용하면 Setter와 매칭되지 않는 경우 각 칼럼마다 alias를 붙여야 하는 번거로움이 있다.
resultMap 속성은 이문제를 해결할 수 있다.
• CommMapper.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="com.camper.community.mapper.CommMapper">
<!-- 게시판 Mapper.xml -->
<!-- 커뮤니티 캠핑로그 / 캠핑꿀팁 / 캠핑가자 List -->
<select id="boardList" parameterType="com.camper.community.model.BoardTO" resultType="com.camper.community.model.BoardTO">
SELECT PSEQ
, TITLE
, NICK
, TYPE
, DATE_FORMAT( WDATE, '%y-%m-%d' ) AS WDATE
FROM p_table
WHERE TYPE = #{type}
ORDER BY PSEQ DESC
LIMIT 5 OFFSET #{offset}
</select>
<!-- 페이징 위한 게시글 count -->
<select id="boardListCount" parameterType="com.camper.community.model.BoardTO" resultType="int" >
SELECT COUNT(1)
FROM p_table
WHERE TYPE = #{type}
</select>
<!-- 커뮤니티 게시물 보기 -->
<select id="viewBoard" parameterType="com.camper.community.model.BoardTO" resultType="com.camper.community.model.BoardTO">
SELECT TITLE
, NICK
, DATE_FORMAT( WDATE, '%y-%m-%d' ) AS WDATE
, CONTENT
, TYPE
, PSEQ
FROM p_table
WHERE PSEQ = #{pseq}
</select>
<!-- 커뮤니티 게시물 등록 -->
<insert id="writeBoard" parameterType="com.camper.community.model.BoardTO">
INSERT INTO p_table
VALUES( 0, #{title}, #{nick}, #{pwd}, #{content}, #{type}, now(), #{heart}, #{preply} )
</insert>
<!-- 커뮤니티 게시물 삭제 확인 -->
<delete id="deleteOkBoard" parameterType="com.camper.community.model.BoardTO">
DELETE FROM p_table
WHERE PSEQ = #{pseq}
</delete>
<!-- 커뮤니티 게시물 수정 -->
<select id="modifyBoard" parameterType="com.camper.community.model.BoardTO" resultType="com.camper.community.model.BoardTO">
SELECT TITLE
, NICK
, CONTENT
, TYPE
, PSEQ
FROM p_table
WHERE PSEQ = #{pseq}
</select>
<!-- 커뮤니티 게시물 수정 확인 -->
<update id="modifyOkBoard" parameterType="com.camper.community.model.BoardTO">
UPDATE p_table SET TITLE = #{title}, CONTENT = #{content}
WHERE PSEQ = #{pseq}
</update>
<!-- 공지사항 List -->
<select id="noticeList" parameterType="com.camper.community.model.BoardTO" resultType="com.camper.community.model.BoardTO">
SELECT NSEQ
, TITLE
, NICK
, TYPE
, DATE_FORMAT( WDATE, '%y-%m-%d' ) AS WDATE
FROM n_board
WHERE TYPE = #{type}
ORDER BY NSEQ DESC
</select>
<!-- 공지사항 게시물 보기 -->
<select id="noticeView" parameterType="com.camper.community.model.BoardTO" resultType="com.camper.community.model.BoardTO">
SELECT TITLE
, NICK
, DATE_FORMAT( WDATE, '%y-%m-%d' ) AS WDATE
, CONTENT
, TYPE
, NSEQ
FROM n_board
WHERE NSEQ = #{nseq}
</select>
<!-- FAQ List -->
<select id="faqList" parameterType="com.camper.community.model.BoardTO" resultType="com.camper.community.model.BoardTO">
SELECT NSEQ
, TITLE
, NICK
, CONTENT
, DATE_FORMAT(WDATE, '%Y-%m-%d' ) AS WDATE
FROM n_board
WHERE TYPE = #{type}
ORDER BY NSEQ DESC
</select>
</mapper>
※ #{ } 사용
• Mybatis에서는 입력 파라미터를 #{프로퍼티}로 표시한다.
• #{ } 사용 시, PreparedStatement 생성
• PreparedStatement가 제공하는 Set 계열 메서드를 사용하여 물음표(?)를 대체할
값을 지정한다.
• ' 값 ' 형태로 쿼리가 수행된다.
▶ CommMapper.java 인터페이스 만들기
• Mapper 인터페이스
- 개발자가 작성한다.
- Mybatis 3.0 이후 생긴 방식이다.
- Mapper.xml 파일에 기재된 SQL문을 호출하기 위한 인터페이스이다.
- Mapper.xml 파일에 있는 SQL을 자바 인터페이스를 통해 지정한다.
- Mapper 인터페이스를 사용하지 않으면, SQL 호출하는 프로그램은 SqlSession의 메서드의 인수에
문자열로 namespace.SQL_ID를 지정해야 한다.
• Mapper 인터페이스 작성
- 반드시 Interface로 선언한다.
- 메서드명은 mapper.xml의 namespace ID랑 맞춘다.
- @Mapper 어노테이션은 단순히 Mybatis의 mappers를 위한 Mapper등록을 위해 사용한다.
package com.camper.community.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import com.camper.community.model.BoardTO;
@Mapper
public interface CommMapper {
// 커뮤니티 메인페이지 3개 List
public List<BoardTO> boardList( BoardTO to );
// 페이징 위한 게시글 count
public int boardListCount( BoardTO to );
// 커뮤니티 게시글 보기
public BoardTO viewBoard( BoardTO to );
// 커뮤니티 게시글 등록
public int writeBoard( BoardTO to );
// 커뮤니티 게시글 삭제
// public BoardTO deleteBoard( BOardTO to );
// 커뮤니티 게시글 삭제 확인
public int deleteOkBoard( BoardTO to );
// 커뮤니티 게시글 수정
public BoardTO modifyBoard( BoardTO to );
// 커뮤니티 게시글 수정 확인
public int modifyOkBoard( BoardTO to );
// 공지사항 게시글 List
public List<BoardTO> noticeList( BoardTO to );
// 공지사항 게시글 보기
public BoardTO noticeView( BoardTO to );
// FAQ 게시글 List
public List<BoardTO> faqList( BoardTO to);
}
▶ CommService.java / CommServiceimpl.java 만들기
• Service / Serviceimpl
- 추상화 , OOP 원칙의 예시로 볼 수 있다.
- Service는 Controller의 요청에 맞추어 데이터를 가공하고 Controller에게 넘겨주는 비즈니스 로직이다.
- 비즈니스 로직을 수행하기 위해 Service는 Interface파일로. Serviceimpl은 class파일로 작성한다.
- MVC 패턴에서 Serviceimpl은 비즈니스 로직 즉, 기능을 구현하는 구현부를 수행하는 역할을 맡는다.
- Interface와 구현체 class를 분리함으로써 구현체를 독립적으로 확장할 수 있으며, 구현체 클래스를 변경하거나
확장해도 이를 사용하는 클라이언트 코드에는 영향을 주지 않는다.
- 인터페이스와 클래스로 분리하기 때문에 의존관계를 최소화하고 기능의 변화에도 최소한의 수정으로
개발할 수 있는 유연함을 가질 수 있다.
- 모듈화를 통해 어디서든 사용할 수 있도록 재사용성을 높인다.
• CommService.java( Interface ) 작성
- 객체의 사용방법을 정의한 타입( = 해당 서비스에서 수행하는 기능들을 먼저 정의해 둔 것이다. )
- Controller는 화면에서 넘어오는 매개변수들을 이용해 Service객체를 호출한다.
package com.camper.community.service;
import java.util.List;
import com.camper.community.model.BoardTO;
import com.camper.model.NboardTO;
public interface CommService {
// 커뮤니티 메인페이지 3개 List
public List<BoardTO> boardList( BoardTO to ) throws Exception;
// 페이징 위한 게시글 count
public int boardListCount( BoardTO to ) throws Exception;
// 커뮤니티 게시글 보기
public BoardTO viewBoard( BoardTO to ) throws Exception;
// 커뮤니티 게시글 등록
public int writeBoard( BoardTO to ) throws Exception;
/*
// 커뮤니티 게시글 삭제
public BoardTO deleteBoard( BoardTO to ) throws Exception;
*/
// 커뮤니티 게시글 삭제 확인
public int deleteOkBoard( BoardTO to ) throws Exception;
// 커뮤니티 게시글 수정
public BoardTO modifyBoard( BoardTO to ) throws Exception;
// 커뮤니티 게시글 수정 확인
public int modifyOkBoard( BoardTO to ) throws Exception;
// 공지사항 게시글 List
public List<BoardTO> noticeList( BoardTO to ) throws Exception;
// 공지사항 게시글 보기
public BoardTO noticeView( BoardTO to ) throws Exception;
// FAQ 게시글 List
public List<BoardTO> faqList( BoardTO to ) throws Exception;
}
• CommServiceimpImpl.java( class) 작성
- CommService.java를 부모로 상속받아 구현하게 된다.
- @Service 어노테이션은 해당 클래스가 비즈니스 로직을 담은 Service클래스임을 명시한다.
- @Autowired 어노테이션은 필드 / 생성자 / 수정자 메서드에 사용한다. ( 객체에 대한 의존성을 주입한다. )
package com.camper.community.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.camper.community.mapper.CommMapper;
import com.camper.community.model.BoardTO;
import com.camper.community.service.CommService;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Service
public class CommServiceImpl implements CommService {
@Autowired
CommMapper commMapper;
// 커뮤니티 게시글 List
@Override
public List<BoardTO> boardList(BoardTO to) throws Exception {
List<BoardTO> list = null;
try {
list = commMapper.boardList( to );
} catch (Exception e) {
log.error( "[게시판 리스트 조회 에러]" + e.getMessage() );
}
return list;
}
// 페이징 위한 게시글 count
public int boardListCount( BoardTO to ) throws Exception {
// 게시판 카운트
return commMapper.boardListCount( to );
}
// 게시판 게시글 상세보기
@Override
public BoardTO viewBoard(BoardTO to) throws Exception {
BoardTO board = null;
try {
board = commMapper.viewBoard( to );
} catch (Exception e) {
log.error( "[게시글 상세 보기 에러]" + e.getMessage() );
}
return board;
}
// 게시판 게시글 등록
@Override
public int writeBoard(BoardTO to) throws Exception {
int flag = 1;
try {
if( commMapper.writeBoard( to ) == 1 ) {
flag = 0;
}
} catch (Exception e) {
log.error( "[게시판 게시글 등록 에러]" + e.getMessage() );
}
return flag;
}
/*
// 게시판 게시글 삭제
@Override
public BoardTO deleteBoard(BoardTO to) throws Exception {
BoardTO board = null;
try {
board = commMapper.deleteBoard( to );
} catch (Exception e) {
log.error( "[게시판 게시글 삭제 에러]" + e.getMessage() );
}
return board;
}
*/
// 게시판 게시글 삭제 확인
@Override
public int deleteOkBoard(BoardTO to) throws Exception {
int flag = 1;
try {
if( commMapper.deleteOkBoard( to ) == 1 ) {
// 정상
flag = 0;
}
} catch (Exception e) {
log.error( "[게시판 게시글 삭제 확인 에러]" + e.getMessage() );
}
return flag;
}
// 게시판 게시글 수정
@Override
public BoardTO modifyBoard(BoardTO to) throws Exception {
BoardTO board2 = null;
try {
board2 = commMapper.modifyBoard( to );
} catch (Exception e) {
log.error( "[게시판 게시글 수정 에러]" + e.getMessage() );
}
return board2;
}
// 게시판 게시글 수정 확인
@Override
public int modifyOkBoard(BoardTO to) throws Exception {
int flag = 1;
try {
if( commMapper.modifyOkBoard( to ) == 1 ) {
// 정상
flag = 0;
}
} catch (Exception e) {
log.error( "[게시판 게시글 수정 확인 에러]" + e.getMessage() );
}
return flag;
}
// 공지사항 List
@Override
public List<BoardTO> noticeList(BoardTO to) throws Exception {
List<BoardTO> list = null;
try {
list = commMapper.noticeList( to );
} catch (Exception e) {
log.error( "[공지사항 리스트 에러]" + e.getMessage() );
}
return list;
}
// 공지사항 글보기
@Override
public BoardTO noticeView(BoardTO to) throws Exception {
BoardTO board3 = null;
try {
board3 = commMapper.noticeView( to );
} catch (Exception e) {
log.error( "[공지사항 글보기 에러]" + e.getMessage() );
}
return board3;
}
// FAQ List
@Override
public List<BoardTO> faqList(BoardTO to) throws Exception {
List<BoardTO> list = null;
try {
list = commMapper.faqList( to );
} catch (Exception e) {
log.error( "[문의응답 리스트 에러]" + e.getMessage() );
}
return list;
}
}
'■ 프로젝트 > 팀프로젝트 수정 2' 카테고리의 다른 글
[ 프로젝트 ] AWS EC2 인스턴스 생성 , 탄력적 IP 추가 (0) | 2022.06.27 |
---|---|
[ 프로젝트 ] JSTL 의 기본 개념 및 사용 방법 (0) | 2022.06.21 |
[ 프로젝트 ] Mybatis 프레임워크 게시판 적용 (2) (0) | 2022.06.21 |
[ 프로젝트 ] SpringBoot 게시판( MyBatis 프레임워크 적용 ) (0) | 2022.06.14 |