코딩기록 저장소 🐕/spring(JPA)🌱

10/16 restApi

kimkongmom 2023. 10. 16. 08:58

 

 

 

 

REST(REpresentational State Transfer)


  1. 요청 주소를 작성하는 새로운 방식이다.
  2. 변수를 파라미터로 추가하는 Query String 방식이 아니다.
  3. 변수를 주소에 포함시키는 Path Variable 방식을 사용한다.
  4. "요청 주소(URL) + 요청 방식(Method)"을 합쳐서 요청을 구분한다.
  5. 예시
           URL         Method
   1) 목록 /members    GET        /members/page/1
   2) 상세 /members/1  GET
   3) 삽입 /members    POST
   4) 수정 /members    PUT
   5) 삭제 /member/1   DELETE     /members/4,3,2

 

 

 

 

동작순서와 반대로 작성순서로 !

 

MyBatis를 사용하요 쿼리문 부터 작성

 

▶ Mapper.xml

<where>: 

이 부분은 동적 SQL의 조건절을 시작하는 부분입니다. 

이 조건절은 조건이 추가될 때 <where> 내의 SQL이 삽입되도록 허용합니다.

<foreach collection="list" item="memberNo" open="IN(" close=")" separator=",">: 

이 부분은 Java 목록을 순회하고 그 내용을 SQL에 삽입하는 역할을 합니다.

 

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
 
<mapper namespace="com.gdu.app14.dao.MemberMapper">
 
  <insert id="insertMember" parameterType="MemberDto">
    INSERT INTO MEMBER_T (
        MEMBER_NO
      , ID
      , NAME
      , GENDER
      , ADDRESS
    ) VALUES (
        MEMBER_SEQ.NEXTVAL
      , #{id}
      , #{name}
      , #{gender}
      , #{address}
    )
  </insert>
  
  <select id="getMemberList" parameterType="Map" resultType="MemberDto">
    SELECT MEMBER_NO, ID, NAME, GENDER, ADDRESS
      FROM (SELECT ROW_NUMBER() OVER(ORDER BY MEMBER_NO DESC) AS RN, MEMBER_NO, ID, NAME, GENDER, ADDRESS
              FROM MEMBER_T)
     WHERE RN BETWEEN #{begin} AND #{end}
  </select>
  
  <select id="getMemberCount" resultType="int">
    SELECT COUNT(*)
      FROM MEMBER_T
  </select>
  
  <select id="getMember" parameterType="int" resultType="MemberDto">
    SELECT MEMBER_NO, ID, NAME, GENDER, ADDRESS
      FROM MEMBER_T
     WHERE MEMBER_NO = #{memberNo}
  </select>
  
  <update id="updateMember" parameterType="MemberDto">
    UPDATE MEMBER_T
       SET NAME = #{name}
         , GENDER = #{gender}
         , ADDRESS = #{address}
     WHERE MEMBER_NO = #{memberNo}
  </update>
  
  <delete id="deleteMember" parameterType="int">
    DELETE
      FROM MEMBER_T
     WHERE MEMBER_NO = #{memberNo}
  </delete>
  
  <delete id="deleteMembers" parameterType="List">
    DELETE
      FROM MEMBER_T
    <where>
      MEMBER_NO
      <foreach collection="list" item="memberNo" open="IN(" close=")" separator=",">
        #{memberNo}
      </foreach>
    </where>
  </delete>
 
</mapper>
cs

 

 

▶ MemberMapper.interface

 

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
29
30
31
32
33
34
package com.gdu.app14.dao;
 
import java.util.List;
import java.util.Map;
 
import org.apache.ibatis.annotations.Mapper;
 
import com.gdu.app14.dto.MemberDto;
 
@Mapper
public interface MemberMapper {
 
  // 삽입
  public int insertMember(MemberDto memberDto);
  
  // 목록
  public List<MemberDto> getMemberList(Map<String, Object> map);
  
  // 전체 개수
  public int getMemberCount();
  
  // 회원 조회
  public MemberDto getMember(int memberNo);
  
