[SpringBoot] 3. 게시판으로 CRUD 기능 구현 - (1)
안녕하세요
오늘로 세 숟가락 째 뜨게되는 글이군요
아직 배는 부르지 않지만, 알듯말듯 아리송 할 정도는 온 것같아요.
알듯말듯 아리송 알리송 ㅋㅋ
역시 새벽 블로그는 제정신이 아닌 맛이죠 레지고
아 참!
그리고 여전히 틀린 정보 속출 가능합니다.
네 오늘은~ 본격적인 프로젝트 생성에 앞서
Oracle DB에 'BOARD'라는 테이블을 먼저 생성하는 사전 작업이 필요합니다.
까짓거 만들면 되죠 뭐.
CREATE TABLE Board (
board_id NUMBER(10) PRIMARY KEY,
title VARCHAR2(100),
content VARCHAR2(200),
author VARCHAR2(50)
);
이렇게 생긴놈을 하나 만들어주면 됩니다.
그리고 PK로 지정한 board_id 번호는 사용자 직접 지정이 아닌, 게시글 작성을 하면 자동으로 값이 부여되도록 시퀀스랑 트리거도 하나씩 만들어서 적용해주겠어요. 급귀찮...
자세한 설명은 생략하겠습니다.. 암튼 다들 알아서 잘 했을거라 믿어요
SQL 원투데이 한거 아니잖아요?
--1부터 시작해서 1씩 증가하는 sequence 생성
CREATE SEQUENCE board_seq
START WITH 1
INCREMENT BY 1
NOCACHE
NOCYCLE;
--board에 값이 들어올 때마다 board_id 값이 증가하는 trigger 생성
CREATE OR REPLACE TRIGGER board_trigger
BEFORE INSERT ON board
FOR EACH ROW
BEGIN
SELECT board_seq.NEXTVAL
INTO:NEW.board_id
FROM dual;
END;
/
사전작업 말하는 김에 프로젝트도 그냥 여기서 만들게용
저는 Spring-Board라는 이름의 Spring Starter 프로젝트를 만들겠습니다.
Type : Maven이랑 Dependency 6개 추가해줬어요
그럼 이제 진짜 끝~
< application.properties >
## DB 연결 설정
spring.datasource.url = jdbc:oracle:thin:@//localhost:1521/XE
spring.datasource.username = [사용자이름]
spring.datasource.password = [사용자비밀번호]
spring.datasource.driver-class-name = oracle.jdbc.OracleDriver
그리고 일단 쓰래서 쓰는 이 친구
무슨 뜻인지 갑자기 궁금해져서 찾아봤더니... (참 빨리도 궁금한 사람)
mybatis.mapper-location = classpath:/mapper/*.xml
mapper 폴더 아래에 존재하는 모든 xml 파일을 mapper로 인식
mybatis.type-aliases-package
xml 파일 result type에 패키지명 생략할 수 있도록 alias 설정 (VO 파일 경로)
그럼 이걸 또 왜 쓰는건가 했는데, 생각해보니 Mapper.java와는 다르게 model이나 mapper.xml 파일같은 경우에는 '얘가 뭐다~'하고 알려주는 어노테이션도 딱히 없어서 그 설정을 따로 해주는 개념이라고 보면 될 것같다.
암튼 다음 단계
< BoardMapper.xml >
이전과 동일하게 resource 폴더 아래에 mapper 폴더 생성 후 파일을 넣어줬다.
이젠 이유를 알아요~
왜? mybatis.mapper-location을 방금 그렇게 정했으니까~
그리고 이번에는 기능 구현을 크게 총 4가지로 잡았다
- 전체 게시물 목록 조회
- board_id를 통해 특정 게시물 1개 조회 (게시물 상세보기)
- 게시글 작성
- 게시글 수정
- 게시글 삭제
얼라리. 쓰고보니 5개네요 죄송 ㅎㅎ 암튼 그에 맞춰 mapper.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.example.springdb.mapper.BoardMapper">
<!-- resultMap으로 다 가지고 오기 -->
<resultMap id="BoardResultMap" type="com.example.springdb.model.Board">
<id property="board_id" column="board_id"/>
<result property="title" column="title"/>
<result property="content" column="content"/>
<result property="author" column="author"/>
</resultMap>
<!-- 전체 게시판 내용 조회하는 어쩌구 --><!-- resultType 아니고 resultMap임 주의 (두 개 동시 사용 불가)-->
<select id="getAllBoards" resultMap="BoardResultMap">
SELECT * FROM board
</select>
<!-- 게시물 1개 상세보기 -->
<select id="getBoardById" parameterType="int" resultMap="BoardResultMap">
SELECT * FROM board WHERE board_id = #{board_id}
</select>
<!-- 게시글 쓰기 -->
<insert id="insertBoard" parameterType="com.example.springdb.model.Board">
INSERT INTO board(board_id, title, content, author)
VALUES(#{board_id}, #{title}, #{content}, #{author})
</insert>
<!-- 게시글 수정 -->
<update id="updateBoard" parameterType="com.example.springdb.model.Board">
UPDATE board
SET title= #{title}, content=#{content}, author=#{author}
WHERE board_id = #{board_id}
</update>
<!-- 게시글 삭제 -->
<delete id="deleteBoard" parameterType="int">
DELETE FROM board
WHERE board_id = #{board_id}
</delete>
</mapper>
이 놈의 태그. 무슨 놈의 종류가 이렇게 많은지 용어도 하나도 모르겠다.. 하면서 친 것같은데
그래도 좀 눈에 익고있는게 웃기다
나름대로 정리.. 고퀄은 기대하지 마시라
1. xml문서 및 DTD(태그 규칙) 선언
2. <mapper>
<mapper> 태그는 root element라고도 불리며, mapper 파일에 작성하는 모든 SQL문은 <mapper> 태그에 묶인다
그리고 namespace 속성에는 뒤에 생성할 mapper 인터페이스 명을 적어준다
이제 당신은 꼼짝없이 BoardMapper라는 인터페이스를 생성해야한다
암튼 그럼 이제 <mapper>태그에 묶인 SQL 구문들이 뒤에 생성될 인터페이스로 호출될 예정.
3. <select>, <insert>, <update>, <delete>
SQL 명령어에 따라서 SELECT문은 <select>, INSERT문은 <insert>...와 같은 모양새로 태그를 만들어서 그 밑에 SQL 구문을 작성해준다
그럼 또 id는 뭐고 resultMap은 뭔지 궁금해진다...
일단 id는 각 SQL구문을 구분하기 위한 녀석으로 알면되겠고
4. resultMap
resultMap이랑 전에 사용한 resultType에 대한 설명은 mybatis 홈페이지에 들어가면 확인 가능하다
진짜 쉽게 말하자면 resultType은 쿼리 실행 결과값을 객체 통째로 받는거고,
resultMap은 사용자가 원하는 컬럼만 뽑아서 쿼리 실행 결과값을 받아올 수 있게 된다.
그래서 resultMap이 좀 더 쓰기 귀찮기는 하지만, 입맛대로 쓰기에는 좋다.
**주의 : resultMap 혹은 resultType 동시 사용 불가
5. parameterType
게시물 상세보기같은 경우, board_id라는 값을 통해 상세정보를 조회할 예정이다.
당연히 int형 매개변수가 필요해서 저렇게 써줬다 (게시글 삭제의 경우도 마찬가지)
나머지는 설명 패스
< BoardMapper.java >
아까 mapper.xml 파일에서 선언한 BoardMapper 인터페이스를 작성한 경로에 맞춰서 생성해준다.
mapper 인터페이스는 결국, 매핑파일(mapper.xml)에 기재된 SQL을 호출하기 위한 공간인 셈
그리고 각 SQL문을 담은 id값에 맞춰서 메서드도 생성해준다.
아니 그런데 쓰다보니까 갑자기 뭔가 이상한 것을 깨달았다. Model을 안만들어줬네 내가;;
board 테이블에 존재하는 컬럼명 및 데이터 타입에 맞춰서 파일하나 만들어주고 올게요..
com.example.springdb.model 패키지에 Board.java 생성 완료 (멤버변수 & GetterSetter)
순서가 이러면 완전 엉터리입니다 여러분들은 이러지 마세요
아무튼 그렇게 작성한 BoardMapper
package com.example.springdb.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import com.example.springdb.model.Board;
@Mapper
public interface BoardMapper {
//전체 게시글 조회
List<Board> getAllBoards();
//게시글 상세보기 by board_id
Board getBoardById(int board_id);
//게시글 작성
void insertBoard(Board board);
//게시글 수정
void updateBoard(Board board);
//게시글 삭제
void deleteBoard(int board_id);
}
< BoardController.java >
이거 이제서야 파일을 만들다가 느낀건데, 작업순서가 어쩌구해서 너무 정석으로 따르니까 정신도 없고 난감할 때가 많다;;
처음에는 내용 작성은 나중에 하더라도, 프로젝트에 필요한 클래스는 알맞은 경로에 다 생성이라도 해놓고 작업해야지 안되겠다.. 아무튼
동일하게 com.example.springdb.controller 패키지에 BoardController.java 생성
분량조절 실패로 2부로 돌아오겠습니다
20231129 기준 : 2부 완성!
[SpringBoot] 3. 게시판으로 CRUD 기능 구현 - (2)
이 글은 '게시판으로 CRUD 기능 구현 -(1)'과 이어집니다. [SpringBoot] 3. 게시판으로 CRUD 기능 구현 - (1) 안녕하세요 오늘로 세 숟가락 째 뜨게되는 글이군요 아직 배는 부르지 않지만, 알듯말듯 아리
im2ho.tistory.com