Primefaces Spring和Hibernate集成示例教程
欢迎使用Spring Primefaces和Hibernate集成示例。
框架之间的集成是一项复杂的任务,并且通常需要很多时间才能实现。
我们已经在单独的教程中讨论了Primeme,Spring和Hibernate框架,但是这次我们将向您展示如何集成所有框架以创建分层(分层)应用程序。
SpringPrimefaces休眠
分层(分层)应用程序是一种流行的设计,大多数企业应用程序都与该设计保持一致。
其中:
Primefaces框架将用于处理所有UI问题并验证客户的输入。
Hibernate框架将用于传达您自己的持久性存储,该存储可能是MySQL数据库。
Spring框架将用于在所有这些框架之间粘合。
本教程旨在使用所有列出的框架来实现分层的应用程序。
Spring Primefaces Hibernate所需工具
在开始深入研究之前,让我们看一下所需的必需工具:
Eclipse开普勒4.3。
休眠3.x。
Spring4.x.
Primefaces5.x。
JDK 1.6以上版本。
MySQL5.x。
Primefaces Spring Hibernate项目结构
我们的最终项目结构将如下图所示,我们将逐一介绍每个组件。
创建数据库员工表
MySQL数据库将用于保留所有员工实例/记录。
已用员工表如下所示:
另外,在其SQL创建脚本下方找到:
CREATE TABLE `employee` ( `EMP_ID` int(11) NOT NULL AUTO_INCREMENT, `EMP_NAME` varchar(45) DEFAULT NULL, `EMP_HIRE_DATE` datetime DEFAULT NULL, `EMP_SALARY` decimal(11,4) DEFAULT NULL, PRIMARY KEY (`EMP_ID`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
创建员工模型Bean
创建Employee表后,现在是时候看看Employee类的样子了:
package com.theitroad.hibernate.data;
import java.util.Date;
public class Employee {
private long employeeId;
private String employeeName;
private Date employeeHireDate;
private double employeeSalary;
public long getEmployeeId() {
return employeeId;
}
public void setEmployeeId(long employeeId) {
this.employeeId = employeeId;
}
public String getEmployeeName() {
return employeeName;
}
public void setEmployeeName(String employeeName) {
this.employeeName = employeeName;
}
public Date getEmployeeHireDate() {
return employeeHireDate;
}
public void setEmployeeHireDate(Date employeeHireDate) {
this.employeeHireDate = employeeHireDate;
}
public double getEmployeeSalary() {
return employeeSalary;
}
public void setEmployeeSalary(double employeeSalary) {
this.employeeSalary = employeeSalary;
}
}
Spring Primefaces休眠Maven依赖关系
Maven是一个构建工具,主要用于管理项目依赖项。
因此,无需像通常那样下载JAR并将其附加到项目中。
MySQL JDBC驱动程序,休眠核心,Spring核心框架,Primefaces以及我们进行Spring Hibernate Primefaces集成所需的许多库。
我们最终的pom.xml文件如下所示。
<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.theitroad</groupId> <artifactId>Primefaces-Hibernate-Spring-Integration-Sample</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>Primefaces-Hibernate-Spring-Integration-Sample Maven Webapp</name> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.6</source> <target>1.6</target> </configuration> </plugin> </plugins> </build> <url>https://maven.apache.org</url> <repositories> <repository> <id>prime-repo</id> <name>PrimeFaces Maven Repository</name> <url>https://repository.primefaces.org</url> <layout>default</layout> </repository> </repositories> <dependencies> <!-- Servlet --> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <scope>provided</scope> </dependency> <!-- Faces Implementation --> <dependency> <groupId>com.sun.faces</groupId> <artifactId>jsf-impl</artifactId> <version>2.2.4</version> </dependency> <!-- Faces Library --> <dependency> <groupId>com.sun.faces</groupId> <artifactId>jsf-api</artifactId> <version>2.2.4</version> </dependency> <!-- Primefaces Version 5 --> <dependency> <groupId>org.primefaces</groupId> <artifactId>primefaces</artifactId> <version>5.0</version> </dependency> <!-- JSP Library --> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>javax.servlet.jsp-api</artifactId> <version>2.3.1</version> </dependency> <!-- JSTL Library --> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.1.2</version> </dependency> <!-- Primefaces Theme Library --> <dependency> <groupId>org.primefaces.themes</groupId> <artifactId>blitzer</artifactId> <version>1.0.10</version> </dependency> <!-- Hibernate library --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>3.6.10.Final</version> </dependency> <!-- MySQL driver connector library --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.31</version> </dependency> <!-- Spring ORM --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>4.0.3.RELEASE</version> </dependency> <!-- Spring Web --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.0.3.RELEASE</version> </dependency> <!-- Required By Hibernate --> <dependency> <groupId>commons-dbcp</groupId> <artifactId>commons-dbcp</artifactId> <version>1.4</version> </dependency> <dependency> <groupId>javassist</groupId> <artifactId>javassist</artifactId> <version>3.12.1.GA</version> </dependency> </dependencies> </project>
Spring Primefaces –休眠配置
Hibernate是一种标准的对象关系映射(ORM)解决方案,用于将您的对象域映射到关系表格公式中。
休眠配置过程需要执行以下步骤:
主要在hibernate配置文件中指定所有相关的数据库信息,例如驱动程序,JDBC URL,hibernate方言和hibernate会话上下文,主要使用hibernate.cfg.xml。
休眠实现本身将使用方言来确保映射过程的执行有效完成。
该文件应位于项目的src/main/resources文件夹下。指定休眠的映射文件。
映射文件将包含所有映射信息,例如对象表,属性列和关联关系,domain-classes.hbm.xml文件主要用于此目的。
该文件应位于项目的src/main/resources文件夹下,以便位于应用程序的类路径中。重要的是要说,当我们要使用Spring时,需要进行一些修改。
hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"https://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/theitroad</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<!-- SQL dialect -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Specify session context -->
<property name="hibernate.current_session_context_class">org.hibernate.context.internal.ThreadLocalSessionContext</property>
<!-- Show SQL -->
<property name="hibernate.show_sql">true</property>
<!-- Referring Mapping File -->
<mapping resource="domain-classes.hbm.xml"
</session-factory>
</hibernate-configuration>
domain-classes.hbm.xml
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "https://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd"> <hibernate-mapping> <class name="com.theitroad.hibernate.data.Employee" table="employee"> <id name="employeeId" column="EMP_ID" type="long"> <generator class="native" </id> <property name="employeeName" column="EMP_NAME" type="string" <property name="employeeHireDate" column="EMP_HIRE_DATE" type="date" <property name="employeeSalary" column="EMP_SALARY" type="double" </class> </hibernate-mapping>
测试我们的Hibernate应用程序
到目前为止,我们已经创建了一个配置有必需依赖项的Eclipse Web项目,创建了数据库Employee Table,并创建了休眠框架。
在进一步进行Spring集成和开发Primefaces UI表单之前,让我们看看如何使用简单的Java应用程序将Employee实例保存到我们自己的数据库中。
有了Java应用程序,它将帮助我们确定我们将获得的好处,特别是稍后使用Spring框架时。
package com.theitroad;
import java.util.Date;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import com.theitroad.hibernate.data.Employee;
public class Main {
public static void main(String [] args){
//Create a configuration instance
Configuration configuration = new Configuration();
//Provide configuration file
configuration.configure("hibernate.cfg.xml");
//Build a SessionFactory
SessionFactory factory = configuration.buildSessionFactory(new StandardServiceRegistryBuilder().configure().build());
//Get current session, current session is already associated with Thread
Session session = factory.getCurrentSession();
//Begin transaction, if you would like save your instances, your calling of save must be associated with a transaction
session.getTransaction().begin();
//Create employee
Employee emp = new Employee();
emp.setEmployeeName("Peter Jousha");
emp.setEmployeeSalary(2000);
emp.setEmployeeHireDate(new Date());
//Save
session.save(emp);
//Commit, calling of commit will cause save an instance of employee
session.getTransaction().commit();
}
}
以下是上述代码的详细说明:
Hibernate需要定义的上下文,以使您获得的会话受到影响。
通过提供hibernate的属性hibernate.current_session_context_class可以实现标准Java应用程序上下文。
org.hibernate.context.internal.ThreadLocalSessionContext的值将把上下文绑定到当前执行的线程。
这意味着,如果您对活动事务中的会话对象调用了任何类型的CRUD操作,则一旦事务提交,它们将在您自己的数据库中执行。
在我们的例子中,新的员工实例已保存。
如果您使用的是休眠3,则此属性应为thread,而不是ThreadLocalSessionContext。Hibernate 4用于测试目的,此版本的hibernate在与Spring 4集成时不适用。
要与Spring 4集成,您已请求使用Hibernate 3。使用最新版本的休眠状态要求您使用" StandardServiceRegistryBuilder"来构建SessionFactory。
设置弹簧
Spring是一个全面的框架,主要用于控制反转(IoC),它考虑了众所周知的概念Dependency Injection的更一般的类别。
但是,提供的简单Java应用程序使您能够将Employee实例保存到自己的数据库中,但是通常,这不是大多数应用程序用来配置其自己的休眠持久层的方式。
使用Spring将帮助您避免所有创建和关联对象的东西。
创建所需的对象,关联其他对象主要是Spring的工作。
接下来是Spring上下文配置文件,更新的休眠配置,更新的Maven pom.xml和我们的部署描述符文件。
让我们看看如何配置所有这些以正确使用Spring。
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="https://www.springframework.org/schema/beans"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns:tx="https://www.springframework.org/schema/tx"
xmlns:context="https://www.springframework.org/schema/context"
xmlns:aop="https://www.springframework.org/schema/aop" xmlns:util="https://www.springframework.org/schema/util"
xsi:schemaLocation="https://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd https://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd https://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context-3.2.xsd https://www.springframework.org/schema/tx https://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
<!-- Enable Spring Annotation Configuration -->
<context:annotation-config
<!-- Scan for all of Spring components such as Spring Service -->
<context:component-scan base-package="com.theitroad.spring.service"></context:component-scan>
<!-- Create Data Source bean -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"
<property name="url" value="jdbc:mysql://localhost:3306/theitroad"
<property name="username" value="root"
<property name="password" value="root"
</bean>
<!-- Define SessionFactory bean -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"
<property name="mappingResources">
<list>
<value>domain-classes.hbm.xml</value>
</list>
</property>
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
</bean>
<!-- Transaction Manager -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"
</bean>
<!-- Detect @Transactional Annotation -->
<tx:annotation-driven transaction-manager="transactionManager"
</beans>
hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"https://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- SQL dialect -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
</session-factory>
</hibernate-configuration>
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns="https://java.sun.com/xml/ns/javaee" xmlns:web="https://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="https://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5" metadata-complete="true"> <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>/faces/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>*.xhtml</url-pattern> </servlet-mapping> <context-param> <description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2</description> <param-name>javax.faces.STATE_SAVING_METHOD</param-name> <param-value>client</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <listener> <listener-class>com.sun.faces.config.ConfigureListener</listener-class> </listener> </web-app>
以下是上面给出的代码的详细说明:
我们通过实例化名为sessionFactory的Spring Bean创建了SessionFactory。
实例化SessionFactory确实需要传递数据源实例的实例,传递映射文件(按原样提供domain-classes.hbm.xml),通过使用hibernate.cfg.xml传递所有必需的Hibernate属性。
您已经注意到,hibernate.cfg.xml不包含数据库信息,因为它是立即定义的-Data Source Bean-不需要休眠会话上下文,因此可以通过Apache Tomcat进行丰富。
甚至Apache Tomact都不是托管服务器,但它包含有助于创建上下文会话的功能。交易管理器将帮助您消除使用诸如session.getTransaction()。
begin()和commit()之类的代码片段。
@Transactional注释将替代使用。
这就是说,任何以@Transactional注释的Spring Service方法的执行都将以跨国方式完成。
如果您在诸如session.save()之类的跨国范围内针对会话调用了CRUD操作,它将在被调用方法结束时直接在您自己的数据库中执行。
这就是所谓的交易分界。您可以使用@Component定义自己的Spring Services。
那将被自动扫描。新的库已添加到我们的pom.xml maven依赖文件中,common-dbcp和javassist是hibernate 3所必需的。
如果您已经注意到,Hibernate 4不需要这些库。必须为您的web.xml文件添加Spring上下文加载器监听器。
该侦听器需要在WEB-INF /文件夹下定义一个applicationContext.xml。
这是Spring配置上下文文件的默认位置和名称。
如果您要更改其位置和名称,则必须在以下带有所需路径的代码段中添加。
配置非默认的Spring上下文位置:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/SpringContext.xml</param-value>
</context-param>
注意:如果您正在寻找Spring 4和Hibernate 4的集成,我们需要在Spring Bean配置文件中进行一些小的更改,您可以在Spring Hibernate Integration Example中获得有关此配置的更多信息。
Spring员工服务
在像我们在此所做的分层应用程序中,所有业务操作都必须通过服务来实现。
Spring提供了定义包含业务规则的服务的能力。
EmployeeService将包含创建Employee所需的业务。
package com.theitroad.spring.service;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import com.theitroad.hibernate.data.Employee;
@Component
public class EmployeeService {
@Autowired
private SessionFactory sessionFactory;
public SessionFactory getSessionFactory() {
return sessionFactory;
}
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
@Transactional
public void register(Employee emp){
//Acquire session
Session session = sessionFactory.getCurrentSession();
//Save employee, saving behavior get done in a transactional manner
session.save(emp);
}
}
以下是上述代码的详细说明:
EmployeeService是一个Spring服务,@ Component批注用于定义Spring Service。
默认情况下,Spring将根据上下文:component-scan标签扫描您提到的软件包以找到您的服务。@Autowired将帮助您注入所需的实例。
那就是依赖注入或者IoC(控制反转)概念。
这是一个重要的概念,它意味着不允许开发人员控制创建实例和进行所需关联的过程。
它使所有这些创建和关联都在后面可见。
这是Spring不可思议的力量。
@Autowired用于注入SessionFactory的一个实例,如果您担心性能问题,可以将SessionFactory bean定义为单例作用域。
有关自动装配的完整信息,请阅读Spring自动装配示例。@Transactional批注用于事务划分目的。
事务划分用于将上下文会话与活动事务相关联。
这将导致针对您自己的数据库执行CRUD操作。
您应该阅读Spring声明式事务管理示例。
Primefaces托管Bean – RegisterEmployee
Managed Bean是一种JSF功能,用于处理所有必需的用户界面验证。
在分层应用程序中,托管Bean用于调用业务服务。
当您知道将EmployeeService Spring bean注入自己的Managed Bean中时,您可能会想知道。
如果您使用@ManagedProperty批注,那将成为事实。
faces-config.xml
<?xml version="1.0" encoding="UTF-8"?> <faces-config 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" version="2.2"> <application> <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver> </application> </faces-config>
package com.theitroad.prime.faces.beans;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import com.theitroad.hibernate.data.Employee;
import com.theitroad.spring.service.EmployeeService;
@ManagedBean
@SessionScoped
public class RegisterEmployee {
@ManagedProperty("#{employeeService}")
private EmployeeService employeeService;
private Employee employee = new Employee();
public EmployeeService getEmployeeService() {
return employeeService;
}
public void setEmployeeService(EmployeeService employeeService) {
this.employeeService = employeeService;
}
public Employee getEmployee() {
return employee;
}
public void setEmployee(Employee employee) {
this.employee = employee;
}
public String register() {
//Calling Business Service
employeeService.register(employee);
//Add message
FacesContext.getCurrentInstance().addMessage(null,
new FacesMessage("The Employee "+this.employee.getEmployeeName()+" Is Registered Successfully"));
return "";
}
}
以下是上述代码的详细说明:
RegisterEmployee托管Bean是使用@ManagedProperty批注开发的,它将帮助您获得Spring EmployeeService实例的注入。
如果您未提供包含新添加的Spring el-resolver的特殊faces-config.xml文件,则该关联将不适用。Primefaces UI表单将帮助您收集有关注册员工的所有必需信息。
注册操作将要求EmployeeService保存给定的雇员实例。
Primefaces –注册表
index.xhtml
<html xmlns="https://www.w3.org/1999/xhtml"
xmlns:ui="https://java.sun.com/jsf/facelets"
xmlns:h="https://java.sun.com/jsf/html"
xmlns:f="https://java.sun.com/jsf/core"
xmlns:p="https://primefaces.org/ui">
<h:head>
<script name="jquery/jquery.js" library="primefaces"></script>
<title>Register Employee</title>
</h:head>
<h:form>
<p:growl id="messages"></p:growl>
<p:panelGrid columns="2">
<p:outputLabel value="Enter Employee Name:"></p:outputLabel>
<p:inputText value="#{registerEmployee.employee.employeeName}"></p:inputText>
<p:outputLabel value="Enter Employee Hire Date:"></p:outputLabel>
<p:calendar value="#{registerEmployee.employee.employeeHireDate}"></p:calendar>
<p:outputLabel value="Enter Employee Salary:"></p:outputLabel>
<p:inputText value="#{registerEmployee.employee.employeeSalary}"></p:inputText>
</p:panelGrid>
<p:commandButton value="Register" action="#{registerEmployee.register}" update="messages"></p:commandButton>
</h:form>
</html>

