일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- EC2
- vagrant
- DISTINCT
- SSL
- centos7
- 책 정리
- Git
- Linux
- Client
- AWS
- 코딩테스트
- spring
- window
- 프로그래머스
- ssh
- spring boot
- docker
- Jenkins
- Hibernate
- 토비의스프링
- sample
- Spring Legacy Project
- WebHook
- db
- TLS
- mariadb
- jdbc
- Java
- TypeScript
- github
- Today
- Total
Woopii Vyeolog
(Spring Legacy Project - MVC모델) JDBC Template을 써서 DB연동 본문
앞의 글들에서 나는 MVC모델의 영역을 하나씩 보면서 프로젝트를 만들었다.
1. Spring Legacy proejct생성 : https://woopi1087.tistory.com/26
2. Repository : https://woopi1087.tistory.com/23
3. Service : https://woopi1087.tistory.com/25
4. Controller : https://woopi1087.tistory.com/31
이번에는 전체 MVC모델로 간단한 성적관리 웹 페이지를 만들것이다.
그리고 JDBC Template을 사용하여 DB연동을 통해 DB서버에 있는 데이터를 가져올 것이다.
프로젝트를 시작하기에 앞서 DB서버가 구축이 돼 있어야 한다.
나는 virtual box 가상 머신에 ubuntu 리눅스 운영체제에서 DB서버를 구축했다.
(구축법 : https://woopi1087.tistory.com/2)
굳이 가상머신을 사용할 필요는 없고 윈도우에 mysql 깔아서 해도 된다.
DB서버도 구축이 되었다면 프로젝트를 만든다.
<전체 구성> (노란 네모 부분을 구성할 것이다.)
프로젝트 생성 및 설정
1. 프로젝트 생성
https://woopi1087.tistory.com/26
2. pom.xml 설정
DB에 연동하기 위해서 필요한 라이브러리를 가져올 것이다.
Mysql Connector와 JDBC Template이다.
<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>com.kopo</groupId>
<artifactId>exam_jdbc</artifactId>
<name>exam_jdbc</name>
<packaging>war</packaging>
<version>1.0.0-BUILD-SNAPSHOT</version>
<properties>
<java-version>1.8</java-version>
<org.springframework-version>5.0.7.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.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.4.3</version>
</dependency>
<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>
<!-- Spring JDBC 추가하기 -->
<!-- Spring JDBC template 가져오기 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<!-- mysql connector 가져오기 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.35</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>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- Test -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
<scope>test</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. web.xml 설정
한글 인코딩(UTF-8)설정을 위해서 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 https://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- 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>
<!-- 한글처리 : 인코딩을 UTF-8로 설정하여 필터링하겠다는 설정이다. -->
<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>
</web-app>
4. 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 https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--JDBC template로 DB다루기 -->
<!--DB연결에 대한 설정을 여기서 한다 -->
<!--jdbc로 연결할 때 메소드로 처리했던 부분이다. -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<!-- jdbc connector를 가져올 때 드라이버 가져오는 부분의 설정 -->
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<!-- 내 아이피와 사용하는 DB를 설정하는 부분 -->
<property name="url" value="jdbc:mysql://192.168.56.1:3306/kopo"></property>
<!-- mysql 아이디 설정하는 부분 -->
<property name="username" value="kopo15"></property>
<!-- mysql 비밀번호 설정하는 부분 -->
<property name="password" value="Qwer1234!!"></property>
</bean>
<!-- jsbc template에 대한 설정을 한다. -->
<!-- 위에 id로 설정한 datasource 연결한다는 의미를 가지고 있다. ref="dataSource" -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
</beans>
5. servlet-context.xml
Bean과 관련된 설정을 한다.
<?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="com.kopo.exam_jdbc" />
<!-- 내가 만을 Bean을 추가하는 곳이다. -->
<!-- 같은 디렉토리에 있기 때문에 적어주지 않더라도 읽어 올 수 있다. -->
<context:component-scan base-package="com.kopo.exam_jdbc.dao" />
<context:component-scan base-package="com.kopo.exam_jdbc.domain" />
<context:component-scan base-package="com.kopo.exam_jdbc.dto" />
<context:component-scan base-package="com.kopo.exam_jdbc.service" />
</beans:beans>
Repository
1. ExamRIO.java
DB에 들어가는 데이터 형식이다. DB테이블과 데이터 구조를 같게 만든다.
Service와 데이터를 주고 받을 때 해당 데이터 형식으로 주고 받는다.
<ExamRIO.java>
package com.kopo.exam_jdbc.domain;
public class ExamRIO {
//다룰 데이터 선언
//실제 DB에 있는 데이터와 동일 시 하는 것이 좋다.
private String name; //이름
private int studentid; //학번
private int kor; //국어성적
private int eng; //영어 성적
private int mat; //수학 성적
//constructor 선언 빈 생성자와 데이터가 같이 들어있는 생성자를 같이 만들어 준다.
public ExamRIO() {
super();
}
//해당 객체를 생성할 때 여기 5개의 데이터가 들어간다.
public ExamRIO(String name, int studentid, int kor, int eng, int mat) {
super();
this.name = name;
this.studentid = studentid;
this.kor = kor;
this.eng = eng;
this.mat = mat;
}
//getter, setter 메소드 생성 : 데이터를 불러오고 적용할 때 사용한다.
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getStudentid() {
return studentid;
}
public void setStudentid(int studentid) {
this.studentid = studentid;
}
public int getKor() {
return kor;
}
public void setKor(int kor) {
this.kor = kor;
}
public int getEng() {
return eng;
}
public void setEng(int eng) {
this.eng = eng;
}
public int getMat() {
return mat;
}
public void setMat(int mat) {
this.mat = mat;
}
}
2. ExamRepo.java
DB와 관련된 처리를 하는 Repository영역이다.
<ExamRepo.java>
package com.kopo.exam_jdbc.dao;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import com.kopo.exam_jdbc.domain.ExamRIO;
//해당 클래스가 Repository임을 선언함(annotation)
@Repository
public class ExamRepo {
//해당 클래스의 로그를 가져온다
private static final Logger logger = LoggerFactory.getLogger(ExamRepo.class);
//Jdbc Template을 사용하기 위해서 Autowired(자동으로 묶어라 라는 의미) 어노테이션을 써서
//이 변수(Jdbc Template)는 스프링 관련 특수변수라고 선언
@Autowired
private JdbcTemplate jdbcTemplate;
/**
* DB데이블을 생성하는 메소드
*/
public void createDB() throws Exception{
//메소드 불러올 때 로그를 남김
logger.info("Repo --- createDB");
//실행하고자 하는 query문을 적어서 문자열 변수에 담는다.
//sql : 이름 학번 각 점수의 데이터가 들어갈 테이블 생성(examtable)
String query = "create table examtable(" +
"name varchar(20)," +
"studentid int not null primary key," +
"kor int," +
"eng int," +
"mat int)" +
"DEFAULT CHARSET=utf8;";
//쿼리문을 실행한다(create는 execute)
//excute명령에서 직업 문자를 넣어도 되지만 그럼 더 복잡해 보여서
//sql문은 문자열 변수에 담고 실행을 변수로 하는 것이 훨씬 깔끔하다
jdbcTemplate.execute(query);
}
/**
* DB데이블을 삭제하는 메소드
*/
public void dropDB() throws Exception{
//메소드 불러올 때 로그를 남김
logger.info("Repo --- dropDB");
//실행하고자 하는 query문을 적고
//sql : 해당 테이블 삭제(examtable)
String query = "drop table examtable";
//쿼리문을 실행한다(drop은 execute).
jdbcTemplate.execute(query);
}
/**
* 데이터를 insert하는 메소드
* @param u : ExanRIO형의 데이터(DB에 삽입하고자 하는 데이터)
* @return int형인 status를 반환한다.(아마 성공 여부인듯 하다)
*/
public int insert(ExamRIO u) throws Exception{
//메소드 불러올 때 로그를 남김
logger.info("Repo --- insert");
//쿼리문을 적고 실행하고 리턴한다.(insert는 update)
//sql : 이름 학번 각 점수를 examtable에 넣음
//insert 시 update메소드 안에 쿼리문을 적고 쿼리문에서 넣고자 하는 데이터는 ?로 처리한다 (preparedstatement 형식)
//그리고 , 쿼리문 뒤에 ?에 해당하는 데이터를 적어준다.(template 형식)
//ExamRIO형의 객체에 들어있는 데이터를 get메소드로 가져왔다.
return jdbcTemplate.update(
"insert into examtable(name,studentid,kor,eng,mat) values (?,?,?,?,?);"
,u.getName(),u.getStudentid(),u.getKor(),u.getEng(),u.getMat());
}
/**
* 데이터를 update 하는 메소드
* @param u : ExanRIO형의 데이터(DB에서 수정하고자 하는 데이터)
* @return int형인 status를 반환한다.
*/
public void update(ExamRIO u) throws Exception{
//메소드 불러올 때 로그를 남김
logger.info("Repo --- update");
//쿼리문을 적고 실행하고 리턴한다.(update는 update)
//sql : examtable안에서 해당하는 학번의 이름 학번 각 점수를 수정한다.
//update 시 update메소드 안에 쿼리문을 적고 쿼리문에서 넣고자 하는 데이터는 ?로 처리한다 (preparedstatement 형식)
//그리고 , 쿼리문 뒤에 ?에 해당하는 데이터를 적어준다.(template 형식)
//ExamRIO형의 객체에 들어있는 데이터를 get메소드로 가져왔다.
jdbcTemplate.update(
"update examtable set name = ?,studentid = ?, kor = ?, eng = ?, mat = ? where studentid = ?;"
,u.getName(),u.getStudentid(),u.getKor(),u.getEng(),u.getMat(),u.getStudentid());
}
/**
* 데이터를 delete 하는 메소드
* @param u : ExanRIO형의 데이터(DB에 삽입된 데이터)
* @return int형인 status를 반환한다.
*/
public void delete(ExamRIO u) throws Exception{
//쿼리문을 적고 실행하고 리턴한다.(delete는 update)
//sql : examtable안에서 해당하는 학번 데이터를 지운다.
//delete 시 문자열 변수에 sql문을 넣고, 넣고자 하는 데이터는 ?로 처리한다. (preparedstatement 형식)
String query = "dalete from examtable where studentid = ?;";
//update메소드에 쿼리문을 넣고,그 뒤에 ?에 넣을 데이터를 적어준다.(template 형식)
//ExamRIO형의 객체에 들어있는 데이터를 get메소드로 가져왔다.
jdbcTemplate.update(query,u.getStudentid());
}
/**
* 전체 데이터를 출력하는 메소드
* @return 전체 데이터가 담긴 리스트를 리턴한다.
*/
public List<ExamRIO> getAllrecords() throws Exception{
//로그를 남긴다.
logger.info("Repo --- getAllrecords");
//generic이 ExamRIO인 list를 선언하고
//jdbc Template의 query메소드를 통해서 전체 데이터 추출하고 list에 담는다.
List<ExamRIO> results = jdbcTemplate.query(
//쿼리문을 쓰고
"select * from examtable;",
//콤마 뒤에 RowMapper 객체를 만든다.
//해당 객체에서 ExamRIO형(u)을 반환하는 maprow메소드를 정의한다.(출력 데이터를 담는다)
//그리고 해당 결과를 results에 담는다.
new RowMapper<ExamRIO>() {
//maprow메소드에 ResultSet이 매개변수로 있어서 각 데이터마다 하나씩 set해준다.
@Override
public ExamRIO mapRow(ResultSet rset, int rowNum) throws SQLException{
ExamRIO u = new ExamRIO();
u.setName(rset.getString("name"));
u.setStudentid(rset.getInt("studentid"));
u.setKor(rset.getInt("kor"));
u.setEng(rset.getInt("eng"));
u.setMat(rset.getInt("mat"));
return u;
}
});
//데이터를 담은 list를 반환한다.
return results;
}
/**
* 해당 학번을 가진 학생만 출력한다.
* @param id : 학번(studentid)
* @return ExamRIO 형의 데이터
*/
public ExamRIO getRecordById(int studentid) throws Exception{
//generic이 ExamRIO인 list를 선언하고 jdbctemplate 실행결과를 담는다.
//특이한 점은 데이터를 하나 뽑는데도 list로 선언한다는 것이다.
//전체 출력 메소드와 매우 흡사하다
List<ExamRIO> results = jdbcTemplate.query(
//쿼리문을 쓰고
"select * from examtable where studentid=?;",
//콤마 뒤에 RowMapper 객체를 만든다.
//해당 객체에서 ExamRIO형(u)을 반환하는 maprow메소드를 정의한다.(출력 데이터를 담는다)
//그리고 해당 결과를 results에 담는다.
new RowMapper<ExamRIO>() {
//maprow메소드에 ResultSet이 매개변수로 있어서 각 데이터마다 하나씩 set해준다.
@Override
public ExamRIO mapRow(ResultSet rset, int rowNum) throws SQLException{
ExamRIO u = new ExamRIO();
u.setName(rset.getString("name"));
u.setStudentid(rset.getInt("studentid"));
u.setKor(rset.getInt("kor"));
u.setEng(rset.getInt("eng"));
u.setMat(rset.getInt("mat"));
return u;
}
//그리고 쿼리문의 ?부분에 들어갈 데이터를 끝에 넣는다.
},studentid);
//데이터를 담은 list를 반환 시 조건을 걸어서 조건에 맞게 보낸다
//삼항 연산자로 isEmpty()인지 아닌지 판단해서 리턴하도록 하였다.
//empty면 null값이 반환되고, 아니면 results.get(0)이 반환된다.
//즉, 메소드에서 정의한 리턴 형(ExamRIO)에 맞게 데이터가 리턴 될 수 있다.
return results.isEmpty() ? null : results.get(0);
}
}
Service
1. ExamSIO.java
Controller와 데이터를 주고 받을 때 해당 데이터 형식으로 주고 받는다.
클라이언트가 요청하는 비지니스 로직과 관련된 데이터가 들어간다.
package com.kopo.exam_jdbc.dto;
public class ExamSIO {
// 요청에 맞게 필요한 데이터가 들어간 객체를 생성하기 위한 틀이라고 보면 될것같다.
// 지금은 간단한 CRUD밖에 하지 않아서 ExamRIO와 같은 데이터가 들어가 있다.
// 다룰 데이터 선언
private String name; // 이름
private int studentid; // 학번
private int kor; // 국어성적
private int eng; // 영어 성적
private int mat; // 수학 성적
// constructor 선언 빈 생성자와 데이터가 같이 들어있는 생성자를 같이 만들어 준다.
public ExamSIO() {
super();
}
// 해당 객체를 생성할 때 여기 5개의 데이터가 들어간다.
public ExamSIO(String name, int studentid, int kor, int eng, int mat) {
super();
this.name = name;
this.studentid = studentid;
this.kor = kor;
this.eng = eng;
this.mat = mat;
}
// getter, setter 메소드 생성 : 데이터를 불러오고 적용할 때 사용한다.
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getStudentid() {
return studentid;
}
public void setStudentid(int studentid) {
this.studentid = studentid;
}
public int getKor() {
return kor;
}
public void setKor(int kor) {
this.kor = kor;
}
public int getEng() {
return eng;
}
public void setEng(int eng) {
this.eng = eng;
}
public int getMat() {
return mat;
}
public void setMat(int mat) {
this.mat = mat;
}
}
2. ExamService.java
service에서 사용할 메소드의 이름을 정의한 인터페이스이다.
<ExamService.java>
package com.kopo.exam_jdbc.service;
import java.util.List;
import com.kopo.exam_jdbc.dto.ExamSIO;
public interface ExamService {
public void createDB() throws Exception; //테이블 생성
public void dropDB() throws Exception; //테이블 삭제
public void allsetDB() throws Exception; //학생 데이터 삽입
//건내준 인자를 기반으로 데이터 삽입
public void insert (ExamSIO examSIO) throws Exception;
//해당 학번에 맞는 데이터를 하나 출력
public ExamSIO selectOne(int studentid) throws Exception;
//데이터 전체 출력
public List<ExamSIO> selectAll() throws Exception;
//해당 이름을 가진 데이터 전체 출력
public List<ExamSIO> selectAllByName(String name) throws Exception;
//해당 학번을 가진 데이터를 수정
public void update (int studentid, ExamSIO examSIO) throws Exception;
//건내준 인자를 기반으로 데이터 수정
public void update (ExamSIO examSIO) throws Exception;
//학번 기반 데이터 삭제
public void delete(int studentid) throws Exception;
//건내준 인자를 기반으로 데이터 삭제
public void delete(ExamSIO examSIO) throws Exception;
}
3. ExamServiceImpl.java
ExamService 인터페이스를 구현(implements) 하여 각 메소드를 재정의(Override)한
구현체이다.
<ExamServiceImpl.java>
package com.kopo.exam_jdbc.service;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.kopo.exam_jdbc.dao.ExamRepo;
import com.kopo.exam_jdbc.domain.ExamRIO;
import com.kopo.exam_jdbc.dto.ExamSIO;
//@Service 어노테이션으로 해당 클래스는 service의 역활을 하는 클래스임을 선언한다.
//ExamServiceImpl클래스는 ExamService인터페이스를 상속 받았다.
//때문에 ExamService에 정의된 메소드를 override해서 각 메소드를 재정의 해주어야 한다.
@Service
public class ExamServiceImpl implements ExamService {
//@Autowired 어노테이션으로 레파지토리를 가져와 사용하기 위해
//스프링 특수 변수로서 레파지토리(ExamRepo)를 선언한다.
@Autowired
private ExamRepo repo;
//테이블을 생성하는 메소드
@Override
public void createDB() throws Exception{
//레파지토리(repo)의 createDB()메소드를 불러와서(DB요청)
//테이블을 생성한다.
repo.createDB();
}
//테이블을 삭제하는 메소드
@Override
public void dropDB() throws Exception{
//레파지토리(repo)의 dropDB()메소드를 불러와서(DB요청)
//테이블을 삭제한다.
repo.dropDB();
}
//몇명의 학생들의 데이터를 통시에 넣는 메소드이다.
@Override
public void allsetDB() throws Exception{
//자기 자신 클래스(this)의 insert 메소드를 실행 한다.
//insert()메소드에 들어갈 인자는 ExamSIO형태의 데이터이며
//ExamSIO데이터르 넣을 때 new를 통해 이름,학번,각 성적 데이터를 가진 객체를 만들어서 넣는다.
this.insert(new ExamSIO("학생1",209901,95,100,95));
this.insert(new ExamSIO("학생2",209902,90,90,100));
this.insert(new ExamSIO("학생3",209903,85,80,95));
this.insert(new ExamSIO("학생4",209904,75,100,85));
this.insert(new ExamSIO("학생5",209905,85,70,75));
this.insert(new ExamSIO("학생6",209906,95,80,95));
this.insert(new ExamSIO("학생7",209907,85,100,85));
this.insert(new ExamSIO("학생8",209908,75,90,65));
this.insert(new ExamSIO("학생9",209909,85,80,95));
}
//ExamSIO를 매개변수로 가지고 데이터를 삽입하는 메소드이다.
@Override
public void insert(ExamSIO examSIO) throws Exception{
//레파지토리(repo)의 insert()메소드를 불러와서(DB요청)
//ExamRIO형의 데이터를 인자로 넣는다.
//ExamRIO형의 데이터를 넣을 때 new를 통해 객체를 만들고
//넣을 데이터로서 매개변수로 받은 ExamSIO의 데이터를 get메소드를 통해
//이름 학번 각 점수를 추출하여 데이터를 넣어준다.
repo.insert(new ExamRIO(examSIO.getName(),examSIO.getStudentid(),
examSIO.getKor(),examSIO.getEng(),
examSIO.getMat()));
}
//학번(studentid)을 조건으로 해서 데이터 조회
@Override
public ExamSIO selectOne(int studentid) throws Exception{
//ExamRIO형의 변수를 하나 만들고
ExamRIO exam = null;
try {
//레파지토리(repo)의 getRecordById()메소드를 불러와서(DB요청)
//인자로 studentid를 넣어서 해당하는 데이터를 exam변수에 담는다.
exam = repo.getRecordById(studentid);
}catch(Exception e) {
e.printStackTrace();
}
//담은 데이터를 다시 ExamSIO객체를 만들어서 각 데이터를 넣고 리턴한다.
return new ExamSIO(exam.getName(), exam.getStudentid(), exam.getKor(), exam.getEng(), exam.getMat());
}
//전체 데이터 조회
@Override
public List<ExamSIO> selectAll() throws Exception{
//List<ExamRIO>형태의 변수를 하나 만든다.
List<ExamRIO> exams = null;
try {
//레파지토리(repo)의 getAllrecords()메소드를 불러와서(DB요청)
//리턴된 데이터를 exams에 담는다.
exams = repo.getAllrecords();
}catch(Exception e) {
e.printStackTrace();
}
//List<ExamSIO>형의 변수를 하나 생성하고
List<ExamSIO> examScores = new ArrayList<ExamSIO>();
//for문을 써서 list갯수 만큼 반복하면서,
for(int i=0;i < exams.size();i++) {
//exams에 담겼던 모든 데이터들을 다시 ExamSIO객체를 생성해서 거기에 담아 examScores리스트에 담는다.
examScores.add(new ExamSIO(exams.get(i).getName(),
exams.get(i).getStudentid(),
exams.get(i).getKor(),
exams.get(i).getEng(),
exams.get(i).getMat()
));
}
//그렇게 담겨진 리스트를 리턴한다.
return examScores;
}
@Override
public List<ExamSIO> selectAllByName(String name) throws Exception {
// TODO Auto-generated method stub
return null;
}
@Override
public void update(int studentid, ExamSIO examSIO) throws Exception{
// TODO Auto-generated method stub
}
@Override
public void update(ExamSIO examSIO) throws Exception{
// TODO Auto-generated method stub
}
@Override
public void delete(int studentid) throws Exception{
// TODO Auto-generated method stub
}
@Override
public void delete(ExamSIO examSIO) throws Exception{
// TODO Auto-generated method stub
}
}
Controller
1. ExamController.java
요청이 들어오면 URL을 매핑해서 service에 요청하고 model에 값을 담아 view에 보내주는 역활을 한다.
<ExamController.java>
package com.kopo.exam_jdbc;
import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.kopo.exam_jdbc.service.ExamService;
//@Controller 어노테이션을 적어서(자동으로 적혀져 있음)
//해당 클래스가 controller임을 선언함
@Controller
public class ExamController {
//service를 사용하고자 @Autowired 어노테이션을 통해 service를 선언했다.
//각 영역 마다 불러올 영역을 Autowired해서 서로 묶었다.
//결국 Controller -> Service -> Repository -> JdbcTemplate이 서로 묶여있는 형태가 된다.
@Autowired
private ExamService service;
//로그 객체를 선언
private static final Logger logger = LoggerFactory.getLogger(ExamController.class);
//해당경로('프로젝트/공백')로 URL이동하면 해당 컨트롤러 메소드로 매핑된다.
@RequestMapping(value = "/", method = RequestMethod.GET)
public String index() {
//로그 표시 후
logger.info("index.jsp start");
//index.jsp파일로 이동한다.
return "index";
}
//URL에 '/menu'를 더 적으면 해당 컨트롤러 메소드로 매핑된다.
@RequestMapping(value = "/menu", method = RequestMethod.GET)
public String menu() {
//로그 표시 후
logger.info("menu.jsp start");
//menu.jsp파일로 이동한다.
return "menu";
}
//URL에 '/home'를 더 적으면 해당 컨트롤러 메소드로 매핑된다.
@RequestMapping(value = "/home", method = RequestMethod.GET)
public String home(Locale locale, Model model) {
//로그를 입력하고
logger.info("Welcome home! The client locale is {}.", locale);
//date형의 객체를 선언한다.(현제 시간)
Date date = new Date();
//date형을 출력할 포맷을 설정한다.
DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
//포맷 적용한 date형 변수를 String형을 문자열에 넣는다.
String formattedDate = dateFormat.format(date);
//key값을 serverTime으로 해서
//시간이 적혀있는 문자열을 value로하고 model에 담는다.
model.addAttribute("serverTime", formattedDate );
//home.jsp로 이동한다.
return "home";
}
//URL에 '/allsetDB'를 더 적으면 해당 컨트롤러 메소드로 매핑된다.
@RequestMapping(value = "/allsetDB", method = RequestMethod.GET)
public String allsetDB(Model model) {
//로그 표시하고
logger.info("allsetDB.jsp start");
//작업 메시지 표시할 변수 선언
String ret=null;
try {
//위에서 선언한 service의 allsetDB메소드 요청한다.
service.allsetDB();
//요청이 성공하면 위 메시지 를 담고
ret = "DB allset 성공";
}catch(Exception e) {
e.printStackTrace();
//위에서 예외처리가 났다면 아래 문구를 넣는다.
ret = "DB allset 실패" + e;
}
//위 처리에 따라 넣어진 메시지 값을 value로 하고
//'msg'라는 key값을 가진 model에 값을 넣는다.
model.addAttribute("msg",ret);
//allsetDB.jsp페이지로 이동한다.
return "allsetDB";
}
//URL에 '/allviewDB'를 더 적으면 해당 컨트롤러 메소드로 매핑된다.
@RequestMapping(value = "/allviewDB", method = RequestMethod.GET)
public String allviewDB(Model model) {
//로그 표시하고
logger.info("allviewDB.jsp start");
try {
//위에서 선언한 service의 selectAll메소드 요청한다.
//selectAll메소드를 통해 나온 리턴값을 value로 해서
//'list'란 key값으로 model에 담는다.
model.addAttribute("list",service.selectAll());
}catch(Exception e) {
e.printStackTrace();
}
//allviewDB.jsp로 간다.
return "allviewDB";
}
//URL에 '/createDB'를 더 적으면 해당 컨트롤러 메소드로 매핑된다.
@RequestMapping(value = "/createDB", method = RequestMethod.GET)
public String createDB(Model model) {
//로그 문구가 뜨고
logger.info("createDB.jsp start");
//메시지를 담을 변수 선언
String ret = null;
try {
//위에서 선언한 service의 createDB메소드 요청한다.
service.createDB();
//메소드 성공 시 결과 메시지를 변수에 담는다.
ret = "DB create 성공";
}catch(Exception e) {
e.printStackTrace();
//메소드가 예외처리 날 시 메시지를 변수에 담는다.
ret = "DB create 실패" + e;
}
// 위 처리에 따라 넣어진 메시지 값을 value로 하고
// 'msg'라는 key값을 가진 model에 값을 넣는다.
model.addAttribute("msg",ret);
//createDB.jsp로 이동한다.
return "createDB";
}
//URL에 '/dropDB'를 더 적으면 해당 컨트롤러 메소드로 매핑된다.
@RequestMapping(value = "/dropDB", method = RequestMethod.GET)
public String dropDB(Model model) {
//로그 문구가 뜨고
logger.info("dropDB.jsp start");
//메시지를 담을 변수 선언
String ret = null;
try {
//위에서 선언한 service의 dropDB메소드 요청한다.
service.dropDB();
//메소드 성공 시 결과 메시지를 변수에 담는다.
ret = "DB drop 성공";
}catch(Exception e) {
e.printStackTrace();
//예외처리 시 아래 메시지를 변수에 담는다.
ret = "DB drop 실패" + e;
}
// 위 처리에 따라 넣어진 메시지 값을 value로 하고
// 'msg'라는 key값을 가진 model에 값을 넣는다.
model.addAttribute("msg",ret);
//dropDB.jsp로 이동한다.
return "dropDB";
}
//oneviewDB으로 갈 controller 메소드
//URL에 oneviewDB를 치고, 뒤에 다시 /하고 파라메터 값을 적는다.
@RequestMapping(value = "/oneviewDB/{studentid}", method = RequestMethod.GET)
//Pathvariable 어노테이션으로 studentid 값을 studentid라는 이름의 매개변수로 만든다.
public String oneviewDB(@PathVariable("studentid") int studentid, Model model) {
//로그 출력하고(로그에 파라미터 값도 포함되도록 함)
logger.info("oneviewDB.jsp start studentid = " + studentid);
try {
//위에서 선언한 service의 selectOne()메소드 요청한다.
//매개변수로 선언한 studentid를 인자로 하여 selectOne()에 넣는다.
//selectOne메소드를 통해 나온 리턴값을 value로 해서
//'list'란 key값으로 model에 담는다.
model.addAttribute("list",service.selectOne(studentid));
}catch(Exception e) {
e.printStackTrace();
}
//oneviewDB.jsp로 이동한다.
return "oneviewDB";
}
}
View
1. index.jsp
프로젝트 시작시 들어오는 페이지
첫 시작시 menu.jsp와 home.jsp를 읽는다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>exam_jdbc</title>
<!-- 프로젝트 실행 시 나오는 부분이다. frameset으로 프레임을 2개로 나누었다. -->
<!-- 메뉴바가 나오는 부분인 곳과(menu) , 실제 내용물이 나오는 부분인 main으로 나누었다. -->
<!-- 첫 시작 시 main 부분은 home.jsp가 불러진다.(현제 시간 날짜 출력) -->
<frameset cols="130,*" border="0" frameborder="1">
<frame src="./menu">
<frame src="./home" name="main">
</frameset>
</head>
<body>
</body>
</html>
2. menu.jsp
메뉴바의 내용이 들어있는 페이지
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page session="false" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Menu</title>
</head>
<body>
<!-- 왼쪽 프레임의 메뉴바가 나오는 부분의 내용물, target을 main으로 적어서 -->
<!-- 다른 프레임에 링크된 내용이 나오도록 하였다. -->
<a href="./createDB" target="main">테이블 생성</a><br>
<a href="./allsetDB" target="main">데이터 입력</a><br>
<a href="./dropDB" target="main">테이블 삭제</a><br>
<a href="./allviewDB" target="main">데이터 보기</a><br>
</body>
</html>
3. home.jsp
본 내용을 출력하는 main부분 첫 시작시 나타나는 페이지
날짜와 시간이 나온다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" %>
<html>
<head>
<title>Home</title>
</head>
<body>
<h1>
Hello world!
</h1>
<!-- 현제 날짜와 시간이 출력된다. -->
<!-- serverTime 이라는 model의 key값을 찾아서 그 value값을 출력한다. -->
<P> The time on the server is ${serverTime}. </P>
</body>
</html>
4. createDB.jsp
테이블 생성 후 메시지를 출력하는 페이지이다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import ="java.sql.*, javax.sql.*, java.io.*" %>
<%@ page import ="com.kopo.exam_jdbc.*" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>createDB</title>
</head>
<body>
<h3>데이터 생성</h3>
<hr>
<!-- 기능은 이미 실행이 되고(테이블 생성) 해당 페이지로 이동된다. -->
<!-- model에 저장된 msg란 key값을 찾아 그 value값을 출력한다.(메시지) -->
${msg}
</body>
</html>
5. dropDB.jsp
테이블 삭제 후 메시지를 출력하는 페이지이다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import ="java.sql.*, javax.sql.*, java.io.*" %>
<%@ page import ="com.kopo.exam_jdbc.*" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>dropDB</title>
</head>
<body>
<h3>데이터 삭제</h3>
<hr>
<!-- 기능은 이미 실행이 되고(테이블 삭제) 해당 페이지로 이동된다. -->
<!-- model에 저장된 msg란 key값을 찾아 그 value값을 출력한다.(메시지) -->
${msg}
</body>
</html>
6. allsetDB.jsp
데이터 삽입 후 메시지를 출력하는 페이지이다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import ="java.sql.*, javax.sql.*, java.io.*" %>
<%@ page import ="com.kopo.exam_jdbc.*" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>allsetDB</title>
</head>
<body>
<h3>데이터 Insert</h3>
<hr>
<!-- 기능은 이미 실행이 되고(데이터 삽입) 해당 페이지로 이동된다. -->
<!-- model에 저장된 msg란 key값을 찾아 그 value값을 출력한다.(메시지) -->
${msg}
</body>
</html>
7. allviewDB.jsp
전체 데이터 출력
주의!) html 주석(<!-- -->)은 JSTL 태그안에서 동작하지 않는다.
jsp 주석을 사용해야 한다. (<%-- --%>)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import ="java.sql.*, javax.sql.*, java.io.*" %>
<%@ page import ="com.kopo.exam_jdbc.*" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>allviewDB</title>
</head>
<body>
<h3>전체 데이터</h3>
<hr>
<%-- 전체 리스트가 출력되는 테이블 생성 --%>
<table cellspacing=1 width=600 border=1>
<tr>
<td width=50><p align=center>이름</p></td>
<td width=50><p align=center>학번</p></td>
<td width=50><p align=center>국어</p></td>
<td width=50><p align=center>영어</p></td>
<td width=50><p align=center>수학</p></td>
</tr>
<%-- JSTL의 choose태그 로 조건문 실행 --%>
<%-- JSTL 태크안에 주석을 다니 실행이 안되서 주석은 --%>
<%-- 그렇지 않다면 foreach문으로 list를 출력한다. --%>
<%-- 학번과 이름쪽엔 a태그로 링크를 걸어주는대, URL의 뒤쪽은 파라메터 이름이다. --%>
<c:choose>
<%-- 만약 model에 담긴 list의 value값이 비어있다면 --%>
<c:when test="${empty list}">
<%-- 아래의 메시지를 출력한다. --%>
<tr>
<td colspan=3>
<spring:message code="common.listEmpty"/>
</td>
</tr>
</c:when>
<%-- 그렇지 않다면 foreach문으로 list를 출력한다. --%>
<c:otherwise>
<%-- model에 담긴 list갯수 만큼 반복해서 데이터를 출력한다. --%>
<%-- item을 list로 한다는건 반복문에 list에 담긴 수만큼 반복한다는 것이고 --%>
<%-- 이 list를 통해 값을 출력할 때 var를 'e'로 해서 e.데이터이름 으로 출력할 수 있게 한다. --%>
<c:forEach items="${list}" var="e">
<tr>
<%-- 이름을 출력한다. a링크를 걸어 클릭시 'oneviewDB/파라메터 값(학번)' 형식으로 보낸다 --%>
<td width=50><p align=center><a href="oneviewDB/${e.studentid}">${e.name}</a></p></td>
<%-- 학번을 출력한다. a링크를 걸어 클릭시 'oneviewDB/파라메터 값(학번)' 형식으로 보낸다 --%>
<td width=50><p align=center><a href="oneviewDB/${e.studentid}">${e.studentid}</a></p></td>
<%-- 국어 성적 출력 --%>
<td width=50><p align=center>${e.kor}</p></td>
<%-- 영어 성적 출력 --%>
<td width=50><p align=center>${e.eng}</p></td>
<%-- 수학 성적 출력 --%>
<td width=50><p align=center>${e.mat}</p></td>
</tr>
</c:forEach>
</c:otherwise>
</c:choose>
</table>
</body>
</html>
8. oneviewDB.jsp
특정 데이터 출력
주의!) html 주석(<!-- -->)은 JSTL 태그안에서 동작하지 않는다.
jsp 주석을 사용해야 한다. (<%-- --%>)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import ="java.sql.*, javax.sql.*, java.io.*" %>
<%@ page import ="com.kopo.exam_jdbc.*" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>oneviewDB</title>
</head>
<body>
<h3>조회</h3>
<hr>
<%-- 전체 리스트가 출력되는 테이블 생성 --%>
<table cellspacing=1 width=600 border=1>
<tr>
<td width=50><p align=center>이름</p></td>
<td width=50><p align=center>학번</p></td>
<td width=50><p align=center>국어</p></td>
<td width=50><p align=center>영어</p></td>
<td width=50><p align=center>수학</p></td>
</tr>
<%-- JSTL의 choose태그 로 조건문 실행 --%>
<%-- 코드를 출력한다????? --%>
<%-- list를 출력한다. --%>
<c:choose>
<%-- 만약 model데 담긴 list의 값이 비어있다면 --%>
<c:when test="${empty list}">
<%-- 아래의 메시지를 출력한다. --%>
<tr>
<td colspan=3>
<spring:message code="common.listEmpty"/>
</td>
</tr>
</c:when>
<%-- 그렇지 않으면 --%>
<c:otherwise>
<%-- 아래 내용을 출력한다. --%>
<tr>
<%-- model에 담긴 list의 값을 출력하는데 해당 list는 ExamSIO형태를 가지고 있다. --%>
<%-- 그래서 list안에 데이터를 출력 할 때 'list.데이터이름' 이렇게 데이터출력을 한다 --%>
<%-- 이름 출력 --%>
<td width=50><p align=center>${list.name}</p></td>
<%-- 학번 출력 --%>
<td width=50><p align=center>${list.studentid}</p></td>
<%-- 국어 성적 출력 --%>
<td width=50><p align=center>${list.kor}</p></td>
<%-- 영어 성적 출력 --%>
<td width=50><p align=center>${list.eng}</p></td>
<%-- 수학 성적 출력 --%>
<td width=50><p align=center>${list.mat}</p></td>
</tr>
</c:otherwise>
</c:choose>
</table>
</body>
</html>
실행 결과
'Spring Framework' 카테고리의 다른 글
(Spring Framework, Hibernate)간단한 성적 관리 페이지 (0) | 2020.03.20 |
---|---|
Hibernate 관련 정리,(3계층 구조, 간단 설명 포함) (0) | 2020.03.20 |
el태그, Jstl (0) | 2020.03.18 |
(Spring Legacy Proejct) parameter넘기기(get,post) (0) | 2020.03.18 |
Spring Legacy Project로 Controller 매핑 (0) | 2020.03.18 |