Primefaces Spring EclipseLink NoSQL与MongoDB和Oracle NoSQL DB

时间:2020-02-23 14:41:40  来源:igfitidea点击:

我们探索了如何在EclipseLink JPA和MySQL等著名的关系数据库之间实现集成。
EclipseLink除了与关系数据库平台集成外,还为您提供了更多功能,并且还支持MongoDB和Oracle NoSQL数据库。

即将发布的下一版本还将使您能够使用:Cassandra,Google Big Table和CouchDB作为NoSQL持久性存储。
在本教程中,我们将为您提供完整的示例,以帮助您与MongoDB和Oracle NoSQL数据库进行JPA集成。

必备工具

  • MongoDB已安装并运行到您的环境中

  • 已安装Oracle NoSQL数据库并在您的环境中运行

  • Apache Tomcat 8

  • JDK 1.7

  • Eclipse开普勒4.3

  • Maven 2+

  • Spring4

  • Mongo EclipseLink 2.6.0-M3。

  • Oracle NoSQL EclipseLink 2.6.0-M3

  • Mongo驱动程序2.6.0-M3。

  • OracleNoSQL驱动程序3.0.5

最终项目结构

员工映射

package com.theitroad.jpa.data;

import java.util.Date;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

import org.eclipse.persistence.nosql.annotations.DataFormatType;
import org.eclipse.persistence.nosql.annotations.Field;
import org.eclipse.persistence.nosql.annotations.NoSql;
@Entity
@NoSql(dataFormat=DataFormatType.MAPPED)
public class Employee {
	@Id
	@GeneratedValue
	@Field(name="_id")
	private String employeeId;
	@Field
	private String employeeName;
	@Field
	private Date employeeHireDate;
	@Field
	private double employeeSalary;

	public String getEmployeeId() {
		return employeeId;
	}

	public void setEmployeeId(String 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;
	}
}

以下是上述代码的详细说明:

  • 员工实体必须带有@Entity注释。
    JPA规范要求该注释。

  • 员工标识符必须以" @Id"注释。
    此属性应映射到默认的_id属性。
    如果您已取消此类映射,则会将新的" EMPLOYEEID"列添加到Employee集合中。
    MongoDB和Oracle NoSQL数据库都自动生成_id属性的值。

  • 您可以选择使用@Field注释来注释员工的属性。
    如果消除它们,则eclipselink将自动进行映射。
    如果您未在自己的MongoDB或者Oracle NoSQL中创建Employee集合,则eclipselink将在您身后进行创建过程,并将分别插入您的文档(即,雇员实例)。

  • 您的实体必须使用@ NoSql进行注释。
    此注释将确保持久存在的实体不代表关系实体。
    DataFormat属性指定用于表示存储的数据的类型。
    MongoDB和Oracle NoSQL使用的Key-BSON格式在结构上类似于地图,因此使用MAPPED值。

MongoDB –持久性上下文

为了连接NoSQL持久性存储,应该定义一个" persistence.xml"文件。

persistence.xml

<persistence xmlns="https://java.sun.com/xml/ns/persistence"
	xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="https://java.sun.com/xml/ns/persistence https://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
	version="2.0">
	<persistence-unit name="eclipselink.mongodb.jpa" transaction-type="RESOURCE_LOCAL">
		<class>com.theitroad.jpa.data.Employee</class>
		<properties>
			<property name="eclipselink.target-database" value="org.eclipse.persistence.nosql.adapters.mongo.MongoPlatform"
          <property name="eclipselink.nosql.connection-spec" value="org.eclipse.persistence.nosql.adapters.mongo.MongoConnectionSpec"
          <property name="eclipselink.nosql.property.mongo.port" value="27017"
          <property name="eclipselink.nosql.property.mongo.host" value="localhost"
          <property name="eclipselink.nosql.property.mongo.db" value="theitroad"
          <property name="eclipselink.logging.level" value="FINEST"
		</properties>
	</persistence-unit>
</persistence>

以下是上面列出的代码的详细说明:

  • NoSQL持久性单元的配置与JPA持久性单元相同,persistence.xml用于定义持久性单元。

  • eclipselink.nosql.connection-spec指定EISConnectionSpec类的名称,该类将用于连接NoSQL持久性存储。

  • " eclipselink.target.database"指定NoSQL平台类。

OracleNoSQL持久性上下文

persistence.xml

<persistence-unit name="eclipselink.oraclenosql.jpa" transaction-type="RESOURCE_LOCAL">
		 <class>com.theitroad.jpa.data.Employee</class>
	     <properties>
	         <property name="eclipselink.target-database" value="org.eclipse.persistence.nosql.adapters.nosql.OracleNoSQLPlatform"
	         <property name="eclipselink.nosql.connection-spec" value="org.eclipse.persistence.nosql.adapters.nosql.OracleNoSQLConnectionSpec"
	         <property name="eclipselink.nosql.property.nosql.host" value="mohammad-amr-lt:5000"
	         <property name="eclipselink.nosql.property.nosql.store" value="kvstore"
	         <property name="eclipselink.logging.level" value="FINEST"
	     </properties>
	</persistence-unit>

以下是上面列出的代码的详细说明:

  • Oracle NoSQL数据库使您能够在引导时创建自己的存储。
    如果已安装Oracle NoSQL数据库,则应执行java -Djava.net.preferIPv4Stack = true -jar lib \ kvstore.jar kvlite来启动Oracle NoSQL数据库。
    作为执行最后一条命令的结果,您应该注意到使用args创建了新的kvlite存储: -root ./kvroot -store kvstore -host mohammad-amr-lt -port 5000 -admin 5001entries。

  • 注意使用在持久性单元中使用的kvstore

