스프링 기초_댓글처리2

bitna's study note·2022년 7월 30일

스프링

목록 보기
38/54

7월 31일

1.@Param 어노테이션과 댓글 목록
댓글은 특정한 게시물의 댓글들만을 대상으로 하기 때문에 추가로 게시물의 번호가 필요하게 됩니다.
MyBatis는 두 개 이상이 데이터를 파라미터로 전달하기 위해서는
별도의 객체로 구성하거나,Map을 이용하거나, @Param을 이용해서 이름을 사용하는 방식이 있다.

(1)ReplyMapper 인터페이스 수정하기
페이징 처리는 기존과 동일하게 Criteria 를 이용함.
해당 게시물의 번호는 파라미터를 전달하도록 ReplyMapper 수정하기
xml처리 할때 "cri","bno"를 '#{cri}''#{bno}'로 쓸수 있다.

package com.keduit.mapper;

public interface ReplyMapper {
	
	public List<ReplyVO> getListWithPaging(
			@Param("cri")Criteria cri,
			@Param("bno")Long bno
			);

}

(2)ReplyMapper.xml 수정하기
xml에서 '#{bno}'가 @Param("bno")와 매칭이 되어야 한다.

<?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.keduit.mapper.ReplyMapper">
  
  <select id="getListWithPaging" resultType="com.keduit.domain.ReplyVO">
  	select rno, bno, reply, replyer, replyDate, updatedate from t_reply
  	where bno=#{bno}
  	order by rno asc 
  </select>
  
  </mapper>

(3)ReplyMapper 테스트

package com.keduit.mapper;

@RunWith(SpringJUnit4ClassRunner.class)//이 클래스로 잘돌아가는지 test해볼꺼야
@ContextConfiguration("file:src/main/webapp/WEB-INF/spring/root-context.xml")//참고할 경로는 여기야
@Log4j //화면에 뿌려주는건 Log4j가 관리 할거야 
public class ReplyMapperTest {
	
	private Long[] bnoArr= {81L,62L,55L,54L,52L};
	
	@Setter(onMethod_ = @Autowired)
	private ReplyMapper mapper;
	
	@Test
	public void testList() {
		Criteria cri = new Criteria();
		List<ReplyVO> replies = mapper.getListWithPaging(cri, bnoArr[0]);
		replies.forEach(reply -> log.info(reply));
	}
}

2.서비스영역과 Controller 처리

(1)ReplyService 인터페이스 작성

package com.keduit.service;

public interface ReplyService {
	
	public int register(ReplyVO vo);
	
	public ReplyVO get(Long rno);
	
	public int modify(ReplyVO vo);
	
	public int remove(int rno);
	
	public List<ReplyVO> getList(Criteria cri, Long bno);
}

(2)ReplyServiceImpl 클래스 작성하기

package com.keduit.service;

@Service
@Log4j
public class ReplyServiceImpl implements ReplyService{

	@Setter(onMethod_ = @Autowired )
	private ReplyMapper mapper;
	
	@Override
	public int register(ReplyVO vo) {
		log.info("register.........."+vo);
		return mapper.insert(vo);
	}

	@Override
	public ReplyVO get(Long rno) {
		log.info("get.........."+rno);
		return mapper.read(rno);
	}

	@Override
	public int modify(ReplyVO vo) {
		log.info("modify.........."+vo);
		return mapper.update(vo);
	}

	@Override
	public int remove(int rno) {
		log.info("remove.........."+rno);
		return mapper.delete(rno);
	}

	@Override
	public List<ReplyVO> getList(Criteria cri, Long bno) {
		log.info("getList............."+bno);
		return mapper.getListWithPaging(cri, bno);
	}

}

3.ReplyController의 설계
Rest방식으로 동작하는 URL을 설계할때는 pk를 기준으로 작성하는 것이 좋다.
pk만으로 조회,수정,삭제가 가능하기 때문.
다만, 댓글의 목록은 pk를 사용할수 없기 때문에 파라미터로 필요한 게시물의 번호(bno)와 페이지번호(page) 정보들을 URL에서 표현하는 방식을 사용함.

