收藏 分销(赏)

jpa开发基础手册专业资料.doc

上传人:a199****6536 文档编号:3031873 上传时间:2024-06-13 格式:DOC 页数:35 大小:139.54KB 下载积分:12 金币
下载 相关 举报
jpa开发基础手册专业资料.doc_第1页
第1页 / 共35页
jpa开发基础手册专业资料.doc_第2页
第2页 / 共35页


点击查看更多>>
资源描述
JPA开发文档 1. 发展中持久化技术 1 1.1 JDBC 1 1.2关系对象映射(Object Relational Mapping,ORM) 2 1.3 Java数据对象(Java Data Object,JDO) 2 1.4 Java Persistence API(JPA) 2 2. JPA体系架构 3 清单1在非Java EE环境使用JPA接口例子 5 清单2在容器中运营JPA例子 5 3. Entity Bean 6 3.1定义对Entity中属性变量访问 6 3.2主键和实体标记(Primary Key and Entity Identity) 8 4. EntityManager 9 4.1配备和获得EntityManager 9 4.2 Entity生命周期和状态 10 4.3持久化Entity(Persist) 11 4.4获取Entity 13 4.5更新Entity 13 4.6删除Entity 14 4.7脱离/附合(Detach/Merge) 14 5. JPA Query 15 5.1 Query接口 15 5.2简朴查询 16 5.3使用参数查询 17 5.4排序(order by) 17 5.5查询某些属性 18 5.6查询中使用构造器(Constructor) 18 5.7聚合查询(Aggregation) 19 5.8关联(join) 20 5.9比较Entity 22 5.10批量更新(Batch Update) 22 5.11批量删除(Batch Remove) 22 1. 发展中持久化技术 1.1 JDBC 诸多公司应用开发者选取使用 JDBC管理关系型数据库中数据。JDBC支持解决大量数据,可以保证数据一致性,支持信息并发访问,提供 SQL查询语言查找数据。JDBC所使用关系模型不是为保存对象而设计,因而迫使开发者选取在解决持久数据时放弃面向对象编程,或者自己去开发将面向对象特性(例如:类之间继承)和关系型数据库进行映射专有解决方案。 1.2关系对象映射(Object Relational Mapping,ORM) ORM是当前完毕对象和关系数据表之间映射最佳一种技术, 这些 ORM框架解决对象和关系数据库之间协调工作,将开发者从这某些工作中解脱出来,集中精力解决对象模型。阻碍 ORM发展问题是,既有每一种 ORM产品均有自己特有 API,开发者只能将自己代码绑定到某一种框架提供商接口上,这种状况形成了厂商锁定,意味着一旦该框架提供商无法解决系统中浮现严重错误,或者由于其他因素转而采用其他框架,将会给开发者公司应用带来极大困难,唯一解决办法是重写所有持久化代码。 1.3 Java数据对象(Java Data Object,JDO) JDO是 Java EE原则中此外一种支持管理持久化数据规范,JDO规范使用和 JPA非常类似 API,只是普通是通过 JCA技术集成到应用服务器上。但是 JDO是针对轻量级容器而设计,不可以支持容器级别声明式安全、事务特性,也无法对远程办法调用提供支持。 1.4 Java Persistence API(JPA) EJB 3.0规范由三某些构成:EJB3.0 Simplified API、EJB核心规范(EJB Core Contracts and Requirements)和 JPA(Java Persistence API)。JPA规范某些详细简介了 JPA中实体 Bean定义,并简介了实体 Bean支持注释、全新查询语言、实体管理接口、容器实现规范等内容。 JPA原则制定过程中充分吸取了当前已经浮现所有持久化技术所有长处,摒弃了它们存在局限,使 JPA在简朴易用、查询能力等方面体现突出。 原则化 JPA是 JCP组织发布 Java EE原则之一,因而任何声称符合 JPA原则框架都遵循同样架构,提供相似访问 API,这保证了基于 JPA开发公司应用可以通过少量修改就可以在不同 JPA框架下运营。 对容器级特性支持 JPA框架中支持大数据集、事务、并发等容器级事务,这使得JPA超越了简朴持久化框架局限,在公司应用发挥更大作用。 简朴易用,集成以便 JPA重要目的之一就是提供更加简朴编程模型:在 JPA框架下创立实体和创立 Java类同样简朴,没有任何约束和限制,只需要使用 javax.persistence.Entity 进行注释;JPA框架和接口也都非常简朴,没有太多特别规则和设计模式规定,开发者可以很容易掌握。JPA基于非侵入式原则设计,因而可以很容易和其他框架或者容器集成。 可媲美JDBC查询能力 JPA定义了独特 JPQL(Java Persistence Query Language),JPQL是 EJB QL一种扩展,它是针对实体一种查询语言,操作对象是实体,而不是关系数据库表,并且可以支持批量更新和修改、JOIN、GROUP BY、HAVING 等普通只有 SQL才可以提供高档查询特性,甚至还可以支持子查询。 支持面向对象高档特性 JPA中可以支持面向对象高档特性,例如类之间继承、多态和类之间复杂关系,这样支持可以让开发者最大限度使用面向对象模型设计公司应用,而不需要自行解决这些特性在关系数据库持久化。 支持内容: JDBC ORM JDO EJB 3(JPA) Java对象 No Yes Yes Yes 高档OO原理 No Yes Yes Yes 事务完整性 Yes Yes Yes Yes 并发 Yes Yes Yes Yes 大数据集 Yes Yes Yes Yes 既有 Schema Yes Yes Yes Yes 关系型和非关系型数据存储 No No Yes No 查询 Yes Yes Yes Yes 严格原则/可移植 No No Yes Yes 简朴易用 Yes Yes Yes Yes 表1持久化技术优缺陷 2. JPA体系架构 JPA中定义一套类和接口用于实现持久化管理和对象/关系映射,下面这张图中显示了 JPA重要组件以及它们之间互有关系。 图1 JPA重要组件和互有关系 · EntityManagerFactory EntityManagerFactory 是 EntityManager 工厂类,负责创立 EntityManager 对象。 · EntityManager EntityManager 是 JPA应用中使用基本对象,通过它提供相应办法可以管理持久化对象,也可以新建或者删除持久化对象。EntityManager还负责创立Query实例。在容器外使用时,EntityManagerFactory和EntityManager之间是一对一关系。 · Entity EntityTransaction提供Entity操作时需要事务管理,和 EntityManager 是一对一关系。在查询操作时不需要使用 EntityTransaction,而在对象持久化、状态更新、对象删除等状况下则必要使用显式使用 EntityTransaction 有关办法管理事务。 · Query Query是查询实体接口,Query对象可以从 EntityManager 中获得。依照 EJB 3.0规范中描述,Query接口需要同步支持JPQL和原生态SQL两种语法。 · Persistence Persistence是一种工具类,负责依照配备文献提供参数创立EntityManagerFactory对象。 下面代码演示了如何通过 JPA提供接口和 JPQL查询语言完毕实体查询和更新例子,例子中代码假定运营在非 Java EE环境中。 清单1在非Java EE环境使用JPA接口例子 EntityManagerFactory factory = Persistence.createEntityManagerFactory (“mysql”); //从 EntityManagerFactory实例 factory中获取 EntityManager EntityManager em = factory.createEntityManager(PersistenceContextType.EXTENDED); //实体更新需要在事务中运营 EntityTransaction tx = em.getTransaction (); tx.begin (); //查找所有公司中女性雇员 Query query = em.createQuery ("select e from Employee e where e.sex = 'femail'"); List results = query.getResultList (); //给所有女性雇员增长半天假期 for (Object res :results) { Employee emp = (Employee) res; emp.setHoliday (emp.getHoliday () +0.5); } //提交事务(持久化所有更新) mit (); em.close (); factory.close (); 下面代码显示了在 EJB容器中开发 JPA应用时接口使用状况,由于容器中 EntityManager 是注入,事务也是声明式,因而在容器中完毕上面业务逻辑要简朴得多。 清单2在容器中运营JPA例子 /* *在容器中运营JPA应用时,EntityManager接口实例”em” *是通过@Resource注释注入。事务也普通是声明式。 */ //查找所有公司中女性雇员 Query query = em.createQuery ("select e from Employee e where e.sex = 'femail'"); List results = query.getResultList (); //给所有女性雇员增长半天假期 for (Object res :results) { Employee emp = (Employee) res; emp.setHoliday (emp.getHoliday () +0.5); } 3. Entity Bean EJB3 Entity可以是很简朴java bean,只要批注了@Entity或者在xml配备中作了阐明,就被做一种可持久化Entity解决。 但还是需要遵行一定规则: · Entity类必要要有一种无参数public或者protectedConstructor。 · 如果在应用中需要将该Entity类分离出来在分布式环境中作为参数传递,该Entity Class需要实现java.io.Serialzable接口。 · Entity类不可以是final,也不可有final办法。 · abstract类和Concrete实体类都可以作为Entity类。 · Entity类中属性变量不可以是public。Entity类属性必要通过getter/setter或者其她商业办法获得。 3.1定义对Entity中属性变量访问 在绝大某些商业应用,开发人员都可以忽视这某些无需关怀。但如果你需要编写复杂Entity类话,你需要理解这个某些。复杂Entity类是指在Entity类getter/setter和商业办法中包括比较复杂业务逻辑而不是仅仅返回/符值某个属性。 在大某些状况下,咱们都建议使Entity类中setter/getter中逻辑尽量简朴,除了必要校验符值外,不要包括复杂业务逻辑,例如对关联其她Entity类进行操作。但有些状况下,咱们还是需要在Entity类setter/getter办法中包括商业逻辑。这时候,采用何种属性访问方式就也许会影响代码性能甚至是逻辑对的产生影响。 EJB3持久化规范中,在默认状况下所有属性都会自动被持久化,除非属性变量用@Transient元数据进行了标注。针对可持久化属性定义了两种属性访问方式(access):FIELD和PROPERTY。 · 如果采用access=FIELD,EJB3 Persistence运营环境直接访问对象属性变量,而不是通过getter。这种访问方式也不规定每个属性必要有getter/setter。如果需要在getter中包括商业逻辑,应当采用access=FIELD方式。 · 如果采用access=PROPERTY,EJB3 Persistence运营环境将通过Entity类上getter来访问对象属性变量,这就规定每个属性变量要有getter/setter办法。在EJB3中,默认属性访问方式是PROPERTY。access=PROPERTY时getter/setter逻辑应当尽量简朴。 规范中access方式尚有多一层含义。就是采用access=FIELD时,元数据应当批注在属性上。 @Id(generate=GeneratorType.NONE) private int id; private String foo; /** * The entity class must have a no-arg constructor. */ public HelloEntityBean() { } public int getId() { return id; } 采用access=PROPERTY(默认方式)时,元数据应当批注在相应属性变量getter上。 private int id; private String foo; /** * The entity class must have a no-arg constructor. */ public HelloEntityBean() { } @Id(generate=GeneratorType.NONE) public int getId() { return id; } Entity类中属性变量可以是如下数据类型: · 原始数据类型和她们对象类型 · java.lang.String · java.math.BigInteger · java.math.BigDecimal · java.util.Date · java.util.Calendar · java.sql.Date · java.sql.Time · java.sql.Timestamp · byte[] · Byte[] · char[] · Character[] · enums · Entity类 · 嵌入实体类(embeddable classes) 还可以是如下集合类型: · java.util.Collection和它实体类 · java.util.Set和它实体类 · java.util.List和它实体类 · java.util.Map和它实体类 3.2主键和实体标记(Primary Key and Entity Identity) 每个Entity类都必要有一种主键。在EJB3中定义了两种主键:键单主键和复合主键。 简朴主键必要相应Entity中一种属性变量(Instance Variable),而该属性相应数据库表中一列。使用简朴主键,咱们只需要用@Id元数据对一种属性变量或者她getter办法进行批注。 当咱们需要使用一种或各种属性变量(表中一列或多列)联合起来作为主键,咱们需要使用复合主键。复合主键规定咱们编写一种复合主键类( Composite Primary Key Class )。复合主键类需要符合如下某些规定: · 复合主键类必要是public和具备一种没有参数constructor · 复合主键类每个属性变量必要有getter/setter,如果没有,每个属性变量则必要是public或者protected · 复合主键类必要实现java.io.serializable · 复合主键类必要实现equals()和hashcode()办法 · 复合主键类中主键属性变量名字必要和相应Entity中主键属性变量名字相似 · 一旦主键值设定后,不要修改主键属性变量值 复合主键例子。Entity类Person,它主键属性变量是firstName和lastName。 @Id private String firstName; @Id private String lastName; public Person() { } Person复合主键类: public class PersonPK implements java.io.Serializable{ private String firstName; private String lastName; public PersonPK() { } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } } 4. EntityManager 对Entity进行操作API都设计在javax.persistence.EntityManager接口上。EntityManager,顾名思义是管理所有EJB 3运营环境中所有Entity。 EntityManager依照运营环境不同分为容器管理EntityManager和应用管理EntityManager。 4.1配备和获得EntityManager 在J2SE环境中,EJB3定义了一种javax.persistence.Persistence类用于启动EJB3运营环境。要获得EntityManager,一方面需要通过javax.persistence.Persistence获得EntityManagerFactory,然后调用EntityManagerFactory.createEntityManager()办法获得。 //获得默认当前EntityManagerFactory final EntityManagerFactory emf = Persistence.createEntityManagerFactory(); final EntityManager entityManager = emf.createEntityManager(); 当调用Persistence.createEntityManagerFactory()时候,Persistence会做如下环节: · 搜索当前jar包META-INFO/persistence.xml配备文献 · 如果没有在META-INFO下找到persistence.xml,搜索当前线程ContextClassLoader中persistence.xml · 依照获得persistence.xml初始化EntityManagerFactory 4.2 Entity生命周期和状态 在EJB3中定义了四种Entity状态: · 新实体(new)。Entity由应用产生,和EJB3 Persistence运营环境没有联系,也没有唯一标示符(Identity)。 · 持久化实体(managed)。新实体和EJB3 Persistence运营环境产生关联(通过persist(),merge()等办法),在EJB3 Persistence运营环境中存在和被管理,标志是在EJB3 Persistence运营环境中有一种唯一标示(Identity)。 · 分离实体(detached)。Entity有唯一标示符,但它标示符不被EJB3 Persistence运营环境管理, 同样该Entity也不被EJB3 Persistence运营环境管理。 · 删除实体(removed)。Entity被remove()办法删除,相应纪录将会在当前事务提交时候从数据库中删除。 · 图2 状态转化 4.3持久化Entity(Persist) final EntityManagerFactory emf = Persistence.createEntityManagerFactory(); final EntityManager entityManager = emf.createEntityManager(); final HelloEntityBean hello = new HelloEntityBean( 1,"foo" ); EntityTransaction trans = entityManager.getTransaction(); trans.begin(); //持久化hello,在此操作之前hello状态为new entityManager.persist( hello ); //这时hello状态变为managed mit(); entityManager.close(); //这时hellow状态变为detached. 当保存一种Entity时,以该对象为根对象整个对象图都会自动被保存。但在EJB3中,咱们依然可以通过关系元数据(例如OneToOne,OneToMany)cascade属性来精准定义保存级联行为。 下面咱们来看看不同cascade属性区别。 不配备cascade状况下,EJB3 Persistence运营环境默认不会采用Persistence by reachability。 public class Father{ @Id int id String name; // OneToOne没有配备cascade属性,因而默认不会使用Persistence by reachablity @OneToOne Son mySon public Father( int id,String name,Son mySon ){ this.id = id; this.name = name; this.mySon = mySon; } } 当前来保存一种Father和Son。 final EntityManager manager = emf.createEntityManager(); manager.getTransaction().begin; Son mySon = new Son(); Father = new Father( 1,"father" mySon ); //保存Father manager.persist( father ); //由于OneToOne关系中没有配备casacade属性,father关联mySon不会被自动保存,需要分别保存 manager.persist( mySon ); manager.getTransaction().commit(); manager.close(); 当前咱们配备casacde=CascadeType.ALL public class Father{ @Id int id String name; // OneToOne配备cascade=CascadeType.ALL,配备cascade=CascadeType.PERSIT也对persist操作也可以获得同样效果。 // CascadeType.ALL包括CascadeType.PERSIST。 @OneToOne(cascade=CascadeType.ALL) Son mySon public Father( int id,String name,Son mySon ){ this.id = id; this.mySon = mySon; this.name = name; } } 在代码中同样持久化Father和mySon。 final EntityManager manager = emf.createEntityManager(); manager.getTransaction().begin; Son mySon = new Son(); Father = new Father( 1,mySon ); //保存Father。由于OneToOne关系中配备casacade=CascadeType.ALL属性,关联mySon会自动地被持久化 manager.persist( father ); manager.getTransaction().commit(); manager.close(); 建议在应用中尽量使用cascade=CascadeType.ALL来减少持久化操作复杂性和代码量,特别是在有复杂对象关系图时候。 4.4获取Entity 如果懂得Entity唯一标示符,咱们可以用find()办法来获得Entity。 Father father = manager.find( Father.class,new Integer( 1 ) ); //由于JDK1.5支持自动转型,也可以如下使用 Father father = manager.find( Father.class,1 ); /* * 或者,可以用Entity名字作为查找。但无法运用JDK 1.5自动转型功能, * 需要使用对象作为查找主键,并需要对获得Entity进行转型 */ Father father = (Father)manager.find( "com.redsoft.samples.Father",new Integer( 1 ) ); 4.5更新Entity 对Entity更新必要在事物内完毕。和persist中同样,关系元数据cascade属性对与否集联删除有影响。 transaction.begin(); Father father = manager.find( Father.class,1 ); //更新原始数据类型 father.setName( "newName" ); //更新对象引用 Son newSon = new Son(); father.setSon( newSon ); //提交事务,刚才更新同步到数据库 mit(); 4.6删除Entity 对Entity删除必要在事物内完毕。 transaction.begin(); Father father = manager.find( Father.class,1 ); //如果father/son@OneToOnecascade=CascadeType.ALL,在删除father时候,也会把son删除。 //把cascade属性设为cascade=CascadeType.REMOVE有同样效果。 manager.remove( father ); //提交事务,刚才更新同步到数据库 mit(); 4.7脱离/附合(Detach/Merge) 在三层或者分布式应用中,咱们诸多时候需要Entity能脱离EntityManager,避免长时间保持EntityManager打开占用资源和可以在不同JVM之间传递Entity。 在脱离EJB3 Persistence Runtime(EntityManager)管理后,咱们依然可以读取或者修改Entity中内容。而在稍后时间,咱们又可以将Entity重新和原有或者新EntityManager附合,如果附合前Entity被改动过,更改数据可以自动被发现并和数据库同步。 EntityManager entityManager = emf.createEntityManager(); //这时Father还是被EntityManager管理 Father father = manager.find( Father.class,1 ); //当entityManger关闭时候,当前被entityManager管理Entity都会自动脱离EntityManager,状态转变为detached entityManager.close(); //脱离EntityManager后,咱们依然可以修改Father属性 father.setName( "newName" ); //在稍后,咱们可以将father重新附和到一种新或者本来EntityManager中 EntityManager newEntityManager = emf.createEntityManager(); //附合( merge )需要在事务中进行 newEntityManager.getTransaction().begin(); newEntityManager.merge( father ); // commit后father中被修改内容会同步到数据库。 newEntityManager.getTransaction().commit(); 5. JPA Query JPA查询语言(JP)是一种和SQL非常类似中间性和对象化查询语言。它可以被编译成不同底层数据库能接受SQL,从而屏蔽不同数据库差别,保证用JPQL查询语言编写代码可在不同数据库上运营。比起EJB 2.1查询语言,EJB3可以运营期构造,支持多态,远远比EJB 2.1查询更灵活和功能强大。在程序中使用JPQL可以使用大写(SELECT)或者小写(select),但不要大小写(例如:Select)混合使用。     5.1 Query接口 javax.persistence.Query是EJB3查询操作接口。进行查询,一方面要通过EntityManager获得Query对象。 public Query createQuery(String ejbqlString); 下面咱们做一种最简朴查询,查询所有com.redsoft.samples.Order类。 final Query query = entityManager.createQuery( "select o from Order o"); final List result = query.getResultList(); final Iterator iterator = result.iterator(); while( iterator.hasNext() ){ // 解决Order } 注意"from Order"。"Order"在EJB3查询中称为com.redsoft.samples.Order类abstract schema Type。查询Entity在JPQL中都是针对EntityAbstract Schema Type进行查询。 在同一种EntityManagerFactory中,不容许同步有两个Abstract Schema Type相似Entity类。例如不容许同步有com.redsoft.samples.Order和com.redsoft.foo.Order。   Query返回一种List集合成果,咱们可以用Iterator或者List.get( int )办法来获得每个符合条件Entity。 如果查询成果结合中包括所有符合条件Entity,EJB3 Persistence运营环境默认会自动缓存每次查询成果。这样下次同样查询操作就无需访问数据库,而直接从缓存中返回成果集合。但如果在下次查询操
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 包罗万象 > 大杂烩

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服