




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
JPA开发文档TOC\o"1-3"\h\u5171.发展中持久化技术 1251501.1JDBC 13321.2关系对象映射(ObjectRelationalMapping,ORM) 2183421.3Java数据对象(JavaDataObject,JDO) 286951.4JavaPersistenceAPI(JPA) 27872.JPA体系架构 326371清单1在非JavaEE环境使用JPA接口例子 524348清单2在容器中运营JPA例子 576883.EntityBean 6293893.1定义对Entity中属性变量访问 6272223.2主键和实体标记(PrimaryKeyandEntityIdentity) 8253124.EntityManager 9229754.1配备和获得EntityManager 966224.2Entity生命周期和状态 10227174.3持久化Entity(Persist) 1156654.4获取Entity 13186574.5更新Entity 1394864.6删除Entity 14214234.7脱离/附合(Detach/Merge) 14238125.JPAQuery 1595485.1Query接口 15296455.2简朴查询 16219325.3使用参数查询 17157695.4排序(orderby) 17153955.5查询某些属性 18165835.6查询中使用构造器(Constructor) 1821775.7聚合查询(Aggregation) 19279185.8关联(join) 2056755.9比较Entity 22145225.10批量更新(BatchUpdate) 22206805.11批量删除(BatchRemove) 221.发展中持久化技术1.1JDBC诸多公司应用开发者选取使用JDBC管理关系型数据库中数据。JDBC支持解决大量数据,可以保证数据一致性,支持信息并发访问,提供SQL查询语言查找数据。JDBC所使用关系模型不是为保存对象而设计,因而迫使开发者选取在解决持久数据时放弃面向对象编程,或者自己去开发将面向对象特性(例如:类之间继承)和关系型数据库进行映射专有解决方案。1.2关系对象映射(ObjectRelationalMapping,ORM)ORM是当前完毕对象和关系数据表之间映射最佳一种技术,这些ORM框架解决对象和关系数据库之间协调工作,将开发者从这某些工作中解脱出来,集中精力解决对象模型。阻碍ORM发展问题是,既有每一种ORM产品均有自己特有API,开发者只能将自己代码绑定到某一种框架提供商接口上,这种状况形成了厂商锁定,意味着一旦该框架提供商无法解决系统中浮现严重错误,或者由于其他因素转而采用其他框架,将会给开发者公司应用带来极大困难,唯一解决办法是重写所有持久化代码。1.3Java数据对象(JavaDataObject,JDO)JDO是JavaEE原则中此外一种支持管理持久化数据规范,JDO规范使用和JPA非常类似API,只是普通是通过JCA技术集成到应用服务器上。但是JDO是针对轻量级容器而设计,不可以支持容器级别声明式安全、事务特性,也无法对远程办法调用提供支持。1.4JavaPersistenceAPI(JPA)EJB3.0规范由三某些构成:EJB3.0SimplifiedAPI、EJB核心规范(EJBCoreContractsandRequirements)和JPA(JavaPersistenceAPI)。JPA规范某些详细简介了JPA中实体Bean定义,并简介了实体Bean支持注释、全新查询语言、实体管理接口、容器实现规范等内容。JPA原则制定过程中充分吸取了当前已经浮现所有持久化技术所有长处,摒弃了它们存在局限,使JPA在简朴易用、查询能力等方面体现突出。原则化JPA是JCP组织发布JavaEE原则之一,因而任何声称符合JPA原则框架都遵循同样架构,提供相似访问API,这保证了基于JPA开发公司应用可以通过少量修改就可以在不同JPA框架下运营。对容器级特性支持JPA框架中支持大数据集、事务、并发等容器级事务,这使得JPA超越了简朴持久化框架局限,在公司应用发挥更大作用。简朴易用,集成以便JPA重要目的之一就是提供更加简朴编程模型:在JPA框架下创立实体和创立Java类同样简朴,没有任何约束和限制,只需要使用javax.persistence.Entity进行注释;JPA框架和接口也都非常简朴,没有太多特别规则和设计模式规定,开发者可以很容易掌握。JPA基于非侵入式原则设计,因而可以很容易和其他框架或者容器集成。可媲美JDBC查询能力JPA定义了独特JPQL(JavaPersistenceQueryLanguage),JPQL是EJBQL一种扩展,它是针对实体一种查询语言,操作对象是实体,而不是关系数据库表,并且可以支持批量更新和修改、JOIN、GROUPBY、HAVING等普通只有SQL才可以提供高档查询特性,甚至还可以支持子查询。支持面向对象高档特性JPA中可以支持面向对象高档特性,例如类之间继承、多态和类之间复杂关系,这样支持可以让开发者最大限度使用面向对象模型设计公司应用,而不需要自行解决这些特性在关系数据库持久化。支持内容:JDBCORMJDOEJB3(JPA)Java对象NoYesYesYes高档OO原理NoYesYesYes事务完整性YesYesYesYes并发YesYesYesYes大数据集YesYesYesYes既有SchemaYesYesYesYes关系型和非关系型数据存储NoNoYesNo查询YesYesYesYes严格原则/可移植NoNoYesYes简朴易用YesYesYesYes表1持久化技术优缺陷2.JPA体系架构JPA中定义一套类和接口用于实现持久化管理和对象/关系映射,下面这张图中显示了JPA重要组件以及它们之间互有关系。图1JPA重要组件和互有关系EntityManagerFactoryEntityManagerFactory是EntityManager工厂类,负责创立EntityManager对象。EntityManagerEntityManager是JPA应用中使用基本对象,通过它提供相应办法可以管理持久化对象,也可以新建或者删除持久化对象。EntityManager还负责创立Query实例。在容器外使用时,EntityManagerFactory和EntityManager之间是一对一关系。EntityEntityTransaction提供Entity操作时需要事务管理,和EntityManager是一对一关系。在查询操作时不需要使用EntityTransaction,而在对象持久化、状态更新、对象删除等状况下则必要使用显式使用EntityTransaction有关办法管理事务。QueryQuery是查询实体接口,Query对象可以从EntityManager中获得。依照EJB3.0规范中描述,Query接口需要同步支持JPQL和原生态SQL两种语法。PersistencePersistence是一种工具类,负责依照配备文献提供参数创立EntityManagerFactory对象。下面代码演示了如何通过JPA提供接口和JPQL查询语言完毕实体查询和更新例子,例子中代码假定运营在非JavaEE环境中。清单1在非JavaEE环境使用JPA接口例子EntityManagerFactoryfactory=Persistence.createEntityManagerFactory(“mysql”);//从EntityManagerFactory实例factory中获取EntityManagerEntityManagerem=factory.createEntityManager(PersistenceContextType.EXTENDED);//实体更新需要在事务中运营EntityTransactiontx=em.getTransaction();tx.begin();//查找所有公司中女性雇员Queryquery=em.createQuery("selectefromEmployeeewheree.sex='femail'");Listresults=query.getResultList();//给所有女性雇员增长半天假期for(Objectres:results){Employeeemp=(Employee)res;emp.setHoliday(emp.getHoliday()+0.5);}//提交事务(持久化所有更新)mit();em.close();factory.close();下面代码显示了在EJB容器中开发JPA应用时接口使用状况,由于容器中EntityManager是注入,事务也是声明式,因而在容器中完毕上面业务逻辑要简朴得多。清单2在容器中运营JPA例子/**在容器中运营JPA应用时,EntityManager接口实例”em”*是通过@Resource注释注入。事务也普通是声明式。*///查找所有公司中女性雇员Queryquery=em.createQuery("selectefromEmployeeewheree.sex='femail'");Listresults=query.getResultList();//给所有女性雇员增长半天假期for(Objectres:results){Employeeemp=(Employee)res;emp.setHoliday(emp.getHoliday()+0.5);}3.EntityBeanEJB3Entity可以是很简朴javabean,只要批注了@Entity或者在xml配备中作了阐明,就被做一种可持久化Entity解决。但还是需要遵行一定规则:Entity类必要要有一种无参数public或者protectedConstructor。如果在应用中需要将该Entity类分离出来在分布式环境中作为参数传递,该EntityClass需要实现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,EJB3Persistence运营环境直接访问对象属性变量,而不是通过getter。这种访问方式也不规定每个属性必要有getter/setter。如果需要在getter中包括商业逻辑,应当采用access=FIELD方式。如果采用access=PROPERTY,EJB3Persistence运营环境将通过Entity类上getter来访问对象属性变量,这就规定每个属性变量要有getter/setter办法。在EJB3中,默认属性访问方式是PROPERTY。access=PROPERTY时getter/setter逻辑应当尽量简朴。规范中access方式尚有多一层含义。就是采用access=FIELD时,元数据应当批注在属性上。@Id(generate=GeneratorType.NONE)privateintid;privateStringfoo;/***Theentityclassmusthaveano-argconstructor.*/publicHelloEntityBean(){}publicintgetId(){returnid;}采用access=PROPERTY(默认方式)时,元数据应当批注在相应属性变量getter上。privateintid;privateStringfoo;/***Theentityclassmusthaveano-argconstructor.*/publicHelloEntityBean(){}@Id(generate=GeneratorType.NONE)publicintgetId(){returnid;}Entity类中属性变量可以是如下数据类型:原始数据类型和她们对象类型java.lang.Stringjava.math.BigIntegerjava.math.BigDecimaljava.util.Datejava.util.Calendarjava.sql.Datejava.sql.Timejava.sql.Timestampbyte[]Byte[]char[]Character[]enumsEntity类嵌入实体类(embeddableclasses)还可以是如下集合类型:java.util.Collection和它实体类java.util.Set和它实体类java.util.List和它实体类java.util.Map和它实体类3.2主键和实体标记(PrimaryKeyandEntityIdentity)每个Entity类都必要有一种主键。在EJB3中定义了两种主键:键单主键和复合主键。简朴主键必要相应Entity中一种属性变量(InstanceVariable),而该属性相应数据库表中一列。使用简朴主键,咱们只需要用@Id元数据对一种属性变量或者她getter办法进行批注。当咱们需要使用一种或各种属性变量(表中一列或多列)联合起来作为主键,咱们需要使用复合主键。复合主键规定咱们编写一种复合主键类(CompositePrimaryKeyClass)。复合主键类需要符合如下某些规定:复合主键类必要是public和具备一种没有参数constructor复合主键类每个属性变量必要有getter/setter,如果没有,每个属性变量则必要是public或者protected复合主键类必要实现java.io.serializable复合主键类必要实现equals()和hashcode()办法复合主键类中主键属性变量名字必要和相应Entity中主键属性变量名字相似一旦主键值设定后,不要修改主键属性变量值复合主键例子。Entity类Person,它主键属性变量是firstName和lastName。@IdprivateStringfirstName;@IdprivateStringlastName;publicPerson(){}Person复合主键类:publicclassPersonPKimplementsjava.io.Serializable{privateStringfirstName;privateStringlastName;publicPersonPK(){}publicStringgetFirstName(){returnfirstName;}publicvoidsetFirstName(StringfirstName){this.firstName=firstName;}publicStringgetLastName(){returnlastName;}publicvoidsetLastName(StringlastName){this.lastName=lastName;}}4.EntityManager对Entity进行操作API都设计在javax.persistence.EntityManager接口上。EntityManager,顾名思义是管理所有EJB3运营环境中所有Entity。EntityManager依照运营环境不同分为容器管理EntityManager和应用管理EntityManager。4.1配备和获得EntityManager在J2SE环境中,EJB3定义了一种javax.persistence.Persistence类用于启动EJB3运营环境。要获得EntityManager,一方面需要通过javax.persistence.Persistence获得EntityManagerFactory,然后调用EntityManagerFactory.createEntityManager()办法获得。//获得默认当前EntityManagerFactoryfinalEntityManagerFactoryemf=Persistence.createEntityManagerFactory();finalEntityManagerentityManager=emf.createEntityManager();当调用Persistence.createEntityManagerFactory()时候,Persistence会做如下环节:搜索当前jar包META-INFO/persistence.xml配备文献如果没有在META-INFO下找到persistence.xml,搜索当前线程ContextClassLoader中persistence.xml依照获得persistence.xml初始化EntityManagerFactory4.2Entity生命周期和状态在EJB3中定义了四种Entity状态:新实体(new)。Entity由应用产生,和EJB3Persistence运营环境没有联系,也没有唯一标示符(Identity)。持久化实体(managed)。新实体和EJB3Persistence运营环境产生关联(通过persist(),merge()等办法),在EJB3Persistence运营环境中存在和被管理,标志是在EJB3Persistence运营环境中有一种唯一标示(Identity)。分离实体(detached)。Entity有唯一标示符,但它标示符不被EJB3Persistence运营环境管理,同样该Entity也不被EJB3Persistence运营环境管理。删除实体(removed)。Entity被remove()办法删除,相应纪录将会在当前事务提交时候从数据库中删除。图2状态转化4.3持久化Entity(Persist)finalEntityManagerFactoryemf=Persistence.createEntityManagerFactory();finalEntityManagerentityManager=emf.createEntityManager();finalHelloEntityBeanhello=newHelloEntityBean(1,"foo");EntityTransactiontrans=entityManager.getTransaction();trans.begin();//持久化hello,在此操作之前hello状态为newentityManager.persist(hello);//这时hello状态变为managedmit();entityManager.close();//这时hellow状态变为detached.当保存一种Entity时,以该对象为根对象整个对象图都会自动被保存。但在EJB3中,咱们依然可以通过关系元数据(例如OneToOne,OneToMany)cascade属性来精准定义保存级联行为。下面咱们来看看不同cascade属性区别。不配备cascade状况下,EJB3Persistence运营环境默认不会采用Persistencebyreachability。publicclassFather{@IdintidStringname;//OneToOne没有配备cascade属性,因而默认不会使用Persistencebyreachablity@OneToOneSonmySonpublicFather(intid,Stringname,SonmySon){this.id=id;=name;this.mySon=mySon;}}当前来保存一种Father和Son。finalEntityManagermanager=emf.createEntityManager();manager.getTransaction().begin;SonmySon=newSon();Father=newFather(1,"father"mySon);//保存Fathermanager.persist(father);//由于OneToOne关系中没有配备casacade属性,father关联mySon不会被自动保存,需要分别保存manager.persist(mySon);manager.getTransaction().commit();manager.close();当前咱们配备casacde=CascadeType.ALLpublicclassFather{@IdintidStringname;//OneToOne配备cascade=CascadeType.ALL,配备cascade=CascadeType.PERSIT也对persist操作也可以获得同样效果。//CascadeType.ALL包括CascadeType.PERSIST。@OneToOne(cascade=CascadeType.ALL)SonmySonpublicFather(intid,Stringname,SonmySon){this.id=id;this.mySon=mySon;=name;}}在代码中同样持久化Father和mySon。finalEntityManagermanager=emf.createEntityManager();manager.getTransaction().begin;SonmySon=newSon();Father=newFather(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。Fatherfather=manager.find(Father.class,newInteger(1));//由于JDK1.5支持自动转型,也可以如下使用Fatherfather=manager.find(Father.class,1);/**或者,可以用Entity名字作为查找。但无法运用JDK1.5自动转型功能,*需要使用对象作为查找主键,并需要对获得Entity进行转型*/Fatherfather=(Father)manager.find("com.redsoft.samples.Father",newInteger(1));4.5更新Entity对Entity更新必要在事物内完毕。和persist中同样,关系元数据cascade属性对与否集联删除有影响。transaction.begin();Fatherfather=manager.find(Father.class,1);//更新原始数据类型father.setName("newName");//更新对象引用SonnewSon=newSon();father.setSon(newSon);//提交事务,刚才更新同步到数据库mit();4.6删除Entity对Entity删除必要在事物内完毕。transaction.begin();Fatherfather=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。在脱离EJB3PersistenceRuntime(EntityManager)管理后,咱们依然可以读取或者修改Entity中内容。而在稍后时间,咱们又可以将Entity重新和原有或者新EntityManager附合,如果附合前Entity被改动过,更改数据可以自动被发现并和数据库同步。EntityManagerentityManager=emf.createEntityManager();//这时Father还是被EntityManager管理Fatherfather=manager.find(Father.class,1);//当entityManger关闭时候,当前被entityManager管理Entity都会自动脱离EntityManager,状态转变为detachedentityManager.close();//脱离EntityManager后,咱们依然可以修改Father属性father.setName("newName");//在稍后,咱们可以将father重新附和到一种新或者本来EntityManager中EntityManagernewEntityManager=emf.createEntityManager();//附合(merge)需要在事务中进行newEntityManager.getTransaction().begin();newEntityManager.merge(father);//commit后father中被修改内容会同步到数据库。newEntityManager.getTransaction().commit();5.JPAQueryJPA查询语言(JP)是一种和SQL非常类似中间性和对象化查询语言。它可以被编译成不同底层数据库能接受SQL,从而屏蔽不同数据库差别,保证用JPQL查询语言编写代码可在不同数据库上运营。比起EJB2.1查询语言,EJB3可以运营期构造,支持多态,远远比EJB2.1查询更灵活和功能强大。在程序中使用JPQL可以使用大写(SELECT)或者小写(select),但不要大小写(例如:Select)混合使用。5.1Query接口javax.persistence.Query是EJB3查询操作接口。进行查询,一方面要通过EntityManager获得Query对象。publicQuerycreateQuery(StringejbqlString);下面咱们做一种最简朴查询,查询所有com.redsoft.samples.Order类。finalQueryquery=entityManager.createQuery("selectofromOrdero");finalListresult=query.getResultList();finalIteratoriterator=result.iterator();while(iterator.hasNext()){//解决Order}注意"fromOrder"。"Order"在EJB3查询中称为com.redsoft.samples.Order类abstractschemaType。查询Entity在JPQL中都是针对EntityAbstractSchemaType进行查询。在同一种EntityManagerFactory中,不容许同步有两个AbstractSchemaType相似Entity类。例如不容许同步有com.redsoft.samples.Order和com.redsoft.foo.Order。Query返回一种List集合成果,咱们可以用Iterator或者List.get(int)办法来获得每个符合条件Entity。如果查询成果结合中包括所有符合条件Entity,EJB3Persistence运营环境默认会自动缓存每次查询成果。这样下次同样查询操作就无需访问数据库,而直接从缓存中返回成果集合。但如果在下次查询操作之前,有针对被缓存Entity类进行update/insert/delete操作,则缓存成果集合会自动被清空,这样下次查询就会从数据库获得数据,保证查询总是获得对的成果,避免缓存脏数据。有时候查询会返回海量数据。注意关闭对集合成果缓存。//假设返回成果数量巨大finalQueryquery=entityManager.createQuery("selectofromOrdero");//关闭对查询成果缓存query.setHint(Constants.QUERY_RESULT_CACHE,"false");finalListresult=query.getResultList();finalIteratoriterator=result.iterator();//这里咱们可以解决海量数据while(iterator.hasNext()){//解决Order}5.2简朴查询下面是一种简朴查询例子,可以看到和SQL用法很类似。finalQueryquery=entityManager.createQuery("selectofromOrderowhereo.id=1");finalQueryquery=entityManager.createQuery("selectofromOrderowhereo.id=1ando.confirm='true'");finalQueryquery=entityManager.createQuery("selectofromOrderowhereo.id=1oro.customer='foo'");//address是Order类上一种对象变量属性,Address有一种streetNumber属性finalQueryquery=entityManager.createQuery("selectofromOrderowhereo.address.streetNumber>=123");注意条件语句中查询是Entity属性,属性名字需要和Entity中属性变量名字一致。5.3使用参数查询参数查询也和SQL中参数查询类似。JPQL支持两种方式参数定义方式:命名参数和位置参数。在同一种查询中只容许使用一种参数定义方式。finalQueryquery=entityManager.createQuery("selectofromOrderowhereo.id=:myId");//设立查询中参数query.setParameter("myId",2);//可以使用各种参数finalQueryquery=entityManager.createQuery("selectofromOrderowhereo.id=:myIdando.customer=:customerName");//设立查询中参数query.setParameter("myId",2);query.setParameter("customerName","foo");finalQueryquery=entityManager.createQuery("selectofromOrderowhereo.id=?1");//设立查询中参数query.setParameter(1,2);//1表达第一种参数,2是参数值//或者finalQueryquery=entityManager.createQuery("selectofromOrderowhereo.id=?1").setParameter(1,2);//可以使用各种参数finalQueryquery=entityManager.createQuery("selectofromOrderowhereo.id=?1ando.customer=?2");//设立查询中参数query.setParameter(1,2);query.setParameter(2,"foo");如果在将来需要在不同EJB3运营环境中运营,请使用位置参数,保证应用是可移植。5.4排序(orderby)下面是一种简朴查询例子,可以看到和SQL用法很类似。"ASC"和"DESC"分别为升序和降序,如果不显式注明,JPQL中默以为asc升序。//不注明话,默以为asc为升序,finalQueryquery=entityManager.createQuery("selectofromOrderoorderbyo.id");finalQueryquery=entityManager.createQuery("selectofromOrderoorderbyo.address.streetNumberdesc");//desc为降序finalQueryquery=entityManager.createQuery("selectofromOrderoorderbyo.id,o.address.streetNumber");5.5查询某些属性在前面例子中,都是对针对Entity类查询,返回也是被查询Entity类实体。JPQL也容许咱们直接查询返回咱们需要属性,而不是返回整个Entity。在某些Entity中属性特别多状况,这样查询可以提高性能。//直接查询咱们感兴趣属性(列)finalQueryquery=entityManager.createQuery("selecto.id,o.customerName,o.address.streetNumberfromOrderoorderbyo.id");//集合中不再是Order,而是一种Object[]对象数组finalListresult=query.getResultList();//第一种行Object[]row=result.get(0);//数组中第一种值是idintid=Integer.parseInt(row[0].toString());StringcustomerName=row[1].toString();StringstreetNumber=Integer.parseInt(row[2].toString());5.6查询中使用构造器(Constructor)JPQL支持将查询属性成果直接作为一种javaclass构造器参数,并产生实体作为成果返回。//咱们把需要三个属性作为一种class(OrderHolder)构造器参数,并使用new函数。Queryquery=entityManager.createQuery("selectnewcom.redsoft.ejb3.dummy.OrderHolder(o.id,o.vender,o.partNumber)FROMOrderASo");//集合中成果是OrderHolderListresult=query.getResultList();该javaclass不需要是EntityClass。new规定javaclass使用全名。5.7聚合查询(Aggregation)象大某些SQL同样,JPQL也支持查询中聚合函数。当前EJBQL支持聚合函数涉及:AVGSUMCOUNTMAXMINfinalQueryquery=entityManager.createQuery("selectMAX(o.id)fromOrderwhereo.customerName='foo'");//如果咱们懂得成果是单个,咱们可以用getSingleResult()获得成果finalObjectresult=query.getSingleResult();//由于Order中id类型为long,finalLongmax=(Long)result;//在某些数据库中max函数返回成果类型不一定于id相应列类型相符,更安全方式可以采用string来转型finalongmax=Long.parseLong(result.toString());聚合函数也可以作为被查询一种属性返回。//返回所有订单生产厂商和她们订单价值总额finalQueryquery=entityManager.createQuery("selecto.vender,sum(o.amount)FROMOrderogroupbyo.vender");");和SQL同样,如果聚合函数不是select...from唯一一种返回列,需要使用"GROUPBY"语句。"GROUPBY"应当包括select语句中除了聚合函数外所有属性。//返回所有订单生产厂商名字,货品号码和每种货品订单价值总额//注意groupby背面必要包括o.vender和o.partNumberfinalQueryquery=entityManager.createQuery("selecto.vender,o.partNumber,sum(o.amount)FROMOrderogroupbyo.vender,o.partNumber");如果还需要加上查询条件,需要使用"HAVING"条件语句而不是"WHERE"语句。//返回所有订单生产厂商是"foo"货品号码和每种货品订单价值总额//这里"havingo.vender='foo'为条件finalQueryquery=entityManager.createQuery("selecto.vender,o.partNumber,sum(o.amount)FROMOrderogroupbyo.vender,o.partNumberhavingo.vender='foo'");在"HAVING"语句里可以跟"WHERE"语句同样使用参数。//返回所有订单生产厂商是"foo"货品号码和每种货品订单价值总额//这里"havingo.vender='foo'为条件finalQueryquery=entityManager.createQuery("selecto.vender,o.partNumber,sum(o.amount)FROMOrderogroupbyo.vender,o.partNumberhavingo.vender=?1");query.setParameter(1,"foo");finalListresult=query.getResultList();5.8关联(join)在JPQL中,大某些状况下,使用对象属性都隐含了关联(join)。例如在如下查询中:finalQueryquery=entityManager.createQuery("selectofromOrderowhereo.address.streetNumber=orderbyo.id");当这个句JPQL编译成如下SQL时就会自动包括了关联,JPQL编译成SQL时关联默认取左关联(leftjoin)。selecto.id,o.vender,o.partNumber,o.amount,addressTable.id,addressTable.streetNumberfromorderTableasoleftjoinaddressTablewhereaddressTable.streetNumber=但在某些状况下,咱们依然需要对关联做精准控制。因而JPQL依然支持和SQL中类似关联语法:leftoutjoin/leftjoininnerjoinleftjoin/innerjoinfetchleftjoin,leftoutjoin等义,都是容许符合条件右边表达式中Entiies为空。//返回所有地址为Order纪录,不论Order中与否有OrderItemfinalQueryquery=entityManager.createQuery("selectofromOrderoleftjoino.orderItemswhereo.address.streetNumber=orderbyo.id");由于JPQL默认采用leftjoin。这样查询和如下JPQL其实是等价。//返回所有地址为Order纪录,不论Order中与否有OrderItemfinalQueryquery=entityManager.createQue
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论