דוגמה לאינטגרציה של Spring MVC Hibernate MySQL עם פעולות CRUD

למדנו כיצד לאינטגרציה Spring ו-Hibernate בשיעור האחרון שלנו. היום נמשיך קדימה ונאינטגר גם את Spring MVC ו-Hibernate בדוגמת CRUD של אפליקציה אינטרנטית. מבנה הפרוייקט הסופי שלנו נראה כמו בתמונה למטה, ונבחן כל אחד מהרכיבים בנפרד. שים לב שאני משתמש ב-Spring 4.0.3.Release וב-Hibernate 4.3.5.Final לדוגמה שלנו, אותו תוכנית גם תואמת ל-Spring 4 ול-Hibernate 3, אך עליך לבצע שינויים קטנים בקובץ התצורה של ביני הפולנים של Spring הנדוש בשיעור האחרון.

תלויות Maven

בוא נבחן את כל תלותי ה-Maven הנדרשים לאינטגרציה של המסגרות Hibernate ו-Spring MVC.

<?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 בתיקיית lib של טומקט וחיבורים קשורים למקורות נתונים מוגדרים עם זה. בשביל בעיות קשורות לחיבור למסד נתונים, יש לשים את דרייבר מסד הנתונים בספריית המעטפת או לכלול אותו בתלותי pom.xml.

תיאור ההפצה

עלינו להוסיף את מערכת הפרימטרים של Spring לאפליקצית האינטרנט שלנו, וזה נעשה על ידי הגדרת DispatcherServlet של Spring כמחלקת הבקרה הראשית. קובץ ה־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>

רוב החלק הוא קוד תבניתי, החלק החשוב ביותר הוא מיקום קובץ ההקשר של Spring בו נגדיר את פריטי הבונים והשירותים שלנו. אם ברצונך, תוכל לשנות אותם לפי דרישות הפרויקט שלך.

שמירת מופע היישות של Hibernate

אנו משתמשים באננוטציות JPA במחלקת יישות היישות שלנו, אך ניתן גם להשתמש בבון Java פשוט ולהגדיר את פרטי המיפוי בקובץ ה-XML. במקרה כזה, עלינו לספק פרטי קובץ המיפוי בזמן הגדרת ה-SessionFactory של Hibernate בתצורות הקובץ של Spring Bean.

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;
	}
}

מופע היישות שלנו ממפה לטבלת PERSON במסד הנתונים של MySQL. שים לב שלא סימנתי את השדות "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;

מימוש DAO של Hibernate

ניצור ממשק PersonDAO כדי להצהיר על השיטות שנשתמש בהן בפרויקט שלנו. לאחר מכן, נספק יישום ספציפי של Hibernate עבורו.

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 הספציפי של Hibernate נראה כמו שמוצג למטה.

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, זה כי הן יתורגשו על ידי הספרינג.

מחלקות שירות של Spring

הנה כיתות השירות שלנו שמשתמשות בכיתות 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);
	}

}

שים לב שניהול העסקאות הפעולה של Spring מיושם באמצעות הערה @Transactional.

מחלקת הבקרה של Spring

כיתות ה-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 של מסגרת ה-Spring. לקריאה מומלצת: אוטואיירינג של בינים של Spring

הגדרת בינים של Spring

השירותים שלנו מוכנים, כל מה שאנחנו צריכים הוא לחבר אותם דרך הגדרות ה־spring bean. הקובץ 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.LocalSessionFactoryBean ו־org.springframework.orm.hibernate3.AnnotationSessionFactoryBean. נקודה חשובה היא שכאשר אנו תלויים ב-Spring framework לניהול סשן של Hibernate, אנו לא צריכים להגדיר את hibernate.current_session_context_class, אחרת תתקבל כמות רבה של בעיות הקשורות להעברת סשן. ה-personDAO וה-personService הם די ברורים בעצמם. הגדרת החלות transactionManager עבור org.springframework.orm.hibernate4.HibernateTransactionManager נדרשת כדי ש-Spring ORM יתמוך בניהול עסקאות סשן של Hibernate. לגרסת Hibernate 3, תמצא מחלקה דומה כמו org.springframework.orm.hibernate3.HibernateTransactionManager. Spring משתמש ב-AOP לניהול עסקאות, אפשר כעת לקשר את זה עם הערת @Transactional. קריאה מומלצת: Spring AOP ו־ניהול עסקאות Spring

הצג עמוד

החלק האחרון של האפליקציה שלנו הוא עמוד התצוגה, שימו לב למאפיינים שנוספו למודל בשיטות עורכי הבקר בקונטרולר, נשתמש בהם כדי ליצור את עמוד התצוגה שלנו. נשתמש גם בתגי JSTL, תגי הליבה של Spring ותגי הטופס של Spring.

<%@ 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>

בדיקת יישום Spring MVC Hibernate

רק בנו והשקו את הפרויקט בתוך כל מאגר סרבל שתבחרו, לדוגמה, Tomcat. בתמונות המסך למטה מוצגות עמודי התצוגה של האפליקציה שלנו. תמצאו גם דוחות דומים בקובץ יומן השרת.

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