  // 회원 정보 수정
  public int updateMember(MemberDto memberDto);
  
  // 회원 정보 삭제
  public int deleteMember(int memberNo);
  
  // 회원들 정보 삭제
  public int deleteMembers(List<String> list);
  
}
cs

 

 

▶  MemverService.interface

웹 컨트롤러에서 호출되어 비즈니스 로직을 수행하고 데이터베이스와 상호 작용합니다.

 

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
29
package com.gdu.app14.service;
 
import java.util.Map;
 
import javax.servlet.http.HttpServletResponse;
 
import com.gdu.app14.dto.MemberDto;
 
public interface MemberService {
 
  // 회원 등록
  public Map<String, Object> register(MemberDto memberDto, HttpServletResponse response);
  
  // 회원 목록
  public Map<String, Object> getMembers(int page);
  
  // 회원 조회
  public Map<String, Object> getMember(int memberNo);
  
  // 회원 정보 수정
  public Map<String, Object> modifyMember(MemberDto memberDto);
  
  // 회원 정보 삭제
  public Map<String, Object> removeMember(int memberNo);
  
  // 회원들 정보 삭제
  public Map<String, Object> removeMembers(String memberNoList);
  
}
cs

 

 

 

 

MemberServiceImpl

실제로 비즈니스 로직을 수행하고 데이터베이스 액세스를 처리합니다.

 

Map은 일반적으로 서비스 메서드에서 여러 종류의 데이터를 반환할 때 사용됩니다. 

이 경우, 각 메서드는 결과를 Map 객체에 담아 클라이언트에게 반환하게 됩니다. 

예를 들어, register 메서드는 addResult라는 이름의 키와 함께 등록 결과를 Map에 넣어 반환하고, 

getMembers 메서드는 회원 목록과 페이징 정보를 Map에 담아 반환합니다.

 

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package com.gdu.app14.service;
 
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
import javax.servlet.http.HttpServletResponse;
 
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
 
import com.gdu.app14.dao.MemberMapper;
import com.gdu.app14.dto.MemberDto;
import com.gdu.app14.util.PageUtil;
 
import lombok.RequiredArgsConstructor;
 
@RequiredArgsConstructor
@Service
public class MemberServiceImpl implements MemberService {
 
  private final MemberMapper memberMapper;
  private final PageUtil pageUtil;
  
  @Override
  public Map<String, Object> register(MemberDto memberDto, HttpServletResponse response) {
    
    Map<String, Object> map = null;
    
    try {
 
      int addResult = memberMapper.insertMember(memberDto);
      map = Map.of("addResult", addResult);
    
    } catch(DuplicateKeyException e) {  // UNIQUE 칼럼에 중복 값이 전달된 경우에 발생함
                                        // $.ajax({})의 error 속성으로 응답됨
      try {
        response.setContentType("text/plain");
        PrintWriter out = response.getWriter();
        response.setStatus(500);                   // 예외객체 jqXHR의 status 속성으로 확인함
        out.print("이미 사용 중인 아이디입니다."); // 예외객체 jqXHR의 responseText 속성으로 확인함
        out.flush();
        out.close();
        
      } catch(Exception e2) {
        e2.printStackTrace();
      }
      
    } catch(Exception e) {
      System.out.println(e.getClass().getName());  // 발생한 예외 클래스의 이름 확인
    }
    
    return map;
    
  }
  
  @Override
  public Map<String, Object> getMembers(int page) {
    
    int total = memberMapper.getMemberCount();
    int display = 2;
    
    pageUtil.setPaging(page, total, display);
    
    Map<String, Object> map = Map.of("begin", pageUtil.getBegin()
                                   , "end", pageUtil.getEnd());
    
    List<MemberDto> memberList = memberMapper.getMemberList(map);
    String paging = pageUtil.getAjaxPaging();
    
    return Map.of("memberList", memberList
                , "paging", paging);
    
  }
  
