Model - DataDto
Lombok 어노테이션 선언 후 DB table 안에 저장한 컬럼명과 똑같이 변수를 작성해준다.
@Data // Lombok 어노테이션(Getter/Setter)
public class DataDto {
private int m_code;
private String m_str;
private int m_int;
private String m_date;
}
View - jsp
- home.xml
각 페이지로 이동할 수 있는 메인페이지
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script src="https://code.jquery.com/jquery-3.6.1.min.js"
integrity="sha256-o88AwQnZB+VDvE9tvIXrMQaPlFFSUTR+nldQm1LuPXQ=" crossorigin="anonymous"></script>
</head>
<body>
<h1>데이터 관리자</h1>
<p>
<a href="inputFrm">[데이터 입력]</a>
<a href="dataList">[데이터 목록]</a>
</p>
<hr>
<p>${nowtime}</p>
</body>
<script>
let m = "${msg}";
if (m != "") {
alert(m);
}
</script>
</html>
- inputFrm.jsp
정보를 입력하는 페이지
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>입력 양식</title>
<script src="https://code.jquery.com/jquery-3.6.1.min.js"
integrity="sha256-o88AwQnZB+VDvE9tvIXrMQaPlFFSUTR+nldQm1LuPXQ=" crossorigin="anonymous"></script>
</head>
<body>
<h1>데이터 입력</h1>
<fieldset>
<legend>다음 데이터를 입력하세요.</legend>
<form action="inputProc">
<p>문자열 : <input type="text" name="m_str"></p>
<p>정수 : <input type="text" name="m_int"></p>
<p>날짜 : <input type="date" name="m_date"></p>
<input type="submit" value="전송">
</form>
</fieldset>
</body>
</html>
- dataList.jsp
입력한 정보 리스트를 한번에 볼 수 있는 페이지
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>데이터 목록</title>
<script src="https://code.jquery.com/jquery-3.6.1.min.js"
integrity="sha256-o88AwQnZB+VDvE9tvIXrMQaPlFFSUTR+nldQm1LuPXQ=" crossorigin="anonymous"></script>
</head>
<body>
<h1>데이터 목록</h1>
<table border="1">
<tr>
<th width="50">코드</th>
<th width="100">문자열</th>
<th width="80">정수</th>
<th width="100">날짜</th>
</tr>
<c:forEach var="d" items="${dList}">
<tr>
<!-- 링크와 전달할 파라미터를 구분하기 위해 ?를 사용 -->
<td><a href="detail?code=${d.m_code}">${d.m_code}</a></td>
<td>${d.m_str}</td>
<td>${d.m_int}</td>
<td>${d.m_date}</td>
</tr>
</c:forEach>
</table>
</body>
<script>
let m = "${msg}";
if (m != "") {
alert(m);
}
</script>
</html>
- detail.jsp
dataList 페이지에서 각 code를 눌렀을 때 해당 정보만 나타나는 페이지
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>상세보기</title>
<script src="https://code.jquery.com/jquery-3.6.1.min.js"
integrity="sha256-o88AwQnZB+VDvE9tvIXrMQaPlFFSUTR+nldQm1LuPXQ=" crossorigin="anonymous"></script>
</head>
<body>
<h1>데이터 상세보기</h1>
<table border="1">
<tr>
<th width="50">CODE</th>
<td width="150">${data.m_code}</td>
</tr>
<tr>
<th width="50">STR</th>
<td width="150">${data.m_str}</td>
</tr>
<tr>
<th width="50">INT</th>
<td width="150">${data.m_int}</td>
</tr>
<tr>
<th width="50">DATE</th>
<td width="150">${data.m_date}</td>
</tr>
<tr>
<td colspan="2">
<button id="ubtn">수정</button>
<button id="dbtn">삭제</button>
</td>
</tr>
</table>
</body>
<script>
const ub = document.getElementsByTagName("button");
ub[0].addEventListener("click", function () {
location.href = "updateFrm?code=${data.m_code}";
});
ub[1].addEventListener("click", function () {
let q = confirm("삭제합니까?");
if (q == true) {
location.href = "deleteProc?code=${data.m_code}";
}
});
let m = "${msg}";
if (m != "") {
alert(m);
}
</script>
</html>
- updateFrm.jsp
코드를 제외한 모든 정보를 수정할 수 있는 페이지
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>수정 양식</title>
<script src="https://code.jquery.com/jquery-3.6.1.min.js"
integrity="sha256-o88AwQnZB+VDvE9tvIXrMQaPlFFSUTR+nldQm1LuPXQ=" crossorigin="anonymous"></script>
</head>
<body>
<h1>데이터 수정</h1>
<fieldset>
<legend>다음 데이터를 입력하세요.</legend>
<form action="updateProc">
<p>코드 : <input type="text" name="m_code"
value="${data.m_code}" readonly></p>
<p>문자열 : <input type="text" name="m_str"
value="${data.m_str}"></p>
<p>정수 : <input type="text" name="m_int"
value="${data.m_int}"></p>
<p>날짜 : <input type="date" name="m_date"
value="${data.m_date}"></p>
<input type="submit" value="전송">
</form>
</fieldset>
</body>
</html>
Controller - DataDao
- DataDto.java
Dao 파일은 클래스가 아닌 인터페이스로 만들어준다.
@Mapper
public interface DataDao {
void insertData(DataDto data);
List<DataDto> selectList();
// 하나의 정보를 가져오는 메소드
DataDto selectData(int code);
// 데이터 수정용 메소드
void updateData(DataDto data);
// 데이터 삭제용 메소드
void deleteData(int code);
}
- resources/mappers/DataDao.xml
인터페이스로 만들어진 Dao의 DB 연결 내용은 Mybatis를 이용하여 이런 식으로 따로 코드를 짜게 된다.
<?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.jsframe.spr_jdbc02.dao.DataDao">
<insert id="insertData" parameterType="DataDto">
INSERT INTO datatbl
VALUES (null, #{m_str}, #{m_int}, #{m_date})
</insert>
<update id="updateData" parameterType="DataDto">
UPDATE datatbl
SET m_str=#{m_str}, m_int=#{m_int}, m_date=#{m_date}
WHERE m_code=#{m_code}
</update>
<delete id="deleteData" parameterType="Integer">
DELETE FROM datatbl WHERE m_code=#{code}
</delete>
<select id="selectList" resultType="DataDto">
SELECT * FROM datatbl
</select>
<select id="selectData" resultType="DataDto" parameterType="Integer">
SELECT * FROM datatbl WHERE m_code = #{code}
</select>
</mapper>
Controller - DataService
메소드별로 msg와 view 변수에 대해 값을 할당해주고, session과 rttr에 대한 매개변수도 처리해준다.
@Service
@Log
public class MemberService {
@Autowired
private MemberDao mDao;
// 비밀번호 암호화 및 확인 객체
private BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
// 회원가입 처리 메소드
public String regMember(MemberDto member, RedirectAttributes rttr) {
log.info("regMember()");
String msg = null;
String view = null;
// 비밀번호 암호화 처리
String cPwd = encoder.encode(member.getM_pwd());
log.info("암호화된 비밀번호 : " + cPwd);
log.info("비밀번호 길이 : " + cPwd.length());
member.setM_pwd(cPwd); // 암호화된 비밀번호로 변경
try {
mDao.insertMember(member);
msg = "가입 성공";
view = "redirect:/";
} catch (Exception e) {
// e.printStackTrace();
msg = "가입 실패";
view = "redirect:register";
}
rttr.addFlashAttribute("msg", msg);
return view;
}
// 로그인 처리 메소드
public String loginProc(MemberDto member, HttpSession session,
RedirectAttributes rttr) {
log.info("loginProc()");
String msg = null;
String view = null;
String cPwd = mDao.selectPwd(member.getM_id());
if(cPwd != null) { // 입력한 회원의 아이디가 있음
if(encoder.matches(member.getM_pwd(), cPwd)) {
member = mDao.selectMember(member.getM_id());
// 세션에 로그인 성공 정보 저장
session.setAttribute("mem", member);
msg = "로그인 성공";
view = "redirect:main";
} else { // 비밀번호가 맞지 않는 경우
msg = "비밀번호가 맞지 않습니다.";
view = "redirect:/";
}
} else { // 잘못된 아이디 입력
msg = "해당 아이디가 없습니다.";
view = "redirect:/";
}
rttr.addFlashAttribute("msg", msg);
return view;
}
public String updateMember(MemberDto member, HttpSession session,
RedirectAttributes rttr) {
// 회원 정보를 수정하고, 세션에 로그인 정보 변경
log.info("updateMember()");
String msg = null;
String view = null;
try {
mDao.updateMember(member);
// session.setAttribute를 해줄 때
// 기존 저장된 정보가 있다면 덮어쓰고, 없으면 새로 넣어줌
session.setAttribute("mem",
mDao.selectMember(member.getM_id()));
msg = "수정 성공";
view = "redirect:main";
} catch (Exception e) {
// e.printStackTrace();
msg = "수정 실패";
view = "redirect:main";
}
rttr.addFlashAttribute("msg", msg);
return view;
}
// 회원 삭제용 메소드 => 회원탈퇴와 로그아웃이 동시에 이뤄져야 함
public String resignMember(HttpSession session, RedirectAttributes rttr) {
log.info("resignMember()");
String msg = null;
String view = null;
// 세션에 저장된 로그인 정보로부터 사용자의 id를 가져옴
// 세션은 어느 것이든 다 받아내기 때문에 정확한 지정이 필요 => 앞에 명시해줌
MemberDto member = (MemberDto) session.getAttribute("mem");
String mid = member.getM_id();
try {
mDao.deleteMember(mid);
// 삭제 성공 후 로그아웃 처리
session.invalidate();
msg = "탈퇴 성공";
view = "redirect:/";
} catch (Exception e) {
// e.printStackTrace();
msg = "탈퇴 실패";
view = "redirect:main";
}
rttr.addFlashAttribute("msg", msg);
return view;
}
}
Controller - DataController
각 화면에 대해 MemberService 클래스의 메소드를 지정함으로써 동작을 할 수 있게 해준다.
@Controller
@Log
public class MemberController {
// Service 자동 처리
@Autowired
private MemberService mServ;
// url 매핑된 메소드
@GetMapping("/")
public String home() {
log.info("home()");
return "home";
}
@GetMapping("register")
public String register() {
log.info("register");
return "register";
}
@PostMapping("regProc")
public String regProc(MemberDto member, RedirectAttributes rttr) {
log.info("regProc()");
String view = mServ.regMember(member, rttr);
return view;
}
@PostMapping("loginProc")
public String loginProc(MemberDto member, HttpSession session,
RedirectAttributes rttr) {
log.info("loginProc()");
String view = mServ.loginProc(member, session, rttr);
return view;
}
@GetMapping("main")
public ModelAndView main() {
log.info("main()");
ModelAndView mv = new ModelAndView();
// 여기에 데이터를 담아줌
mv.setViewName("main");
return mv;
}
@GetMapping("logoutProc")
public String logoutProc(HttpSession session) {
log.info("logoutProc");
// session.removeAttribute("mem");
session.invalidate();
// 세션 제거 후 첫 페이지로
return "redirect:/";
}
@PostMapping("updateProc")
public String updateProc(MemberDto member, HttpSession session,
RedirectAttributes rttr) {
log.info("updateProc()");
String view = mServ.updateMember(member, session, rttr);
return view;
}
@GetMapping("resignProc")
public String resignProc(HttpSession session, RedirectAttributes rttr) {
log.info("resignProc()");
String view = mServ.resignMember(session, rttr);
return view;
}
}