학습 목표
- 자잘한 비동기 + 첨부파일 의 핵심 개념을 안다
- 비동기 패턴 응용 + 파일 업로드 의 동작을 안다
- 게시판이 풍성해졌다. v10.
1. 문제
인기글을 보여주려면 조회수가 필요하고, 글에 사진을 첨부하려면 컬럼이 필요. 그런데 myboard 에는 둘 다 없음.
2. 새 도구
ALTER ADD COLUMN — 두 번: 기존 myboard 에 view_count(DEFAULT 0) 와 photo(NULL) 두 컬럼을 더한다. 동적 SQL 첫 등장.
3. 코드
-- ① 조회수 컬럼 (DEFAULT 0 — 기존 글도 0)
ALTER TABLE myboard ADD COLUMN view_count INT DEFAULT 0;
-- ② 사진 컬럼 (NULL 허용 — 기존 글은 NULL)
ALTER TABLE myboard ADD COLUMN photo VARCHAR(200) NULL;
// com.smhrd.domain.Board — 두 필드 추가
private int viewCount;
private String photo;
<!-- BoardMapper.xml — 동적 SQL -->
<update id="update" parameterType="com.smhrd.domain.Board">
UPDATE myboard SET title = #{title}, content = #{content}
<if test="photo != null">, photo = #{photo}</if>
WHERE num = #{num}
</update>
<update id="incrementViewCount" parameterType="int">
UPDATE myboard SET view_count = view_count + 1 WHERE num = #{num}
</update>
// 조회수 +1 (com.smhrd.controller)
@PostMapping("/api/boards/{num}/view")
public Map<String, Integer> incrementView(@PathVariable int num) {
int newCount = service.incrementViewCount(num);
return Map.of("viewCount", newCount);
}
// 첨부파일 업로드
@PostMapping("/api/boards/upload")
public Map<String, String> upload(@RequestParam("file") MultipartFile file)
throws IOException {
String saved = UUID.randomUUID() + "_" + file.getOriginalFilename();
file.transferTo(new File("/uploads/" + saved));
return Map.of("filename", saved);
}
// 클라이언트 — FormData
const formData = new FormData();
formData.append('file', fileInput.files[0]);
fetch('/api/boards/upload', {method: 'POST', body: formData});
4. 정리
- ALTER ADD COLUMN — 기존 테이블 확장
- DEFAULT 0 / NULL 두 가지 패턴
- 동적 SQL
<if test="photo != null">
- MultipartFile + FormData 로 파일 업로드
- v10 마일스톤
5. Before / After
전 차시
myboard 4 컬럼 + created_at. 조회수·사진 없음.
이번 차시
myboard 에 view_count·photo 두 컬럼이 ALTER 로 추가. v10.
학습 확인 체크리스트
- ALTER ADD COLUMN — 기존 테이블 확장
- DEFAULT 0 / NULL 두 가지 패턴
- 동적 SQL
<if test="photo != null">
- MultipartFile + FormData 로 파일 업로드
- v10 마일스톤