Woopii Vyeolog

(Spring Legacy Project - MVC모델) JDBC Template을 써서 DB연동 본문

Spring Framework

(Spring Legacy Project - MVC모델) JDBC Template을 써서 DB연동

WooPii 2020. 3. 19. 16:17

앞의 글들에서 나는 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>

 

실행 결과

 

Comments