게시판을 만드는 과정에서 파일 업로드를 해야 할 일이 생겼다.
게시글을 작성하고, 동시에 파일 업로드를 하는 과정에서
생성된 게시글의 글번호 값을 파일 테이블에서 참조해야 하는 것이다.
테이블을 먼저 살펴보자.
게시판 테이블
글번호에 해당하는 boardId 는 auto_increment 로 1부터 자동 증가하게 했고, 따라서 row 를 insert 할 때는 boardId 는 insert 하지 않는다.
CREATE TABLE tbl_board(
boardId Long auto_increment,
title varchar (10000) not null,
replyContent varchar (10000) not null,
name varchar (10000) not null,
read varchar (10000) not null default 0,
primary key(boardId)
);
INSERT INTO tbl_board( title, content, name, read) VALUES ('제목1', '내용1', '이름1',0);
파일 업로드
게시글을 업로드하는 페이지에서 파일 업로드도 동시에 진행할 것이다.
다음은 파일 테이블이다.
테이블을 생성하는 sql 문을 살펴보자.
CREATE TABLE TBL_FILE
(
FILE_NO NUMBER auto_increment, --파일 번호
boardId NUMBER NOT NULL, --게시판 번호
ORG_FILE_NAME VARCHAR2(260) NOT NULL, --원본 파일 이름
STORED_FILE_NAME VARCHAR2(36) NOT NULL, --변경된 파일 이름
FILE_SIZE NUMBER, --파일 크기
REGDATE DATE DEFAULT SYSDATE NOT NULL, --파일등록일
DEL_GB VARCHAR2(1) DEFAULT 'N' NOT NULL,--삭제구분
PRIMARY KEY(FILE_NO) --기본키 FILE_NO
);
문제는 컨트롤러에서 postMapping 을 통해 게시글 업로드, 파일 업로드를 동시에 진행해야 하는데 게시글의 boardId 는 게시글을 업로드 해야 auto increment 로 생기기 때문에 파일 업로드 메소드를 실행할 때는 그 값이 존재하지 않아 boardId 를 insert 할 수 없다는 것이다.
구체적으로 이해하기 위해 컨트롤러 코드를 살펴보자.
@PostMapping("/upload")
public String uploadBoard(
@RequestPart MultipartFile file, // 게시글 업로드 페이지에서 첨부된 파일을 받아옴
Board board // 게시글 업로드 페이지에서 입력된 제목, 작성자, 글내용을 한꺼번에 받아옴
) throws IOException {
String path = "C:\\"+"pic\\"; // 파일을 저장할 경로
if(!file.isEmpty()){
String filename = file.getOriginalFilename();
String uploadPath = path + filename;
// 파일을 저장하기 위한 파일 객체 생성
File files = new File(uploadPath);
try {
// 파일 저장
file.transferTo(files);
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
service.uploadBoard(board); // 게시글 업로드 메소드 실행
service.uploadFile(file); // 파일 업로드 메소드 실행
return "/boards/upload";
}
<insert id="uploadBoard" parameterType="wedatalab.bulletinboard.domain.Board">
INSERT INTO tbl_board (title, content, name, read)
VALUES
(#{title}, #{content}, #{name}, 0);
</insert>
<insert id="uploadFile" parameterType="wedatalab.bulletinboard.domain.Board">
INSERT INTO tbl_file (boardId, org_file_name, stored_file_name)
VALUES(#{boardId}, #{filename}, #{filename});
</insert>
그래서 다음과 같이 매개변수로 받아오는 boardId 값이 없다는 오류가 발생한다.
There was an unexpected error (type=Internal Server Error, status=500).
nested exception is org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'boardId' in 'class
해결방법
이를 해결하는 방법은 useGeneratedKeys="true", keyProperty 속성을 사용하는 것이다.
uploadBoard 메소드 sql 문에 이 속성을 추가해보자.
<insert id="uploadBoard" useGeneratedKeys="true" keyProperty="boardId" parameterType="wedatalab.bulletinboard.domain.Board">
INSERT INTO tbl_board (title, content, name, read)
VALUES
(#{title}, #{content}, #{name}, 0);
</insert>
그러면 게시판 업로드 시 auto increment 로 생성된 boardId 를 매개변수로 받아 uploadFile 메소드를 실행할 수 있게 되는 것이다.