[member.sql]
DROP TABLE MEMBER_T;
CREATE TABLE MEMBER_T(
MEMBER_NO NUMBER NOT NULL,
EMAIL VARCHAR2(100 BYTE) NOT NULL UNIQUE,
NAME VARCHAR2(100 BYTE),
GENDER VARCHAR2(5 BYTE),
ADDRESS VARCHAR2(100 BYTE),
CONSTRAINT PK_MEMBER PRIMARY KEY(MEMBER_NO)
);
DROP SEQUENCE MEMBER_SEQ;
CREATE SEQUENCE MEMBER_SEQ NOCACHE;
[mybatis-config.xml]
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--설정 -->
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<!--환경 설정(Transaction,Connection Pool)-->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="oracle.jdbc.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:@localhost:1521:xe"/>
<property name="username" value="GD"/>
<property name="password" value="1111"/>
</dataSource>
</environment>
</environments>
<!--매퍼 설정(매퍼의 위치와 이름) -->
<!--매퍼는 쿼리문을 저장하는 장소 (매퍼의 파일 이름을 통상적으로 테이블의 이름을 따라서 지음) -->
<mappers>
<mapper resource="repository/member.xml"/>
</mappers>
</configuration>
[index.jsp]
<%@ 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>
<script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>
<script>
$(function(){
fnMemberList();
fnInit();
fnMemberAdd();
fnEmailCheck();
fnMemberDetail();
fnMemberModify();
fnMemberDelete();
})
function fnMemberList(){
$.ajax({
type: 'get',
url: '${contextPath}/member/list.do',
dataType: 'text',
success: function(resData){
var obj = JSON.parse(resData);
$('#member_count').text(obj.memberCount);
var memberList = $('#member_list');
memberList.empty(); // 기존의 회원 목록을 지운다.
if(obj.memberCount === 0){
memberList.append('<tr><td colspan="6">등록된 회원이 없습니다.</td></tr>');
} else {
// $.each(배열, function(인덱스, 요소){})
$.each(obj.memberList, function(i, elem){
var str = '<tr>';
str += '<td>' + elem.memberNo + '</td>';
str += '<td>' + elem.email + '</td>';
str += '<td>' + elem.name + '</td>';
str += '<td>' + (elem.gender === 'man' ? '남자' : (elem.gender === 'woman' ? '여자' : '선택안함')) + '</td>';
str += '<td>' + elem.address + '</td>';
str += '<td><button class="btn_detail" data-email="' + elem.email + '">조회</button></td>';
str += '</tr>';
memberList.append(str);
})
}
}
})
}
function fnInit(){
$('#btn_init').click(fnInitDetail);
}
function fnInitDetail(){
$('#email').val('');
$('#name').val('');
$('#none').prop('checked', true);
$('#address').val('');
$('#msg_email').text('');
}
function fnMemberAdd(){
$('#btn_add').click(function(){
if(!ableEmail){
alert('등록할 수 없는 이메일입니다.');
$('#email').focus();
return;
}
$.ajax({
type: 'post',
url: '${contextPath}/member/add.do',
data: $('#frm_member').serialize(), // 폼의 모든 입력 요소를 파라미터로 전송함(입력 요소는 name 속성이 필요함)
dataType: 'text',
success: function(resData){ // resData === '{"addResult":1}' string
var obj = JSON.parse(resData); // obj === {"addResult":1} object
if(obj.addResult === 1){
alert('회원 정보가 등록되었습니다.');
fnMemberList();
fnInitDetail();
} else {
alert('회원 정보 등록이 실패했습니다.');
}
}
})
})
}
var ableEmail = false;
function fnEmailCheck(){
$('#email').keyup(function(){
$.ajax({
type: 'get',
url: '${contextPath}/member/emailCheck.do',
data: 'email=' + $(this).val(),
dataType: 'text',
success: function(resData){ // resData === '{"ableEmail":true}'
var obj = JSON.parse(resData); // obj === {"ableEmail":true}
ableEmail = obj.ableEmail;
if(ableEmail){
$('#msg_email').text('');
} else {
$('#msg_email').text('이미 등록된 이메일입니다.');
}
}
})
})
}
function fnMemberDetail(){
$(document).on('click', '.btn_detail', function(){
$.ajax({
type: 'get',
url: '${contextPath}/member/detail.do',
data: 'email=' + $(this).data('email'),
dataType: 'text',
success: function(resData){ // resData === '{"member":{"memberNo":1,...}}'
var obj = JSON.parse(resData); // obj === {"member":{"memberNo":1,...}}
$('#email').val(obj.member.email);
$('#name').val(obj.member.name);
$(':radio[name=gender][value=' + obj.member.gender + ']').prop('checked', true);
$('#address').val(obj.member.address);
$('#memberNo').val(obj.member.memberNo);
}
})
})
}
function fnMemberModify(){
$('#btn_modify').click(function(){
$.ajax({
type: 'post',
url: '${contextPath}/member/modify.do',
data: $('#frm_member').serialize(),
dataType: 'text',
success: function(resData){ // resData === '{"modifyResult":1}'
var obj = JSON.parse(resData); // obj === {"modifyResult":1}
if(obj.modifyResult == 1){
alert('회원 정보가 수정되었습니다.');
fnMemberList();
} else {
alert('회원 정보 수정이 실패했습니다.');
}
}
})
})
}
function fnMemberDelete(){
$('#btn_delete').click(function(){
if(!confirm('회원 정보를 삭제할까요?')){
return;
}
$.ajax({
type: 'get',
url: '${contextPath}/member/delete.do',
data: 'memberNo=' + $('#memberNo').val(),
dataType: 'text',
success: function(resData){ // resData === '{"deleteResult":1}'
var obj = JSON.parse(resData); // obj === {"deleteResult":1}
if(obj.deleteResult == 1){
alert('회원 정보가 삭제되었습니다.');
fnMemberList();
fnInitDetail();
} else {
alert('회원 정보 삭제가 실패했습니다.');
}
}
})
})
}
</script>
</head>
<body>
<div class="wrap">
<form id="frm_member">
<div>
<label for="email">이메일</label>
<input type="text" name="email" id="email">
<span id="msg_email"></span>
</div>
<div>
<label for="name">이름</label>
<input type="text" name="name" id="name">
</div>
<div>
<input type="radio" name="gender" id="man" value="man">
<label for="man">남자</label>
<input type="radio" name="gender" id="woman" value="woman">
<label for="woman">여자</label>
<input type="radio" name="gender" id="none" value="none" checked>
<label for="none">선택안함</label>
</div>
<div>
<label for="address">주소</label>
<input type="text" name="address" id="address">
</div>
<div>
<input type="hidden" name="memberNo" id="memberNo">
<button type="button" id="btn_init">입력초기화</button>
<button type="button" id="btn_add">회원신규등록</button>
<button type="button" id="btn_modify">회원정보수정</button>
<button type="button" id="btn_delete">회원정보삭제</button>
</div>
</form>
<hr>
<table border="1">
<caption>전체 회원수 <span id="member_count"></span>명</caption>
<thead>
<tr>
<td>회원번호</td>
<td>이메일</td>
<td>이름</td>
<td>성별</td>
<td>주소</td>
<td></td>
</tr>
</thead>
<tbody id="member_list"></tbody>
</table>
</div>
</body>
</html>
[MemberController.java]
package controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import service.MemberService;
import service.MemberServiceImpl;
@WebServlet("*.do")
public class MemberController extends HttpServlet {
private static final long serialVersionUID = 1L;
private MemberService memberService = new MemberServiceImpl();
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/plain; charset=UTF-8"); // JSON 데이터를 문자열로 반환함
String requestURI = request.getRequestURI();
String contextPath = request.getContextPath();
String urlMapping = requestURI.substring(contextPath.length());
switch(urlMapping) {
case "/member/list.do":
memberService.getMemberList(response);
break;
case "/member/add.do":
memberService.memberAdd(request, response);
break;
case "/member/emailCheck.do":
memberService.memberEmailCheck(request, response);
break;
case "/member/detail.do":
memberService.memberDetail(request, response);
break;
case "/member/modify.do":
memberService.memberModify(request, response);
break;
case "/member/delete.do":
memberService.memberDelete(request, response);
break;
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
[MemberDto.java]
package domain;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@NoArgsConstructor
@AllArgsConstructor
@Data
@Builder
public class MemberDto {
private int memberNo;
private String email;
private String name;
private String gender;
private String address;
}
[MemberDao.java]
package repository;
import java.io.InputStream;
import java.util.List;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import domain.MemberDto;
public class MemberDao {
private SqlSessionFactory factory;
private static MemberDao dao = new MemberDao();
private MemberDao() {
try {
String resource = "config/mybatis-config.xml";
InputStream in = Resources.getResourceAsStream(resource);
factory = new SqlSessionFactoryBuilder().build(in);
} catch(Exception e) {
e.printStackTrace();
}
}
public static MemberDao getDao() {
return dao;
}
private final String NS = "repository.member.";
public List<MemberDto> memberList() {
SqlSession ss = factory.openSession();
List<MemberDto> list = ss.selectList(NS + "memberList");
ss.close();
return list;
}
public int memberCount() {
SqlSession ss = factory.openSession();
int count = ss.selectOne(NS + "memberCount");
ss.close();
return count;
}
public int memberAdd(MemberDto dto) {
SqlSession ss = factory.openSession(false);
int addResult = ss.insert(NS + "memberAdd", dto);
if(addResult == 1) {
ss.commit();
}
ss.close();
return addResult;
}
public MemberDto getMemberByEmail(String email) {
SqlSession ss = factory.openSession();
MemberDto dto = ss.selectOne(NS + "getMemberByEmail", email);
ss.close();
return dto;
}
public int memberModify(MemberDto dto) {
SqlSession ss = factory.openSession(false);
int modifyResult = ss.update(NS + "memberModify", dto);
if(modifyResult == 1) {
ss.commit();
}
ss.close();
return modifyResult;
}
public int memberDelete(int memberNo) {
SqlSession ss = factory.openSession(false);
int deleteResult = ss.delete(NS + "memberDelete", memberNo);
if(deleteResult == 1) {
ss.commit();
}
ss.close();
return deleteResult;
}
}
[member.xml]
<?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="repository.member">
<select id="memberList" resultType="domain.MemberDto">
SELECT MEMBER_NO, EMAIL, NAME, GENDER, ADDRESS
FROM MEMBER_T
ORDER BY MEMBER_NO DESC
</select>
<select id="memberCount" resultType="int">
SELECT COUNT(*)
FROM MEMBER_T
</select>
<insert id="memberAdd" parameterType="domain.MemberDto">
INSERT INTO MEMBER_T (
MEMBER_NO
, EMAIL
, NAME
, GENDER
, ADDRESS
) VALUES (
MEMBER_SEQ.NEXTVAL
, #{email}
, #{name}
, #{gender}
, #{address}
)
</insert>
<select id="getMemberByEmail" parameterType="String" resultType="domain.MemberDto">
SELECT MEMBER_NO, EMAIL, NAME, GENDER, ADDRESS
FROM MEMBER_T
WHERE EMAIL = #{email}
</select>
<update id="memberModify" parameterType="domain.MemberDto">
UPDATE MEMBER_T
SET EMAIL = #{email}
, NAME = #{name}
, GENDER = #{gender}
, ADDRESS = #{address}
WHERE MEMBER_NO = #{memberNo}
</update>
<delete id="memberDelete" parameterType="int">
DELETE
FROM MEMBER_T
WHERE MEMBER_NO = #{memberNo}
</delete>
</mapper>
[MemberService.java]
package service;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public interface MemberService {
public void getMemberList(HttpServletResponse response) throws IOException;
public void memberAdd(HttpServletRequest request, HttpServletResponse response) throws IOException;
public void memberEmailCheck(HttpServletRequest request, HttpServletResponse response) throws IOException;
public void memberDetail(HttpServletRequest request,HttpServletResponse response)throws IOException;
public void memberModify(HttpServletRequest request,HttpServletResponse response)throws IOException;
public void memberDelete(HttpServletRequest request,HttpServletResponse response)throws IOException;
}
[MemberServiceImpl.java]
package service;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.json.JSONObject;
import domain.MemberDto;
import repository.MemberDao;
public class MemberServiceImpl implements MemberService {
private MemberDao dao = MemberDao.getDao();
@Override
public void getMemberList(HttpServletResponse response) throws IOException {
List<MemberDto> memberList = dao.memberList();
int memberCount = dao.memberCount();
JSONObject obj = new JSONObject(); // { }
obj.put("memberList", memberList); // {"memberList":[{}, {}, {}, ...]}
obj.put("memberCount", memberCount); // {"memberList":[{}, {}, {}, ...], "memberCount":5}
// -------------------------------------------------
// ↓
PrintWriter out = response.getWriter(); // ↓
out.println(obj.toString()); // $.ajax({success: function(resData){}})
// ↓ ↑
// └--------------------------------------------┘
out.flush();
out.close();
}
@Override
public void memberAdd(HttpServletRequest request, HttpServletResponse response) throws IOException {
MemberDto dto = MemberDto.builder()
.email(request.getParameter("email"))
.name(request.getParameter("name"))
.gender(request.getParameter("gender"))
.address(request.getParameter("address"))
.build();
int addResult = dao.memberAdd(dto);
JSONObject obj = new JSONObject(); // { }
obj.put("addResult", addResult); // {"addResult":1}
PrintWriter out = response.getWriter();
out.println(obj.toString());
out.flush();
out.close();
}
@Override
public void memberEmailCheck(HttpServletRequest request, HttpServletResponse response) throws IOException {
String email = request.getParameter("email");
MemberDto dto = dao.getMemberByEmail(email);
JSONObject obj = new JSONObject(); // { }
obj.put("ableEmail", dto == null); // {"ableEmail":true}
PrintWriter out = response.getWriter();
out.println(obj.toString());
out.flush();
out.close();
}
@Override
public void memberDetail(HttpServletRequest request, HttpServletResponse response) throws IOException {
String email = request.getParameter("email");
MemberDto dto = dao.getMemberByEmail(email);
JSONObject obj = new JSONObject(); // { }
obj.put("member", new JSONObject(dto)); // {"member":{"memberNo":1,...}}
PrintWriter out = response.getWriter();
out.println(obj.toString());
out.flush();
out.close();
}
@Override
public void memberModify(HttpServletRequest request, HttpServletResponse response) throws IOException {
MemberDto dto = MemberDto.builder()
.email(request.getParameter("email"))
.name(request.getParameter("name"))
.gender(request.getParameter("gender"))
.address(request.getParameter("address"))
.memberNo(Integer.parseInt(request.getParameter("memberNo")))
.build();
int modifyResult = dao.memberModify(dto);
JSONObject obj = new JSONObject(); // { }
obj.put("modifyResult", modifyResult); // {"modifyResult":1}
PrintWriter out = response.getWriter();
out.println(obj.toString());
out.flush();
out.close();
}
@Override
public void memberDelete(HttpServletRequest request, HttpServletResponse response) throws IOException {
int memberNo = Integer.parseInt(request.getParameter("memberNo"));
int deleteResult = dao.memberDelete(memberNo);
JSONObject obj = new JSONObject(); // { }
obj.put("deleteResult", deleteResult); // {"deleteResult":1}
PrintWriter out = response.getWriter();
out.println(obj.toString());
out.flush();
out.close();
}
}