  @Override
  public Map<String, Object> getMember(int memberNo) {
    Map<String, Object> map = new HashMap<String, Object>();
    map.put("member", memberMapper.getMember(memberNo));
    return map;
  }
  
  @Override
  public Map<String, Object> modifyMember(MemberDto memberDto) {
    int modifyResult = memberMapper.updateMember(memberDto);
    return Map.of("modifyResult", modifyResult);
  }
  
  @Override
  public Map<String, Object> removeMember(int memberNo) {
    return Map.of("removeResult", memberMapper.deleteMember(memberNo));
  }
  
  @Override
  public Map<String, Object> removeMembers(String memberNoList) {
    List<String> list = Arrays.asList(memberNoList.split(","));
    return Map.of("removeResult", memberMapper.deleteMembers(list));
  }
  
}
cs

 

 

MemberController

클라이언트의 요청을 받아 해당 요청에 대한 서비스 메서드를 호출하고 응답을 반환하는 역할을 합니다

 

@RestController 어노테이션을 붙였으므로 이 컨트롤러는 

모든 메서드에서 @ResponseBody 어노테이션이 자동으로 추가됩니다. 

따라서 모든 메서드는 JSON 형식의 응답을 반환합니다.

 

@PathVariable 어노테이션을 사용하여 경로 변수 {mNo}를 가져와 회원 번호로 사용합니다

 

@RequestBody 어노테이션을 사용하여 요청 본문에서 JSON 형식의 데이터를 MemberDto 객체로 변환합니다.

 

produces (생산)는 Spring Framework에서 컨트롤러 메서드가 클라이언트에게 반환하는 응답의 형식(미디어 타입)을 지정하는 데 사용되는 어노테이션입니다. 

여기서는 JSON

 

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
package com.gdu.app14.controller;
 
import java.util.Map;
import java.util.Optional;
 
import javax.servlet.http.HttpServletResponse;
 
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
 
import com.gdu.app14.dto.MemberDto;
import com.gdu.app14.service.MemberService;
 
import lombok.RequiredArgsConstructor;
 
 
@RequiredArgsConstructor
@RestController  // 모든 메소드에 @ResponseBody를 추가한다.
public class MemberController {
  
  private final MemberService memberService;
 
  // 회원 등록 요청
  @RequestMapping(value="/members", method=RequestMethod.POST, produces="application/json")
  public Map<String, Object> registerMember(@RequestBody MemberDto memberDto, HttpServletResponse response) {
    return memberService.register(memberDto, response);
  }
  
  // 회원 목록 요청
  // 경로에 포함되어 있는 변수 {p}는 @PathVariable을 이용해서 가져올 수 있다.
  @RequestMapping(value="/members/page/{p}", method=RequestMethod.GET, produces="application/json")
  public Map<String, Object> getMembers(@PathVariable(value="p", required=false) Optional<String> opt) {
    int page = Integer.parseInt(opt.orElse("1"));
    return memberService.getMembers(page);
  }
  
