
ํ์๊ฐ์ :
1. ํ์๊ฐ์ ๊ธฐ๋ฅ(C)
2. ๊ฐ์ ๋ ํ์ ๋ชฉ๋ก ๋ณด์ฌ์ฃผ๋ ๊ธฐ๋ฅ(R)
3. ํ์ ์ ๋ณด ์์ ํ๋ ๊ธฐ๋ฅ(U)
4. ํ์ ์ ๋ณด ์ญ์ ํ๋ ๊ธฐ๋ฅ(D)
Member ์๋ฐ ๋น์ ์์ฑํฉ๋๋ค.
@Data
public class Member {
private Integer id;
private String email;
private String password;
private String nickName;
private LocalDateTime inserted;
}
MemberController
@GetMapping("signup")
public void signup() {
}
@PostMapping("signup")
public String signup(Member member) {
service.signup(member);
return "redirect:/member/list";
}
@GetMapping("signup") : /signup ๊ฒฝ๋ก๋ก ์์ฒญ์ด ๋ค์ด์ค๋ฉด ํ์๊ฐ์
ํ์ด์ง๋ก ์ด๋ํฉ๋๋ค.@PostMapping("signup") : member๋ฅผ ๋งค๊ฐ๋ณ์๋ก ๋ฐ์ ์๋น์ค๋ฅผ ํตํด ํ์๊ฐ์
์ ์ฒ๋ฆฌํ๊ณ ๊ฐ์
์ด ์๋ฃ๋๋ฉด member/list ๊ฒฝ๋ก๋ก ๊ฐ์ ํ์ ๋ชฉ๋ก ํ์ด์ง(list.jsp)๋ก ๋ฆฌ๋ค์ด๋ ํธํฉ๋๋ค. MemberService
public void signup(Member member) {
mapper.insert(member);
}
MemberMapper
@Insert("""
INSERT INTO member (email, password, nick_name) VALUES (#{email}, #{password}, #{nickName})
""")
void insert(Member member);
โ๏ธ ๋ชจ๋ ๊ฒ์๊ธ์ ๋ณด์ฌ์ฃผ๋ ๊ธฐ๋ฅ
MemberController
@GetMapping("list")
public String list(Member member, Model model) {
model.addAttribute("memberList", service.list());
return "member/list";
}
MemberService
public List<Member> list() {
return mapper.selectAll();
}
MemberMapper
@Select("SELECT * FROM member ORDER BY id DESC ")
List<Member> selectAll();
โ๏ธ ํน์ id๋ฅผ ๋ฐ์ ๋ณด์ฌ์ฃผ๋ ๊ธฐ๋ฅ
MemberController
@GetMapping("")
public String view(Integer id, Model model) {
model.addAttribute("member", service.get(id));
return "member/info";
}
member/info ๊ฒฝ๋ก์ธ ํ์ ์ ๋ณด๋ฅผ ๋ณด์ฌ์ฃผ๋ ํ์ด์ง(info.jsp)๋ก ์ด๋ํฉ๋๋ค.MemberService
public Member get(Integer id) {
return mapper.selectById(id);
}
MemberMapper
@Select("SELECT * FROM member WHERE id = #{id}")
Member selectById(Integer id);
MemberController
// ์ฒ์์ ์์ ํด๋ฆญ ์ member/modify?id=?๋ก
@GetMapping("modify")
public String modify(Integer id, Model model) {
model.addAttribute("member", service.get(id));
return "member/modify";
}
// member/modify?id=?์์ ์์ ํด๋ฆญ ์ member/list๋ก ๋ฆฌ๋ค์ด๋ ํธ
@PostMapping("modify")
public String modifyPost(Member member, RedirectAttributes rttr) {
service.modify(member);
rttr.addAttribute("id", member.getId());
return "redirect:/member";
}
@GetMapping("modify") : /modify ๊ฒฝ๋ก๋ก Get ์์ฒญ์ด ๋ค์ด์ service์์ id๋ฅผ ๋ฐ์์ ํด๋น ํ์์ ์ ๋ณด๋ฅผ ๋ชจ๋ธ์ ์ถ๊ฐํ์ฌ member/modify ๊ฒฝ๋ก๋ก ๊ฐ์ ํ์ ์ ๋ณด ์์ ํ์ด์ง(modify.jsp)๋ก ์ด๋ํฉ๋๋ค.
@PostMapping("modify") : Post ์์ฒญ์ด ๋ค์ด์์ ๋ service์์ member๋ฅผ ๋งค๊ฐ๋ณ์๋ก ๋ฐ์ ํ์ ์ ๋ณด๋ฅผ ์์ ํ์ฌ ์์ ๋ ํ์์ id๋ฅผ getId()๋ก ๋ฐํํ์ฌ ๋ฆฌ๋ค์ด๋ ํธ ์ ํ๋ผ๋ฏธํฐ๋ก ์ถ๊ฐ๋ฉ๋๋ค. ๋ง์ง๋ง์ผ๋ก /member ๊ฒฝ๋ก๋ก ํด๋น ํ์์ ์์ ๋ ์ ๋ณด ํ์ด์ง๋ก ๋ฆฌ๋ค์ด๋ ํธํฉ๋๋ค.
MemberService
public Member get(Integer id) {
return mapper.selectById(id);
}
public void modify(Member member) {
mapper.update(member);
}
get(Integer id) : mapper๋ฅผ ํตํด ์ ๋ฌ๋ id์ ํด๋นํ๋ ํ์ ์ ๋ณด๋ฅผ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์กฐํํฉ๋๋ค.modify(Member member) : mapper๋ฅผ ํตํด ์ ๋ฌ๋ member ๊ฐ์ฒด์ ํ์ ์ ๋ณด๋ฅผ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์์ ํฉ๋๋ค.MemberMapper
@Select("SELECT * FROM member WHERE id = #{id}")
Member selectById(Integer id);
@Update("""
UPDATE member SET password = #{password}, nick_name = #{nickName} WHERE id = #{id}
""")
int update(Member member);
selectById(Integer id) : ํ์์ id๋ฅผ ์กฐํํ์ฌ ํด๋น ํ์๋ง ์กฐํํ๊ธฐ ์ํด์ @Select ์ด๋
ธํ
์ด์
์ ์ฌ์ฉํฉ๋๋ค.update(Member member) : ํ์์ password, nick_name๋ง ๋ณ๊ฒฝํ๊ธฐ ์ํด์ @Update ์ด๋
ธํ
์ด์
์ ์ฌ์ฉํฉ๋๋ค.MemberController
@PostMapping("remove")
public String remove(Integer id) {
service.delete(id);
return "redirect:/member/list";
}
member/list ๊ฒฝ๋ก๋ก ๊ฐ์ ํ์ ๋ชฉ๋ก ํ์ด์ง(list.jsp)๋ก ๋ฆฌ๋ค์ด๋ ํธํฉ๋๋ค.MemberService
public void delete(Integer id) {
mapper.delete(id);
}
MemberMapper
@Delete("DELETE FROM member WHERE id = #{id}")
int delete(Integer id);
MemberController
@Controller
@RequiredArgsConstructor
@RequestMapping("member") // /member + (/view or /signup/delete)
public class MemberController {
private final MemberService service;
@GetMapping("signup")
public void signup() {
}
@PostMapping("signup")
public String signup(Member member) {
service.signup(member);
return "redirect:/member/list";
}
@GetMapping("list")
public String list(Member member, Model model) {
model.addAttribute("memberList", service.list());
return "member/list";
}
@GetMapping("")
public String view(Integer id, Model model) {
model.addAttribute("member", service.get(id));
return "member/info";
}
@PostMapping("remove")
public String remove(Integer id) {
service.delete(id);
return "redirect:/member/list";
}
// ์ฒ์์ ์์ ํด๋ฆญ ์ member/modify?id=?๋ก
@GetMapping("modify")
public String modify(Integer id, Model model) {
model.addAttribute("member", service.get(id));
return "member/modify";
}
// member/modify?id=?์์ ์์ ํด๋ฆญ ์ member/list๋ก ๋ฆฌ๋ค์ด๋ ํธ
@PostMapping("modify")
public String modifyPost(Member member, RedirectAttributes rttr) {
service.modify(member);
rttr.addAttribute("id", member.getId());
return "redirect:/member";
}
//์ด๋ฉ์ผ check
@GetMapping("email")
@ResponseBody
public String emailCheck(String email) {
String message = service.emailCheck(email);
return message;
}
}
MemberService
@Service
@RequiredArgsConstructor
@Transactional(rollbackFor = Exception.class)
public class MemberService {
private final MemberMapper mapper;
public void signup(Member member) {
mapper.insert(member);
}
public List<Member> list() {
return mapper.selectAll();
}
public Member get(Integer id) {
return mapper.selectById(id);
}
public void delete(Integer id) {
mapper.delete(id);
}
public void modify(Member member) {
mapper.update(member);
}
public String emailCheck(String email) {
Member member = mapper.selectByEmail(email);
if (member == null) {
//์ฌ์ฉ ๊ฐ๋ฅํ ์ด๋ฉ์ผ
return "์ฌ์ฉ ๊ฐ๋ฅํ ์ด๋ฉ์ผ์
๋๋ค.";
} else {
// ์ด๋ฏธ ์กด์ฌํ๋ ์ด๋ฉ์ผ
return "์ด๋ฏธ ์กด์ฌํ๋ ์ด๋ฉ์ผ์
๋๋ค.";
}
}
}
MemberMapper
@Mapper
public interface MemberMapper {
@Insert("""
INSERT INTO member (email, password, nick_name) VALUES (#{email}, #{password}, #{nickName})
""")
void insert(Member member);
@Select("SELECT * FROM member WHERE id = #{id}")
Member selectById(Integer id);
@Select("SELECT * FROM member ORDER BY id DESC ")
List<Member> selectAll();
@Delete("DELETE FROM member WHERE id = #{id}")
int delete(Integer id);
@Update("""
UPDATE member SET password = #{password}, nick_name = #{nickName} WHERE id = #{id}
""")
int update(Member member);
@Select("SELECT * FROM member WHERE email = #{email}")
Member selectByEmail(String email);
}
JSP
ํ์๊ฐ์ ํ๋ฉด(signup.jsp)
<c:import url="/WEB-INF/fragment/navbar.jsp"/>
<%--div.container>div.row.justify-content-center>div.col-6--%>
<div class="container" style="font-family: 'TTHakgyoansimUndongjangL'">
<div class="row justify-content-center">
<div class="col-8">
<h3 class="mb-4">ํ์ ๊ฐ์
</h3>
<form action="/member/signup" method="post" onsubmit="return checkValues()">
<%-- div*3>label.form-label+input.form-control--%>
<div class="mb-3">
<label for="emailInput" class="form-label">์ด๋ฉ์ผ</label>
<div class="input-group">
<input name="email" id="emailInput" required type="email" class="form-control"
placeholder="E-mail">
<button onclick="emailCheck();" type="button" id="btnEmailCheck"
class="btn btn-outline-secondary">์ค๋ณต ํ์ธ
</button>
</div>
<small class="form-text text-muted">์ด๋ฉ์ผ ์์์ ๋ง์ถฐ ์์ฑํด์ฃผ์ธ์</small>
</div>
<div class="mb-3">
<label for="pwdInput" class="form-label">ํจ์ค์๋</label>
<input oninput="passwordCheck()" name="password" id="pwdInput" required type="password"
class="form-control"
placeholder="password">
</div>
<div class="mb-3">
<label for="pwdCheckInput" class="form-label">ํจ์ค์๋ ํ์ธ</label>
<input oninput="passwordCheck()" id="pwdCheckInput" required type="password" class="form-control"
placeholder="password">
<div class="form-text" id="passwordMessage"></div>
</div>
<div class="mb-3">
<label for="nickInput" class="form-label">๋ณ๋ช
</label>
<input name="nickName" id="nickInput" required type="text" class="form-control"
placeholder="nick name">
</div>
<div>
<button class="btn btn-primary">๊ฐ์
</button>
</div>
</form>
</div>
</div>
</div>
<script>
async function emailCheck() {
const emailValue = document.querySelector("#emailInput").value;
const url = "/member/email?email=" + emailValue;
//ajax ์์ฒญ
const response = await fetch(encodeURI(url));
// ์๋ต์ฒ๋ฆฌ
// console.log(response.text());
alert(await response.text())
}
function passwordCheck() {
const password = document.querySelector("#pwdInput").value;
const passwordCheck = document.querySelector("#pwdCheckInput").value;
if (password != passwordCheck) {
//๋ฉ์์ง ๋ณด์ฌ์ฃผ๊ธฐ
document.querySelector("#passwordMessage").textContent = "ํจ์ค์๋๊ฐ ์ผ์นํ์ง ์์ต๋๋ค.";
} else {
document.querySelector("#passwordMessage").textContent = "";
}
}
function checkValues() {
const password = document.getElementById("pwdInput").value;
const passwordCheck = document.getElementById("pwdCheckInput").value;
if (password != "" && password == passwordCheck) {
return true;
} else {
alert("ํจ์ค์๋๊ฐ ์ผ์นํ์ง ์์ต๋๋ค.");
return false;
}
}
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.3/js/bootstrap.min.js"
integrity="sha512-ykZ1QQr0Jy/4ZkvKuqWn4iF3lqPZyij9iRv6sGqLRdTPkY69YX6+7wvVGmsdBbiIfN/8OdsI7HABjvEok6ZopQ=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
</body>
</html>
ํ์ ์ ๋ณด ๋ชฉ๋ก ํ๋ฉด(list.jsp)
<body>
<c:import url="/WEB-INF/fragment/navbar.jsp"/>
<%--div.container>div.row.justify-content-center>div.col-6--%>
<div class="container" style="font-family: 'TTHakgyoansimUndongjangL'">
<div class="row justify-content-center">
<div class="col-12 col-xl-6">
<h3 class="mb-4">ํ์ ๋ชฉ๋ก</h3>
<%-- table.table.table-striped>thead>tr>th*5--%>
<table class="table">
<thead>
<tr>
<th>NO</th>
<th>์ด๋ฉ์ผ</th>
<th>๋น๋ฐ๋ฒํธ</th>
<th>๋๋ค์</th>
<th>๊ฐ์
์ผ์</th>
</tr>
</thead>
<tbody class="table-group-divider">
<c:forEach items="${memberList}" var="member" varStatus="status">
<c:url value="/member" var="viewMember">
<c:param name="id" value="${member.id}"/>
</c:url>
<tr onclick="location.href='${viewMember}'">
<td style="color: blue">
${fn:length(memberList)-status.index}
</td>
<td>
${member.email}
</td>
<%--<a href="/member?id=${member.id}}">${member.id}</a>--%>
<td>${member.password}</td>
<td>${member.nickName}</td>
<td>${member.inserted}</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.3/js/bootstrap.min.js"
integrity="sha512-ykZ1QQr0Jy/4ZkvKuqWn4iF3lqPZyij9iRv6sGqLRdTPkY69YX6+7wvVGmsdBbiIfN/8OdsI7HABjvEok6ZopQ=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
</body>
</html>
ํ์ ์ ๋ณด ํ๋ฉด (info.jsp)
<body>
<c:import url="/WEB-INF/fragment/navbar.jsp"/>
<%--div.container>div.row.justify-content-center>div.col-6--%>
<div class="container" style="font-family: 'TTHakgyoansimUndongjangL'">
<div class="row justify-content-center">
<div class="col-8">
<h3 class="mb-4">ํ์ ์ ๋ณด ์กฐํ</h3>
<%-- div*3>label.form-label+input.form-control--%>
<div class="mb-3">
<label for="emailInput" class="form-label">์ด๋ฉ์ผ</label>
<input readonly name="email" id="emailInput" type="email" class="form-control"
placeholder="E-mail" value="${member.email}">
</div>
<div class="mb-3">
<label for="pwdInput" class="form-label">ํจ์ค์๋</label>
<input readonly name="password" id="pwdInput" required type="text"
class="form-control" value="${member.password}">
</div>
<div class="mb-3">
<label for="nickInput" class="form-label">๋ณ๋ช
</label>
<input readonly name="nickName" id="nickInput" required type="text"
class="form-control" value="${member.nickName}">
</div>
<div class="mb-3">
<label for="insertedInput" class="form-label">๊ฐ์
์ผ์</label>
<input readonly name="inserted" id="insertedInput" required type="text"
class="form-control" value="${member.inserted}">
</div>
<div>
<button class="btn btn-danger" form="formDelete">์ญ์ </button>
<a href="/member/modify?id=${member.id}" class="btn btn-primary">์์ </a>
</div>
</div>
</div>
</div>
<%--div.d-none>form>input:h[name=id]--%>
<div class="d-none">
<form action="/member/remove" id="formDelete" method="post" onsubmit="return confirm('ํํด ํ์๊ฒ ์ต๋๊น?')">
<input type="hidden" name="id" value="${member.id}">
</form>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.3/js/bootstrap.min.js"
integrity="sha512-ykZ1QQr0Jy/4ZkvKuqWn4iF3lqPZyij9iRv6sGqLRdTPkY69YX6+7wvVGmsdBbiIfN/8OdsI7HABjvEok6ZopQ=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
</body>
ํ์ ์ ๋ณด ์์ ํ๋ฉด(modify.jsp)
<body>
<c:import url="/WEB-INF/fragment/navbar.jsp"/>
<div class="container" style="font-family: 'TTHakgyoansimUndongjangL'">
<div class="row justify-content-center">
<div class="col-8">
<h3 class="mb-4">${member.id}๋ฒ ํ์ ์ ๋ณด</h3>
<form action="/member/modify" method="post"
">
<input type="hidden" name="id" value="${member.id}">
<div class="mb-4">
<small style="background-color: beige; color: gray">โ ์ด๋ฉ์ผ๊ณผ ๊ฐ์
์ผ์๋ ์์ ํ ์ ์์ต๋๋ค.</small>
</div>
<div class="mb-3">
<label for="emailInput" class="form-label">์ด๋ฉ์ผ</label>
<input id="emailInput" class="form-control" value="${member.email}" type="text"
aria-label="Disabled input example"
disabled>
</div>
<div class="mb-3">
<label for="pwdInput" class="form-label">ํจ์ค์๋</label>
<input name="password" id="pwdInput" required type="text"
class="form-control" value="${member.password}">
</div>
<div class="mb-3">
<label for="pwdCheckInput" class="form-label">ํจ์ค์๋ ํ์ธ</label>
<input oninput="pwdCheck()" id="pwdCheckInput" required type="text"
class="form-control" value="${member.password}">
<div class="form-text" id="checkMessage"></div>
</div>
<div class="mb-3">
<label for="nickInput" class="form-label">๋ณ๋ช
</label>
<input oninput="pwdCheck()" name="nickName" id="nickInput" required type="text"
class="form-control" value="${member.nickName}">
</div>
<div class="mb-3">
<label for="insertedInput" class="form-label">๊ฐ์
์ผ์</label>
<input readonly name="inserted" id="insertedInput" required type="text"
class="form-control" value="${member.inserted}" aria-label="Disabled input example"
disabled>
</div>
<div class="mb-3">
<button class="btn btn-secondary">์์ </button>
</div>
</form>
</div>
</div>
</div>
<script>
function pwdCheck() {
const pw = document.querySelector("#pwdInput").value;
const pwCheck = document.querySelector("#pwdCheckInput").value;
if (pw != pwCheck) {
document.querySelector("#checkMessage").textContent = "ํจ์ค์๋๊ฐ ์ผ์นํ์ง ์์ต๋๋ค."
} else {
document.querySelector("#checkMessage").textContent = ""
}
}
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.3/js/bootstrap.min.js"
integrity="sha512-ykZ1QQr0Jy/4ZkvKuqWn4iF3lqPZyij9iRv6sGqLRdTPkY69YX6+7wvVGmsdBbiIfN/8OdsI7HABjvEok6ZopQ=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
</body>
ํ์ ๊ฐ์
ํ๋ฉด

ํ์ ์ ๋ณด ๋ชฉ๋ก ํ๋ฉด

ํ์ ์ ๋ณด ํ๋ฉด

ํ์ ์ ๋ณด ์์ ํ๋ฉด
