JSF Spring Hibernate集成示例教程

时间:2020-02-23 14:33:45  来源:igfitidea点击:

欢迎使用JSF Spring Hibernate Integration示例教程。
在上一个教程中,我们了解了如何将JSF和Spring框架集成在一起。
今天,我们将学习如何集成JSF Spring Hibernate框架。
在我们为用户界面,服务器端依赖项注入和ORM工具使用最佳选择的情况下,这是一个很好的组合。

JSF Spring Hibernate

我们的目标是创建一个单页用户界面,从中我们可以输入一些数据进入数据库。
我们在同一响应页面上也显示了表中的数据,因此新添加的数据也应该在页面提交中。

下图显示了我们最终的Spring jsf Hibernate集成项目结构。
让我们从项目开始,看看如何将每个框架粘合在一起以实现我们的目标。

JSF Spring Hibernate项目设置

在Eclipse中创建一个动态Web项目,然后将其转换为Maven项目,以便我们准备好基本设置。
现在,我们必须在pom.xml文件中添加所需的依赖项。
以下是我们最终的pom.xml文件。
注意JSF,Spring,Spring ORM和Hibernate依赖项。
我们在示例中使用MySQL数据库,在创建简单数据库连接池时使用Apache DBCP。

<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/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>JSF_Spring_Hibernate</groupId>
	<artifactId>JSF_Spring_Hibernate</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>

	<properties>

		<!-- Generic properties -->
		<java.version>1.6</java.version>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

		<!-- Spring -->
		<spring-framework.version>4.0.3.RELEASE</spring-framework.version>
		<aspectj.version>1.7.4</aspectj.version>

		<!-- Hibernate/JPA -->
		<hibernate.version>4.3.5.Final</hibernate.version>

		<!-- JSF Version -->
		<jsf.version>2.2.10</jsf.version>

		<!-- Logging -->
		<logback.version>1.0.13</logback.version>
		<slf4j.version>1.7.5</slf4j.version>

	</properties>

	<dependencies>
		<!-- Spring and Transactions -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>${spring-framework.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-tx</artifactId>
			<version>${spring-framework.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${spring-framework.version}</version>
		</dependency>
		<!-- @Inject -->
		<dependency>
			<groupId>javax.inject</groupId>
			<artifactId>javax.inject</artifactId>
			<version>1</version>
		</dependency>
		<!-- AspectJ -->
		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjrt</artifactId>
			<version>${aspectj.version}</version>
		</dependency>
		<!-- Spring ORM support -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-orm</artifactId>
			<version>${spring-framework.version}</version>
		</dependency>

		<!-- Hibernate -->
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-entitymanager</artifactId>
			<version>${hibernate.version}</version>
		</dependency>
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-core</artifactId>
			<version>${hibernate.version}</version>
		</dependency>

		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.9</version>
		</dependency>
		<dependency>
			<groupId>commons-dbcp</groupId>
			<artifactId>commons-dbcp</artifactId>
			<version>1.4</version>
		</dependency>

		<!-- JSF Dependencies -->
		<dependency>
			<groupId>com.sun.faces</groupId>
			<artifactId>jsf-api</artifactId>
			<version>${jsf.version}</version>
		</dependency>

		<dependency>
			<groupId>com.sun.faces</groupId>
			<artifactId>jsf-impl</artifactId>
			<version>${jsf.version}</version>
		</dependency>

		<!-- Logging with SLF4J & LogBack -->
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>${slf4j.version}</version>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>ch.qos.logback</groupId>
			<artifactId>logback-classic</artifactId>
			<version>${logback.version}</version>
			<scope>runtime</scope>
		</dependency>
		<!-- https://repo1.maven.org/maven -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
		</dependency>

		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>2.5</version>
		</dependency>

		<dependency>
			<groupId>javax.servlet.jsp</groupId>
			<artifactId>jsp-api</artifactId>
			<version>2.1</version>
		</dependency>

		<dependency>
			<groupId>com.sun.el</groupId>
			<artifactId>el-ri</artifactId>
			<version>1.0</version>
		</dependency>

		<dependency>
			<groupId>javax</groupId>
			<artifactId>javaee-web-api</artifactId>
			<version>7.0</version>
			<scope>provided</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<artifactId>maven-war-plugin</artifactId>
				<version>2.3</version>
				<configuration>
					<warSourceDirectory>WebContent</warSourceDirectory>
					<failOnMissingWebXml>false</failOnMissingWebXml>
				</configuration>
			</plugin>
			<plugin>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.1</version>
				<configuration>
					<source>1.7</source>
					<target>1.7</target>
				</configuration>
			</plugin>
		</plugins>
		<finalName>${project.artifactId}</finalName>
	</build>
</project>

现在,使用以下脚本在数据库中创建所需的表。

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;

接下来,我们需要在web.xml文件中添加Spring Listener和JSF Controller Servlet,如下所示。

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="https://xmlns.jcp.org/xml/ns/javaee" 
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="https://xmlns.jcp.org/xml/ns/javaee 
https://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
  
<listener>
	<listener-class>
		org.springframework.web.context.ContextLoaderListener
	</listener-class>
</listener>
<listener>
	<listener-class>
		org.springframework.web.context.request.RequestContextListener
	</listener-class>
</listener>
  
  <context-param>
      <param-name>javax.faces.PROJECT_STAGE</param-name>
      <param-value>Development</param-value>
  </context-param>
  <servlet>
      <servlet-name>Faces Servlet</servlet-name>
      <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
      <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
      <servlet-name>Faces Servlet</servlet-name>
      <url-pattern>/*</url-pattern>
  </servlet-mapping>
  <session-config>
      <session-timeout>
          30
      </session-timeout>
  </session-config>
  
</web-app>

接下来,我们需要JSF与Spring框架集成,为此,我们需要在" faces-config.xml"文件中配置" SpringBeanFacesELResolver"。
它将确保将JSF视图页面变量映射到后端托管Bean。

faces-config.xml

<?xml version='1.0' encoding='UTF-8'?>
<faces-config version="2.2"
            xmlns="https://xmlns.jcp.org/xml/ns/javaee"
            xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="https://xmlns.jcp.org/xml/ns/javaee 
            https://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd">

  <application>
      <el-resolver>
          org.springframework.web.jsf.el.SpringBeanFacesELResolver
      </el-resolver>
  </application>
  
</faces-config>

我们需要的最后一个配置是spring bean配置,但是在遍历java类之后我们将对其进行介绍。

JSF Spring Hibernate模型类

我们有Person.java类,该类与数据库中的Person表映射。
注意使用JPA和JSF批注。

package com.theitroad.springhibernate.model;

import javax.faces.bean.ManagedBean;
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 hyman
 *
 */
@Entity
@Table(name="PERSON")
@ManagedBean(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;
  }
}

现在,我们将继续创建DAO类以与数据库表进行交互。

JSF Spring Hibernate DAO类

PersonDAO.java

package com.theitroad.springhibernate.dao;

import java.util.List;

import com.theitroad.springhibernate.model.Person;
 
public interface PersonDAO {
 
  public void addPerson(Person p);
  public List<Person> listPersons();
}

我们有两种方法,一种是将数据插入数据库表,另一种是获取要在用户界面中显示的人员列表。

下面是以上DAO的实现类。

PersonDAOImpl.java

package com.theitroad.springhibernate.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.theitroad.springhibernate.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);
  }
 
  @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;
  }
 
}

