folder | src/views/members |
vue | MemberDetailView.vue |
<template>
<div>
<h1>MemberDetailView</h1>
<h2>{{ member.name }}</h2>
<p>{{ member.sal }}</p>
<hr class="my-4" />
<!-- <p>params: {{ $route.params }}</p>
<p>Query: {{ $route.query }}</p>
<p>hash: {{ router.hash }}</p> -->
<div class="row g-2">
<div class="col-auto">
<button class="btn btn-outline-dark">이전글</button>
</div>
<div class="col-auto">
<button class="btn btn-outline-dark">다음글</button>
</div>
<div class="col-auto me-auto"></div>
<div class="col-auto">
<button class="btn btn-outline-dark" @click="goListPage">목록</button>
</div>
<div class="col-auto">
<button class="btn btn-outline-primary" @click="goMemberUpdatePage">수정</button>
</div>
<div class="col-auto">
<button class="btn btn-outline-danger" @click="remove">삭제</button>
api --> deleteMember(props.id)
</div>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { deleteMember, getMemberById } from '@/api/members'
import router from '@/router'
// import { useRoute } from 'vue-router'
const props = defineProps({
id: String
})
// const route = useRouter()
const member = ref({
name: null,
sal: null
})
const fetchMembers = async () => {
console.log('1. memberPostValue props.id -> ', props.id)
//오류발생지점
const { data } = await getMemberById(props.id)
console.log('3.PostDetailValue data -> ', data)
SetMember(data)
}
const SetMember = ({ name, sal }) => {
member.value.name = name
member.value.sal = sal
}
fetchMembers()
const remove = async () => {
try {
if (confirm('당신은 진정 이 멤버를 삭제하시겠습니까?')) {
await deleteMember(props.id)
router.push({ name: 'MemberList' })
}
} catch (error) {
console.error(error)
}
}
const goListPage = () => router.push({ name: 'MemberList' })
const goMemberUpdatePage = () => {
console.log('1.goMemberUpdatePage props.id-> ', props.id)
router.push({
name: 'MemberEdit',
params: { id: props.id }
})
}
</script>
<style lang="scss" scoped></style>
view 단 |
folder | src/router |
js | index.js |
import AboutView from '@/views/AboutView.vue'
import HomeView from '@/views/HomeView.vue'
import MemberCreateView from '@/views/members/MemberCreateView.vue'
import MemberDetailView from '@/views/members/MemberDetailView.vue'
import MemberEditView from '@/views/members/MemberEditView.vue'
import MemberListView from '@/views/members/MemberListView.vue'
import NestedHomeView from '@/views/nested/NestedHomeView.vue'
import NestedOneView from '@/views/nested/NestedOneView.vue'
import NestedTwoView from '@/views/nested/NestedTwoView.vue'
import NestedView from '@/views/nested/NestedView.vue'
import { createRouter, createWebHistory } from 'vue-router'
const routes = [
{
path: '/',
name: 'Home',
component: HomeView
},
{
path: '/about',
name: 'About',
component: AboutView
},
{
path: '/members',
name: 'MemberList',
component: MemberListView
},
{
path: '/members/create',
name: 'MemberCreate',
component: MemberCreateView
},
{
path: '/members/detail/:id',
name: 'MemberDetail',
component: MemberDetailView,
props: true
},
{
path: '/members/:id/edit',
name: 'MemberEdit',
component: MemberEditView,
props: true
},
{
path: '/nested',
name: 'Nested',
component: NestedView,
children: [
{
path: '',
name: 'NestedHome',
component: NestedHomeView
},
{
path: 'one',
name: 'NestedOne',
component: NestedOneView
},
{
path: 'two',
name: 'NestedTwo',
component: NestedTwoView
}
]
}
]
const router = createRouter({
history: createWebHistory('/'),
routes: routes
})
export default router
view 단 |
folder | src/views/members |
vue | MemberEditView.vue |
<template>
<div>
<h2>회원(Member) 수정</h2>
<hr class="my-4" />
<MemberForm v-model:sal="form.sal" v-model:name="form.name" @submit.prevent="memberUpdate">
<template #actions>
<button type="button" class="btn btn-outline-danger" @click="goDetailPage">취소</button>
<button class="btn btn-primary">수정</button>
</template>
</MemberForm>
</div>
</template>
<script setup>
import { getMemberById, updateMember } from '@/api/members'
import MemberForm from '@/components/members/MemberForm.vue'
import { ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
//route : parameter에 관련된 정보
const route = useRoute()
const router = useRouter()
const id = parseInt(route.params.id)
const form = ref({
sal: null,
name: null
})
const fetchMember = async () => {
const { data } = await getMemberById(id)
console.log('MemberEditValue id-> ', id)
console.log('MemberEditValue data-> ', data)
setForm(data)
}
const setForm = ({ sal, name }) => {
form.value.sal = parseInt(sal)
form.value.name = name
}
fetchMember()
const memberUpdate = async () => {
try {
console.log('MembersEditValue memberUpdate form.value-> ', form.value)
const { data } = await updateMember(id, { ...form.value })
console.log('await ... updateMember data-> ', data)
router.push({ name: 'MemberDetail', params: { id } })
} catch (error) {
console.error(error)
}
}
const goDetailPage = () => router.push({ name: 'MemberDetail', params: { id } })
</script>
<style lang="scss" scoped></style>
view 단 |
** emit 은 하위 component가 상위 component에 보내주면 된다.
folder | src/api |
js | member.js |
import axios from 'axios'
export function getMembers() {
console.log('getMembers Start...')
//axios는 ajax 프로그램과 같은
return axios.get('http://localhost:8389/restApi/v1/members') //Risk API
}
//신규 members 등록
export function createMember(data) {
console.log('신규 members 등록(createMember)..')
console.log('신규 members 등록 data ->' + data)
return axios.post('http://localhost:8389/restApi/v2/memberSave', data)
}
//단일 member 조회
export function getMemberById(id) {
console.log('getMemberById typeof id-> ', typeof id)
console.log('getMemberById id-> ', id)
return axios.get('http://localhost:8389/restApi/v15/members/' + id)
}
export function updateMember(id, data) {
console.log('updateMember typeof id-> ', typeof id)
console.log('updateMember id-> ', id)
//수정이기 때문에 put이다.
return axios.put('http://localhost:8389/restApi/v21/members/' + id, data)
}
export function deleteMember(id) {
console.log('deletePost id-> ', id)
return axios.delete('http://localhost:8389/restApi/v21/deleteMember/' + id)
}
view 단 |
삭제 로직을 추가하기 위해서 spring에서 delete 추가해주기
Spring Starter Project | oBootJpaApi01 |
package | com.oracle.oBootMybatis01.controller |
class | JpaRestApiController |
package com.oracle.oBootJpaApi01.controller;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import javax.naming.spi.DirStateFactory.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.oracle.oBootJpaApi01.domain.Member;
import com.oracle.oBootJpaApi01.service.MemberService;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotEmpty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
//@Controller + @ResponseBody = @RestController
@RestController
//private static final Logger logger = LoggerFactory.getLogger(JpaRestApiController.class);
@Slf4j
@RequiredArgsConstructor
public class JpaRestApiController {
private final MemberService memberService;
@RequestMapping("/helloText")
public String helloText() {
System.out.println("JpaRestApiController Start...");
String hello = "안녕";
// StringConverter
return hello;
}
//Bad Api
@GetMapping("/restApi/v1/members")
public List<Member> membersVer1() {
System.out.println("JpaRestApiController /restApi//v1/members start...");
//return return되어서 결국에는 listMember에 쌓일 것이다.
List<Member> listMember = memberService.getListAllMember();
System.out.println("JpaRestApiController /restApi//v1/members listMember.size() -> "+listMember.size());
return listMember;
}
//Good Api Easy Version
//목표 : 이름 & 급여 만 전송
@GetMapping("/restApi/v21/members")
public Result membersVer21() {
List<Member> fineMembers = memberService.getListAllMember();
System.out.println("JpaRestApiController restApi/v21/members findMembers.size()-> "+fineMembers.size());
//보내주는 Data의 List를 새로 만들었다. (넘어온 list 값이 과도하기 때문에)
List<MemberRtnDto> resultList = new ArrayList<MemberRtnDto>();
//이전 목적 : 반드시 필요한 Data만 보여준다. (외부 노출 최대한 금지)
//향상형 for문을 이용
for(Member member: fineMembers) {
//아래 문이 생성자가 없이도 잘 실행되는 이유 -> MemberRtnDto에 @AllArgsConstructor를 걸어주었기 때문에
MemberRtnDto memberRtnDto = new MemberRtnDto(member.getName(), member.getSal());
System.out.println("/restApi/v21/members getName -> "+memberRtnDto.getName());
System.out.println("/restApi/v21/members getSal -> "+memberRtnDto.getSal());
resultList.add(memberRtnDto);
}
System.out.println("/restApi/v21/members resultList.size()"+resultList.size());
return new Result(resultList.size(), resultList);
}
//Good API 람다버전
//목표 : 이름 & 급여 만 전송
@GetMapping("/restApi/v22/members")
public Result membersVer22() {
List<Member> fineMembers = memberService.getListAllMember();
System.out.println("JpaRestApiController restApi/v22/members findMembers.size()-> "
+fineMembers.size());
// 자바 8에서 추가한 스트림(Streams)은 람다(->)를 활용할 수 있는 기술 중 하나
//람다 형식 : 화살표 (->) 이용하는 것, stream()을 써 주어야지만 가능
List<MemberRtnDto> memberCollect =
fineMembers.stream()
// m이라해도 되고 member라고 해도 된다.
// m이 있는 만큼 향상형 for문처럼 돌아가는 것
// 하지만 map은 list로 수집을 하지는 못한다. 갖고만 있게 하는 로직
.map(m->new MemberRtnDto(m.getName(), m.getSal()))
//따라서 list로 만들어주는 작업을 해야한다.
.collect(Collectors.toList())
;
System.out.println("/restApi/v22/members memberCollect.size()-> "+memberCollect.size());
//Result 생성자 (@AllArgsConstructor로 인해 생성자 정의 안해도 만들 수 있다.)
// totCount T data
return new Result(memberCollect.size(), memberCollect);
}
@Data
@AllArgsConstructor
class Result<T> {
private final int totCount; //총 인원수 추가
//들어오는 Data가 어떤 데이터형이든지 상관없이 T에 잡힌다. (Api의 경우는 T를 쓰는게 좋다.)
private final T data;
}
//innerclass를 쓴 이유는 controller에서 값을 보내줄 때 딱 한번 쓰기 때문에
//만일 이 로직을 service와 dao에도 넘겨준다면 domain(DTO)에 class를 만들어주면 된다.
@Data
//Data = getter + setter + Tostring
//@AllArgsConstructor는 생성자
@AllArgsConstructor
class MemberRtnDto {
//name과 sal만 뽑아서 data 전송해준다.
//생성자가 없는 이유 -> AllArgsConstructor때문에!!
//만약 하나를 final로 만들게 되면, @RequiredArgsConstructor로!!
private String name;
private Long sal;
}
//Ver1. Bad
@PostMapping("/restApi/v1/memberSave")
// @RequestBody : Json(member)으로 온것을 --> Member member Setting
public CreateMemberResponse saveMemberV1(@RequestBody @Valid Member member) {
System.out.println("JpaRestApiController /api/v1/memberSave member-> "+member);
System.out.println("JpaRestApiController /api/v1/memberSave member.getId()-> "+member.getId());
log.info("member.getName()-> {}.",member.getName());
log.info("member.getSal()-> {}.", member.getSal());
Long id = memberService.saveMember(member);
//그냥 보내면 String으로 보내지지만(id), 생성자로 보내기 위해서 새로 만들어서 보내야 Json 으로 보내진다.
return new CreateMemberResponse(id);
}
//Ver2.
// 목적 : Entity Member member --> 직접 화면이나 API위한 Setting 금지
// 예시 : @NotEmpty --> @Column(name = "userName")
@PostMapping("/restApi/v2/memberSave")
// @RequestBody : Json(member)으로 온것을 --> Member member Setting
public CreateMemberResponse saveMemberV2(@RequestBody @Valid CreateMemberRequest cMember) {
System.out.println("JpaRestApiController /api/v2/memberSave cMember->"+cMember);
log.info("member.getName()-> {}.", cMember.getName());
log.info("member.getSal()-> {}.", cMember.getSal());
Member member = new Member();
member.setName(cMember.getName());
member.setSal(cMember.getSal());
Long id = memberService.saveMember(member);
return new CreateMemberResponse(id);
}
/*
* 단일 Id 조회 API
* URI 상에서 '{ }' 로 감싸여있는 부분과 동일한 변수명을 사용하는 방법
* 해당 데이터가 있으면 업데이트를 하기에
* GET요청이 여러번 실행되어도 해당 데이터는 같은 상태이기에 멱등
*/
//BadApi (이유: 보안문제, 전부 다 보내줘서!!)
@GetMapping("/restApi/v15/members/{id}")
public Member membersVer15(@PathVariable("id") Long id) {
System.out.println("JpaRestApiController restApi/v15/members id-> "+id);
Member findMember = memberService.findByMember(id);
System.out.println("JpaRestApiController restApi/v15/members findMember->"+findMember);
return findMember;
}
@Data
static class CreateMemberRequest {
@NotEmpty
private String name;
private Long sal;
}
@Data
@RequiredArgsConstructor
class CreateMemberResponse {
private final Long id;
//위에 @RequiredArgsConstructor를 썼기 때문에 생략해도 된다.
// public CreateMemberResponse(Long id) {
// this.id = id;
// }
}
@PutMapping("/restApi/v21/members/{id}")
public UpdateMemberResponse updateMemberV21(@PathVariable("id") Long id,
@RequestBody @Valid UpdateMemberRequest uMember) {
System.out.println("JpaRestApiController updateMemberV21 id->"+id);
System.out.println("JpaRestApiController updateMemberV21 uMember->"+uMember);
memberService.updateMember(id, uMember.getName(), uMember.getSal());
Member findMember = memberService.findByMember(id);
return new UpdateMemberResponse(findMember.getId(),findMember.getName(), findMember.getSal() );
}
// @PutMapping("/restApi/v21/members/{id}")
// public UpdateMemberResponse updateMemberV21(@PathVariable("id") Long id,
// @RequestBody @Valid UpdateMemberRequest uMember) {
// System.out.println("JpaRestApiController updateMemberV21 start...");
// System.out.println("JpaRestApiController updateMemberV21 id ->"+id);
// System.out.println("JpaRestApiController updateMemberV21 uMember ->"+uMember);
// memberService.updateMember(id, uMember.getName(), uMember.getSal());
// Member findMember = memberService.findByMember(id);
// return new UpdateMemberResponse(findMember.getId(), findMember.getName(), findMember.getSal());
// }
//수정
@DeleteMapping("/restApi/v21/deleteMember/{id}")
//{id}를 id로 놓고 쓰겠다.
public CreateMemberResponse deleteMemberV21(@PathVariable("id") Long id) {
System.out.println("JpaRestApiController /restApi/v21/deleteMember/{id} start...");
System.out.println("JpaRestApiController updateMemberV21 id-> "+id);
memberService.deleteMember(id);
//JSON 형태로
return new CreateMemberResponse(id);
}
@Data
static class UpdateMemberRequest {
private String name;
private Long sal;
}
@Data
@AllArgsConstructor
class UpdateMemberResponse {
private Long id;
private String name;
private Long sal;
}
}
Console |
- delete를 해주기 위해 spring에 추가해준다.
Spring Starter Project | oBootJpaApi01 |
package | com.oracle.oBootMybatis01.service |
class | MemberService |
package com.oracle.oBootJpaApi01.controller;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import javax.naming.spi.DirStateFactory.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.oracle.oBootJpaApi01.domain.Member;
import com.oracle.oBootJpaApi01.service.MemberService;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotEmpty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
//@Controller + @ResponseBody = @RestController
@RestController
//private static final Logger logger = LoggerFactory.getLogger(JpaRestApiController.class);
@Slf4j
@RequiredArgsConstructor
public class JpaRestApiController {
private final MemberService memberService;
@RequestMapping("/helloText")
public String helloText() {
System.out.println("JpaRestApiController Start...");
String hello = "안녕";
// StringConverter
return hello;
}
//Bad Api
@GetMapping("/restApi/v1/members")
public List<Member> membersVer1() {
System.out.println("JpaRestApiController /restApi//v1/members start...");
//return return되어서 결국에는 listMember에 쌓일 것이다.
List<Member> listMember = memberService.getListAllMember();
System.out.println("JpaRestApiController /restApi//v1/members listMember.size() -> "+listMember.size());
return listMember;
}
//Good Api Easy Version
//목표 : 이름 & 급여 만 전송
@GetMapping("/restApi/v21/members")
public Result membersVer21() {
List<Member> fineMembers = memberService.getListAllMember();
System.out.println("JpaRestApiController restApi/v21/members findMembers.size()-> "+fineMembers.size());
//보내주는 Data의 List를 새로 만들었다. (넘어온 list 값이 과도하기 때문에)
List<MemberRtnDto> resultList = new ArrayList<MemberRtnDto>();
//이전 목적 : 반드시 필요한 Data만 보여준다. (외부 노출 최대한 금지)
//향상형 for문을 이용
for(Member member: fineMembers) {
//아래 문이 생성자가 없이도 잘 실행되는 이유 -> MemberRtnDto에 @AllArgsConstructor를 걸어주었기 때문에
MemberRtnDto memberRtnDto = new MemberRtnDto(member.getName(), member.getSal());
System.out.println("/restApi/v21/members getName -> "+memberRtnDto.getName());
System.out.println("/restApi/v21/members getSal -> "+memberRtnDto.getSal());
resultList.add(memberRtnDto);
}
System.out.println("/restApi/v21/members resultList.size()"+resultList.size());
return new Result(resultList.size(), resultList);
}
//Good API 람다버전
//목표 : 이름 & 급여 만 전송
@GetMapping("/restApi/v22/members")
public Result membersVer22() {
List<Member> fineMembers = memberService.getListAllMember();
System.out.println("JpaRestApiController restApi/v22/members findMembers.size()-> "
+fineMembers.size());
// 자바 8에서 추가한 스트림(Streams)은 람다(->)를 활용할 수 있는 기술 중 하나
//람다 형식 : 화살표 (->) 이용하는 것, stream()을 써 주어야지만 가능
List<MemberRtnDto> memberCollect =
fineMembers.stream()
// m이라해도 되고 member라고 해도 된다.
// m이 있는 만큼 향상형 for문처럼 돌아가는 것
// 하지만 map은 list로 수집을 하지는 못한다. 갖고만 있게 하는 로직
.map(m->new MemberRtnDto(m.getName(), m.getSal()))
//따라서 list로 만들어주는 작업을 해야한다.
.collect(Collectors.toList())
;
System.out.println("/restApi/v22/members memberCollect.size()-> "+memberCollect.size());
//Result 생성자 (@AllArgsConstructor로 인해 생성자 정의 안해도 만들 수 있다.)
// totCount T data
return new Result(memberCollect.size(), memberCollect);
}
@Data
@AllArgsConstructor
class Result<T> {
private final int totCount; //총 인원수 추가
//들어오는 Data가 어떤 데이터형이든지 상관없이 T에 잡힌다. (Api의 경우는 T를 쓰는게 좋다.)
private final T data;
}
//innerclass를 쓴 이유는 controller에서 값을 보내줄 때 딱 한번 쓰기 때문에
//만일 이 로직을 service와 dao에도 넘겨준다면 domain(DTO)에 class를 만들어주면 된다.
@Data
//Data = getter + setter + Tostring
//@AllArgsConstructor는 생성자
@AllArgsConstructor
class MemberRtnDto {
//name과 sal만 뽑아서 data 전송해준다.
//생성자가 없는 이유 -> AllArgsConstructor때문에!!
//만약 하나를 final로 만들게 되면, @RequiredArgsConstructor로!!
private String name;
private Long sal;
}
//Ver1. Bad
@PostMapping("/restApi/v1/memberSave")
// @RequestBody : Json(member)으로 온것을 --> Member member Setting
public CreateMemberResponse saveMemberV1(@RequestBody @Valid Member member) {
System.out.println("JpaRestApiController /api/v1/memberSave member-> "+member);
System.out.println("JpaRestApiController /api/v1/memberSave member.getId()-> "+member.getId());
log.info("member.getName()-> {}.",member.getName());
log.info("member.getSal()-> {}.", member.getSal());
Long id = memberService.saveMember(member);
//그냥 보내면 String으로 보내지지만(id), 생성자로 보내기 위해서 새로 만들어서 보내야 Json 으로 보내진다.
return new CreateMemberResponse(id);
}
//Ver2.
// 목적 : Entity Member member --> 직접 화면이나 API위한 Setting 금지
// 예시 : @NotEmpty --> @Column(name = "userName")
@PostMapping("/restApi/v2/memberSave")
// @RequestBody : Json(member)으로 온것을 --> Member member Setting
public CreateMemberResponse saveMemberV2(@RequestBody @Valid CreateMemberRequest cMember) {
System.out.println("JpaRestApiController /api/v2/memberSave cMember->"+cMember);
log.info("member.getName()-> {}.", cMember.getName());
log.info("member.getSal()-> {}.", cMember.getSal());
Member member = new Member();
member.setName(cMember.getName());
member.setSal(cMember.getSal());
Long id = memberService.saveMember(member);
return new CreateMemberResponse(id);
}
/*
* 단일 Id 조회 API
* URI 상에서 '{ }' 로 감싸여있는 부분과 동일한 변수명을 사용하는 방법
* 해당 데이터가 있으면 업데이트를 하기에
* GET요청이 여러번 실행되어도 해당 데이터는 같은 상태이기에 멱등
*/
//BadApi (이유: 보안문제, 전부 다 보내줘서!!)
@GetMapping("/restApi/v15/members/{id}")
public Member membersVer15(@PathVariable("id") Long id) {
System.out.println("JpaRestApiController restApi/v15/members id-> "+id);
Member findMember = memberService.findByMember(id);
System.out.println("JpaRestApiController restApi/v15/members findMember->"+findMember);
return findMember;
}
@Data
static class CreateMemberRequest {
@NotEmpty
private String name;
private Long sal;
}
@Data
@RequiredArgsConstructor
class CreateMemberResponse {
private final Long id;
//위에 @RequiredArgsConstructor를 썼기 때문에 생략해도 된다.
// public CreateMemberResponse(Long id) {
// this.id = id;
// }
}
@PutMapping("/restApi/v21/members/{id}")
public UpdateMemberResponse updateMemberV21(@PathVariable("id") Long id,
@RequestBody @Valid UpdateMemberRequest uMember) {
System.out.println("JpaRestApiController updateMemberV21 id->"+id);
System.out.println("JpaRestApiController updateMemberV21 uMember->"+uMember);
memberService.updateMember(id, uMember.getName(), uMember.getSal());
Member findMember = memberService.findByMember(id);
return new UpdateMemberResponse(findMember.getId(),findMember.getName(), findMember.getSal() );
}
// @PutMapping("/restApi/v21/members/{id}")
// public UpdateMemberResponse updateMemberV21(@PathVariable("id") Long id,
// @RequestBody @Valid UpdateMemberRequest uMember) {
// System.out.println("JpaRestApiController updateMemberV21 start...");
// System.out.println("JpaRestApiController updateMemberV21 id ->"+id);
// System.out.println("JpaRestApiController updateMemberV21 uMember ->"+uMember);
// memberService.updateMember(id, uMember.getName(), uMember.getSal());
// Member findMember = memberService.findByMember(id);
// return new UpdateMemberResponse(findMember.getId(), findMember.getName(), findMember.getSal());
// }
//수정
@DeleteMapping("/restApi/v21/deleteMember/{id}")
//{id}를 id로 놓고 쓰겠다.
public CreateMemberResponse deleteMemberV21(@PathVariable("id") Long id) {
System.out.println("JpaRestApiController /restApi/v21/deleteMember/{id} start...");
System.out.println("JpaRestApiController updateMemberV21 id-> "+id);
memberService.deleteMember(id);
//JSON 형태로
return new CreateMemberResponse(id);
}
@Data
static class UpdateMemberRequest {
private String name;
private Long sal;
}
@Data
@AllArgsConstructor
class UpdateMemberResponse {
private Long id;
private String name;
private Long sal;
}
}
Console |
-
- json으로 담아주기 때문에 CreateMemberResponse로 가진다.
Spring Starter Project | oBootJpaApi01 |
package | com.oracle.oBootMybatis01.repository |
interface | MemberRepository |
package com.oracle.oBootJpaApi01.repository;
import java.util.List;
import com.oracle.oBootJpaApi01.domain.Member;
public interface MemberRepository {
Long save(Member member);
List<Member> findAll();
Member findByMember(Long memberId);
int updateByMember(Member member);
void deleteById(Long id);
}
Console |
Spring Starter Project | oBootJpaApi01 |
package | com.oracle.oBootMybatis01.repository |
class | JpaMemberRepository |
package com.oracle.oBootJpaApi01.repository;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.oracle.oBootJpaApi01.domain.Member;
import jakarta.persistence.EntityManager;
import lombok.RequiredArgsConstructor;
@Repository
@RequiredArgsConstructor
public class JpaMemberRepository implements MemberRepository {
//JPA는 반드시 Entity Manager를 써야한다. -> 이 이후에 injection이 되어야한다.
// 생성자 or @RequiredArgsConstructor로!!
private final EntityManager em;
//final은 반드시 생성자에 들어가야한다. instance를 받아줄 곳이 없다.
//따라서 final은 생성자를 반드시 넣어주어야 한다.
// 생성자에 넣어주지 않으면, EntityManager를 구현할 수 가 없다.
// 하지만 이 대신에 @RequiredArgsConstructor 가 이것과 같은 역할을 한다.
// @Autowired
// public JpaMemberRepository(EntityManager em) {
// this.em = em;
// }
@Override
public Long save(Member member) {
System.out.println("JpaMemberRepository save before...");
em.persist(member);
return member.getId();
}
@Override
public List<Member> findAll() {
List<Member> memberList = em.createQuery("SELECT m FROM Member m", Member.class)
.getResultList();
System.out.println("JpaMemberRepository findAll memberList.size()-> "+memberList.size());
return memberList;
}
@Override
public Member findByMember(Long memberId) {
Member member = em.find(Member.class, memberId);
return member;
}
@Override
public int updateByMember(Member member) {
int result = 0;
Member member3 = em.find(Member.class, member.getId());
if (member3 != null) {
// 회원 저장
member3.setName(member.getName());
member3.setSal(member.getSal());
result = 1;
System.out.println("JpaMemberRepository updateByMember Update...");
} else {
result = 0;
System.out.println("JpaMemberRepository updateByMember No Exist..");
}
return result;
}
@Override
public void deleteById(Long did) {
System.out.println("JpaMemberRepository deleteById before...");
Member member3 = em.find(Member.class, did);
em.remove(member3);
return;
}
}
Console |
- 먼저 id를 찾아준 후 그 다음에 remove로 삭제해준다.
Spring Starter Project | oBootJpaApi01 |
package | com.oracle.oBootMybatis01 |
class | WebConfig |
package com.oracle.oBootJpaApi01;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
//CORS는 한 도메인이 도메인 간의 요청을 가진 다른 도메인의 리소스에 액세스할 수 있게 해주는
//보안 메커니즘으로 최신 브라우저에서 구현된 동일 출처 정책 때문에 등장
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
// TODO Auto-generated method stub
// WebMvcConfigurer.super.addCorsMappings(registry);
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "POST", "PUT","DELETE")
.maxAge(3000);
}
}
- DELETE를 추가시켜주어야 한다.
그 다음에 다시 도커에 스프링 해준다. (Day72 보고 따라하기)
그 다음 vue에서 delete관련해서 새로 수정시켜준 후 실행해보기
'클라우드 데브옵스' 카테고리의 다른 글
Day75 2024.09.06.금 #코딩일기 (0) | 2024.09.06 |
---|---|
Day73 2024.09.04.수 #코딩일기 (0) | 2024.09.04 |
Day72 2024.09.03.화 #코딩일기 (0) | 2024.09.03 |
Day71 2024.09.02.월 #코딩일기 (0) | 2024.09.02 |
Day69 2024.08.29.목 #코딩일기 (0) | 2024.08.29 |