2024. 3. 11. 17:28ㆍ카테고리 없음
Database (Heidi SQL 에 삽입한 SQL문)
그리고 작업을 시작함
USE abbs;
INSERT INTO board(title, content, uid) VALUES
('게시판 오픈 공지', ' 스프링부트와 타임리프로 만들었어요', 'admin'),
('테스트 제목', '테스트 본문', 'james'),
('테스트 제목2', '테스트 본문2', 'maria'),
('테스트 제목3', '테스트 본문3', 'brian'),
('테스트 제목4', '테스트 본문4', 'emma'),
('테스트 제목5', '테스트 본문5', 'yj9632');
SELECT b.*, u.uname FROM board b
JOIN users u ON b.uid=u.uid
WHERE b.isDeleted=0
ORDER BY b.bid DESC
LIMIT 10 OFFSET 0; // BoardDao 에 사용한 SQL문
INSERT INTO reply(COMMENT, uid, bid) VALUES
('멋지네요', 'james', 1), ('수고가 많습니다', 'maria', 1);
UPDATE board SET replyCount=2 WHERE bid=1;
페이지 구현 로직
오늘은 .java file 은
controller단
1. UserController
package com.example.abbs.controller;
import java.io.File;
import java.io.IOException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import com.example.abbs.entity.User;
import com.example.abbs.service.UserService;
import com.example.abbs.util.AsideUtil;
import com.example.abbs.util.ImageUtil;
import jakarta.servlet.http.HttpSession;
@Controller
@RequestMapping("/user")
public class UserController {
private final Logger log = LoggerFactory.getLogger(getClass());
@Autowired private UserService uSvc;
@Autowired private ImageUtil imageUtil;
@Autowired private AsideUtil asideUtil;
@Autowired private ResourceLoader resourceLoader;
@Value("${spring.servlet.multipart.location}") private String uploadDir;
@GetMapping("/register")
public String registerForm() {
return "user/register";
}
@PostMapping("/register")
public String registerProc(MultipartHttpServletRequest req, Model model,
String uid, String pwd, String pwd2, String uname, String email,
String github, String insta, String location) {
String filename = null;
MultipartFile filePart = req.getFile("profile");
if (uSvc.getUserByUid(uid) != null) {
model.addAttribute("msg", "사용자 ID가 중복되었습니다.");
model.addAttribute("url", "/abbs/user/register");
return "common/alertMsg";
}
if (pwd.equals(pwd2) && pwd != null) {
if (filePart.getContentType().contains("image")) {
filename = filePart.getOriginalFilename();
String path = uploadDir + "profile/" + filename;
try {
filePart.transferTo(new File(path));
} catch (Exception e) {
e.printStackTrace();
}
filename = imageUtil.squareImage(uid, filename);
}
User user = new User(uid, pwd, uname, email, filename, github, insta, location);
uSvc.registerUser(user);
model.addAttribute("msg", "등록을 마쳤습니다. 로그인하세요.");
model.addAttribute("url", "/abbs/user/login");
return "common/alertMsg";
} else {
model.addAttribute("msg", "패스워드 입력이 잘못되었습니다.");
model.addAttribute("url", "/abbs/user/register");
return "common/alertMsg";
}
}
@GetMapping("/login")
public String loginForm() {
return "user/login";
}
@PostMapping("/login")
public String loginProc(String uid, String pwd, HttpSession session, Model model) {
int result = uSvc.login(uid, pwd);
switch(result) {
case UserService.CORRECT_LOGIN:
User user = uSvc.getUserByUid(uid);
session.setAttribute("sessUid", uid);
session.setAttribute("sessUname", user.getUname());
session.setAttribute("profile", user.getProfile());
session.setAttribute("email", user.getEmail());
session.setAttribute("github", user.getGithub());
session.setAttribute("insta", user.getInsta());
session.setAttribute("location", user.getLocation());
// 상태 메세지
// c:/Temp/abbs/data/todayQuote.txt
// String quoteFile = uploadDir + "data/todayQuote.txt";
// resources/static/data/todayQuote.txt
Resource resource = resourceLoader.getResource("classpath:/static/data/todayQuote.txt");
String quoteFile = null;
try {
quoteFile = resource.getURI().getPath();
} catch (IOException e) {
e.printStackTrace();
}
String stateMsg = asideUtil.getTodayQuote(quoteFile);
session.setAttribute("stateMsg", stateMsg);
// 환영 메세지
log.info("Info Login: {}, {}", uid, user.getUname());
model.addAttribute("msg", user.getUname()+"님 환영합니다.");
model.addAttribute("url", "/abbs/board/list");
break;
case UserService.USER_NOT_EXIST:
model.addAttribute("msg", "ID가 없습니다. 회원가입 페이지로 이동합니다.");
model.addAttribute("url", "/abbs/user/register");
break;
case UserService.WRONG_PASSWORD:
model.addAttribute("msg", "패스워드 입력이 잘못되었습니다. 다시 입력하세요.");
model.addAttribute("url", "/abbs/user/login");
}
return "common/alertMsg";
}
@GetMapping("/logout")
public String logout(HttpSession session) {
session.invalidate();
return "redirect:/user/login";
}
}
2. BoardController
package com.example.abbs.controller;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.example.abbs.entity.Board;
import com.example.abbs.service.BoardService;
import jakarta.servlet.http.HttpSession;
@Controller
@RequestMapping("/board")
public class BoardController {
@Autowired private BoardService boardService;
@GetMapping("/list")
public String list(@RequestParam(name="p", defaultValue="1") int page,
@RequestParam(name="f", defaultValue="title") String field,
@RequestParam(name="q", defaultValue="") String query,
HttpSession session, Model model) {
List<Board> boardList = boardService.getBoardList(page, field, query);
int totalBoardCount = boardService.getBoardCount(field, query);
int totalPages = (int) Math.ceil(totalBoardCount / (double)BoardService.COUNT_PER_PAGE);
int startPage = (int) Math.ceil((page-0.5)/BoardService.PAGE_PER_SCREEN - 1) * BoardService.PAGE_PER_SCREEN + 1;
int endPage = Math.min(totalPages, startPage + BoardService.PAGE_PER_SCREEN - 1);
List<String> pageList = new ArrayList<>();
for (int i = startPage; i <= endPage; i++)
pageList.add(String.valueOf(i));
session.setAttribute("currentBoardPage", page);
model.addAttribute("boardList", boardList);
model.addAttribute("field", field);
model.addAttribute("query", query);
model.addAttribute("totalPages", totalPages);
model.addAttribute("startPage", startPage);
model.addAttribute("endPage", endPage);
model.addAttribute("pageList", pageList);
return "board/list";
}
}
dao단
1.BoardDao
package com.example.abbs.dao;
import java.util.List;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import com.example.abbs.entity.Board;
@Mapper // 구현체는 마이바티스가 알아서 만들어줌
public interface BoardDao {
@Select("SELECT b.*, u.uname FROM board b"
+ " JOIN users u ON b.uid=u.uid"
+ " WHERE b.bid=#{bid}") // ("") = SQL 채워넣을 자리
Board getBoard(int bid);
@Select("select count(bid) from board where isDeleted=0 and ${field} like #{query}")
int getBoardCount(String field, String query); // field 이름 매핑에는 $ 를 씀
@Select("SELECT b.*, u.uname FROM board b"
+ " JOIN users u ON b.uid=u.uid"
+ " WHERE b.isDeleted=0 and ${field} like #{query}"
+ " ORDER BY b.modTime desc"
+ " LIMIT ${count} OFFSET #{offset}")
List<Board> getBoardList(String field, String query, int count, int offset);
@Insert("insert into board values(default, #{title}, #{content}, #{uid}, "
+ " default, default, default, default, default, #{files})")
void insertBoard(Board board);
@Update("update board set title=#{title}, content=#{content}, modTime=now(),"
+ " files=#{files} where bid=#{bid}")
void updateBoard(Board board);
@Update("update board set isDeleted=1 where bid=#{bid}")
void deleteBoard(int bid);
@Update("update board set ${field}=${field}+1 where bid=#{bid}")
void increaseCount(String field, int bid);
}
service단
1. Boardservice
package com.example.abbs.service;
import java.util.List;
import com.example.abbs.entity.Board;
public interface BoardService {
public static final int COUNT_PER_PAGE = 10; // 한 페이지당 글 목록의 갯수
public static final int PAGE_PER_SCREEN = 10; // 한 화면에 표시되는 페이지 갯수
Board getBoard(int bid);
int getBoardCount(String field, String query);
List <Board> getBoardList(int page, String field, String query);
void insertBoard(Board board);
void updateBoard(Board board);
void deleteBoard(int bid);
void increaseviewCount(int bid);
void increaseReplyCount(int bid);
void increaseLikeCount(int bid);
}
2. BoardserviceImpl
package com.example.abbs.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.example.abbs.dao.BoardDao;
import com.example.abbs.entity.Board;
@Service
public class BoardServiceImpl implements BoardService{
@Autowired private BoardDao boardDao;
@Override
public Board getBoard(int bid) {
return boardDao.getBoard(bid);
}
@Override
public int getBoardCount(String field, String query) {
query = "%" + query + "%";
return boardDao.getBoardCount(field, query);
}
@Override
public List<Board> getBoardList(int page, String field, String query) {
int offset = (page - 1) * COUNT_PER_PAGE;
query = "%" + query + "%";
return boardDao.getBoardList(field, query, COUNT_PER_PAGE, offset);
}
@Override
public void insertBoard(Board board) {
boardDao.insertBoard(board);
}
@Override
public void updateBoard(Board board) {
boardDao.updateBoard(board);
}
@Override
public void deleteBoard(int bid) {
boardDao.deleteBoard(bid);
}
@Override
public void increaseviewCount(int bid) {
String field = "viewCount";
boardDao.increaseCount(field, bid);
}
@Override
public void increaseReplyCount(int bid) {
String field = "replyCount";
boardDao.increaseCount(field, bid);
}
@Override
public void increaseLikeCount(int bid) {
String field = "likeCount";
boardDao.increaseCount(field, bid);
}
}
파일을 만들어 Spring 으로 Web을 구현할 수 있도록 작성해나갔다.
내일은 insert와 update 를 구현하는 코드를 작성하기로 한다.
게시판 에디터를 추가하여
1. 표와 그림 등을 첨부할 수 있음
2. 첨부파일 multiple 사용 _ json 코드 사용
미리 공부할 사람은 레퍼런스라고 생각하고 insert 연습 해 보기