现在,我们将创建服务类,然后进行接线。

JSF Spring Hibernate服务类

PersonService.java

package com.theitroad.springhibernate.service;

import java.util.List;

import com.theitroad.springhibernate.model.Person;
 
public interface PersonService {
 
  public void addPerson(Person p);
  public List<Person> listPersons();
   
}

PersonServiceImpl.java

package com.theitroad.springhibernate.service;

import java.util.List;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

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

import com.theitroad.springhibernate.dao.PersonDAO;
import com.theitroad.springhibernate.model.Person;

@Service
@ManagedBean(name="personService")
@SessionScoped
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 List<Person> listPersons() {
      return this.personDAO.listPersons();
  }
 
}

注意在事务管理中使用了@ ManagedBeanJSF注释和@ Transactional注释。

推荐阅读:Spring Hibernate集成和Spring事务管理

Spring Beans配置文件

我们基于Spring Hibernate的后端服务已经准备就绪,现在我们可以将它们连接到spring bean配置文件中,如下所示。

applicationContext.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/" 

	<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="hyman" 
		<beans:property name="password" value="hyman123" 
	</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.theitroad.springhibernate.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.theitroad.springhibernate.dao.PersonDAOImpl">
		<beans:property name="sessionFactory"
			ref="hibernate4AnnotatedSessionFactory" 
	</beans:bean>
	<beans:bean id="personService"
		class="com.theitroad.springhibernate.service.PersonServiceImpl">
		<beans:property name="personDAO" ref="personDAO"></beans:property>
	</beans:bean>
	
	<context:component-scan base-package="com.theitroad" 

	<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配置,您将必须根据设置进行调整。

JSF查看页面

最后一部分是编写JSF视图页面并使用上面配置的托管Bean。

person.xhtml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="https://www.w3.org/1999/xhtml"
	xmlns:h="https://java.sun.com/jsf/html"
	xmlns:ui="https://java.sun.com/jsf/facelets"
	xmlns:c="https://java.sun.com/jsp/jstl/core">
<h:head>
	<title>JSF Spring Hibernate Integration</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>
</h:head>
<h:body>
	<h1>Add a Person</h1>
	<h:form>
		<table>
			<tr>
				<td><label>Name</label></td>
				<td><h:inputText id="name" value="#{person.name}"></h:inputText>
				</td>
			</tr>
			<tr>
				<td><label>Country</label></td>
				<td><h:inputText id="country" value="#{person.country}"></h:inputText>
				</td>
			</tr>
			<tr>
				<td colspan="2"><h:commandButton
						action="#{personService.addPerson(person)}" value="Add Person"></h:commandButton>
				</td>
			</tr>

		</table>

	</h:form>

	<br>
	<h3>Persons List</h3>
	

	<c:if test="${!empty personService.listPersons()}">
		<table class="tg">
			<tr>
				<th width="80">Person ID</th>
				<th width="120">Person Name</th>
				<th width="120">Person Country</th>
			</tr>
			<ui:repeat value="${personService.listPersons()}" var="person">
				<tr>
					<td>${person.id}</td>
					<td>${person.name}</td>
					<td>${person.country}</td>
				</tr>
			</ui:repeat>
		</table>
	</c:if>

</h:body>
</html>

现在只需将应用程序部署到您喜欢的servlet容器中并运行它 .