JPA EntityManager – Hibernate EntityManager

时间:2020-02-23 14:35:22  来源:igfitidea点击:

JPA EntityManager是Java Persistence API的核心。
Hibernate是使用最广泛的JPA实现。

JPA实体管理器

  • 程序最重要的方面之一是与数据库的连接。
    数据库连接和与数据库的事务被认为是最昂贵的事务。
    在这方面,ORM是非常重要的工具。
    ORM帮助用Java对象表示数据库关系。

  • ORM包含面向对象和关系编程的两个概念。

  • Hibernate是一个ORM框架,程序员可以其中描述对象在数据库中的表示方式。
    Hibernate自动处理转换。

  • Hibernate提供了JPA接口" EntityManagerFactory"和" EntityManager"的实现。

  • EntityManagerFactory提供用于连接到相同数据库的EntityManager实例。
    所有实例均配置为使用与默认实现定义的设置相同的设置。
    可以准备几个实体管理器工厂以连接到不同的数据存储。

  • JPA EntityManager用于访问特定应用程序中的数据库。
    它用于管理持久实体实例,通过其主键标识查找实体以及查询所有实体。

JPA EntityManager方法

以下方法集支持JPA EntityManager。
为了提高可读性,我没有提到方法参数。

  • 持久–将实例设为托管和持久。

  • 合并–将给定实体的状态合并到当前的持久性上下文中。

  • remove –删除实体实例。

  • 查找-通过主键查找。
    搜索指定类和主键的实体。
    如果实体实例包含在持久性上下文中,则从那里返回它。

  • getReference –返回和延迟获取的实例,并且在首次访问该实例时将抛出EntityNotFoundException。

  • flush –将持久性上下文与数据库同步。

  • setFlushMode –为持久性上下文的所有对象设置刷新模式。

  • getFlushMode –获取持久性上下文中所有对象的刷新模式。

  • lock –使用指定的锁定模式类型锁定持久性上下文中包含的实体实例。

  • refresh –刷新数据库中实例的状态,还将覆盖对实体的更改。

  • clear –清除持久性上下文,导致所有受管实体分离。
    对尚未刷新到数据库的实体所做的更改将不会保留。

  • detach –这类似于clear方法,只是前面引用了分离对象的实体将继续这样做。

  • 包含–检查受管实体是否属于当前持久性上下文。

  • getLockMode –获取实体实例的当前锁定模式。

  • setProperty –设置实体管理器属性或者提示。

  • getProperties –获取与实体管理器关联的属性和提示。

  • createQuery –创建用于执行Java Persistence查询语言语句的Query实例。

  • createNamedQuery –创建用于执行Java Persistence命名查询语言语句的Query实例。

  • createNativeQuery –创建用于执行本机sql语句的Query实例。

  • createNamedStoredProcedureQuery –创建StoredProcedureQuery的实例以在数据库中执行存储过程。

  • createStoredProcedureQuery –创建一个StoredProcedureQuery实例以在数据库中执行存储过程。

  • joinTransaction –向实体管理器指示JTA事务处于活动状态。
    应该在活动事务范围之外创建的JTA应用程序管理的实体管理器上调用此方法,以将其与当前JTA事务相关联。

  • isJoinedToTransaction –确定entityManager是否链接到当前事务。

  • 展开–返回指定类型的对象,以允许访问提供程序特定的API

  • getDelegate –返回entityManager的提供程序对象。

  • close –关闭应用程序管理的entityManager。

  • isOpen –确定entityManager是否打开。

  • getTransaction –返回资源级的EntityTransaction对象。

  • getEntityManagerFactory –为实体管理器提供实体管理器工厂。

  • getCriteriaBuilder –返回CriteriaBuilder的实例以创建CriteriaQuery对象。

  • getMetamodel –返回用于访问持久性单元的元模型的元模型接口的实例。

  • createEntityGraph –返回可用于动态创建EntityGraph的可变EntityGraph。

  • getEntityGraph –返回一个命名的EntityGraph

让我们来看一下EntityManager示例项目中的一些方法。

Hibernate EntityManager示例

我们将为JPA Hibernate EntityManager示例创建一个maven项目,下图说明了Eclipse项目的不同组件。

我正在使用MySQL作为数据库,下面的查询将创建我们的测试表。

CREATE TABLE `employee` (
`employee_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`employee_name` varchar(32) NOT NULL DEFAULT '',
PRIMARY KEY (`employee_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

这是一个非常简单的表格,但适合我们的示例来展示EntityManager的用法。

休眠Maven依赖关系

我们必须在pom.xml文件中包含Hibernate和MySQL Java驱动程序依赖项。
我正在将Hibernate 5与最新版本的mysql-connector-java jar一起使用。

<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>com.theitroad.hibernate</groupId>
	<artifactId>hibernate-entitymanager</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>hibernate-entitymanager</name>
	<url>https://maven.apache.org</url>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>

	<dependencies>
		<!-- MySQL connector -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>6.0.5</version>
		</dependency>
		<!-- Hibernate 5.2.6 Final -->
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-core</artifactId>
			<version>5.2.6.Final</version>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>3.8.1</version>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<sourceDirectory>src/main/java</sourceDirectory>
		<plugins>
			<plugin>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.5.1</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

休眠的persistence.xml

使用休眠的最重要部分是提供persistence.xml文件。
该xml包含用于连接数据库的配置。

<persistence xmlns="https://xmlns.jcp.org/xml/ns/persistence"
	xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="https://xmlns.jcp.org/xml/ns/persistence
           https://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
	version="2.1">

	<persistence-unit name="persistence">
		<description>Hibernate Entity Manager Example</description>
		<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>

		<properties>
			<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" 
			<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/Test" 
			<property name="javax.persistence.jdbc.user" value="theitroad" 
			<property name="javax.persistence.jdbc.password" value="theitroad" 
			<property name="hibernate.show_sql" value="true" 
		</properties>

	</persistence-unit>

</persistence>
  • hibernate.show_sql用于告诉hibernate将sql查询打印到日志文件或者控制台中。

  • 最重要的配置是provider类,即
    org.hibernate.jpa.HibernatePersistenceProvider。
    这就是Hibernate挂接到我们的应用程序中以用作JPA实现的方式。

  • 有一些属性可以连接到数据库和驱动程序以供使用。

  • 重要的是要注意,如在项目镜像中可以看到的那样,应该将persistence.xml放置在META-INF目录中。

休眠实体Bean

现在,我们将创建一个" Employee.java"类,该类与数据库中创建的employee表相对应。
使用" @Entity"注释将employee类声明为实体。

package com.theitroad.jpa.hibernate.model;

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
@Table(name = "employee")
public class Employee {
	private int employeeId;

	private String name;

	@Id
	@Column(name = "employee_id")
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	public int getEmployeeId() {
		return employeeId;
	}

	public void setEmployeeId(int employeeId) {
		this.employeeId = employeeId;
	}

	@Column(name = "employee_name")
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Override
	public String toString() {
		return "Employee [employeeId=" + employeeId + ", name=" + name + "]";
	}

}

现在该创建我们的主程序并使用EntityManager方法运行一些查询。

package com.theitroad.jpa.hibernate.main;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import com.theitroad.jpa.hibernate.model.Employee;

public class App {
	public static void main(String[] args) {
		EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("persistence");
		EntityManager entityManager = entityManagerFactory.createEntityManager();

		System.out.println("Starting Transaction");
		entityManager.getTransaction().begin();
		Employee employee = new Employee();
		employee.setName("hyman");
		System.out.println("Saving Employee to Database");

		entityManager.persist(employee);
		entityManager.getTransaction().commit();
		System.out.println("Generated Employee ID = " + employee.getEmployeeId());

		//get an object using primary key.
		Employee emp = entityManager.find(Employee.class, employee.getEmployeeId());
		System.out.println("got object " + emp.getName() + " " + emp.getEmployeeId());

		//get all the objects from Employee table
		@SuppressWarnings("unchecked")
		List<Employee> listEmployee = entityManager.createQuery("SELECT e FROM Employee e").getResultList();

		if (listEmployee == null) {
			System.out.println("No employee found . ");
		} else {
			for (Employee empl : listEmployee) {
				System.out.println("Employee name= " + empl.getName() + ", Employee id " + empl.getEmployeeId());
			}
		}
		//remove and entity
		entityManager.getTransaction().begin();
		System.out.println("Deleting Employee with ID = " + emp.getEmployeeId());
		entityManager.remove(emp);
		entityManager.getTransaction().commit();

		//close the entity manager
		entityManager.close();
		entityManagerFactory.close();

	}
}
  • Persistence.createEntityManagerFactory将使用在persistence.xml文件中提供的persistence-unit提供EntityManagerFactory实例。

  • " entityManagerFactory.createEntityManager()"将创建供我们使用的EntityManager实例。
    每当我们调用createEntityManager()方法时,它将返回一个EntityManager的新实例。

  • " entityManager.getTransaction()。
    begin()"方法首先从当前的持久性上下文中拉出事务,然后使用begin()方法开始事务。

  • " entityManager.persist(employee)"用于将员工对象保留在数据库中。

  • 使用entityManager.getTransaction.commit()方法来获取交易,然后提交相同的交易。
    这会将所有更改提交到数据库。

  • " entityManager.find()"用于使用主键在数据库中查找实体。

  • 如果您想编写一个自定义查询,可以使用entityManager.createQuery()方法。
    这里要注意的重要一点是createQuery()方法将具有在实体类中给定的名称,而不是实际的表名。

  • 仅当我们必须从数据库中删除实体时,才应使用" entityManager.remove()"。

  • entityManager.close()用于关闭实体管理器。
    类似地,entityManagerFactory.close()将关闭EntityManagerFactory。
    一旦完成处理,我们应该立即关闭这些资源。

下面是上述程序的一个示例运行产生的输出。

Starting Transaction
Saving Employee to Database
Hibernate: insert into employee (employee_name) values (?)
Generated Employee ID = 11
got object hyman 11
Dec 07, 2016 1:05:23 PM org.hibernate.hql.internal.QueryTranslatorFactoryInitiator initiateService
INFO: HHH000397: Using ASTQueryTranslatorFactory
Hibernate: select employee0_.employee_id as employee1_0_, employee0_.employee_name as employee2_0_ from employee employee0_
Employee name= Test, Employee id 5
Employee name= hyman, Employee id 6
Employee name= hyman, Employee id 11
Deleting Employee with ID = 11
Hibernate: delete from employee where employee_id=?

请注意,将员工ID保存到数据库中后如何将其映射回对象。
还请注意,SQL查询已打印到控制台中。