Woopii Vyeolog

(Spring Framework, Hibernate)간단한 성적 관리 페이지 본문

Spring Framework

(Spring Framework, Hibernate)간단한 성적 관리 페이지

WooPii 2020. 3. 20. 22:09

github 주소 : https://github.com/leewoopyo/exam_hibernate

 

이번엔 Hibernate를 이용해서 DB처리를 할 것이다.

 

이전 블로그 페이지에서 JDBC Template을 이용하여 같은 프로젝트를 한 적이 있다.

 

그거랑 똑같은 프로젝트이기 때문에 Hibernate가 처리하는 Repository영역을 제외한 나머지 영역은  JDBC Template을 이용한 영역과 같다.

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

 

 

<프로젝트 전체 구성>

설정 하기

 

1. pom.xml

Hibernate프레임워크를 사용하기 위해서 mysqlconnector, JPA , hibernate dependency를 추가한다. 

 

<?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_hibernate</artifactId>
	<name>exam_hibernate</name>
	<packaging>war</packaging>
	<version>1.0.0-BUILD-SNAPSHOT</version>
	
	<properties>
		<java-version>1.8</java-version>
		<org.springframework-version>4.3.18.RELEASE</org.springframework-version>
		<org.aspectj-version>1.7.4</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>

		<!-- Spring-webmvc : MVC프로젝트를 하기 위해서 추가하는 기본적인 dependency -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${org.springframework-version}</version>
		</dependency>
		<!-- JPA를 사용하고자 할 때 추가해야하는 dependency -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-orm</artifactId>
			<version>${org.springframework-version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aspects</artifactId>
			<version>${org.springframework-version}</version>
		</dependency>
		<!-- Spring transaction을 사용하기 위한 dependency -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-tx</artifactId>
			<version>${org.springframework-version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aop</artifactId>
			<version>${org.springframework-version}</version>
		</dependency>
		<dependency>
			<groupId>javax.xml.bind</groupId>
			<artifactId>jaxb-api</artifactId>
			<version>2.3.0</version>
		</dependency>
		<!-- AspectJ -->
		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjrt</artifactId>
			<version>${org.aspectj-version}</version>
		</dependency>
		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjweaver</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 -->
		<!-- servlet dependency 이다. -->
		<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>

		<!-- Hibernate -->
		<!-- hibernate core : JPA를 사용하고 hibernate를 사용하고자 할 때 추가하는 dependency -->
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-core</artifactId>
			<version>4.2.1.Final</version>
		</dependency>
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-entitymanager</artifactId>
			<version>4.2.1.Final</version>
		</dependency>
		<!-- hibernate validator : entity에서 유효성 검증을 위해 추가하는 dependency -->
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-validator</artifactId>
			<version>4.3.1.Final</version>
		</dependency>
		<dependency>
			<groupId>org.hibernate.javax.persistence</groupId>
			<artifactId>hibernate-jpa-2.1-api</artifactId>
			<version>1.0.2.Final</version>
		</dependency>
		<dependency>
			<groupId>javax.validation</groupId>
			<artifactId>validation-api</artifactId>
			<version>1.0.0.GA</version>
		</dependency>

		<!-- MySQL Connector -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>8.0.12</version>
		</dependency>
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-pool2</artifactId>
			<version>2.6.0</version>
		</dependency>
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-dbcp2</artifactId>
			<version>2.5.0</version>
			<exclusions>
				<exclusion>
					<groupId>commons-logging</groupId>
					<artifactId>commons-logging</artifactId>
				</exclusion>
				<exclusion>
					<groupId>xml-apis</groupId>
					<artifactId>xml-apis</artifactId>
				</exclusion>
			</exclusions>
		</dependency>

		<dependency>
			<groupId>commons-collections</groupId>
			<artifactId>commons-collections</artifactId>
			<version>3.2.1</version>
		</dependency>
		<dependency>
			<groupId>javax.transaction</groupId>
			<artifactId>jta</artifactId>
			<version>1.1</version>
		</dependency>

		<!-- jackson -->
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-core</artifactId>
			<version>2.8.8</version>
		</dependency>

		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-annotations</artifactId>
			<version>2.8.8</version>
		</dependency>

		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>2.8.8</version>
		</dependency>




		<!-- Test -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.12</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>${org.springframework-version}</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>

 

2. Root-context.xml

Hibernate, jdbc 정보가 담겨있는 applicationContext.xml파일을 root-context.xml에서 임포트 해서 적용될 수 있게 함(파일의 경로는 위에 있음)

 

<?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">
	
	<!-- root-context.xml파일에서 applicationContext.xml을 임포트 해서 사용한다. -->
	<import resource = "classpath:META-INF/applicationContext.xml" />	
		
</beans>

 

3. servlet-context.xml

트랜젝션 어노테이션(@Transactional)을 쓰기 위해서 태그를 추가해줌

 

<?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"
	xmlns:tx="http://www.springframework.org/schema/tx"
	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
		http://www.springframework.org/schema/tx https://www.springframework.org/schema/tx/spring-tx-3.2.xsd">

	<!-- transactional 어노테이션 사용을 위해서 위에 몇가지를 추가해 주었다.-->
	<!-- 아래와 같이 태그를 사용하기 위해서 위에서처럼 인터넷 URI로 해당 태그를 정의한 부분을 명시해야한다  -->
	<!-- 즉 아래의 "tx:annotation-driven" 태그를 명시하려면 위에  xmlns:tx 이부분을 명시하고 나서 사용해야 한다.-->
	
	<!-- 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_hibernate" />
	
	<!-- Transactional이라는 어노테이션을 사용하기 위해서  -->
	<!-- 아래와 같은 태그를 넣었다. -->
	<tx:annotation-driven />
	
</beans:beans>

 

4. applicationContext.xml

Hibernate, jdbc 정보가 담겨있는 파일이다. root-context.xml에서 임포트 한다.

 

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
         http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
         http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">

<!-- 같은 디렉토리 안의  '.properties' 인 파일에 데이터가 있어서 거길 참고하라는 의미이다. -->
<context:property-placeholder location="classpath*:META-INF/*.properties" />

<context:component-scan base-package="com.kopo.exam_hibernate" />	<!-- 다른 데에서 복사했다면 베이스 패키지 부분을 수정한다 -->

<tx:annotation-driven />

<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
<property name="driverClassName" value="${database.driverClassName}" />	<!-- 같은 디렉토리에 있는  jdbc.properties 를 읽어 해당 내용을 가져옴-->
<property name="url" value="${database.url}" />		<!-- 같은 디렉토리에 있는  jdbc.properties 를 읽어 해당 내용을 가져옴-->
<property name="username" value="${database.username}" />		<!-- 같은 디렉토리에 있는  jdbc.properties 를 읽어 해당 내용을 가져옴-->
<property name="password" value="${database.password}" />		<!-- 같은 디렉토리에 있는  jdbc.properties 를 읽어 해당 내용을 가져옴-->
</bean>

<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.kopo.exam_hibernate" />	<!-- 다른 데에서 복사했다면 베이스 패키지 부분을 수정한다 -->
<property name="hibernateProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
</props>
</property>
</bean>

<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>

</beans>

 

5. jdbc.properties

DB connector와 hibernate의 설정 값이 들어있다.

 

# database
#database.driverClassName=com.mysql.cj.jdbc.Driver	
database.driverClassName=com.mysql.jdbc.Driver
database.url=jdbc\:mysql\://192.168.56.1\:3306/kopo?useUnicode\=true&characterEncoding\=utf8&serverTimezone=Asia/Seoul
database.username=kopo15
database.password=Qwer1234!!
# hibernate
hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
hibernate.show_sql=true
hibernate.hbm2ddl.auto=update

 

Repository

1. ExamRIO.java

@Entity 어노테이션으로 선언하면서 실제 DB테이블과 매핑이 되는 persistence object이다.

 

package com.kopo.exam_hibernate.domain;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

//해당 클래스가 DB table과 매핑이 되는 클래스이다.
//@Entity 어노테이션을 통해서  hiberante에 해당클래스가 테이블 정보임을 알린다.
//그리고 @Table(name="examtable") 을 써줌으로서
//해당 클래스는 examtable테이블과 연결이 된다는 것을 표시한다.
@Entity
@Table(name="examtable")
public class ExamRIO {
	
	//@Id는 키 필드라는 정보이다. 즉, table의 studentid콜론에 PK설정을 했으면
	//여기에 @Id를 적어준다.
	//그리고 	@Column(name="studentid")을 사용해서 해당 데이터가 
	//DB 테이블에서 studentid필드에 들어가는 데이터라는 것을 명시한다. 
	//(@GeneratedValue를 사용하면 auto_increment기능을 붙일 수 있다.)
	@Id
//	@GeneratedValue(strategy = GenerationType.AUTO)
	@Column(name="studentid")
	private int studentid;	//학번
	
	//@Column(name="name")을 사용해서 해당 데이터가 
	//DB 테이블에서 name필드에 들어가는 데이터라는 것을 명시한다. 
	@Column(name="name")
	private String name;	//이름
	
	//@Column(name="kor")을 사용해서 해당 데이터가 
	//DB 테이블에서 kor필드에 들어가는 데이터라는 것을 명시한다. 
	@Column(name="kor")
	private int kor;	//국어점수 
	
	//@Column(name="eng")을 사용해서 해당 데이터가 
	//DB 테이블에서 eng필드에 들어가는 데이터라는 것을 명시한다. 
	@Column(name="eng")
	private int eng;	//영서점수
	
	//@Column(name="mat")을 사용해서 해당 데이터가 
	//DB 테이블에서 mat필드에 들어가는 데이터라는 것을 명시한다. 
	@Column(name="mat")
	private int mat;	//수학점수
	
	//constructor 선언 빈 생성자와 데이터가 같이 들어있는 생성자를 같이 만들어 준다.
	public ExamRIO() {
		super();
	}
	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

Repository영역의 메소드 이름의 정의하는 인터페이스 부분이다.

 

package com.kopo.exam_hibernate.dao;

import java.util.List;

import com.kopo.exam_hibernate.domain.ExamRIO;

//인터페이스로 만들어서 메소드의 이름을 정의한다.
public interface ExamRepo {
	
	//데이터의 갯수를 구하는 메소드	
	Long count();
	//학번을 조건으로 특정 데이터 조회
	ExamRIO selectOne(int studentid);
	//전체 데이터 조회
	List<ExamRIO> selectAll();
	//페이지네이션 기능이 있는 전체 데이터 조회
	List<ExamRIO> selectAllByPagination(int page, int itemSizePerPage);
	//데이터 삽입
	void createOne(ExamRIO exam);
	//데이터 수정 
	void updateOne(ExamRIO exam);
	//데이터 삭제 
	void daleteOne(ExamRIO exam);
	//전체 데이터 삭제 
	int deleteAll();
	//테이블 생성 
	void createDB() throws Exception;
	//테이블 삭제
	void dropDB() throws Exception;
}

 

3. ExamRepoImpl.java

ExamRepo.java 의 메소드를 implements(구현)하고 메소드를 override(재정의) 하는 부분이다.

여기에 hibernate 처리가 이루어진다. (transaction)

 

package com.kopo.exam_hibernate.dao;

import java.sql.Statement;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.internal.SessionImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.kopo.exam_hibernate.domain.ExamRIO;

//@Transactional 어노테이션으로  여러쿼리문이 있을 때(트랜젝션으로 묶임)
//트랜젝션으로 묶인 쿼리중 하나라도 실패하면 rollback하고 모두 성공했을 때만 commit을 시켜준다. 
//@Repository 어노테이션을 통해 해당 클래스가 Repository임을 명시한다. 
//ExamRepo를 구현(implements)했기 때문에 메소드를 @override해서 재정의 한다.
@Transactional
@Repository
public class ExamRepoImpl implements ExamRepo{
	
	//hibernate는 SessionFactory클래스를 @Autowired하여 선언한다.
	//SessionFactory를 통해서 hibernate가 불러와진다. 
	@Autowired
	private SessionFactory sessionFactory;
	
	//로그 객체 
	private static final Logger logger = LoggerFactory.getLogger(ExamRepoImpl.class);

	//SessionFactory로부터 통신 연결된 식별자 값이 세션인데
	//이 세션 값을 갖기 위해서 getsession메소드를 만들었다.
	//이 세션값을 가지고 hibernate작업을 한다. 
	private Session getSession() {
		logger.info("getSession().start");
		Session ss = null;
		try {
			ss = sessionFactory.getCurrentSession();
			//System.out.println("111");
		}catch(org.hibernate.HibernateException he) {
			ss = sessionFactory.openSession();
			//System.out.println("222");
		}
		return ss;
	}
	
	//데이터의 갯수가 몇개인지 구하는 메소드 
	@Override
	public Long count() {
		//로그 표시
		logger.info("count().start");
		//hql문을 작성한다. DB의 테이블명(examtable)이 아닌 ExamRIO클래스명으로
		//테이블을 읽을 수 있다.(hibernate의 특징)
		String hql = "select count(*) from ExamRIO";
		//세션값.createQuery를 통해 hql문을 넣어서 쿼리문을 생성한다.
		Query query = getSession().createQuery(hql);
		//query.uniqueResult() 를 통해 결과값을 나오게 한다. 
		Long totalCount = (Long) query.uniqueResult();
		//결과값을 리턴한다.
		return totalCount;
	}

	//학번을 조건으로 특정 데이터 조회하는 메소드 
	@Override
	public ExamRIO selectOne(int studentid) {
//		ExamRIO exam = (ExamRIO)getSession().get(ExamRIO.class, id); 
		//hql문은 조회 시 "select *" 을 생략하는 것이 가능한 듯 하다.
		//where조건으로 ExamRIO중에 studentid를 조건으로 데이터를 찾는다.
		String hql = "From ExamRIO e where e.studentid = " + studentid;
		//세션값.createQuery에 hql문을 담아 쿼리를 생성하고 query에 담는다.
		Query query = getSession().createQuery(hql);
		//그리고 query.uniqueResult()를 통해 그 값을 가져와 리턴 할 수 있다.
		return (ExamRIO) query.uniqueResult();
	}
	
	//전체 데이터 조회
	//@SuppressWarnings는 컴파일러가 정적분석을 진행할 때 오류가 아니라고 마킹해주는 역할을 하고 있다.
	//컴파일러가 일반적으로 경고하는 내용 중"이건 하지마"하고 제외시킬 때 사용한다.
	//unchecked는 검증되지 않은 연산자 관련 경고를 억제 하는 역활이다.
	@SuppressWarnings("unchecked")
	@Override
	public List<ExamRIO> selectAll() {
		//hql문은 조회 시 "select *" 을 생략하는 것이 가능한 듯 하다.
		//전체 데이터를 출력한다. 
		String hql = "from ExamRIO";
		//세션값.createQuery에 hql문을 담아 쿼리를 생성하고 query에 담는다.
		Query query = getSession().createQuery(hql);
		//query.list로 query실행 결과를 list로 리턴할 수 있다. 
		return query.list();	
	}

	//전체 데이터 조회(페이지네이션 기능)
	//@SuppressWarnings는 컴파일러가 정적분석을 진행할 때 오류가 아니라고 마킹해주는 역할을 하고 있다.
	//컴파일러가 일반적으로 경고하는 내용 중"이건 하지마"하고 제외시킬 때 사용한다.
	//unchecked는 검증되지 않은 연산자 관련 경고를 억제 하는 역활이다.
	//page : 몇번째 페이지 , itemSizePerPage : 페이지의 크기
	@SuppressWarnings("unchecked")
	@Override
	public List<ExamRIO> selectAllByPagination(int page, int itemSizePerPage) {
		//studentid 기준으로 정렬하면서 전체 출력하는 hql문을 만든다.
		String hql = "from ExamRIO order by studentid";
		//세션값.createQuery에 hql문을 담아 쿼리를 생성하고 query에 담는다.
		Query query = getSession().createQuery(hql);
		//아래 두줄은 페이지네이션 하는데 필요한 메소드이다.
		query.setFirstResult((page-1) * itemSizePerPage);
		query.setMaxResults(itemSizePerPage);
		//query.list로 query실행 결과를 list로 리턴할 수 있다. 
		return query.list();
	}
	
	//데이터의 삽입
	@Override
	public void createOne(ExamRIO exam) {
		//세션값.save()에 매개변수인 exam을 인자로 넣으면 자동으로 insert가 된다. 
		getSession().save(exam);
		//getSession().flush();
	}
	
	//데이터의 수정
	@Override
	public void updateOne(ExamRIO exam) {
		//세션값.saveOrUpdate()에 매개변수인 exam을 인자로 넣으면 자동으로 update가 된다.
		getSession().saveOrUpdate(exam);
	}

	//데이터의 삭제
	@Override
	public void daleteOne(ExamRIO exam) {
		//세션값.delete()에 매개변수인 exam을 인자로 넣으면 자동으로 delete가 된다.
		getSession().delete(exam);
	}

	//전체 데이터의 삭제
	@Override
	public int deleteAll() {
		// 해당 테이블의 전체 데이터를 삭제하는 hql문 작성
		String hql = "delete from ExamRIO";
		//세션값.createQuery()에 hql을 넣어 쿼리 생성 
		Query query = getSession().createQuery(hql);
		//query.executeUpdate() 쿼리를 실행하고 결과값을 리턴한다.
		return query.executeUpdate();
	}
	
	//테이블 생성의 경우(createDB) DDL이기 때문에 hibernate에서는 사용되지 않는다.
	//테이블 생성
	@Override
	public void createDB() throws Exception {
		//statement 변수 생성
		Statement stmt;
		//try {
			//getSession()메소드를 통해 나온 세션값을 SessionImpl로 형변환 해서
			//세션값.connection().createStatement() 메소드를 통해 나온 값을
			//stmt에 넣는다. 
			//세션값을 import시켜서 jdbc처리 한것(DDL문장 처리)
			stmt = ((SessionImpl)getSession()).connection().createStatement();
			//stmt.execute()메소드로 테이블 생성을 한다.
			//이름, 학번, 각 성적 필드를 만든다.
			stmt.execute("create table examtable(" +
					"name varchar(20)," +
					"studentid int not null primary key," +
					"kor int," + "eng int," +
					"mat int)" +
					"DEFAULT CHARSET=utf8;");
			//Statement 객체를 닫는다.
			stmt.close();
		//}catch(Exception e) {
			//e.printStackTrace();
		//}
	}

	//테이블 삭제
	@Override
	public void dropDB() throws Exception {
		//statement 변수 생성
		Statement stmt;
		//try {
			//getSession()메소드를 통해 나온 세션값을 SessionImpl로 형변환 해서
			//세션값.connection().createStatement() 메소드를 통해 나온 값을
			//stmt에 넣는다. 
			//세션값을 import시켜서 jdbc처리 한것(DDL문장 처리)
			stmt = ((SessionImpl)getSession()).connection().createStatement();
			//stmt.execute()메소드로 테이블 삭제를 한다.
			stmt.execute("drop table examtable;");
			//처리가 끝난 Statement객체는 close()메소드로 닫는다.
			stmt.close();
		//}catch(Exception e) {
			//e.printStackTrace();
		//}
	}
}

 

Service

Service영역은 원래 안바뀌는 영역인데 ExamRepo에서 메소드이름이 바뀌어서 

그 부분을 수정해 주었다.

 

1. ExamServiceImpl.java

비지니스 로직을 처리하는 부분

 

package com.kopo.exam_hibernate.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_hibernate.dao.ExamRepo;
import com.kopo.exam_hibernate.domain.ExamRIO;
import com.kopo.exam_hibernate.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)의 createOne()메소드를 불러와서(DB요청)
		//ExamRIO형의 데이터를 인자로 넣는다.
		//ExamRIO형의 데이터를 넣을 때 new를 통해 객체를 만들고 
		//넣을 데이터로서 매개변수로 받은 ExamSIO의 데이터를 get메소드를 통해
		//이름 학번 각 점수를 추출하여 데이터를 넣어준다.
		repo.createOne(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)의 selectOne()메소드를 불러와서(DB요청)
			//인자로 studentid를 넣어서 해당하는 데이터를 exam변수에 담는다.
			exam = repo.selectOne(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)의 selectAll()메소드를 불러와서(DB요청)
			//리턴된 데이터를 exams에 담는다.
			exams = repo.selectAll();
		}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
	}
}

 

 

이 외에 나머지 부분은 위 링크에 걸었던 부분과 똑같다.

 

 

 

 

 

 

Comments