EclipseLink – Spring上下文集成

Eclipselink可以与Spring Framework无缝集成。
这种类型的集成将使您轻松获得所需的实体管理器,而无需您参与。

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>

 <!-- Necessary to get the entity manager injected into the factory bean -->
 <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"  

 <!-- Entity Manager Factory -->
 <bean id="entityManagerFactory"
 class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
 <property name="persistenceUnitName" value="eclipselink.mongodb.jpa"></property>
 </bean>

 <!-
 <bean id="entityManagerFactory"
 class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
 <property name="persistenceUnitName" value="eclipselink.oraclenosql.jpa"></property>
 </bean>
 -->

 <!-- Transaction Manager -->
 <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
 <property name="entityManagerFactory" ref="entityManagerFactory" 
 </bean>

 <!-- Detect @Transactional -->
 <tx:annotation-driven transaction-manager="transactionManager" 
</beans>

以下是上面列出的代码的详细说明:

  • 服务器启动侦听器后,Spring框架将寻找其配置上下文-默认为applicationContext.xml。
    应该在应用程序的部署描述符中定义Spring框架的侦听器。
    请参阅下面的" Primefaces部署描述符"部分。

  • MongoDB是一个事务性持久性存储,因此,必须包括所有事务性职员才能保留您的文档。

  • 这次通过传递持久性单元的名称来配置EntityManagerFactory。
    与Oracle和MySQL不同,为创建实例,应传递EclipseJPAVendor实例。

  • 想要连接Oracle NoSQL数据库时,请使用为Oracle NoSQL定义的给定持久性单元名称。

Primefaces部署描述符

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>

以下是上面列出的代码的详细说明:

  • 定义" ContextLoaderListener"对于启动Spring框架是必不可少的。

Primefaces –面孔配置

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>

以下是上面列出的代码的详细说明:

  • SpringBeanFacesELResolver将帮助您将Spring bean注入自己的JSF ManagedBean

Spring员工服务

package com.theitroad.spring.service;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

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

import com.theitroad.jpa.data.Employee;

@Component
public class EmployeeService {
	@PersistenceContext
	private EntityManager em;

	public EntityManager getEm() {
		return em;
	}

	public void setEm(EntityManager em) {
		this.em = em;
	}

	@Transactional
	public void register(Employee emp) {
		//Save employee
		this.em.persist(emp);
	}

}

以下是上面列出的代码的详细说明:

  • 使用@ PersistenceContext将注入EntityManager的实例。
    在Spring上下文中定义的EntityManagerFactory将用于创建EntityManager的实例

Primefaces RegisterEmployee ManagedBean

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.jpa.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 "";
	}
}

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>

MongoDB演示

在下面,您会看到所有屏幕快照,向您解释了员工的注册过程以及针对Mongo数据库保留的员工文档。

  • 我们使用了MongoVUE工具来显示Mongo数据库集合和记录。

  • 正如我们前面提到的,_id列会自动为您定义的所有集合添加。
    要映射您的收藏集ID和_id默认为一个,应使用@Filed(name =" _ id")批注。
    如果您尚未映射它,则会添加一个新列EMPLOYEEID。

OracleNoSQL演示

技术帮助

要安装Oracle NoSQL数据库并将其启动到您的环境中并非易事。
遵循主要步骤,您需要确保有助您实现目标。

  • 下载Oracle NoSQL二进制文件。

  • 解压缩下载的文件。

  • 执行java -Djava.net.preferIPv4Stack = true -jar lib \ kvstore.jar kvlite来启动数据库。

  • 通过在其VM参数中添加-Djava.net.preferIPv4Stack = true配置Apache Tomcat 8。

Maven依赖文件

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-EclipseLink-Spring-Mongo-Oracle-NoSQL-Sample</artifactId>
	<packaging>war</packaging>
	<version>0.0.1-SNAPSHOT</version>
	<name>Primefaces-EclipseLink-Spring-Mongo-Oracle-NoSQL-Sample Maven Webapp</name>
	<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>
		<repository>
			<id>oss.sonatype.org</id>
			<name>OSS Sonatype Staging</name>
			<url>https://oss.sonatype.org/content/groups/staging</url>
		</repository>
	</repositories>
	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>3.8.1</version>
			<scope>test</scope>
		</dependency>
		<!-- 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>
		<!-- 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>
		<!-- Dependencies for Eclipse JPA Persistence API -->
		<dependency>
			<groupId>org.eclipse.persistence</groupId>
			<artifactId>eclipselink</artifactId>
			<version>2.6.0-M3</version>
		</dependency>
		<!-- Dependency for EclipseLink NoSQL Persistence API -->
		<dependency>
			<groupId>org.eclipse.persistence</groupId>
			<artifactId>org.eclipse.persistence.nosql</artifactId>
			<version>2.6.0-M3</version>
		</dependency>
		<!-- MongoDB Driver -->
		<dependency>
			<groupId>org.mongodb</groupId>
			<artifactId>mongo-java-driver</artifactId>
			<version>2.12.3</version>
		</dependency>
		<!-- EclipseLink JPA for OracleNoSQL -->
		<dependency>
			<groupId>org.eclipse.persistence</groupId>
			<artifactId>org.eclipse.persistence.oracle.nosql</artifactId>
			<version>2.6.0-M3</version>
		</dependency>
		<!-- Oracle NoSQL Client Driver -->
		<dependency>
			<groupId>com.oracle.kv</groupId>
			<artifactId>kvclient_3.0.5</artifactId>
			<version>3.0.5</version>
		</dependency>
	</dependencies>
	<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>
</project>