(1)등록작업과 테스트
Rest방식으로 처리할때 주의해야하는 점은 브라우저나 외부에서 서버를 호출할때 데이터의 포맷과 서버에서 보내주는 데이터의 타입을 명확하게 설계해야한다.

package com.keduit.controller;

@RequestMapping("/replies/")
@RestController
@Log4j
@AllArgsConstructor //모든 필드 값을 파라미터로 받는 생성자를 만듦,ReplyService 타입의 객체를 필요로 하는 생성자를 만들어서 사용
public class ReplyController {
	
	private ReplyService service;
	
	
	@PostMapping(value="/new",
				 consumes = "application/json", //클라이언트가 서버에게 보내는 데이터 타입을 명시한다.
				 produces = {MediaType.TEXT_PLAIN_VALUE}) //서버가 클라이언트에게 반환하는 데이터 타입을 명시한다.
	public ResponseEntity<String> create(@RequestBody ReplyVO vo){
		log.info("ReplyVO: "+vo);
		int insertCount= service.register(vo);
		log.info("Reply insert Count:"+insertCount);
		return insertCount==1
		? new ResponseEntity<>("success", HttpStatus.OK)
		: new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
	}
}

consumes 클라이언트가 서버에게 보내는 데이터 타입을 명시한다.
produces 서버가 클라이언트에게 반환하는 데이터 타입을 명시한다.
create()는 @PostMapping으로 Post 방식으로만 동작하도록 설계하고 consumes과 produces를 이용해서 json 방식의 데이터만 처리하도록 하고, 그 결과값을 문자열로반환하도록 설계한다.
create()의 파라미터는 @RequestBody를 적용해서 json데이터를 ReplyVO타입으로 변환하도록 지정한다.

(2)특정 게시물의 댓글 목록 확인

@GetMapping(value="/pages/{bno}/{page}",
				produces = {MediaType.APPLICATION_ATOM_XML_VALUE,
							MediaType.APPLICATION_JSON_UTF8_VALUE})
	public ResponseEntity<List<ReplyVO>> getList(@PathVariable("page")int page,@PathVariable("bno")Long bno){
		log.info("getList.................");
		Criteria cri = new Criteria(page,10);
		log.info(cri);
		return new ResponseEntity<>(service.getList(cri, bno),HttpStatus.OK);
	}

getList()는 Criteria를 이용해서 파라미터를 수집하는데, '/{bno}/{page}'의 page은 Criteria를 생성해서 직접 처리해야 합니다. 게시물의 번호는 @PathVariable을 이용해서 파라미터로 처리한다.

(3)댓글 삭제/조회/수정

	@GetMapping(value="/{rno}",
				produces = {MediaType.APPLICATION_XML_VALUE,
							MediaType.APPLICATION_JSON_UTF8_VALUE})
	public ResponseEntity<ReplyVO> get(@PathVariable("rno")Long rno){
		log.info("get: "+rno);
		return new ResponseEntity<>(service.get(rno),HttpStatus.OK);
	}
	
	@DeleteMapping(value="/{rno}",produces = {MediaType.TEXT_PLAIN_VALUE})
	public ResponseEntity<String> remove(@PathVariable("rno")int rno){
		log.info("remove: "+rno);
		return service.remove(rno)==1
		? new ResponseEntity<>("success", HttpStatus.OK)
		: new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
	}
	
	@RequestMapping(method= {RequestMethod.PUT, RequestMethod.PATCH},
					value="/{rno}",
					consumes = "application/json",
					produces = {MediaType.TEXT_PLAIN_VALUE})
	public ResponseEntity<String> modify(@RequestBody ReplyVO vo,@PathVariable("rno")Long rno){
		
		vo.setRno(rno);
		log.info("rno: "+rno);
		log.info("modify: "+vo);
		
		return service.modify(vo)==1
		? new ResponseEntity<>("success", HttpStatus.OK)
		: new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
	}

댓글 수정은 'put'방식이나 'patch'방식을 이용하도록 하고, 실제 수정되는 데이터는 json포맷이므로 @RequestBody를 이용해서 처리함.

profile
좋은개발자가 되기위한 삽질기록 노트

0개의 댓글