스프링 MVC 하이버네이트 MySQL 통합 CRUD 예제 튜토리얼

우리는 지난 강의에서 Spring과 Hibernate을 통합하는 방법을 배웠습니다. 오늘은 Spring MVC와 Hibernate 프레임워크를 웹 애플리케이션 CRUD 예제에 통합해 보겠습니다. 최종 프로젝트 구조는 아래 이미지와 같습니다. 각 구성 요소를 하나씩 살펴보겠습니다. 우리 예제에는 Spring 4.0.3.Release와 Hibernate 4.3.5.Final 버전을 사용하고 있음을 유의하십시오. 동일한 프로그램은 Spring 4와 Hibernate 3에도 호환됩니다. 그러나 지난 강의에서 논의된 spring bean 구성 파일에서 작은 변경을 해야합니다.

Maven Dependencies

하이버네이트와 스프링 MVC 프레임워크 통합에 필요한 모든 Maven 종속성을 살펴보겠습니다.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.journaldev.spring</groupId>
	<artifactId>SpringMVCHibernate</artifactId>
	<name>SpringMVCHibernate</name>
	<packaging>war</packaging>
	<version>1.0.0-BUILD-SNAPSHOT</version>
	<properties>
		<java-version>1.6</java-version>
		<org.springframework-version>4.0.3.RELEASE</org.springframework-version>
		<org.aspectj-version>1.7.4</org.aspectj-version>
		<org.slf4j-version>1.7.5</org.slf4j-version>
		<hibernate.version>4.3.5.Final</hibernate.version>
	</properties>
	<dependencies>
		<!-- Spring -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${org.springframework-version}</version>
			<exclusions>
				<!-- Exclude Commons Logging in favor of SLF4j -->
				<exclusion>
					<groupId>commons-logging</groupId>
					<artifactId>commons-logging</artifactId>
				 </exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${org.springframework-version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-tx</artifactId>
			<version>${org.springframework-version}</version>
		</dependency>
		
		<!-- Hibernate -->
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-core</artifactId>
			<version>${hibernate.version}</version>
		</dependency>
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-entitymanager</artifactId>
			<version>${hibernate.version}</version>
		</dependency>
		
		<!-- Apache Commons DBCP -->
		<dependency>
			<groupId>commons-dbcp</groupId>
			<artifactId>commons-dbcp</artifactId>
			<version>1.4</version>
		</dependency>
		<!-- Spring ORM -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-orm</artifactId>
			<version>${org.springframework-version}</version>
		</dependency>
				
		<!-- AspectJ -->
		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjrt</artifactId>
			<version>${org.aspectj-version}</version>
		</dependency>	
		
		<!-- Logging -->
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>${org.slf4j-version}</version>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>jcl-over-slf4j</artifactId>
			<version>${org.slf4j-version}</version>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>${org.slf4j-version}</version>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.15</version>
			<exclusions>
				<exclusion>
					<groupId>javax.mail</groupId>
					<artifactId>mail</artifactId>
				</exclusion>
				<exclusion>
					<groupId>javax.jms</groupId>
					<artifactId>jms</artifactId>
				</exclusion>
				<exclusion>
					<groupId>com.sun.jdmk</groupId>
					<artifactId>jmxtools</artifactId>
				</exclusion>
				<exclusion>
					<groupId>com.sun.jmx</groupId>
					<artifactId>jmxri</artifactId>
				</exclusion>
			</exclusions>
			<scope>runtime</scope>
		</dependency>

		<!-- @Inject -->
		<dependency>
			<groupId>javax.inject</groupId>
			<artifactId>javax.inject</artifactId>
			<version>1</version>
		</dependency>
				
		<!-- Servlet -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>2.5</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.6</source>
                    <target>1.6</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>
        <finalName>${project.artifactId}</finalName>
    </build>
</project>

STS(Spring Tool Suite)를 사용하여 Spring MVC 프로젝트를 생성할 때 포함되는 의존성 중 중요한 의존성은 spring-context, spring-webmvc, spring-tx, hibernate-core, hibernate-entitymanager, 그리고 spring-orm입니다. 저는 Apache Commons DBCP를 연결 풀링에 사용하고 있지만, 실제 상황에서는 대부분 컨테이너에 의해 연결 풀링이 수행되고, 우리가 해야 할 일은 JNDI 참조 세부 정보를 제공하는 것입니다. 주의: 일부 독자들이 데이터베이스 연결 문제를 겪고 있는 것을 확인했습니다. 내 pom.xml에는 데이터베이스 드라이버가 없다는 점을 유의하세요. 이는 MySQL 드라이버가 tomcat lib 디렉토리에 있고, 그것과 일부 DataSource 연결이 구성되어 있기 때문에 저에게는 문제가 없습니다. 데이터베이스 연결 관련 문제가 있다면, 컨테이너 lib에 데이터베이스 드라이버를 넣거나 pom.xml 의존성에 포함시키세요.

배포 설명자

우리는 웹 애플리케이션에 스프링 프레임워크를 플러그인해야 합니다. 이는 DispatcherServlet을 프론트 컨트롤러로 구성함으로써 수행됩니다. 우리의 web.xml 파일은 아래와 같습니다.

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="https://java.sun.com/xml/ns/javaee"
	xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="https://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>

</web-app>

대부분의 부분은 보일러플레이트 코드이며, 가장 중요한 부분은 스프링 빈과 서비스를 구성할 스프링 컨텍스트 파일 위치입니다. 원한다면, 프로젝트 요구사항에 따라 이를 변경할 수 있습니다.

Hibernate 엔티티 빈

우리는 엔티티 빈 클래스에서 JPA 주석을 사용하고 있습니다. 그러나 간단한 자바 빈과 매핑 세부 정보를 XML 파일에도 지정할 수 있습니다. 그 경우에는 스프링 빈 구성에서 Hibernate SessionFactory를 구성할 때 매핑 파일 세부 정보를 제공해야 합니다.

package com.journaldev.spring.model;

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

/**
 * Entity bean with JPA annotations
 * Hibernate provides JPA implementation
 * @author pankaj
 *
 */
@Entity
@Table(name="PERSON")
public class Person {

	@Id
	@Column(name="id")
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	private int id;
	
	private String name;
	
	private String country;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getCountry() {
		return country;
	}

	public void setCountry(String country) {
		this.country = country;
	}
	
	@Override
	public String toString(){
		return "id="+id+", name="+name+", country="+country;
	}
}

우리의 엔티티 빈은 MySQL 데이터베이스의 PERSON 테이블에 매핑되는데, “name”과 “country” 필드에는 @Column 주석을 달지 않았음을 주의하십시오. 이는 그들이 동일한 이름을 가지기 때문입니다. 아래 SQL 스크립트는 테이블 세부 정보를 보여줍니다.

CREATE TABLE `Person` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(20) NOT NULL DEFAULT '',
  `country` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

Hibernate DAO 구현

PersonDAO 인터페이스를 생성하여 프로젝트에서 사용할 메서드를 선언할 것입니다. 그런 다음, 이를 위해 하이버네이트 특정 구현을 제공할 것입니다.

package com.journaldev.spring.dao;

import java.util.List;

import com.journaldev.spring.model.Person;

public interface PersonDAO {

	public void addPerson(Person p);
	public void updatePerson(Person p);
	public List<Person> listPersons();
	public Person getPersonById(int id);
	public void removePerson(int id);
}

하이버네이트 특정 DAO 구현은 아래와 같습니다.

package com.journaldev.spring.dao;

import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Repository;

import com.journaldev.spring.model.Person;

@Repository
public class PersonDAOImpl implements PersonDAO {
	
	private static final Logger logger = LoggerFactory.getLogger(PersonDAOImpl.class);

	private SessionFactory sessionFactory;
	
	public void setSessionFactory(SessionFactory sf){
		this.sessionFactory = sf;
	}

	@Override
	public void addPerson(Person p) {
		Session session = this.sessionFactory.getCurrentSession();
		session.persist(p);
		logger.info("Person saved successfully, Person Details="+p);
	}

	@Override
	public void updatePerson(Person p) {
		Session session = this.sessionFactory.getCurrentSession();
		session.update(p);
		logger.info("Person updated successfully, Person Details="+p);
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Person> listPersons() {
		Session session = this.sessionFactory.getCurrentSession();
		List<Person> personsList = session.createQuery("from Person").list();
		for(Person p : personsList){
			logger.info("Person List::"+p);
		}
		return personsList;
	}

	@Override
	public Person getPersonById(int id) {
		Session session = this.sessionFactory.getCurrentSession();		
		Person p = (Person) session.load(Person.class, new Integer(id));
		logger.info("Person loaded successfully, Person details="+p);
		return p;
	}

	@Override
	public void removePerson(int id) {
		Session session = this.sessionFactory.getCurrentSession();
		Person p = (Person) session.load(Person.class, new Integer(id));
		if(null != p){
			session.delete(p);
		}
		logger.info("Person deleted successfully, person details="+p);
	}

}

하이버네이트 트랜잭션을 사용하지 않고 있다는 점에 유의하십시오. 이는 스프링 프레임워크에서 처리될 것이기 때문입니다.

스프링 서비스 클래스

여기 Hibernate DAO 클래스를 사용하여 Person 객체와 작업하는 서비스 클래스가 있습니다.

package com.journaldev.spring.service;

import java.util.List;

import com.journaldev.spring.model.Person;

public interface PersonService {

	public void addPerson(Person p);
	public void updatePerson(Person p);
	public List<Person> listPersons();
	public Person getPersonById(int id);
	public void removePerson(int id);
	
}
package com.journaldev.spring.service;

import java.util.List;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.journaldev.spring.dao.PersonDAO;
import com.journaldev.spring.model.Person;

@Service
public class PersonServiceImpl implements PersonService {
	
	private PersonDAO personDAO;

	public void setPersonDAO(PersonDAO personDAO) {
		this.personDAO = personDAO;
	}

	@Override
	@Transactional
	public void addPerson(Person p) {
		this.personDAO.addPerson(p);
	}

	@Override
	@Transactional
	public void updatePerson(Person p) {
		this.personDAO.updatePerson(p);
	}

	@Override
	@Transactional
	public List<Person> listPersons() {
		return this.personDAO.listPersons();
	}

	@Override
	@Transactional
	public Person getPersonById(int id) {
		return this.personDAO.getPersonById(id);
	}

	@Override
	@Transactional
	public void removePerson(int id) {
		this.personDAO.removePerson(id);
	}

}

스프링 선언적 트랜잭션 관리가 @Transactional 어노테이션을 사용하여 적용되었음을 주목하십시오.

스프링 컨트롤러 클래스

저희 DAO 및 서비스 클래스가 준비되었습니다. 이제 클라이언트 요청을 처리하고 서비스 클래스를 사용하여 데이터베이스별 작업을 수행한 다음 뷰 페이지를 반환할 컨트롤러 클래스를 작성할 때입니다.

package com.journaldev.spring;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.journaldev.spring.model.Person;
import com.journaldev.spring.service.PersonService;

@Controller
public class PersonController {
	
	private PersonService personService;
	
	@Autowired(required=true)
	@Qualifier(value="personService")
	public void setPersonService(PersonService ps){
		this.personService = ps;
	}
	
	@RequestMapping(value = "/persons", method = RequestMethod.GET)
	public String listPersons(Model model) {
		model.addAttribute("person", new Person());
		model.addAttribute("listPersons", this.personService.listPersons());
		return "person";
	}
	
	// 사람 추가 및 업데이트 모두에 대해
	@RequestMapping(value= "/person/add", method = RequestMethod.POST)
	public String addPerson(@ModelAttribute("person") Person p){
		
		if(p.getId() == 0){
			// 새로운 사람을 추가하십시오
			this.personService.addPerson(p);
		}else{
			// 기존의 사람인 경우, 업데이트 호출
			this.personService.updatePerson(p);
		}
		
		return "redirect:/persons";
		
	}
	
	@RequestMapping("/remove/{id}")
    public String removePerson(@PathVariable("id") int id){
		
        this.personService.removePerson(id);
        return "redirect:/persons";
    }
 
    @RequestMapping("/edit/{id}")
    public String editPerson(@PathVariable("id") int id, Model model){
        model.addAttribute("person", this.personService.getPersonById(id));
        model.addAttribute("listPersons", this.personService.listPersons());
        return "person";
    }
	
}

@Controller 어노테이션을 사용하고 있음을 주목하십시오. 따라서 Spring 프레임워크가 이를 클라이언트 요청을 처리하기 위한 컨트롤러 클래스로 처리합니다. 또한 @Autowired@Qualifier 어노테이션을 사용하여 PersonService를 주입하고 있습니다. 스프링 컨텍스트 XML 파일에서도 이를 수행할 수 있었습니다. 권장 독서: 스프링 빈 자동 연결

스프링 빈 구성

우리의 서비스가 준비되었습니다. 필요한 모든 것은 스프링 빈 구성을 통해 연결하는 것뿐입니다. 우리의 root-context.xml 파일은 비어 있으므로 servlet-context.xml 파일만 살펴볼 것입니다.

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="https://www.springframework.org/schema/mvc"
	xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns:beans="https://www.springframework.org/schema/beans"
	xmlns:context="https://www.springframework.org/schema/context" xmlns:tx="https://www.springframework.org/schema/tx"
	xsi:schemaLocation="https://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
		https://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
		https://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd
		https://www.springframework.org/schema/tx https://www.springframework.org/schema/tx/spring-tx-4.0.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>

	<beans:bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
		destroy-method="close">
		<beans:property name="driverClassName" value="com.mysql.jdbc.Driver" />
		<beans:property name="url"
			value="jdbc:mysql://localhost:3306/TestDB" />
		<beans:property name="username" value="pankaj" />
		<beans:property name="password" value="pankaj123" />
	</beans:bean>

	<!-- Hibernate 4 SessionFactory Bean definition -->
	<beans:bean id="hibernate4AnnotatedSessionFactory"
		class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
		<beans:property name="dataSource" ref="dataSource" />
		<beans:property name="annotatedClasses">
			<beans:list>
				<beans:value>com.journaldev.spring.model.Person</beans:value>
			</beans:list>
		</beans:property>
		<beans:property name="hibernateProperties">
			<beans:props>
				<beans:prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect
				</beans:prop>
				<beans:prop key="hibernate.show_sql">true</beans:prop>
			</beans:props>
		</beans:property>
	</beans:bean>
	
	<beans:bean id="personDAO" class="com.journaldev.spring.dao.PersonDAOImpl">
		<beans:property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory" />
	</beans:bean>
	<beans:bean id="personService" class="com.journaldev.spring.service.PersonServiceImpl">
		<beans:property name="personDAO" ref="personDAO"></beans:property>
	</beans:bean>
	<context:component-scan base-package="com.journaldev.spring" />
	
	<tx:annotation-driven transaction-manager="transactionManager"/>
	
	<beans:bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
		<beans:property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory" />
	</beans:bean>

</beans:beans>

dataSource 빈은 기본 연결 풀링을 위해 org.apache.commons.dbcp.BasicDataSource 클래스에 정의됩니다. org.springframework.orm.hibernate4.LocalSessionFactoryBean 빈은 Hibernate 4 SessionFactory에 사용됩니다. Hibernate 3의 경우, org.springframework.orm.hibernate3.LocalSessionFactoryBeanorg.springframework.orm.hibernate3.AnnotationSessionFactoryBean과 유사한 클래스를 찾을 수 있습니다. 중요한 점은 Hibernate Session 관리를 위해 Spring 프레임워크에 의존할 때 hibernate.current_session_context_class를 정의하지 않아야 합니다. 그렇지 않으면 많은 세션 트랜잭션 관련 문제가 발생합니다. personDAOpersonService 빈은 자명합니다. transactionManager 빈은 Spring ORM에서 Hibernate 세션 트랜잭션 관리를 지원하기 위해 org.springframework.orm.hibernate4.HibernateTransactionManager에 대한 정의가 필요합니다. Hibernate 3의 경우, org.springframework.orm.hibernate3.HibernateTransactionManager와 유사한 클래스를 찾을 수 있습니다. Spring은 트랜잭션 관리를 위해 AOP를 사용합니다. 이제 이것을 @Transactional 어노테이션과 관련짓을 수 있습니다. 추천 도서: Spring AOPSpring 트랜잭션 관리

페이지 보기

우리 어플리케이션의 마지막 부분은 페이지 보기입니다. 컨트롤러 핸들러 메소드에서 모델에 추가된 속성에 주목하세요. 이러한 속성들을 사용하여 페이지 보기를 만들 것입니다. 또한 JSTL 태그, 스프링 코어 및 스프링 폼 태그를 사용할 것입니다.

<%@ taglib uri="https://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="https://www.springframework.org/tags" prefix="spring" %>
<%@ taglib uri="https://www.springframework.org/tags/form" prefix="form" %>
<%@ page session="false" %>
<html>
<head>
	<title>Person Page</title>
	<style type="text/css">
		.tg  {border-collapse:collapse;border-spacing:0;border-color:#ccc;}
		.tg td{font-family:Arial, sans-serif;font-size:14px;padding:10px 5px;border-style:solid;border-width:1px;overflow:hidden;word-break:normal;border-color:#ccc;color:#333;background-color:#fff;}
		.tg th{font-family:Arial, sans-serif;font-size:14px;font-weight:normal;padding:10px 5px;border-style:solid;border-width:1px;overflow:hidden;word-break:normal;border-color:#ccc;color:#333;background-color:#f0f0f0;}
		.tg .tg-4eph{background-color:#f9f9f9}
	</style>
</head>
<body>
<h1>
	Add a Person
</h1>

<c:url var="addAction" value="/person/add" ></c:url>

<form:form action="${addAction}" commandName="person">
<table>
	<c:if test="${!empty person.name}">
	<tr>
		<td>
			<form:label path="id">
				<spring:message text="ID"/>
			</form:label>
		</td>
		<td>
			<form:input path="id" readonly="true" size="8"  disabled="true" />
			<form:hidden path="id" />
		</td> 
	</tr>
	</c:if>
	<tr>
		<td>
			<form:label path="name">
				<spring:message text="Name"/>
			</form:label>
		</td>
		<td>
			<form:input path="name" />
		</td> 
	</tr>
	<tr>
		<td>
			<form:label path="country">
				<spring:message text="Country"/>
			</form:label>
		</td>
		<td>
			<form:input path="country" />
		</td>
	</tr>
	<tr>
		<td colspan="2">
			<c:if test="${!empty person.name}">
				<input type="submit"
					value="<spring:message text="Edit Person"/>" />
			</c:if>
			<c:if test="${empty person.name}">
				<input type="submit"
					value="<spring:message text="Add Person"/>" />
			</c:if>
		</td>
	</tr>
</table>	
</form:form>
<br>
<h3>Persons List</h3>
<c:if test="${!empty listPersons}">
	<table class="tg">
	<tr>
		<th width="80">Person ID</th>
		<th width="120">Person Name</th>
		<th width="120">Person Country</th>
		<th width="60">Edit</th>
		<th width="60">Delete</th>
	</tr>
	<c:forEach items="${listPersons}" var="person">
		<tr>
			<td>${person.id}</td>
			<td>${person.name}</td>
			<td>${person.country}</td>
			<td><a href="<c:url value='/edit/${person.id}' />" >Edit</a></td>
			<td><a href="<c:url value='/remove/${person.id}' />" >Delete</a></td>
		</tr>
	</c:forEach>
	</table>
</c:if>
</body>
</html>

스프링 MVC 하이버네이트 어플리케이션 테스트

프로젝트를 빌드하고 선택한 서블릿 컨테이너(예: 톰캣)에 배포하세요. 아래 스크린샷은 어플리케이션의 페이지 보기를 보여줍니다. 서버 로그 파일에서도 유사한 로그를 찾을 수 있습니다.

Hibernate: insert into PERSON (country, name) values (?, ?)
INFO : com.journaldev.spring.dao.PersonDAOImpl - Person saved successfully, Person Details=id=15, name=Pankaj, country=USA
Hibernate: select person0_.id as id1_0_, person0_.country as country2_0_, person0_.name as name3_0_ from PERSON person0_
INFO : com.journaldev.spring.dao.PersonDAOImpl - Person List::id=10, name=Raman, country=UK2
INFO : com.journaldev.spring.dao.PersonDAOImpl - Person List::id=11, name=Lisa, country=France
INFO : com.journaldev.spring.dao.PersonDAOImpl - Person List::id=15, name=Pankaj, country=USA

요약

이 자습서는 Spring MVC 및 Hibernate 통합을 시작하는 데 충분한 세부 정보를 제공하기 위해 목표로 했습니다. 이를 유용하게 활용하시기를 바랍니다. 최종 프로젝트를 아래 링크에서 다운로드하고 시도해 볼 수 있습니다.

Spring MVC Hibernate 통합 프로젝트 다운로드

또한 프로젝트를 우리의 GitHub 저장소에서 확인할 수도 있습니다.

Source:
https://www.digitalocean.com/community/tutorials/spring-mvc-hibernate-mysql-integration-crud-example-tutorial