欢迎使用Spring Primefaces和Hibernate集成示例。框架之间的集成是一项复杂的任务,而且通常需要大量的时间来实现。我们讨论了Spring Primefaces,Spring和Hibernate框架在一个单独的教程中,但这次我们将向您展示如何集成所有这些框架来创建一个分层(分层)应用程序。
SpringSpring PrimefacesHibernate
分层(分层)应用程序是一种流行的设计,大多数企业应用程序都与之一致。在哪儿:
- Primefaces框架将用于处理所有UI问题并验证客户端的输入。
- Hibernate框架将用于通信您自己的持久性存储(可能是MySQL数据库)。
- Spring框架将被用来粘合所有这些框架。
本教程旨在使用所有列出的框架实现分层应用程序。
Spring PrimefacesHibernate所需的工具
在开始深入研究之前,让我们看看您需要哪些工具:
- Eclipse开普勒4.3。
- Hibernate3.x。
- Spring4.x。
- Spring Primefaces5.x。
- JDK 1.6+。
- MySQL5.x。
Prime Spring项目Hibernate Faces结构
我们的最终项目结构将如下图所示,我们将逐一介绍每个组件。
创建数据库雇员表
MySQL数据库将用于保留所有employees实例/记录。Used Employee表如下所示:
另外,可以在下面找到它的SQL create脚本:
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.journaldev.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;
}
}
SpringPrimeFaces Hibernate Maven依赖项
Maven是一个构建工具,它主要用于管理项目依赖关系。所以不需要像平常一样下载jar并将其附加到项目中。MySQL JDBC驱动程序,Hibernate核心,Spring核心框架,Spring Primefaces以及许多我们需要的库来集成springhibernate 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.journaldev</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配置
Hibernate是一个标准的对象关系映射(ORM)解决方案,它用于将对象域映射到关系表公式中。Hibernate配置过程需要以下步骤:
- 在hibernate配置文件中指定所有相关的数据库信息,如驱动程序、JDBC URL、hibernate方言和hibernate会话上下文,主要使用hibernate.cfg.xml. hibernate实现本身将使用方言,以确保映射过程的执行是有效的。此文件应位于project&;s src/main/resources文件夹下。
- 指定hibernate的映射文件。映射文件将包含所有映射信息,如对象表、属性列和关联关系,域-类.hbm.xml文件主要用于此目的。此文件应位于project&;s 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/journaldev</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.journaldev.hibernate.data.Employee" table="employee">
<id name="employeeId" column="EMP_ID" type="long">
<generator />
</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应用程序
到目前为止,我们已经创建了一个配置了所需依赖项的eclipseweb项目,创建了数据库Employee表,并创建了hibernate框架。
在深入研究Spring集成和开发Primefaces UI表单之前,让我们看看如何使用一个简单的Java应用程序将Employee实例保存在我们自己的数据库中。给定的Java应用程序将帮助我们确定我们将获得的好处,特别是在以后使用Spring框架时。
package com.journaldev;
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.journaldev.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需要一个已定义的上下文,以使获取的会话受到影响。标准的Java应用程序上下文可以通过提供hibernate&8217;s属性来实现hibernate.current_session_context_类.价值org.hibernate.context.internal.ThreadLocalSessionContext将上下文绑定到当前执行的线程。这意味着,如果您对其调用了任何类型的CRUD操作阶段对象,一旦事务提交,它们将在您自己的数据库中执行。在我们的例子中,保存了一个新的employee实例。如果您使用了hibernate 3,则此属性应为线而不是使用ThreadLocalSessionContext。
- hibernate4用于测试目的,Hibernate的这个版本在与spring4集成时不适用。为了与Spring4集成,您已经请求使用Hibernate3。
- 使用hibernate的最新版本需要使用
StandardServiceRegistryBuilder
to build SessionFactory.
安装Spring
Spring是一个综合性的框架,它主要用于控制反转(IoC),它考虑了更一般的概念范畴依赖注入.
然而,提供的简单Java应用程序使您能够根据自己的数据库保存员工实例,但通常情况下,这不是大多数应用程序用来配置自己的hibernate持久性层的方式。
使用Spring将帮助您避免创建和关联对象填充。创建所需对象、关联其他对象主要是Spring作业。下面是Spring上下文配置文件、更新的hibernate配置、更新的Mavenpom.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.journaldev.spring.service"></context:component-scan>
<!-- Create Data Source bean -->
<bean id="dataSource"
destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/journaldev" />
<property name="username" value="root" />
<property name="password" value="root" />
</bean>
<!-- Define SessionFactory bean -->
<bean id="sessionFactory"
>
<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"
>
<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确实需要传递数据源实例的瞬间,传递映射文件(域-类.hbm.xml按原样),通过使用hibernate.cfg.xml. 正如您所注意到的,hibernate.cfg.xml不包含数据库信息,因为它是立即定义的;数据源Bean而且不需要hibernate会话上下文,因为apachetomcat丰富了它。即使阿帕奇Tomact也不是托管服务器,但它包含帮助创建上下文会话的工具。
- 事务管理器将帮助您消除使用类似会话.getTransaction().开始()以及提交(). @事务性注解也可以使用。这意味着,任何带有@Transactional注解的Spring服务方法的执行都将以跨国的方式完成。万一你对你的会议类似的跨国范围会话.保存(),它将在被调用方法的末尾直接执行到您自己的数据库中。这就是所谓的事务划分。
- 您可以使用@Component定义自己的Spring服务。会自动扫描的。
- 我们的pom.xml文件 maven依赖项文件通用dbcp以及javassist是hibernate 3所必需的。如果您注意到,Hibernate 4不需要这些库。
- 必须为您的web.xml文件文件。此侦听器需要应用程序上下文.xml 在下面定义WEB-INF/文件夹。这是Spring配置上下文文件的默认位置和名称。如果要更改其位置和名称,则必须在下面添加随所需路径提供的代码片段。
配置非默认Spring上下文位置:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/SpringContext.xml</param-value>
</context-param>
注意:如果您正在寻找Spring4和Hibernate4的集成,我们需要对SpringBean配置文件进行一些小的更改,您可以在Spring Hibernate集成示例.
Spring就业服务
在分层应用程序中,如我们在这里所做的,所有业务操作都必须通过服务实现。Spring为您提供了定义包含自己业务规则的服务的能力,EmployeeService将包含创建员工所需的业务。
package com.journaldev.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.journaldev.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服务。默认情况下,Spring将扫描您提到的包,以便根据上下文:组件扫描 标签。
- @Autowired将帮助您获得所需的实例注入。这是依赖注入或IoC(inversionofcontrol)的概念。它是一个重要的概念,它意味着它不允许开发人员控制创建实例和创建所需关联的过程。它使所有这些创造和联系在背后被看到。那是一种不可思议的Spring的力量。@Autowired用于注入SessionFactory的一个实例,如果您担心性能问题,可以将SessionFactory bean定义为单例作用域。有关自动布线的完整信息,请阅读Spring自动布线示例.
- @事务注解用于事务划分。事务划分用于将上下文会话与活动事务关联起来。这将导致对您自己的数据库执行CRUD操作。你应该通过Spring声明性事务管理示例.
Primefaces托管Bean和注册员工
托管Bean是一个JSF工具,用于处理所有必需的用户界面验证。在分层应用程序中,托管Bean用于调用业务服务。一旦您知道将employeeServiceSpringbean注入自己的托管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.journaldev.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.journaldev.hibernate.data.Employee;
import com.journaldev.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 "";
}
}
以下是对上述代码的详细说明:
- registereemployee托管Bean是使用
@ManagedProperty
annotation that will help you get a Spring EmployeeService instance injected. That association won’t be applicable if you don’t provide a special 面孔-配置.xml包含一个新添加的Spring&8217;s el解析器的文件。 - PrimeFacesUI表单将帮助您收集有关注册员工的所有必需信息。
- Register操作将要求EmployeeService保存给定的EmployeeService实例。
Primefaces和#8211;登记表
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>