이클립스에서 DB 연결해보기
Data Source Explorer -> 버튼 클릭
MySQL 선택하기, MariaDB 가 없음
DB 추가하기
MySQL 5.1 버전 선택 후 MariaDB connector 넣기
Jar List 에서 기존에 있던 jar 은 제거하고 해당 링크의 jar 파일 넣기
Properties 에서 mysql, localhost 등 서버 주소 변경하기
연결까지 완료하면 하단의 Test Connection 해보기
쿼리 실행해보기, 우측 맨 끝 파란색 파일 모양 버튼 클릭
실행결과 보기, 실행은 우클릭 Execute All
Div 로 테이블 만들어보기, BootStrap 과 style 둘 다 넣어보기
기존의 <table> 로 작성한 테이블
<table class="text-center">
<thead>
<tr>
<th>번호</th>
<th>제목</th>
<th>작성자</th>
<th>작성일</th>
<th>IP</th>
<th>조회수</th>
</tr>
</thead>
<tbody>
<tr th:each="row : ${board}">
<td th:text="${row.mtno}">번호가나올곳</td>
<td><a th:href="@{/detail(no=${row.mtno})}" th:text="${row.mttitle}">제목이나올곳</a></td>
<td th:text="${row.mname}">작성자가나올곳</td>
<td th:text="${row.mtdate}">작성일이나올곳</td>
<td th:text="${row.mtip}">IP가나올곳</td>
<td th:text="${row.mtread}">조회수가나올곳</td>
</tr>
</tbody>
</table>
<div> 로 테이블 만들어보기, style="display" 가 부트스트랩 없이 style 적용하는 것
<div class="makeTable text-center">
<div class="table">
<div class="thead" style="display: table-row;">
<div class="col-1 th" style="display: table-cell">번호</div>
<div class="col-5 th" style="display: table-cell">제목</div>
<div class="col-2 th" style="display: table-cell">작성자</div>
<div class="col-2 th" style="display: table-cell">작성일</div>
<div class="col-1 th" style="display: table-cell">IP</div>
<div class="col-1 th" style="display: table-cell">조회수</div>
</div>
<div class="table tbody" th:each="row : ${board}" style="display: table-row;">
<div class="col-1 td" th:text="${row.mtno}" style="display: table-cell">번호내용</div>
<div class="col-5 text-start td" th:text="${row.mttitle}" style="display: table-cell">제목내용</div>
<div class="col-2 td" th:text="${row.mname}" style="display: table-cell">작성자내용</div>
<div class="col-2 td" th:text="${row.mtdate}" style="display: table-cell">작성일내용</div>
<div class="col-1 td" th:text="${row.mtip}" style="display: table-cell">IP내용</div>
<div class="col-1 td" th:text="${row.mtread}" style="display: table-cell">조회수내용</div>
</div>
</div>
</div>
카테고리 별로 게시글 다른 것 출력해보기
parameter 로 받아도되고, dto 만들어서 한꺼번에도 해보기
일단 카테고리 중 1번 카테고리 출력
@GetMapping("/board")
public String freeboard(UrlDTO urlDTO, Model model) {
if (urlDTO.getCate() == null) {
urlDTO.setCate("1");
}
List<BoardDTO> board = indexService.board(urlDTO);
model.addAttribute("board", board);
model.addAttribute("boardName", "자유게시판");
return "board";
}
2번 카테고리 출력
@GetMapping("/notice")
public String notice(UrlDTO urlDTO, Model model) {
if (urlDTO.getCate() == null) {
urlDTO.setCate("2");
}
List<BoardDTO> board = indexService.board(urlDTO);
model.addAttribute("board", board);
model.addAttribute("boardName", "공지사항");
return "board";
}
UrlDTO 는 이렇게 만들었음
지금은 카테고리만 받고 있지만 나중에는 검색, 페이지, 삭제 여부 등 url 에 들어갈 것이 많아 미리 만듦
@Getter
@Setter
public class UrlDTO {
private String cate, page, mtdel, boardName;
}
고민해야할 것
- dto 는 default 값을 어떻게 할까
- boardName 을 어떻게 띄우는 것이 좋을까
- page 어떻게 만드는게 좋을까
- 등등 부족한 것은 많은 것 같은데 생각이 잘 안남
게시판 이름도 직접 넣어보기, 게시판 이름이 들어간 테이블 만들기
-- 이건 내가 그냥 해보는 거
DB 에서 테이블 명을 받아와 model 에 add 하기 - 이렇게 하면 같은 html 로 여러 페이지를 띄울 수 있음
==> 아직 DB 에 못만듬 만들 게시판들을 5개 정도 추려서 해보기
지금은 Controller 에서 직접 하드코딩으로 add 하고 있음
model.addAttribute("boardName", "공지사항");
출력하기
<title th:text="${boardName}">타이틀넣는곳</title>
<h1 th:text="${boardName}">게시판 이름</h1>
게시판의 글이 있으면 출력, 없으면 없다는 멘트 띄우기
게시글 사이즈 보는 법
<span th:text="${#lists.size(board)}"></span> // 숫자 return
타임리프 if-else 문법
if 와 unless 의 조건은 같은 것으로 설정
<div th:if="${#lists.size(board) eq 0 }">
<h2>출력 값 없음</h2>
</div>
<div th:unless="${#lists.size(board) eq 0 }">
<h2>출력 값 있음</h2>
</div>
글쓰기 버튼 만들어보기
--- mtcate 가져오기
---- 글이 없다면 ? -- param 으로 받기 -- param 도 없다면 ?
글 받아보기, Map 사용
@PostMapping("/write")
public String write(@RequestParam Map<String, Object> map) {
System.out.println(map);
return "redirect:/board?cate=1";
}
로그인 해보기
로그인 페이지 만들기, 간단하게만 만들기
<form action="/login" method="post">
<input class="form-control" type="text" name="id" />
<input class="form-control" type="password" name="pw" />
<button class="btn btn-dark" type="submit">로그인</button>
</form>
새로운 MemberController 생성해서 쭉 이어보기, Service, DAO, Mapper
==> 로그인 하면 세션을 받아와 세션에 값 넣기
// Controller
@PostMapping("/login")
public String login(@RequestParam Map<String, Object> map) {
Map<String, Object> login = memberService.login(map);
if ((int) login.get("count") == 1) {
HttpSession session = util.getSession();
session.setAttribute("mid", login.get("mid"));
session.setAttribute("mname", login.get("mname"));
return "redirect:/board";
} else {
return "redirect:/login";
}
}
// Service
public Map<String, Object> login(Map<String, Object> map) {
return memberDAO.login(map);
}
// DAO, Interface
Map<String, Object> login(Map<String, Object> map);
Mapper
<select id="login" parameterType="Map" resultType="HashMap">
select count(*) as count , mno, mid, mname
from member
where mid = #{id} and mpw = HEX(AES_ENCRYPT(#{pw}, #{id}))
</select>
여기서 if 문장 안에서 오류 발생
Object 를 바로 (int) 로 캐스팅 하지말고, String -> int 로 바꾸기
Integer.valueOf((String) login.get("count"));
아니면 Util 에 int 로 변환할 수 있게 추가하기
public int str2Int2(String str) {
return Integer.parseInt(str.replaceAll("[^0-9]", ""));
}
public int str2Int2(Object obj) {
return str2Int2(String.valueOf(obj));
}
==>
util.str2Int2(login.get("count")) == 1
menu.html 에 로그인 한 것과 로그인 안된 상태 if 문 넣기
jsp 에서는 sessionScope 를 사용했는데, 여기서는 session 을 사용
<th:block th:if="${session.mid eq null}">
<li class="nav-item"><a class="nav-link me-lg-3" href="./login">/login</a></li>
</th:block>
<th:block th:unless="${session.mid eq null}">
<li class="nav-item"><a class="nav-link me-lg-3" href="./myInfo" th:text="|${session.mname} 님|">닉네임 님</a></li>
<li class="nav-item"><a class="nav-link me-lg-3" href="./logout">/logout</a></li>
</th:block>
Logout 넣기
@GetMapping("/logout")
public String logout() {
HttpSession session = util.getSession();
if (session.getAttribute("mid") != null) {
session.removeAttribute("mid");
}
if (session.getAttribute("mname") != null) {
session.removeAttribute("mname");
}
session.invalidate();
return "redirect:/";
}
Test 해보기
정상 로그인 되는지 확인해보기
@Test
void contextLoads() {
Map<String, Object> map = new HashMap<String, Object>();
map.put("id", "test1");
map.put("pw", "654321");
Map<String, Object> result = memberService.login(map);
// Assertions.assertEquals(1L, result.get("count"));
assertEquals(1, Integer.valueOf(String.valueOf(result.get("count"))));
}
실행해보기
해서 초록색으로 뜨면 통과, 빨간색으로 뜨면 오류 발생한 것
김영한님 강의에서는 실제로는 하드코딩을 하지 않고 어떤 값이 들어가도 정상적으로 통과되는 것이 좋은 테스트 라고 하였음
글 삭제하기
detail.html 에 글 삭제하는 버튼 추가
<i class="bi bi-arrow-up" th:id="${detail.mtno}" onclick="update(this.id)"></i>
<i class="bi bi-arrow-down" th:id="${detail.mtno}" onclick="del(this.id)"></i>
스크립트 작성, 가상 form
function update(no){
Swal.fire({
title: "수정합니까?",
text: "해당 내용을 수정합니다.",
icon: "warning",
showCancelButton: true,
confirmButtonColor: "#3085d6",
cancelButtonColor: "#d33",
confirmButtonText: "수정"
}).then((result) => {
if (result.isConfirmed) {
// Swal.fire({ title: "수정을 선택했습니다.", text: "수정합니다.", icon: "success" });
}
});
}
function del(no){
Swal.fire({
title: "삭제합니까?",
text: "해당 내용을 삭제합니다. 복구가 불가능합니다.",
icon: "warning",
showCancelButton: true,
confirmButtonColor: "#3085d6",
cancelButtonColor: "#d33",
confirmButtonText: "삭제"
}).then((result) => {
if (result.isConfirmed) {
// Swal.fire({ title: "삭제를 선택했습니다.", text: "삭제합니다.", icon: "success" });
let form = document.createElement('form');
form.setAttribute('method', 'post');
form.setAttribute('action', '/postDel');
let input = document.createElement('input');
input.setAttribute('type', 'hidden');
input.setAttribute('name', 'no');
input.setAttribute('value', no);
form.appendChild(input);
document.body.appendChild(form);
form.submit();
}
});
Controller, Service, DAO, Mapper 타고 가서 Update 문 실행
@PostMapping("/postDel")
public String postDel(@RequestParam("no") String mtno) {
int result = indexService.postDel(mtno);
return "redirect:/board";
}
// Service
public int postDel(String mtno) {
return indexDAO.postDel(mtno);
}
// DAO, Interface
int postDel(String mtno);
Mapper
<update id="postDel" parameterType="String">
update multiboard set mtdel = '0'
where mtno = #{mtno}
</update>
페이징 만들기
https://chung-develop.tistory.com/17
'Spring' 카테고리의 다른 글
240312 스프링 부트 (0) | 2024.03.12 |
---|---|
240311 스프링 부트 (0) | 2024.03.11 |
240307 스프링 부트 (0) | 2024.03.07 |
240306 스프링 부트 (1) | 2024.03.06 |
240305 스프링 프로젝트 (4) | 2024.03.05 |