코딩 노트

React06 - Rest API2(insert, delete, selectOne, update) 본문

React

React06 - Rest API2(insert, delete, selectOne, update)

newbyeol 2023. 11. 3. 10:30

PocketmonRestController 구문 추가

@PostMapping("/")

public void insert(@ModelAttribute PocketmonDto pocketmonDto) {

pocketmonDao.insert(pocketmonDto);

}

PocketmonDao에 구문 추가

void insert(PocketmonDto pocketmonDto);

PocketmonDaoImpl에 구문 추가

@Override

public void insert(PocketmonDto pocketmonDto) {

sqlSession.insert("pocketmon.save", pocketmonDto);

}

pocketmon-mapper.xml에 insert 구문 추가

<insert id="save">

insert into pocketmon(no, name, type) values(pocketmon_seq.nextval, #{name}, #{type})

</insert>

properties에 디버그 설정 구문 추가

#logging setting

logging.level.root=warn

logging.level.com.kh=debug

logging.level.pocketmon=debug

 

전송 데이터 타입이 맞지 않아서 오류가 뜬다.

 

@ModelAttribute

- 전달되는 파라미터를 객체에 매핑 (파라미터의 형식이 form-data인 경우만 가능)

<form-data 형식이다.>

application/x-www-form-urlencoded

key=value&key=value&key=value

- Model에 객체를 자동 첨부

 

백엔드 전용 시스템을 구축할 때는 request body

기존 처럼 폼에 데이터를 받아서 페이지를 만들 때는 ModelAttribute

 

PocketmonRestController에 구문 수정

@PostMapping("/")

// public void insert(@ModelAttribute PocketmonDto pocketmonDto) { //form-data 수신용

public void insert(@RequestBody PocketmonDto pocketmonDto) { //request body 직접 해석(ex:), spring 거를 import

pocketmonDao.insert(pocketmonDto);

}

 

결과가 올바르게 나온다.

pocketmon-mapper.xml에 delete 구문 추가

<delete id="remove">

delete pocketmon where no = #{no}

</delete>

PocketmonDao에 구문 추가

boolean delete(int no);

PocketmonDaoImpl에 구문 추가

@Override

public boolean delete(int no) {

return sqlSession.delete("pocketmon.remove", no) > 0; //이 구문에 no를 줄테니 결과가 0보다 큰지를 판단해서 반환해라

}

 

주소에 데이터가 들어가는 방식 = 경로변수 (클래식방식)

 

PocketmonRestController에 구문 추가

//파라미터는 주소가 매우 지저분해지므로 최대한 경로변수를 활용

@DeleteMapping("/{no}")

// public boolean delete(@PathVariable int no) { //데이터를 반환하면 상태설정이 불가능(우리는 상태설정이 필요)

public ResponseEntity<String> delete(@PathVariable int no) { //상태 설정이 가능한 객체를 반환( 데이터<응답객체> )

boolean result = pocketmonDao.delete(no);

if(result) {

// return ResponseEntity.ok().build(); //메세지

return ResponseEntity.status(200).build(); //숫자

}

else {

// return ResponseEntity.notFound().build(); //메세지

return ResponseEntity.notFound().build(); //숫자

}

}

PocketmonRestController에 구문 추가

@GetMapping("/{no}")

public PocketmonDto find(@PathVariable int no) {

PocketmonDto pocketmonDto = pocketmonDao.selectOne(no);

return pocketmonDto;

}

PocketmonDao에 구문 추가

PocketmonDto selectOne(int no);

PocketmonDaoImpl에 구문 추가

@Override

public PocketmonDto selectOne(int no) {

return sqlSession.selectOne("pocketmon.find",no);

}

pocketmon-mapper.xml에 구문 추가

<select id="find" resultType="PocketmonDto">

select * from pocketmon where no = #{no}

</select>

이런식으로 써도 가능하지만 밑에 방법이 더 업그레이드 된 것

PocketmonRestController에 업그레이드 구문으로 수정

@GetMapping("/{no}")

public ResponseEntity<PocketmonDto> find(@PathVariable int no) {

PocketmonDto pocketmonDto = pocketmonDao.selectOne(no);

 

if(pocketmonDto != null) {

return ResponseEntity.ok(pocketmonDto);

}

else {

return ResponseEntity.notFound().build();

}

}

성공 / 실패

프라이머리키까지 합해서 다 바꾸고 싶다면

필요한 데이터
빨간색이 맞다.

PocketmonRestController에 구문 추가

@PutMapping("/{no}") //원래 번호

//ResponseEntity에는 꼭 String을 적어야하는 것이 아니고 주고 싶은 형태로 써도 됨, 없으면 Void를 쓰기도 함

public ResponseEntity<String> edit(

@PathVariable int no, @RequestBody PocketmonDto pocketmonDto) {

boolean result = pocketmonDao.edit(no, pocketmonDto);

return result ? ResponseEntity.ok().build() : ResponseEntity.notFound().build();

}

PocketmonDao에 구문 추가

boolean edit(int no, PocketmonDto pocketmonDto);

PocketmonDaoImpl에 구문 추가

@Override

public boolean edit(int no, PocketmonDto pocketmonDto) {

Map<String, Object> params = new HashMap<>();

params.put("no", no); //origin no

params.put("dto", pocketmonDto);

return sqlSession.update("pocketmon.edit", params) > 0;

}

pocketmon-mapper.xml에 구문 추가

<update id ="edit">

update pocketmon

set

<if test="dto.no > 0">

no=#{dto.no},

</if>

name=#{dto.name}, type=#{dto.type}

where no = #{no}

</update>

번호가 있으면 번호를 바꾸고 아니면 현상태를 유지해라...

 

put과 patch의 차이?

PocketmonRestController에 수정 patch 구문 추가

@PatchMapping("/{no}")

public ResponseEntity<String> editUnit(

@PathVariable int no, @RequestBody PocketmonDto pocketmonDto){

boolean result = pocketmonDao.editUnit(no, pocketmonDto);

return result ? ResponseEntity.ok().build() : ResponseEntity.notFound().build();

}

PocketmonDao에 구문 추가

boolean editUnit(int no, PocketmonDto pocketmonDto);

PocketmonDaoImpl에 구문 추가

@Override

public boolean editUnit(int no, PocketmonDto pocketmonDto) {

Map<String, Object> params = new HashMap<>();

params.put("no", no); //origin no

params.put("dto", pocketmonDto);

return sqlSession.update("pocketmon.editUnit", params) > 0;

}

pocketmon-mapper.xml에 구문 추가

<update id="editUnit">

update pocketmon

<set>

<if test="dto.no > 0">no = #{dto.no},</if>

<if test="dto.name != null">name = #{dto.name},</if>

<if test="dto.type != null">type = #{dto.type},</if>

</set>

where no = #{no}

</update>

성공 / 실패

PocketmonDto에 구문추가

Dto가 비어있으면 badRequest를 내보낸다.

@Data @Builder @NoArgsConstructor @AllArgsConstructor

public class PocketmonDto {

private int no;

private String name, type;

 

public boolean isEmpty() {

return no == 0 && name == null && type == null;

}

 

}

PocketmonRestController에 구문추가

@PatchMapping("/{no}")

public ResponseEntity<String> editUnit(

@PathVariable int no, @RequestBody PocketmonDto pocketmonDto){

if(pocketmonDto.isEmpty()) {

ResponseEntity.badRequest().build();

}

 

boolean result = pocketmonDao.editUnit(no, pocketmonDto);

return result ? ResponseEntity.ok().build() : ResponseEntity.notFound().build();

}

configuration 패키지 생성 후 

RestApiConfiguration 파일 생성

@OpenAPIDefinition(

info = @Info(

title = "테스트용 REST API 서비스",

description = "KH정보교육원 백엔드 수업자료",

version = "v1",

contact = @Contact(

name="피카츄",

email="pika@kh.com",

url= "https://github.com/pika"

)

)

)

@Configuration

public class RestApiConfiguration {

 

}

PocketmonDto에 구문추가

//문서용 annotation

@Tag(name="포켓몬스터 리엑트용 백엔드", description = "피카츄~")

PocketmonDto에 구문추가

@Data @Builder @NoArgsConstructor @AllArgsConstructor

public class PocketmonDto {

 

@Schema(description = "몬스터번호(등록시x")

private int no;

 

@Pattern(regexp = "[가-힣]+")

@Schema(description = "몬스터이름", nullable = false, example = "피카츄")

private String name;

 

@Schema(description = "몬스터속성", allowableValues = {"풀", "불", "물", "전기", "무속성"},

nullable = false, example ="전기")

private String type;

 

@Schema(hidden = true)

public boolean isEmpty() {

return no == 0 && name == null && type == null;

}

 

}

PocketmonRestController에 구문추가

insert 부분

//등록 매핑에 대한 설명용 annotaion

@Operation(

description = "포켓몬스터 신규 생성",

responses = {

@ApiResponse(

responseCode="200",

description = "포켓몬스터 생성 완료"),

@ApiResponse(

responseCode="400",

description = "전송한 파라미터가 서버에서 요구하는 값과 다름"),

@ApiResponse(

responseCode="500",

description = "서버 오류 발생")

}

)

 

@PostMapping("/")

PocketmonRestController에 구문추가

select 부분

//목록 매핑에 대한 설명용 annotation

@Operation(

description = "포켓몬스터 조회",

responses = {

@ApiResponse (

responseCode = "200",

description = "조회 성공",

content = {

@Content(

mediaType = "application/json",

array = @ArraySchema(

schema = @Schema(implementation = PocketmonDto.class)

)

)

}

),

@ApiResponse(

responseCode = "500",

description = "서버 오류",

content = @Content(

mediaType = "text/plain",

schema = @Schema(implementation = String.class),

examples = @ExampleObject("server error")

)

)

}

)

 

@GetMapping("/")

PocketmonRestController에 구문추가

insert 부분

@PostMapping("/")

// public void insert(@ModelAttribute PocketmonDto pocketmonDto) { //form-data 수신용

public void insert(

@Parameter(

description = "생성할 몬스터명/타입 객체",

required = true,

schema = @Schema(implementation = PocketmonDto.class)

)

@RequestBody PocketmonDto pocketmonDto) { //request body 직접 해석(ex:), spring 거를 import

 

pocketmonDao.insert(pocketmonDto);

}