2024. 3. 9. 17:44ㆍ복습/전자정부-게시판만들기
프로젝트 만들기 > myweb
new>project>Spring Boot>Spring Starter Project
New Spring Starter Project Dependencies 추가
application.properties 설정
# DB
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
spring.datasource.url=jdbc:mariadb:
spring.datasource.username=
spring.datasource.password=
# mybatis
mybatis.type-aliases-package=com.myhand.web.dto
# 페이지 구동되면 아래 static 하위 폴더들이 먼저 실행 됨
mybatis.mapper-locations=static/mapper/*.xml
# 포트변경시
server.port=80
#session time out = 1800 ->30분
server.servlet.session.timeout=1800
build.gradle> dependencies 추가된 사항 확인
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:3.0.3'
implementation 'org.mariadb.jdbc:mariadb-java-client:3.0.8'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
runtimeOnly 'com.mysql:mysql-connector-j'
annotationProcessor 'org.projectlombok:lombok'
providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter-test:3.0.3'
}
controller 패키지, 클래스 생성
어노테이션 설정
package com.myhand.web.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class IndexController {
@GetMapping("/index")
public String index() {
return "index";
}
}
resources> templates >index.hrml 생성
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>나는 인덱스</title>
</head>
<body>
<h1>나는 인덱스입니다. </h1>
</body>
</html>
데이터 보내기
IndexController
@Controller
public class IndexController {
@GetMapping("/index")
public String index(Model model) {
model.addAttribute("test", "테스트 입니다.");
return "index";
}
}
'/index' 경로로 GET 요청이 들어오면 'index' 메소드가 호출되고, 이 메소드는 Model 객체를 매개변수로 받아 뷰(html)에 데이터 > "테스트 입니다." 라는 문자열을 'test'라는 이름으로 값을 추가한다.
'/index' URL로 들어오면 GET요청을 처리하는 메서드, Model 객체를 매개변수로 받아, 뷰에 데이터를 전달하는 역할이다.
'return "index";' 구문은 'index'라는 이름의 뷰를 찾아 응답으로 렌더링 하는 의미이다.
Thymeleaf를 사용하기 때문에 'src/main/resources/templates ' 디렉토리 아래 'index.html' 파일의 뷰를 열어준다.
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>나는 인덱스</title>
</head>
<body>
<h1>나는 인덱스입니다. </h1>
[[${test}]]<br>
</body>
</html>
localhost로 접근하면 나오는 페이지.
localhost/index로 접근하면 나오는 페이지
[[${test}]]의 또다른 방법으로 출력할 수 있다.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>나는 인덱스</title>
</head>
<body>
<h1>나는 인덱스입니다. </h1>
<th:block th:text="${test}"></th:block>
</body>
</html>
'th:text' 속성을 사용해서 test 변수의 값을 표시한다. > 테스트 입니다. 출력
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>나는 인덱스</title>
</head>
<body>
<h1>나는 인덱스입니다.</h1>
[[${test}]]
<br>
<th:block th:text="${test}"></th:block>
</body>
</html>
board 불러오기
IndexController
IndexService 생성해서 @Autowired로 연결
package com.myhand.web.controller;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import com.myhand.web.service.IndexService;
@Controller
public class IndexController {
@Autowired
private IndexService indexService;
@GetMapping("/index")
public String index(Model model) {
model.addAttribute("test", "테스트 입니다.");
List<Map<String, Object>> list = indexService.baordList();
model.addAttribute("list", list);
return "index";
}
}
IndexService와 연결
@Autowired
private IndexService indexService;
게시판 목록 가져와서 뷰(html)로 반환
@GetMapping("/index")
public String index(Model model) {
model.addAttribute("test", "테스트 입니다.");
List<Map<String, Object>> list = indexService.baordList();//게시판 목록을 가져온다.
model.addAttribute("list", list);//가져온 목록을 모델에 추가
return "index"; //뷰 이름을 반환
}
com.myhand.web.service 패키지 생성, IndexService 클래스 생성
어노테이션 설정
package com.myhand.web.service;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.myhand.web.dao.IndexDAO;
@Service
public class IndexService {
@Autowired
private IndexDAO indexDAO;
public List<Map<String, Object>> baordList() {
return indexDAO.boardList();
}
}
> IndexDAO 생성해서 indexDAO.boardList로 연결
com.myhand.web.dao 패키지 생성, IndexDAO 인터페이스 생성
어노테이션 설정 > 매퍼까지 함께 설정
package com.myhand.web.dao;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
@Repository
@Mapper
public interface IndexDAO {
List<Map<String, Object>> boardList();
}
static > mapper 폴더 생성 > new > other> myBatis XML Mapper >indexMapper 생성
mapper namespace 변경
<?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.myhand.web.dao.IndexDAO"></mapper>
쿼리문 삽입
<select id="boardList" resultType="Map">
SELECT board_no, board_title, board_write, board_date, board_count, comment
FROM boardview
LIMIT 0,10
</select>
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>나는 인덱스</title>
</head>
<body>
<h1>나는 인덱스입니다.</h1>
<table>
<thead>
<tr>
<th>번호</th>
<th>제목</th>
<th>글쓴이</th>
<th>날짜</th>
<th>조회수</th>
</tr>
</thead>
<tbody>
<tr th:each="row : ${list}">
<td th:text="${row.board_no}"></td>
<td th:text="${row.board_title}"></td>
<td th:text="${row.board_write}"></td>
<td th:text="${row.board_date}"></td>
<td th:text="${row.board_count}"></td>
</tr>
</tbody>
</table>
</body>
</html>
동적으로 데이터를 포함하는 테이블 만들기
<table> 태그: 테이블 정의
<thead>태그 : 테이블의 헤더 부분을 정의 >테이블의 컬럼명을 담고 있다.
<tbody>태그 : 테이블의 본문 부분을 정의 > 실제 데이터가 표시되는 영역
<tr th:each="row ${boardList}">~</tr> :boardList라는 이름의 객체 리스트를 순회하며 각 객체를 row라는 변수로 참조, model에 추가된 boardList 객체를 사용
이 테이블은 서버로부터 받은 boardList라는 리스트 객체를 화면에 표시합니다. boardList는 게시판의 글 목록을 담고 있는 객체의 리스트로, 각 객체는 게시글의 번호, 제목, 글쓴이, 날짜, 조회수 등의 정보를 가지고 있습니다. Thymeleaf의 th:each 지시어를 사용하여 이 리스트를 반복 처리하고, 각 게시글에 대한 정보를 테이블의 각 행에 표시합니다.
출력되는 index 페이지
성공!
multiboard 만들기
freeboard생성
>controller, service, dao, mapper 생성하기(dto 안쓰게 만들기>map사용)
IndexController > freebaord 생성
@GetMapping("/freeboard")
public String freeboard(Model model) {
List<Map<String, Object>> board = indexService.freeboard();
model.addAttribute("board", board);
return "freeboard";
}
IndexService > freeboard
public List<Map<String, Object>> freeboard() {
return indexDAO.freeboard();
}
IndexDAO
List<Map<String, Object>> freeboard();
indexMapper
<select id="freeboard" resultType="Map">
SELECT mtno, mttitle, mtcontent, mtdate, mtip, mtdel, mtread, mtcate, mno FROM multiboard
</select>
freeboard.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>나는 프리보드!!</title>
</head>
<body>
<h1>나는 프리보드임댜</h1>
<table>
<thead>
<tr>
<th>번호</th>
<th>제목</th>
<th>날짜</th>
<th>조회수</th>
</tr>
</thead>
<tbody>
<tr th:each="row : ${board}">
<td th:text="${row.mtno}"></td>
<td th:text="${row.mttitle}"></td>
<td th:text="${row.mtdate}"></td>
<td th:text="${row.mtread}"></td>
</tr>
</tbody>
</table>
</body>
</html>
부트스트랩 설정하기
https://startbootstrap.com/theme/new-age
사용하려는 부트스트랩 다운받아서 index 소스 코드 내 index.html에 넣기
나머지 파일들 저장하기
menu.html 만들기
상단에 thymeleaf 추가하기
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://thymeleaf.org">
index에 있는 <head> 부분 가져오기
>
<th:block th:fragment="head"> 으로 구역을 나눠서 다른 파일에서도 쓸 수 있게 해준다.
<th:block th:fragment="head">
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<meta name="description" content="" />
<meta name="author" content="" />
<title>New Age - Start Bootstrap Theme</title>
<link rel="icon" type="image/x-icon" href="assets/favicon.ico" />
<!-- Bootstrap icons-->
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.5.0/font/bootstrap-icons.css" rel="stylesheet" />
<!-- Google fonts-->
<link rel="preconnect" href="https://fonts.gstatic.com" />
<link href="https://fonts.googleapis.com/css2?family=Newsreader:ital,wght@0,600;1,600&display=swap" rel="stylesheet" />
<link href="https://fonts.googleapis.com/css2?family=Mulish:ital,wght@0,300;0,500;0,600;0,700;1,300;1,500;1,600;1,700&display=swap" rel="stylesheet" />
<link href="https://fonts.googleapis.com/css2?family=Kanit:ital,wght@0,400;1,400&display=swap" rel="stylesheet" />
<!-- Core theme CSS (includes Bootstrap)-->
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<link href="css/styles.css" rel="stylesheet" />
</th:block>
<th:block th:fragment="menu">
<th:block th:fragment="menu">
<nav class="navbar navbar-expand-lg navbar-light fixed-top shadow-sm" id="mainNav">
<div class="container px-5">
<a class="navbar-brand fw-bold" href="/">Start Bootstrap</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation">
Menu
<i class="bi-list"></i>
</button>
<div class="collapse navbar-collapse" id="navbarResponsive">
<ul class="navbar-nav ms-auto me-4 my-3 my-lg-0">
<li class="nav-item"><a class="nav-link me-lg-3" href="/freeboard?cate=1">freeboard</a></li>
<li class="nav-item"><a class="nav-link me-lg-3" href="/notice?cate=2">notice</a></li>
<li class="nav-item"><a class="nav-link me-lg-3" href="/notice?cate=3">notice</a></li>
<li class="nav-item"><a class="nav-link me-lg-3" href="/notice?cate=4">notice</a></li>
<th:block th:if="${session.mid ne null}">
<li class="nav-item"><a class="nav-link me-lg-3" href="/myInfo">[[${session.mname}]]님</a></li>
<li class="nav-item"><a class="nav-link me-lg-3" href="/logout">logout</a></li>
</th:block>
<th:block th:unless="${session.mid ne null}">
<li class="nav-item"><a class="nav-link me-lg-3" href="/login">login</a></li>
</th:block>
</ul>
</div>
</div>
</nav>
</th:block>
메뉴 전체 코드
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://thymeleaf.org">
<body>
<th:block th:fragment="head">
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<meta name="description" content="" />
<meta name="author" content="" />
<title>New Age - Start Bootstrap Theme</title>
<link rel="icon" type="image/x-icon" href="assets/favicon.ico" />
<!-- Bootstrap icons-->
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.5.0/font/bootstrap-icons.css" rel="stylesheet" />
<!-- Google fonts-->
<link rel="preconnect" href="https://fonts.gstatic.com" />
<link href="https://fonts.googleapis.com/css2?family=Newsreader:ital,wght@0,600;1,600&display=swap" rel="stylesheet" />
<link href="https://fonts.googleapis.com/css2?family=Mulish:ital,wght@0,300;0,500;0,600;0,700;1,300;1,500;1,600;1,700&display=swap" rel="stylesheet" />
<link href="https://fonts.googleapis.com/css2?family=Kanit:ital,wght@0,400;1,400&display=swap" rel="stylesheet" />
<!-- Core theme CSS (includes Bootstrap)-->
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<link href="css/styles.css" rel="stylesheet" />
</th:block>
<footer class="bg-black text-center py-5" th:fragment="footer">
<div class="container px-5">
<div class="text-white-50 small">
<div class="mb-2">© Your Website 2023. All Rights Reserved.</div>
<a href="#!">Privacy</a>
<span class="mx-1">·</span>
<a href="#!">Terms</a>
<span class="mx-1">·</span>
<a href="#!">FAQ</a>
</div>
</div>
</footer>
<th:block th:fragment="menu">
<nav class="navbar navbar-expand-lg navbar-light fixed-top shadow-sm" id="mainNav">
<div class="container px-5">
<a class="navbar-brand fw-bold" href="/">Start Bootstrap</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation">
Menu
<i class="bi-list"></i>
</button>
<div class="collapse navbar-collapse" id="navbarResponsive">
<ul class="navbar-nav ms-auto me-4 my-3 my-lg-0">
<li class="nav-item"><a class="nav-link me-lg-3" href="/freeboard?cate=1">freeboard</a></li>
<li class="nav-item"><a class="nav-link me-lg-3" href="/notice?cate=2">notice</a></li>
<li class="nav-item"><a class="nav-link me-lg-3" href="/notice?cate=3">notice</a></li>
<li class="nav-item"><a class="nav-link me-lg-3" href="/notice?cate=4">notice</a></li>
<th:block th:if="${session.mid ne null}">
<li class="nav-item"><a class="nav-link me-lg-3" href="/myInfo">[[${session.mname}]]님</a></li>
<li class="nav-item"><a class="nav-link me-lg-3" href="/logout">logout</a></li>
</th:block>
<th:block th:unless="${session.mid ne null}">
<li class="nav-item"><a class="nav-link me-lg-3" href="/login">login</a></li>
</th:block>
</ul>
</div>
</div>
</nav>
</th:block>
</body>
</html>
index.html 변경 부분
상단에 추가
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://thymeleaf.org">
<head>에 추가
<head>
<th:block th:insert="~{menu.html :: head}"></th:block>
</head>
<!-- Navigation--> 부분 메뉴 추가
<!-- Navigation-->
<th:block th:insert="~{menu.html :: menu}"></th:block>
freeboard 부트스트랩 설정하기
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://thymeleaf.org">
<head>
<th:block th:insert="~{menu.html :: head}"></th:block>
</head>
<body id="page-top">
<!-- Navigation-->
<th:block th:insert="~{menu.html :: menu}"></th:block>
<!-- Mashead header-->
<!-- Quote/testimonial aside-->
<aside class="text-center">
<div class="container px-5">
<span>[[${#lists.size(board)} ]]개 글이 있습니다.</span>
<div th:if="${#lists.size(board) le 0}">
<h2>출력할 데이터가 없습니다 </h2>
<h3>관리자에게 문의하세요.</h3>
</div>
<div th:unless="${#lists.size(board) lt 0}">
<div class="table table-hover">
<div class="row" th:each="row : ${board }">
<div class="col-1" th:text="${row.mtno }"></div>
<div class="col-5 text-start" th:onclick="|location.href='@{/detail(no=${row.mtno})}'|">[[${row.mttitle }]]</div>
<div class="col-3" th:text="${row.mname }"></div>
<div class="col-2" th:text="${row.mtdate }"></div>
<div class="col-1" th:text="${row.mtread }"></div>
</div>
</div>
<button type="button" th:with="cate=${board[0].mtcate}"
class="btn btn-primary" th:onclick="|location.href='@{/write(cate=${cate})}'|">글쓰기</button>
</div>
</div>
</div>
</aside>
<!-- App features section-->
<!-- Footer-->
<th:block th:insert="~{menu.html :: footer}"></th:block>
<!-- Feedback Modal-->
</body>
</html>
다음엔 멀티보드 연결해서 글쓰기까지 가져오기
<div class="col-5 text-start"
th:onclick="|location.href='@{/detail(no=${row.mtno})}'|">[[${row.mttitle }]]</div>
이렇게 detail로 연결하면
mtno가 찍힌다.
'복습 > 전자정부-게시판만들기' 카테고리의 다른 글
202040312 전자전부 복습(상세보기(detail) (0) | 2024.03.11 |
---|