  // 회원 조회 요청
  @RequestMapping(value="/members/{mNo}", method=RequestMethod.GET, produces="application/json")
  public Map<String, Object> getMember(@PathVariable(value="mNo"int memberNo) {
    return memberService.getMember(memberNo);
  }
  
  // 회원 정보 수정 요청
  @RequestMapping(value="/members", method=RequestMethod.PUT, produces="application/json")
  public Map<String, Object> modifyMember(@RequestBody MemberDto memberDto) {
    return memberService.modifyMember(memberDto);
  }
  
  // 회원 정보 삭제 요청
  @RequestMapping(value="/member/{memberNo}", method=RequestMethod.DELETE, produces="application/json")
  public Map<String, Object> removeMember(@PathVariable(value="memberNo"int memberNo) {
    return memberService.removeMember(memberNo);
  }
  
  // 회원들 정보 삭제 요청
  @RequestMapping(value="/members/{memberNoList}", method=RequestMethod.DELETE, produces="application/json")
  public Map<String, Object> removeMembers(@PathVariable(value="memberNoList"String memberNoList) {
    return memberService.removeMembers(memberNoList);
  }
  
}
cs

 

 

index.jsp

fnChkAll 함수:
HTML에서 id가 chk_all인 체크박스를 클릭하면 모든 개별 선택 체크박스의 상태를 변경합니다. 전체 선택 체크박스를 클릭하면 개별 선택 체크박스들이 모두 선택됩니다.


fnChkOne 함수:
개별 선택 체크박스(chk_one)를 클릭하면 전체 선택 체크박스(chk_all)의 상태를 변경합니다. 모든 개별 선택 체크박스가 선택되었을 때, 전체 선택 체크박스도 선택됩니다.


fnInit 함수:
입력란 초기화를 처리합니다. 이 함수는 사용자가 회원 정보를 입력하는 입력란을 초기화하고, 등록, 수정, 삭제 버튼의 활성/비활성 상태를 조절합니다.


fnMemberRegister 함수:
회원 등록을 처리합니다. 사용자가 회원 정보를 입력하고 "등록" 버튼을 클릭하면 이 함수가 실행됩니다. 사용자가 입력한 데이터를 JSON 형식으로 서버로 전송하여 새 회원을 등록합니다. 서버로부터 응답을 받아 성공 또는 실패 메시지를 표시합니다.


fnMemberList 함수:
회원 목록을 조회합니다. 페이지가 로드될 때와 페이징 버튼을 클릭할 때, 이 함수가 실행됩니다. 서버에게 현재 페이지에 해당하는 회원 목록을 요청하고, 응답 데이터를 사용하여 회원 목록을 HTML 테이블에 표시합니다.


fnAjaxPaging 함수:
페이징을 처리하는 함수입니다. 페이지 번호를 변경할 때 사용됩니다. 페이지 번호가 변경되면 fnMemberList 함수를 호출하여 해당 페이지의 회원 목록을 다시 가져옵니다.


fnMemberDetail 함수:
개별 회원 정보 조회를 처리합니다. "조회" 버튼을 클릭하면 이 함수가 실행되며, 선택한 회원의 상세 정보를 서버에서 가져와서 입력란에 표시합니다.


fnMemberModify 함수:
회원 정보 수정을 처리합니다. "수정" 버튼을 클릭하면 이 함수가 실행되며, 선택한 회원의 정보를 수정하여 서버에 업데이트합니다.


fnRemoveMember 함수:
개별 회원 정보 삭제를 처리합니다. "삭제" 버튼을 클릭하면 이 함수가 실행되며, 선택한 회원을 서버에서 삭제합니다.


fnRemoveMembers 함수:
여러 회원 정보 삭제를 처리합니다. "선택삭제" 버튼을 클릭하면 이 함수가 실행되며, 선택한 여러 회원을 서버에서 삭제합니다.

 

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<c:set var="contextPath" value="${pageContext.request.contextPath}" />
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style>
  #paging a {
    margin: 10px;
  }
</style>
<script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>
<script>
 
  $(function(){
      fnChkAll();
      fnChkOne();
      fnInit();
      fnMemberRegister();
      fnMemberList();
      fnMemberDetail();
      fnMemberModify();
      fnRemoveMember();
      fnRemoveMembers();
  })
 
  // 전체 선택을 클릭하면 개별 선택에 영향을 미친다.
  function fnChkAll(){
      $('#chk_all').click(function(){
          $('.chk_one').prop('checked', $(this).prop('checked'));
      })
  }
  
  // 개별 선택을 클릭하면 전체 선택에 영향을 미친다.
  function fnChkOne(){
      $(document).on('click''.chk_one'function(){
          var total = 0;
          $.each($('.chk_one'), function(i, elem){
              total += $(elem).prop('checked');
          })
          $('#chk_all').prop('checked', total === $('.chk_one').length);
      })
  }
  
  // 입력란 초기화
  function fnInit(){
      $('#memberNo').val('');
      $('#id').val('').prop('disabled'false);
      $('#name').val('');
      $(':radio[value=none]').prop('checked'true);
      $('#address').val('');
      $('#btn_register').prop('disabled'false);
    $('#btn_modify').prop('disabled'true);
    $('#btn_remove').prop('disabled'true);
  }
  
  // 회원 등록
  function fnMemberRegister(){
      $('#btn_register').click(function(){
        $.ajax({
        // 요청
        type: 'post',
        url: '${contextPath}/members',
        contentType: 'application/json',
        data: JSON.stringify({
          id: $('#id').val(),
          name: $('#name').val(),
          gender: $(':radio:checked').val(),
          address: $('#address').val()
        }),
        // 응답
        dataType: 'json',
        success: function(resData){  // resData === {"addResult": 1}
          if(resData.addResult === 1){
              alert('회원 정보가 등록되었습니다.');
              page = 1;
              fnMemberList();
              fnInit();
          } else {
              alert('회원 정보가 등록되지 않았습니다.');
          }
        },
        error: function(jqXHR){
            alert(jqXHR.responseText + '(예외코드 ' + jqXHR.status + ')');
        }
      })
      })
  }
  
  // 전역변수 (모든 함수에서 사용할 수 있는 변수)
  var page = 1;
  
  // 회원 목록
  function fnMemberList(){
      $.ajax({
          // 요청
          type: 'get',
          url: '${contextPath}/members/page/' + page,
          // 응답
          dataType: 'json',
          success: function(resData){
              // 회원 목록을 테이블로 만들기
              $('#member_list').empty();
              $.each(resData.memberList, function(i, member){
                  var tr = '<tr>';
                  tr += '<td><input type="checkbox" class="chk_one" value="'+member.memberNo+'"></td>';
                  tr += '<td>'+member.id+'</td>';
                  tr += '<td>'+member.name+'</td>';
                  tr += '<td>'+member.gender+'</td>';
                  tr += '<td>'+member.address+'</td>';
                  tr += '<td><button type="button" class="btn_detail" data-member_no="'+member.memberNo+'">조회</button></td>';
                  tr += '</tr>';
                  $('#member_list').append(tr);
              })
              // 페이징
              $('#paging').html(resData.paging);
          }
      })
  }
  
  // 페이지를 바꿀때마다 호출되는 fnAjaxPaging 함수
  function fnAjaxPaging(p){
      page = p;        // 페이지 번호를 바꾼다.
      fnMemberList();  // 새로운 목록을 가져온다.
  }
  
  // 회원 정보 상세 조회하기
  function fnMemberDetail(){
      $(document).on('click''.btn_detail'function(){
          $.ajax({
              // 요청
              type: 'get',
              url: '${contextPath}/members/' + $(this).data('member_no'),
              // 응답
              dataType: 'json',
              success: function(resData){
                  console.log(resData);
                  var member = resData.member;
                  if(!member){
                      alert('회원 정보를 조회할 수 없습니다.');
                  } else {
                      $('#memberNo').val(member.memberNo);
                      $('#id').val(member.id).prop('disabled'true);
                      $('#name').val(member.name);
                      $(':radio[value=' + member.gender + ']').prop('checked'true);
                      $('#address').val(member.address);
                      $('#btn_register').prop('disabled'true);
                      $('#btn_modify').prop('disabled'false);
                      $('#btn_remove').prop('disabled'false);
                  }
              }
          })
      });
  }
 
  // 회원 정보 수정하기
  function fnMemberModify(){
      $('#btn_modify').click(function(){
          $.ajax({
              // 요청
              type: 'put',
              url: '${contextPath}/members',
              contentType: 'application/json',
              data: JSON.stringify({
                  memberNo: $('#memberNo').val(),
                  name: $('#name').val(),
                  gender: $(':radio:checked').val(),
                  address: $('#address').val()
              }),
              // 응답
              dataType: 'json',
              success: function(resData){
                  if(resData.modifyResult === 1){
                      alert('회원 정보가 수정되었습니다.');
                      fnMemberList();
                  } else {
                      alert('회원 정보가 수정되지 않았습니다.');
                  }
              }
          })
      })
  }
  
  // 회원 정보 삭제
  function fnRemoveMember(){
      $('#btn_remove').click(function(){
          if(!confirm('회원 정보를 삭제할까요?')){
              return;
          }
          $.ajax({
              // 요청
              type: 'delete',
              url: '${contextPath}/member/' + $('#memberNo').val(),
              // 응답
              dataType: 'json',
              success: function(resData){
                  if(resData.removeResult === 1){
                      alert('회원 정보가 삭제되었습니다.');
              page = 1;
              fnMemberList();
              fnInit();
                  } else {
                      alert('회원 정보가 삭제되지 않았습니다.');
                  }
              }
          })
      })
  }
 
  // 회원들의 정보 삭제
  function fnRemoveMembers(){
      $('#btn_remove_list').click(function(){
          // 체크된 요소의 value를 배열 arr에 저장하기(push 메소드)
          var arr = [];
          var chkOne = $('.chk_one');
          $.each(chkOne, function(i, elem){
              if($(elem).is(':checked')){  // if($(elem).prop('checked'))
                  arr.push($(elem).val());
              }
          })
          // 체크된 요소가 없으면 삭제 중지
          if(arr.length === 0){
              alert('선택된 회원 정보가 없습니다. 다시 시도하세요.');
              return;
          }
          // 선택된 회원 삭제
          $.ajax({
              // 요청
              type: 'delete',
              url: '${contextPath}/members/' + arr.join(','),
              // 응답
              dataType: 'json',
              success: function(resData){
                  if(resData.removeResult > 0){
                      alert('선택한 회원 정보들이 삭제되었습니다.');
                  page = 1;
            fnMemberList();
            fnInit();
                  } else {
                      alert('선택한 회원 정보들이 삭제되지 않았습니다.');
                  }
              }
          })
      })
  }
  
</script>
 
</head>
<body>
 
  <div>
    <h1>회원 관리하기</h1>
    <div>
      <label for="id">아이디</label>
      <input type="text" id="id">
    </div>
    <div>
      <label for="name">이름</label>
      <input type="text" id="name">
    </div>
    <div>
      <input type="radio" id="none" name="gender" value="none" checked>
      <label for="none">선택안함</label>
      <input type="radio" id="man" name="gender" value="man">
      <label for="man">남자</label>
      <input type="radio" id="woman" name="gender" value="woman">
      <label for="woman">여자</label>
    </div>
    <div>
      <label for="address">주소</label>
      <select id="address">
        <option value="">:::선택:::</option>
        <option>서울</option>
        <option>경기</option>
        <option>인천</option>
      </select>
    </div>
    <input type="hidden" id="memberNo">
    <div>
      <button type="button" onclick="fnInit()">초기화</button>
      <button type="button" id="btn_register">등록</button>
      <button type="button" id="btn_modify">수정</button>
      <button type="button" id="btn_remove">삭제</button>
    </div>
  </div>
 
  <hr>
  
  <div>
    <div>
      <button type="button" id="btn_remove_list">선택삭제</button>
    </div>
    <table border="1">
      <thead>
        <tr>
          <td><input type="checkbox" id="chk_all"><label for="chk_all">전체선택</label></td>
          <td>아이디</td>
          <td>이름</td>
          <td>성별</td>
          <td>주소</td>
          <td></td>
        </tr>
      </thead>
      <tbody id="member_list"></tbody>
      <tfoot>
        <tr>
          <td colspan="6" id="paging"></td>
        </tr>
      </tfoot>
    </table>
  </div>
 
</body>
</html>
cs

 

 

 

 

'코딩기록 저장소 🐕 > spring(JPA)🌱' 카테고리의 다른 글

10/17 RestApi 이어서 페이징 처리  (0) 2023.10.17
시험 review  (0) 2023.10.16
트랜잭션  (0) 2023.10.12
SpringMyBatis  (0) 2023.10.12
Spring AOP  (0) 2023.10.11