欢迎来到Jsf Spring Hibernate集成示例教程。在上一个教程中,我们看到了如何集成JSF和Spring框架在一起。今天我们将学习如何整合JSF Spring Hibernate框架。在用户界面、服务器端依赖注入和ORM工具方面,这是一个很好的组合。
目录
JSF Spring Hibernate
我们的目标是创建一个单页用户界面,从中我们可以输入一些进入数据库的数据。我们得到了相同的响应页面,其中还显示了表中的数据,因此新添加的数据也应该在submit页面上。
下图显示了我们最终的Spring Jsf-hibernate集成项目结构。现在让我们从这个项目开始,看看每个框架是如何粘合在一起以实现我们的目标的。
JSF Spring Hibernate项目设置
在Eclipse中创建一个动态Web项目,然后将其转换为Maven项目,这样我们就可以准备好基本的设置了。现在我们必须在pom.xml文件文件。下面是我们的决赛pom.xml文件文件。注意JSF、Spring、Spring Orm和Hibernate依赖项。我们使用MySQL数据库作为示例,apachedbcp用于创建简单的数据库连接池。
<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文件文件如下所示。
<?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框架集成,为此我们需要配置SpringBeanFacesELResolver
in faces-config.xml
file. It will make sure that JSF view pages variables are mapped to the backend managed beans.
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 Beans配置,但是我们将在看过java类之后再看一下。
JSF-Spring-Hibernate模型类
我们有Person.java
class that is mapped with the Person table in database. Notice the use of JPA and JSF annotations.
package com.journaldev.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 pankaj
*
*/
@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.journaldev.springhibernate.dao;
import java.util.List;
import com.journaldev.springhibernate.model.Person;
public interface PersonDAO {
public void addPerson(Person p);
public List<Person> listPersons();
}
我们有两种方法,一种是在数据库表中插入数据,另一种是获取用户界面中显示的人员列表。
下面是上述DAO的实现类。
PersonDAOImpl.java
package com.journaldev.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.journaldev.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.journaldev.springhibernate.service;
import java.util.List;
import com.journaldev.springhibernate.model.Person;
public interface PersonService {
public void addPerson(Person p);
public List<Person> listPersons();
}
PersonServiceImpl.java
package com.journaldev.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.journaldev.springhibernate.dao.PersonDAO;
import com.journaldev.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();
}
}
注意使用@ManagedBean
JSF annotation and @Transactional
annotation for transaction management.
推荐阅读:Spring Hibernate集成和Spring事务管理
Spring Beans配置文件
我们基于springhibernate的后端服务已经准备好了,现在我们可以将它们连接到Spring Beans配置文件中,如下所示。
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"
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"
>
<beans:property name="dataSource" ref="dataSource" />
<beans:property name="annotatedClasses">
<beans:list>
<beans:value>com.journaldev.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"
>
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory" />
</beans:bean>
<beans:bean id="personService"
>
<beans:property name="personDAO" ref="personDAO"></beans:property>
</beans:bean>
<context:component-scan base-package="com.journaldev" />
<tx:annotation-driven transaction-manager="transactionManager" />
<beans:bean id="transactionManager"
>
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory" />
</beans:bean>
</beans:beans>
注意数据源配置,你必须根据你的设置来调整它们。
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>
<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容器中并运行它,您应该会看到下面的页面。