일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- db
- Eclipse
- SpringBoot
- mysql
- spring
- html
- Controller
- 배열
- Database
- Java
- JDBC
- 상속
- Board
- jsp
- View
- Thymeleaf
- Oracle
- Scanner
- rpa
- API
- jquery
- MVC
- 조건문
- string
- git
- 이클립스
- Uipath
- React
- 문자열
- Array
- Today
- Total
유정잉
61~64일차 스프링 [ xml로 Board 만들기 ] 본문
1) Dynamic project 생성 -> Configure -> Convert to Maven
2) 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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>kr.board</groupId>
<artifactId>controller</artifactId>
<name>Test</name>
<packaging>war</packaging>
<version>1.0.0-BUILD-SNAPSHOT</version>
<properties>
<java-version>1.6</java-version>
<org.springframework-version>5.0.2.RELEASE</org.springframework-version>
<org.aspectj-version>1.6.10</org.aspectj-version>
<org.slf4j-version>1.6.6</org.slf4j-version>
</properties>
<dependencies>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework-version}</version>
<exclusions>
<!-- Exclude Commons Logging in favor of SLF4j -->
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<!-- AspectJ -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${org.aspectj-version}</version>
</dependency>
<!-- Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${org.slf4j-version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${org.slf4j-version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${org.slf4j-version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.15</version>
<exclusions>
<exclusion>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
</exclusion>
<exclusion>
<groupId>javax.jms</groupId>
<artifactId>jms</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jdmk</groupId>
<artifactId>jmxtools</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jmx</groupId>
<artifactId>jmxri</artifactId>
</exclusion>
</exclusions>
<scope>runtime</scope>
</dependency>
<!-- @Inject -->
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
<!-- Servlet 변경 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.8</version>
</dependency>
<!-- Test -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.9</version>
<configuration>
<additionalProjectnatures>
<projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
</additionalProjectnatures>
<additionalBuildcommands>
<buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand>
</additionalBuildcommands>
<downloadSources>true</downloadSources>
<downloadJavadocs>true</downloadJavadocs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<compilerArgument>-Xlint:all</compilerArgument>
<showWarnings>true</showWarnings>
<showDeprecation>true</showDeprecation>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<configuration>
<mainClass>org.test.int1.Main</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
3) src/main/webapp/WEB-INF -> web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Processes application requests -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
4) src/main/webapp/WEB-INF -> spring 폴더 생성 -> appServlet 폴더 생성 -> servlet-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<!-- Enables the Spring MVC @Controller programming model -->
<annotation-driven />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<context:component-scan base-package="kr.bit.controller" />
</beans:beans>
5) src/main/webapp/WEB-INF -> spring 폴더 -> root-context.xml 기본 셋팅 -> DB 연결 셋팅
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mybatis-spring="http://mybatis.org/schema/mybatis-spring"
xsi:schemaLocation="http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring-1.2.xsd
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/yujung?serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="00000000"/>
</bean>
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource"
destroy-method="close">
<constructor-arg ref="hikariConfig" />
</bean>
<mybatis-spring:scan base-package="kr.bit.mapper"/>
<bean class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
</bean>
</beans>
6) src/main/webapp/WEB-INF -> views 폴더 -> home.jsp
7) src/main/java -> kr.bit.entity package 생성 -> Board.java class 생성 (이제부턴 Beans 대신 Entity 사용)
@Data 어노테이션을 이용하면 Getter&Setter, toString ... 생략 가능 / 또한 lombok을 사용했기 때문에 Date 대신 String 사용
package kr.bit.entity;
import lombok.Data;
@Data //- Lombok API
public class Board {
public int idx; // 번호
public String title; // 제목
public String content; // 내용
public String writer; // 작성자
public String indate; // 작성일
public int count; // 조회수
// setter , getter
}
8) src/main/java -> kr.bit.mapper package 생성 -> BoardMapper.java Interface 생성, BoardMapper.xml xml 생성
<?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" >
9) src/main/java -> kr.bit.controller package 생성 -> BoardController.java class 생성
객체 타입 Cotroller 리턴 반환
(서버 쪽에서 .getList()함수 호출 해서 boardMapper DB에 있는 데이터 싹다 뽑아서 list에 전달&저장 하겠단 의미)
package kr.bit.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import kr.bit.entity.Board;
import kr.bit.mapper.BoardMapper;
@Controller
public class BoardController{
@Autowired
BoardMapper boardMapper;
@RequestMapping("/")
public String home() {
return "home";
}
@RequestMapping("/boardList")
public @ResponseBody List<Board> boardList(){
List<Board> list=boardMapper.getLists();
return list;
}
@RequestMapping("/boardInsert")
public @ResponseBody void boardInsert(Board vo){
boardMapper.boardInsert(vo);
}
@RequestMapping("/boardDelete")
public @ResponseBody void boardDelete(@RequestParam("idx") int idx) {
boardMapper.boardDelete(idx);
}
}
10) MySQL bitboard table 생성
use yujung;
create table bitboard(
idx int not null auto_increment,
title varchar(50) not null,
content varchar(100) not null,
writer varchar(20) not null,
indate datetime default now(), -- 작성날자
count int default 0, -- 조회수
primary key(idx));
desc bitboard;
insert into bitboard(title, content, writer)
values ('제목1','내용1','홍길동');
insert into bitboard(title, content, writer)
values ('제목2','내용2','이길동');
insert into bitboard(title, content, writer)
values ('제목3','내용3','김길동');
11) xml을 활용해서 하는 프로젝트이기 때문에 Dao, Service 대신 -> BoardMapper.java와 BoardMapper.xml 사용
메서드 이름과 xml의 id 이름이 같아야지만 쿼리문이 실행 됨 !!!
(BoardMapper.xml에서 쿼리문을 작성해도 되고 BoardMapper에서 @어노테이션을 줘서 작성해도 됨 ! 둘다 상괸 없음)
package kr.bit.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Update;
import kr.bit.entity.Board;
@Mapper // Mybatis API
public interface BoardMapper {
public List<Board> getLists();
public void boardInsert(Board vo);
public Board boardContent(int idx);
public void boardDelete(int idx);
public void boardUpdate(Board vo);
@Update("UPDATE bitboard SET count=count+1 WHERE idx=#{idx}")
public void boardCount(int idx);
}
12) BoardMapper.xml에 namespacce 값을 적어줘야지만 연동이 됨
<mapper namespace="kr.bit.mapper.BoardMapper">
메서드 이름과 xml의 id 이름이 같아야지만 쿼리문이 실행 됨 !!!
select는 resultType 값이 있어야 됨, insert&delete&update는 parameterType 값이 있어야 함
(이때 delete는 기본형만 적음, 나머지는 패키지명이랑 클래스명까지 다 적어줌)
즉, BoardMapper.java에서 getLists() 함수 호출을 하면 BoardMapper.xml에 id="getLists"의 쿼리문이 실행 됨
<?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="kr.bit.mapper.BoardMapper">
<select id="getLists" resultType="kr.bit.entity.Board">
SELECT * FROM bitboard ORDER BY idx DESC
</select>
<insert id="boardInsert" parameterType="kr.bit.entity.Board">
INSERT INTO bitboard(title, content, writer) VALUES(#{title}, #{content}, #{writer})
</insert>
<select id="boardContent" resultType="kr.bit.entity.Board">
SELECT * FROM bitboard WHERE idx=#{idx}
</select>
<delete id="boardDelete" parameterType="int">
DELETE FROM bitboard WHERE idx=#{idx}
</delete>
<update id="boardUpdate" parameterType="kr.bit.entity.Board">
UPDATE bitboard SET title=#{title}, content=#{content} WHERE idx=#{idx}
</update>
</mapper>
13) views 폴더 안에 home.jsp 파일 -> c코어 , bootstrap 사용 / <head></head>에 <script>작성 $(document) $.ajax({})
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script
src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
loadBoard();
});
function loadBoard(){
$.ajax({
url : "boardList",
type : "get",
dataType : "json",
success : make,
error : function(){ alert("error"); }
});
}
function make(data){
var li="<table class='table table-bordered'>";
li+="<tr>";
li+="<td>번호</td>";
li+="<td>제목</td>";
li+="<td>작성자</td>";
li+="<td>작성일</td>";
li+="<td>조회수</td>";
li+="</tr>";
$.each(data, function(index,obj){
li+="<tr>";
li+="<td>"+obj.idx+"</td>";
li+="<td id='tit"+obj.idx+"'><a href='javascript:goContent("+obj.idx+")'>"+obj.title+"</a></td>";
li+="<td>"+obj.writer+"</td>";
li+="<td>"+obj.indate.split(' ')[0]+"</td>";
li+="<td id='cnt"+obj.idx+"'>"+obj.count+"</td>";
li+="</tr>";
li+="<tr id='con"+obj.idx+"' style='display:none'>";
li+="<td>내용</td>";
li+="<td colspan='4'>";
li+="<textarea id='ta"+obj.idx+"' readonly rows='7' class='form-control'></textarea>";
li+="<br/>";
li+="<span id='up"+obj.idx+"'><button class='btn btn-success btn-sm' onclick='goUpdateForm("+obj.idx+")'>수정화면</button></span> ";
li+="<button class='btn btn-danger btn-sm' onclick='goDelete("+obj.idx+")'>삭제</button>";
li+="</td>";
li+="</tr>";
} );
li+="<tr>";
li+="<td colspan='5'>";
li+="<button class='btn btn-primary btn-sm' onclick='getForm()'>글작성</button>";
li+="</td>";
li+="</tr>";
li+="</table>";
$("#view").html(li);
$("#view").css("display","block");
$("#wfrom").css("display","none");
}
function getForm(){
$("#view").css("display","none"); //게시글 목록은 안 보임
$("#wfrom").css("display","block"); //글작성 폼은 보임
}
function goList(){
$("#view").css("display","block");
$("#wfrom").css("display","none");
}
</script>
</head>
<body>
<div class="container">
<h2>Spring Legacy</h2>
<div class="panel panel-default">
<div class="panel-heading">게시판</div>
<div class="panel-body" id="view">본문</div>
<div class="panel-body" id="wfrom">
<form id="frm">
<table class="table">
<tr>
<td>제목</td>
<td><input type="text" id="title" name="title" class="form-control"/></td>
</tr>
<tr>
<td>내용</td>
<td><textarea rows="7" class="form-control" id="content" name="content"></textarea> </td>
</tr>
<tr>
<td>글쓴이</td>
<td><input type="text" id="writer" name="writer" class="form-control"/></td>
</tr>
<tr>
<td colspan="2" align="center">
<button type="button" class="btn btn-success btn-sm" onclick="goInsert()">등록</button>
<button type="reset" class="btn btn-warning btn-sm" id="formclear">취소</button>
<button type="button" class="btn btn-info btn-sm" onclick="goList()">리스트</button>
</td>
</tr>
</table>
</form>
</div>
<div class="panel-footer">비트캠프</div>
</div>
</div>
</body>
</html>
14) home.jsp에서 수정누르면 제목부분 idx값 접근해서 글 수정할 수 있게 -> 제목은 계속 떠야함
작성일에 날짜만 나오도록 시간은 안 나오게 split
15)
[ Controller의 리턴 타입 ] - 대부분 String , 객체 타입
- String : jsp 파일의 경로와 파일 이름을 나타내기 위해서 사용
- void : 호출하는 URL과 동일한 이름의 jsp를 의미
- 객체 타입 : 주로 JSON 타입의 데이터를 만들어서 반환하는 용도 {"id":"yujung", "pw":1234}
- ResponseEntity 타입 : response할 때 Http헤더 정보와 내용을 가공하는 용도
[ @RequestBody, @ResponseBody ]
: 스프링 프레임워크에서 비동기 통신, API 통신을 구현하기 위해 @RequestBody, @ResponseBody를 사용할 수 있다.
@RequestBody : 클라이언트 -> 서버 요청 (json기반의 HTTP Body를 자바 객체로 변환)
@ResponseBody : 서버 -> 클라이언트 응답 (자바 객체를 json기반의 HTTP Body로 변환)
[ REST 방식 / Ajax ]
: 브라우저에서 순수 데이터만을 전달할 수 있음 => 서버는 클라이언트의 요청 결과를 xml, json형태로 전달하고,
브라우저에서는 이를 가공하여 사용자에게 보여주는 방식
Ex) 만약 하나의 페이지(jsp)에서 두가지 일을 처리해야 할 경우 게시판 리스트와 로그인을 출력하는 일
- 동기식 처리방식 : 1번일이 끝날때까지 기다린 후 2번일을 처리하는 방식(응답시간이 길어지며 화면이 바뀐다)
- 비동기식 처리방식 : 1번 일과는 상관없이 2번일을 처리하는 방식(응답시간이 빠르고, 화면전환이 없다)
=> 콜백함수를 만들어 처리하게 해야한다
[ 콜백함수 ]
: 클라이어트가 서버로 요청 후 서버에서 응답하는 데이터를 클라이언트에서 받아서 처리하는 함수
[ Ajax 동작 방식 ]
$.ajax(
type : "post" or "get",
url : "요청할 url",
data : { 서버로 전송할 데이터},
dataType : "서버에서 전송받을 데이터 형식",
success : function(서버로부터 데이터 받기){ // 정상 요청, 응답시 처리
},
error : function(오류정보) { // 오류 발생시 처리
}
);
[ REST - REpresentational State Transfer ]
: URI + 요청방식
'네이버 클라우드 부트캠프 > 복습 정리' 카테고리의 다른 글
72일차 리액트 [ 구조분해할당, spread연산자, props, 이벤트, state ] (1) | 2024.06.04 |
---|---|
71일차 리액트 [ node.js, Vite, react ] (0) | 2024.06.03 |
57일차 스프링 [ MVC - restcontroller, mybatis ] [ Board ] (2) | 2024.05.13 |
56일차 스프링 [ MVC - 어노테이션, 유효성, 인터셉터, DB 설정 ] (4) | 2024.05.10 |
55일차 스프링 [ MVC - session, properties, 유효성검사 ] (2) | 2024.05.09 |