티스토리 뷰
[ 아이디어 정리 ]
- 게시판이 여러 개이기만 하면 멀티 게시판이라고 하는 것 같다. 게시글 컬럼 하나를 게시판 id로 두어 구현하는 방법과 테이블 하나 자체를 게시판 이름으로 하고 게시글을 담아두는 방법이 있다. 전자의 방법을 이용해서 구현하는 중이다.
- 모든 게시판이 같은 구조를 가지기 때문에 게시판 별로 따로 테이블을 가질 필요가 없다. 하나의 테이블로 모두 관리한다.
[ DB Table and Sequence ]
create table forums (
forum_number number(20) primary key,
forum_name varchar2(30) unique not null,
forum_description varchar2(255) not null,
forum_slug varchar2(30) unique not null,
date_forum_registered date default sysdate not null
);
create sequence seq_forum;
[ ForumVO ]
@Data
public class ForumVO {
private Long number;
private String name;
private String description;
private String slug;
private Date dateRegistered;
}
[ ForumMapper interface and Impl ]
public interface ForumMapper {
public int insertForum(ForumVO forum);
public ForumVO readForumByForumNumber(Long forumNumber);
public int modifyForum(ForumVO forum);
public int deleteForumByForumNumber(Long forumNumber);
}
<?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.bibidi.mapper.ForumMapper">
<resultMap type="com.bibidi.domain.ForumVO" id="forumMap">
<id property="number" column="forum_number"/>
<result property="number" column="forum_number" />
<result property="name" column="forum_name" />
<result property="description" column="forum_description" />
<result property="slug" column="forum_slug" />
<result property="dateRegistered" column="date_forum_registered" />
</resultMap>
<insert id="insertForum">
INSERT INTO forums
(forum_number, forum_name, forum_description, forum_slug)
VALUES
(seq_forum.nextval, #{name}, #{description}, #{slug})
</insert>
<select id="readForumByForumNumber" resultMap="forumMap">
SELECT * FROM forums WHERE forum_number = #{forumNumber}
</select>
<update id="updateForum">
UPDATE forums
SET forum_name = #{name}, forum_description = #{description}, forum_slug = #{slug}
WHERE forum_number = #{number}
</update>
<delete id="deleteForumByForumNumber">
DELETE FROM forums
WHERE forum_number = #{forumNumber}
</delete>
</mapper>
[ ForumMapper Tests ]
@RunWith(SpringRunner.class)
@ContextConfiguration("file:src/main/webapp/WEB-INF/spring/root-context.xml")
@Log4j
public class ForumMapperTests {
@Setter(onMethod_ = @Autowired)
private ForumMapper forumMapper;
@Test
public void testInsertForum() {
ForumVO forum = new ForumVO();
forum.setName("tName");
forum.setDescription("tDescription");
forum.setSlug("tSlug");
log.info("THE NUMBER OF INSERTED FORUMS : "
+ forumMapper.insertForum(forum));
}
@Test
public void testReadForumByForumNumber() {
log.info(forumMapper.readForumByForumNumber(1L));
}
@Test
public void testUpdateForum() {
ForumVO forum = new ForumVO();
forum.setNumber(2L);
forum.setName("updated name");
forum.setDescription("updated description");
forum.setSlug("updated slug");
log.info("THE NUMBER OF UPDATED FORUMS : "
+ forumMapper.updateForum(forum));
}
@Test
public void testDeleteForumByForumNumber() {
log.info("THE NUMBER OF DELETED FORUMS : "
+ forumMapper.deleteForumByForumNumber(0L));
}
}
[ ForumService Interface and Impl ]
public interface ForumService {
public int registerForum(ForumVO forum);
public ForumVO getForumByForumNumber(Long forumNumber);
public int modifyForum(ForumVO forum);
public int deleteForumByForumNumber(Long forumNumber);
}
@Service
@Log4j
public class ForumServiceImpl implements ForumService {
@Setter(onMethod_ = @Autowired)
ForumMapper forumMapper;
@Override
public int registerForum(ForumVO forum) {
log.info("register forum.........");
return forumMapper.insertForum(forum);
}
@Override
public ForumVO getForumByForumNumber(Long forumNumber) {
log.info("get forum by forum number.........");
return forumMapper.readForumByForumNumber(forumNumber);
}
@Override
public int modifyForum(ForumVO forum) {
log.info("modify forum...............");
return forumMapper.updateForum(forum);
}
@Override
public int deleteForumByForumNumber(Long forumNumber) {
log.info("delete forum by forum number.............");
return forumMapper.deleteForumByForumNumber(forumNumber);
}
}
[ ForumService Tests ]
@RunWith(SpringRunner.class)
@ContextConfiguration("file:src/main/webapp/WEB-INF/spring/root-context.xml")
@Log4j
public class ForumServiceTests {
@Setter(onMethod_ = @Autowired)
private ForumService forumService;
@Test
public void testExist() {
log.info(forumService);
assertNotNull(forumService);
}
@Test
public void testRegisterForum() {
ForumVO forum = new ForumVO();
forum.setName("tsName");
forum.setDescription("tsDescription");
forum.setSlug("tsSlug");
log.info("THE NUMBER OF REGISTERED FORUMS : "
+ forumService.registerForum(forum));
}
@Test
public void testGetForumByForumNumber() {
log.info(forumService.getForumByForumNumber(1L));
}
@Test
public void testModifyForum() {
ForumVO forum = new ForumVO();
forum.setNumber(3L);
forum.setName("updated name");
forum.setDescription("updated description");
forum.setSlug("updated slug");
log.info("THE NUMBER OF MODIFIED FORUMS : "
+ forumService.modifyForum(forum));
}
@Test
public void testDeleteForumByForumNumber() {
log.info("THE NUMBER OF DELETED FORUMS : "
+ forumService.deleteForumByForumNumber(0L));
}
}
[ URI 설계 ]
- 다 괜찮은데, forum 등록할 때 사용할 form을 가져올 때 문제가 된다. 애초에 서버로부터 데이터만 받으면 저걸로 충분한데, 프런트까지 생각하니 collection + method로 처리할 수가 없다. REST API 원칙 자체가 URI가 정보 자원을 의미하도록 하는 것이니까 Registration Form을 자원으로 보고 /admin/forums/registration이라 표현하는 것이 어떨가 생각하고 만들었다.
- 처음엔 forum form을 가져올 때 다른 사이트들 참고해서 write나 register 같은 동사를 쓸까 했지만 REST API 관련 글들을 보면 동사를 쓸 이유가 없다. 그런데 이렇게 생각하면 로그인, 회원가입은 login, signup으로 썼던 거 같은데, 이거 말고 적절한 명사가 있나 찾아봐야겠다.
- 찾아보니 login, sign-up이 명사다.
GET /admin/forums/registration : forum registration form을 가져온다.
GET /admin/forums
POST /admin/forums
PUT /admin/forums
DELETE /admin/forums
[ AdminController ]
@Controller
@RequestMapping("/admin/*")
@Log4j
public class AdminController {
@Setter(onMethod_ = @Autowired)
private ForumService forumService;
@RequestMapping(value="", method=RequestMethod.GET)
public String getAdminHome() {
log.info("get admin home");
return "/admin/home";
}
@RequestMapping(value="/forums/registration", method=RequestMethod.GET)
public String getForumForm() {
log.info("get forum form");
return "/admin/forumForm";
}
// 미구현
@RequestMapping(value="/forums", method=RequestMethod.GET)
public String getForums() {
// 요구하는 사이즈 체크. 없으면 기본값, 있으면서 제한을 넘지 않으면 그 사이즈 만큼 반환하도
return "";
}
@RequestMapping(value="/forums", method=RequestMethod.POST)
public String postForumForm(String forumName, String forumDescription, String forumSlug) {
log.info("post forum form");
ForumVO forum = new ForumVO();
forum.setName(forumName);
forum.setDescription(forumDescription);
forum.setSlug(forumSlug);
forumService.registerForum(forum);
return "redirect:/admin/forums/registration";
}
}
- 나중에 form으로부터 데이터가 제대로 왔는지 검증하는 부분을 추가해야 될 것 같다. 프런트에서 실수로 데이터를 잘못 보냈을 수도 있으니까. 그런데 그 폼 검증을 어디서 해야 되는지가 문제. 컨트롤러 내에서 해야되나 아니면 서비스 내에서 해야되나 그게 헷갈리는 중.
[ 관리자 페이지 작성 ]
- 아직 초기 화면이라 디자인이 구리다. 부트스트랩 그리드 시스템 덕분에 레이아웃 까는 법은 조금 익혔는데, 어떻게 해야 보기 좋은지 근거가 없으니 손 대기가 그렇다. 거기에 디자인 쪽 지식도 꽤 필요할 텐데, 아직 그거까지 익힐 시간은 나지 않는다.
[ 게시판 작성 테스트 ]
- 적당히 작성해서 테스트 해봤는데, 잘 작동한다. 한글도 안 깨지고 잘 들어가고 날짜도 자동으로 잘 입력된다.
//
- ROLE_USER가 왜 필요한가? 그냥 인증만 되면 글을 쓸 수 있도록 하면 되지 않을까 생각했는데, 사용자 상태에 따라 글을 못 쓰게 하려면 유저 정보를 활용해야한다. 기본 사용자 권한 박탈 기능 등을 생각.
'(구)게시판 프로젝트' 카테고리의 다른 글
게시글(updated 21.06.01) (0) | 2021.05.07 |
---|---|
권한 관련 작업 (0) | 2021.05.05 |
이름 짓는 법 총 정리 (1) | 2021.04.28 |
메인 화면 (0) | 2021.04.27 |
회원가입 (0) | 2021.04.26 |
- Total
- Today
- Yesterday
- 백준 16562
- boj 10775
- boj 3006
- 백준 10473
- 백준 2243
- 백준 12713
- 백준 3006
- boj 1106
- boj 2336
- boj 14868
- 인간 대포
- boj 2243
- boj 9345
- boj 10473
- 제로베이스 백엔드 스쿨
- 백준 10775
- 백준 1280
- 디지털 비디오 디스크
- 사탕상자
- Ugly Numbers
- 백준 9345
- 터보소트
- 백준 1106
- 백준 14868
- boj 1280
- 부트 캠프
- 제로베이스 스쿨
- 백준 2336
- boj 16562
- boj 12713
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |