JPA EntityManager – Hibernate EntityManager
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查询已打印到控制台中。