JPA

JPA基础
一 简介
1.JPA规范本质上就是一种ORM规范,它制定了一些规范,提供了一些编程的API接口,具体实现由应用服务器厂商来提供,JBoss应用服务器底层就以Hibernate作为JPA实现。也就是说,基于JPA基础的具体JPA实现可以包括Hibernate,TopLink以及其他ORM框架。
2.JPA规范虽然与EJB3规范一同出现,但是JPA规范并不属于EJB3规范,它是一套完全独立的规范。JPA不仅可以在基于EJB的JavaEE中使用,而且可以在普通Java SE中使用。
3.JPA中最常用的3种组件:
实体:就是一个普通的POJO,可以通过orm.xml映射文件或者Annotation建立实体与底层数据表之间的对应关系
EntityManager:实体没有任何持久化能力,需要使用EntityManager操作实体,作用类似于Hibernate中的Session
JPQL查询:类似于Hibernate中的HQL查询语言。JPA提供了一个Query接口来执行查询。
二 具体应用
1.实体
@Entity
@Table(name="product")
public class ProductType {
private Integer typeid;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
public Integer getTypeid() {
return typeid;
}
public void setTypeid(Integer typeid) {
this.typeid = typeid;
}
}
在进行实际的数据库访问之前,Hibernate需要使用hibernate.cfg.xml文件管理数据库连接、连接池信息,JPA需要使用persistence.xml来进行管理。不管是哪种JPA实现,persistence.xml文件总是在放在类加载路径的META-INF路径下。
2.persistence.xml
首先下载hibernate,解压,将hibernate3.jar(Hibernate核心jar包),lib路径下的required目录和jpa目录下的所有jar包添加到应用的类加载路径中。
以下是一个简单的persistence.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
version="2.1">

<persistence-unit name="itcast" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>com.itcast.bean.product.ProductType</class>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
<property name="hibernate.connection.url" value="jdbc:mysql:///mydb" />
<property name="hibernate.connection.username" value="root" />
<property name="hibernate.connection.password" value="123456" />
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="show_sql" value="true" />
<property name="hibernate.format_sql" value="false" />
</properties>
</persistence-unit>
</persistence>
persistence.xml文件通过<persistence-unit>元素配置持久化单元,其中name指定持久化单元名称,transaction-type指定事务类型,支持以下两个属性值:
JTA:使用JTA全局事务,这是默认值,指定该值后还需要使用<jta-data-resource>元素指定容器管理的XA数据源
RESOURCE_LOCAL:使用局部事务,JavaSE程序通常采用局部事务
<persistence-unit>中还包含3个子元素:
(1)<provider>:指定JPA实现的提供类,在应用服务器环境中无须指定该元素
(2)<class>,<mapping-file>,<jar-file>:用于指定实体,其中<class>指定实体类的类名,<mapping-file>指定实体类的映射文件,<jar-file>指定实体类所在的JAR包。
(3)<properties>:可以包含多个<property>子元素,用于为特定JPA实现配置对应的属性。
除此之外,如果希望让JPA使用容器管理的数据源,则应该在<persistence-unit>元素内添加<jta-data-resource>子元素,该子元素的内容就是JTA数据源的JNDI名称。
其他一些配置:
<property name="hibernate.ejb.cfgfile" value=".../../hibernate.cfg.xml" /> 如果程序已经在hibernate.cfg.xml文件中指定了数据库的相关信息,则可以在persistence.xml中指定hibernate.cfg.xml的位置即可
hibernate.max_fetch_depth:设置关联实体的最大抓取深度,0表示不抓取实体,建议在0-3之间,默认为1
hibernate.default_batch_fetch_size:设置加载关联实体集时所加载的关联实体的个数,建议使用2的倍数。
3.EntityManager
JPA的核心API就是EntityManager,EntityManager负责管理JPA持久化上下文中的所有实体,在程序中使用EntityManager大致有三种情况:
(1)在EJB中使用:直接使用依赖注入进行管理
(2)在Servlet,JSF的托管Bean中使用:不能直接使用依赖注入,因为多个请求线程可能共享同一个Servlet或JSF的托管Bean,而EntityManager并没有被设计成线程安全的,因此可能会导致线程安全问题。这个问题有两种解决方法:使用JNDI查找来获得EntityManager对象;使用依赖注入管理EntityManagerFactory对象,再通过EntityManagerFactory来获取EntityManager对象
(3)在Java SE应用中使用:需要应用程序显式的创建EntityManager,过程如下:
通过javax.persistence.Persistence工厂类提供的createEntityManagerFactory()静态方法创建EntityManagerFactory对象,调用该方法时需要传入persistence.xml文件中持久化单元的名称。
调用EntityManagerFactory的createEntityManager()或createEntityManager(Map map)方法来创建EntityManager对象。如果传入了一个Map参数,那么这个Map参数传入的属性会补充或覆盖persistence.xml文件中配置的属性。
这里可以将EntityManager类比为Hibernate中的Session,EntityManagerFactory类比为Hibernate中的SessionFactory
具体使用:
public class ProductTest {
private static final EntityManagerFactory=Persistence.createEntityManagerFactory("itcast");
public static void main(String[] args){
final EntityManager em=factory.createEntityManager();
ProductType product =new ProductType();
try{
em.getTransaction().begin();
em.persist(product);
em.getTransaction().commit();
}finally{
em.close();
}
}
}
4.EntityManager包含了大量方法来对实体执行保存、删除和检索等操作,常用的一些方法如下:
void persist(Object entity):持久化实体到数据库
T merge(T entity):将指定实体合并到数据库
void remove(T entity)
void detach(Object entity):将指定实体从缓存中清除
T find(Class<T> entityClass,Object pk):根据主体的主键加载实体
T getReference(Class<T> entityClass,Object pk):根据主体的主键加载实体,有延迟加载的功能
void setFlushMode(FlushModeType flushMode):设置持久化上下文的flush模式,该模式可以是AUTO(EntityManager自动管理实体和数据库的同步)或COMMIT
void flush():将持久化上下文中的实体状态同步到数据库
void refresh(Object entity):刷新指定实体状态
Query createQuery(String sql):根据指定JPQL语句创建查询
Query createNamedQuery(String name):根据配置中的查询名创建命名查询
Query createNativeQuery(String sqlString):根据指定SQL语句创建原生的SQL查询
void close()
boolean isOpen():判断EntityManager是否打开
JPA除了用Annotation来管理实体和数据表之间的对应关系外,还可以使用orm.xml文件来进行管理,就像Hibernate使用*.hbm.xml文件一样。
一旦为实体提供了orm.xml映射文件,就要在persistence.xml中使用<mapping-file>元素来加载该映射文件。
注意:persistence.xml文件必须位于META-INF路径下,包含META-INF路径的路径或JAR包被称为持久化单元的根,持久化单元的作用域由持久化单元的根确定。主要包括以下三种情况:
对于一个Java SE应用程序而言,如果程序没有将persistence.xml文件打成JAR包,则应该将该文件放在应用类加载路径的META-INF路径下;
如果将persistence.xml文件打包到某个EJB JAR包中,则应该将persistence.xml文件放在该EJB JAR包的META-INF路径下;
如果将persistence.xml打包成某个Web应用的JAR包,则将persistence.xml放在该WAR的WEB-INF/classes/META-INF路径下;对于不打包成WAR包的Web应用,也应该将persistence.xml文件放在Web应用的WEB-INF/classes/META-INF路径下。

原文地址:https://www.cnblogs.com/lyy-2016/p/5866304.html