반응형
1) 스프링 tool설치
2) 프로젝트생성
2-1) lombok적용
2-2) 기존패키지가져오기
2-3) application설정
2-4) siteMesh설정
3)board(스프링부트에 동작방식을 이해하려면 보길)
1) 스프링tool 설치
방법1)
이클립스의 marketplace에 들어가
springTools를 설치!!!!!!
방법2)
Spring | Tools
spring.io
해당사이트에 접속 후 다음과같이 클릭해 다운로드 후
압축을 풀어
해당이름과같은 파일을 실행시켜주면 끝
2) 프로젝트생성
의존성을 미리 추가
2-1 ) lombok적용
lombok.jar파일을 실행시켜보자
아마처음에는 springtool이 뜨지않을거다
specify location을 클릭해서 아까 실행시켰던 exe파일을 추가해준후
install/Update를 클릭해주자
2-2) 기존패키지가져오기
shop1프로젝트의 패키지들을 다 가져오자
(경로를 일일이 바꿔줘야함)
pom.xml설정
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.5.0</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>kr.gdu</groupId>
<artifactId>shop2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>shop2</name>
<description>Demo project for Spring Boot</description>
<url />
<licenses>
<license />
</licenses>
<developers>
<developer />
</developers>
<scm>
<connection />
<developerConnection />
<tag />
<url />
</scm>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web-services</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!--JSP사용을 위해 -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.14</version>
</dependency>
<dependency>
<groupId>jakarta.servlet.jsp.jstl</groupId>
<artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>jakarta.servlet.jsp.jstl</artifactId>
</dependency>
<dependency>
<groupId>org.sitemesh</groupId>
<artifactId>sitemesh</artifactId>
<version>3.2.0-M2</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>3.0.4</version>
</dependency>
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.5</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
2-3) application설정
스프링부트가 시작되는곳이라 생각하면됨
(기존방식처럼 componentScan을 사용해 패키지를 하나하나 써서 등록할필요X)
package kr.gdu;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import kr.gdu.sitemesh.SiteMeshFilter;
@SpringBootApplication
@ServletComponentScan //하위패키지모두를 scan대상으로 삼음
@EnableAspectJAutoProxy
public class Shop2Application {
public static void main(String[] args) {
SpringApplication.run(Shop2Application.class, args);
}
@Bean
public FilterRegistrationBean<SiteMeshFilter> siteMeshFilter(){
FilterRegistrationBean<SiteMeshFilter> filter =
new FilterRegistrationBean<>();
filter.setFilter(new SiteMeshFilter());
return filter;
}
}
2-4) sitemesh 설정
application쪽에 siteMeshFilter를 적용해놓은것을 확인할수있다
(모든페이지에 적용하겠다는 뜻이다)
다음과 같이 sitemesh로 지정할 페이지와,제외할경로를 입력해준다.
package kr.gdu.sitemesh;
import org.sitemesh.builder.SiteMeshFilterBuilder;
import org.sitemesh.config.ConfigurableSiteMeshFilter;
import jakarta.servlet.annotation.WebFilter;
@WebFilter("/*")
public class SiteMeshFilter extends ConfigurableSiteMeshFilter {
@Override
protected void applyCustomConfiguration(SiteMeshFilterBuilder builder) {
builder.addDecoratorPath("/*", "layout/gdulayout.jsp")
.addExcludedPath("/user/idSearch*")
.addExcludedPath("/user/pwSearch")
.addExcludedPath("/user/login")
.addExcludedPath("/user/join");
}
}
/WEB-INF/decorators/layout/gdulayout.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<sitemesh:write property="title" />
<sitemesh:write property="head" />
<sitemesh:write property="body" />
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title><sitemesh:title default="관리자 대시보드" /></title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap 5 -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
body {
overflow-x: hidden;
}
.sidebar {
width: 250px;
transition: all 0.3s ease;
position: fixed;
top: 56px;
bottom: 0;
left: 0;
background-color: #f8f9fa;
overflow-y: auto;
z-index: 1000;
}
.sidebar.collapsed {
width: 80px;
}
.main-content {
margin-left: 250px;
transition: all 0.3s ease;
padding: 1.5rem;
margin-top: 56px;
}
.main-content.collapsed {
margin-left: 80px;
}
.sidebar .list-group-item {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.footer {
text-align: center;
padding: 1rem;
border-top: 1px solid #dee2e6;
margin-top: 2rem;
}
</style>
<sitemesh:head />
</head>
<body>
<!-- 상단 네비게이션 -->
<nav class="navbar navbar-expand-lg navbar-dark bg-dark fixed-top">
<div class="container-fluid">
<button class="btn btn-outline-light me-2" id="toggleSidebar">☰</button>
<a class="navbar-brand" href="#">MyAdmin</a>
<div class="collapse navbar-collapse">
<ul class="navbar-nav ms-auto">
<li class="nav-item"><a class="nav-link" href="#">홈</a></li>
<li class="nav-item"><a class="nav-link" href="#">설정</a></li>
<li class="nav-item"><a class="nav-link" href="/user/logout">로그아웃</a></li>
</ul>
</div>
</div>
</nav>
<!-- 왼쪽 사이드바 -->
<div id="sidebar" class="sidebar border-end">
<div class="list-group list-group-flush mt-3">
<a href="/admin/dashboard" class="list-group-item list-group-item-action">📊 대시보드</a>
<a href="/admin/users" class="list-group-item list-group-item-action">👥 사용자 관리</a>
<a href="/board/list?boardid=1" class="list-group-item list-group-item-action">📌 공지사항</a>
<a href="/board/list?boardid=2" class="list-group-item list-group-item-action">💬 자유게시판</a>
<a href="/board/list?boardid=3" class="list-group-item list-group-item-action">❓ Q&A</a>
<a href="#" class="list-group-item list-group-item-action">⚙️ 설정</a>
</div>
</div>
<!-- 메인 콘텐츠 -->
<div id="mainContent" class="main-content">
<sitemesh:body />
</div>
<!-- 푸터 -->
<footer class="footer text-muted">
© 2025 MyAdmin. All rights reserved.
</footer>
<!-- JS -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script>
const toggleBtn = document.getElementById("toggleSidebar");
const sidebar = document.getElementById("sidebar");
const mainContent = document.getElementById("mainContent");
toggleBtn.addEventListener("click", () => {
sidebar.classList.toggle("collapsed");
mainContent.classList.toggle("collapsed");
});
</script>
</body>
</html>
3) Board
3-1)controller
package kr.gdu.controller;
import java.util.List;
import java.util.Map;
@Controller
@RequestMapping("board")
public class BoardController {
@Autowired
private BoardService service;
@GetMapping("*")
public ModelAndView write() {
ModelAndView mav = new ModelAndView();
mav.addObject(new Board());
return mav;
}
/* Spring에서 파라미터 전달 방식
* 1. 파라미터이름과 매개변수의 이름이 같은 경우 매핑
* 2. Bean 클래스의 프로퍼티명과 파라미터이름이 같은 경우 매핑
* 3. Map 객체에 RequestParam 어노테이션을 이용한 매핑
*
* @RequestParam : 파라미터값을 Map 객체에 매핑하여 전달
*/
@GetMapping("list")
public String list(@RequestParam Map<String,String> param,
HttpSession session,Model model) {
Integer pageNum = null;
for(String key : param.keySet()) {
if(param.get(key) == null || param.get(key).trim().equals("")) {
param.put(key, null);
}
}
if (param.get("pageNum") != null) {
pageNum = Integer.parseInt(param.get("pageNum"));
} else {
pageNum = 1;
}
String boardid = param.get("boardid");
String searchtype = param.get("searchtype");
String searchcontent = param.get("searchcontent");
String boardName = null;
switch(boardid) {
case "1" : boardName = "공지사항"; break;
case "2" : boardName = "자유게시판"; break;
case "3" : boardName = "QNA"; break;
default : boardName = "공지사항";
boardid = "1";
break;
}
//게시판 조회 처리
int limit = 10;
int listcount = service.boardcount(boardid,searchtype,searchcontent);
List<Board> boardlist = service.boardlist
(pageNum,limit,boardid,searchtype,searchcontent);
int maxpage = (int)((double)listcount/limit + 0.95);
int startpage = (int)((pageNum/10.0 + 0.9) - 1) * 10 + 1;
int endpage = startpage + 9;
if(endpage > maxpage) endpage = maxpage;
int boardno = listcount - (pageNum - 1) * limit;
model.addAttribute("boardid",boardid);
model.addAttribute("boardName",boardName);
model.addAttribute("pageNum",pageNum);
model.addAttribute("maxpage",maxpage);
model.addAttribute("startpage",startpage);
model.addAttribute("endpage",endpage);
model.addAttribute("listcount",listcount);
model.addAttribute("boardlist",boardlist);
model.addAttribute("boardno",boardno);
return "/board/list";
}
}
기존 스프링레거시 방식과 다르게 model을 이용해 속성등록을 진행했으며(request영역)
String(뷰페이지가 존재하는경로) 를 반환해 해당페이지로 이동!!!!
3-2) service
package kr.gdu.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import kr.gdu.dao.BoardDao;
import kr.gdu.logic.Board;
@Service
public class BoardService {
@Autowired
BoardDao boardDao;
public int boardcount(String boardid, String searchtype, String searchcontent) {
return boardDao.count(boardid,searchtype,searchcontent);
}
public List<Board> boardlist
(Integer pageNum, int limit, String boardid, String searchtype, String searchcontent) {
return boardDao.list(pageNum,limit,boardid,searchtype,searchcontent);
}
}
여기서 서비스계층이 뭔가 dao를 호출하는 용도로 사용했다
(솔직히말하면 컨트롤러는 주소만 반환해주는곳이고
서비스계층에서 무거운로직을 다루는게맞음 이건 이상한방식임)
3-3) Dao
package kr.gdu.dao;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import kr.gdu.dao.mapper.BoardMapper;
import kr.gdu.logic.Board;
@Repository
public class BoardDao {
@Autowired
private SqlSessionTemplate template;
private Class<BoardMapper> cls = BoardMapper.class;
private Map<String,Object> param = new HashMap<>();
public int count(String boardid, String searchtype, String searchcontent) {
param.clear();
param.put("boardid", boardid);
param.put("searchtype",searchtype);
param.put("searchcontent",searchcontent);
return template.getMapper(cls).count(param);
}
public List<Board> list (Integer pageNum, int limit,
String boardid, String searchtype, String searchcontent) {
param.clear();
param.put("startrow", (pageNum - 1) * limit);
param.put("limit", limit);
param.put("boardid", boardid);
param.put("searchtype",searchtype);
param.put("searchcontent",searchcontent);
return template.getMapper(cls).select(param);
}
}
dao도 솔직히 다른방법으로도 mapper를 호출가능함
다음과같이 map에 담아서 전달하는 방식이 아닌
그냥 설정 조금만 해준다면 객체를 넘기고 받는 방식이가능해짐
3-4) mapper
package kr.gdu.dao.mapper;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import kr.gdu.logic.Board;
@Mapper
public interface BoardMapper {
String select = "select num,writer,pass,title,content,file1 fileurl,"
+ " regdate, readcnt, grp, grplevel, grpstep, boardid from board";
@Select({"<script>",
"select count(*) from board where boardid=#{boardid} ",
"<if test='searchtype != null'> "
+ " and ${searchtype} like '%${searchcontent}%'</if>",
"</script>"})
int count(Map<String, Object> param);
@Select({"<script>",
select,
"<where>",
"<if test='num != null'> num = #{num} </if>",
"<if test='num == null and boardid != null'> boardid = #{boardid} </if>",
"<if test='searchtype != null'> and ${searchtype} like '%${searchcontent}%'</if>",
"</where>",
"<if test='limit != null and startrow != null'> "
+ " order by grp desc, grpstep asc limit #{startrow},#{limit}</if>",
"<if test='limit != null and startrow == null'> "
+ " order by grp desc, grpstep asc limit 0,#{limit}</if>",
"</script>"})
List<Board> select(Map<String, Object> param);
}
해당코드를 이용해 넘어온값을 사용해
DB를 조회해 값을 반환해줌!!!
'Spring' 카테고리의 다른 글
부트캠프87일차 (ajax) (2) | 2025.06.16 |
---|---|
부트캠프86일차 (interceptor) (1) | 2025.06.13 |
부트캠프84일차(주문관련 및 회원목록조회(관리자용)) (2) | 2025.06.10 |
부트캠프83일차(회원정보수정, idpw찾기 , 장바구니) (3) | 2025.06.09 |
부트캠프82-1일차 ( spring에서의 예외처리) (1) | 2025.06.07 |