- 浏览: 483193 次
- 性别:
- 来自: 大连
文章分类
最新评论
-
龘龘龘:
TrueBrian 写道有个问题,Sample 1中,为了控制 ...
What's New on Java 7 Phaser -
龘龘龘:
楼主总结的不错。
What's New on Java 7 Phaser -
TrueBrian:
有个问题,Sample 1中,为了控制线程的启动时机,博主实际 ...
What's New on Java 7 Phaser -
liguanqun811:
不知道楼主是否对zookeeper实现的分布式锁进行过性能测试 ...
Distributed Lock -
hobitton:
mysql的get lock有版本限制,否则get lock可 ...
Distributed Lock
6 Query
6.1 JPQL Queries
6.1.1Query Basics
public Query createQuery(String jpql);
EntityManager上的这个方法用来根据给定的JPQL创建Query。
public List getResultList();
Query上的这个方法用来得到query的执行结果,以下是个简单的例子:
EntityManager em = entityManagerFactory.createEntityManager(); Query q = em.createQuery("SELECT x FROM Magazine x"); List<Magazine> results = (List<Magazine>) q.getResultList(); em.close();
JPQL query的from子句中定义了query内部命名空间。可以将任意的标识符赋值给entities,之后就可以在query的任意位置上通过标识符引用entities。 在from子句中,关键字as是可选的。例如以下两个JPQL等效:
SELECT x FROM Magazine x SELECT x FROM Magazine AS x
当查询entities的时候,关键字object也是可选的,例如select x 和 SELECT OBJECT(x) 是等效的。JPQL中的关键字不是大小写敏感的,而entity、identifier和member names是大小写敏感的。以下是一些JPQL的例子:
SELECT x FROM Magazine x WHERE x.TITLE = 'JDJ' SELECT x FROM Magazine x WHERE x.title = 'JDJ' OR x.title = 'JavaPro' SELECT x FROM Magazine x WHERE x.price > 3.00 AND x.price <= 5.00 SELECT x FROM Magazine x WHERE x.price <> 3.00 SELECT x FROM Magazine x WHERE (x.price > 3.00 AND x.price <= 5.00) OR x.price = 7.00 SELECT x FROM Magazine x WHERE x.price > 3.00 AND (x.price <= 5.00 OR x.price = 7.00) SELECT x FROM Magazine x WHERE x.price >= 3.00 AND x.price <= 5.00 SELECT x FROM Magazine x WHERE x.price BETWEEN 3.00 AND 5.00 SELECT x FROM Magazine x WHERE x.title LIKE 'J%' SELECT x FROM Magazine x WHERE x.title LIKE 'J__' SELECT x FROM Magazine x WHERE x.title IN ('JDJ', 'JavaPro', 'IT Insider') SELECT x FROM Magazine x WHERE x.articles is empty SELECT x FROM Magazine x WHERE x.publisher is null SELECT x FROM Magazine x WHERE NOT(x.price = 10.0)
6.1.2 Relation Traversal
可以通过类似Java的语法来遍历对象间的关系。例如Magazine中有个Publisher类型的属性publisher,那么可以通过以下方式编写JPQL query:
SELECT x FROM Magazine x WHERE x.publisher.name = 'Random House'
以上的遍历中假设关系不是null。在SQL术语中类似于inner join。如果你希望包含为null 的关系,那么可以如下指定:
SELECT x FROM Magazine x WHERE x.publisher.name = 'Random House' or x.publisher is null
也可以在query中遍历集合字段,但是必须首先在from子句中定义遍历相关的identification variable,例如:
SELECT x FROM Magazine x, IN(x.articles) y WHERE y.authorName = 'John Doe'
IN() 类型的语法可以使用inner join关键词,例如以下两个JPQL等效:
SELECT x FROM Magazine x, IN(x.articles) y WHERE y.authorName = 'John Doe' SELECT x FROM Magazine x inner join x.articles y WHERE y.authorName = 'John Doe'
6.1.3 Fetch Joins
JPQL query中可以指定一个或多个join fetch来指定哪些字段被pre-fetched,以5.6.1中的Publisher和Magazine为例:
em = entityManagerFactory.createEntityManager(); Query q2 = em.createQuery("SELECT x FROM Publisher x WHERE x.id = 1"); List<Publisher> r2 = (List<Publisher>)q2.getResultList(); em.close(); for(Iterator<Publisher> iter = r2.iterator(); iter.hasNext(); ) { System.out.println(iter.next().toString()); }
以上代码执行后的输出是:
id: 1, name: publisher1, grade: null, magazines[]
em = entityManagerFactory.createEntityManager(); Query q3 = em.createQuery("SELECT x FROM Publisher x join fetch x.grade join fetch x.magazines WHERE x.id = 1"); List<Publisher> r3 = (List<Publisher>)q3.getResultList(); em.close(); for(Iterator<Publisher> iter = r3.iterator(); iter.hasNext(); ) { System.out.println(iter.next().toString()); }
以上代码执行后的输出是:
id: 1, name: publisher1, grade: excellent, magazines[isbn: isbn1, title: title1; isbn: isbn1, title: title1; isbn: isbn2, title: title2; isbn: isbn2, title: title2]
6.1.4 JPQL Functions
JPQL 支持一系列预定义的标量函数,例如:
SELECT x FROM Magazine x WHERE CONCAT(x.title, 's') = 'JDJs' SELECT x FROM Magazine x WHERE SUBSTRING(x.title, 1, 1) = 'J' SELECT x FROM Magazine x WHERE TRIM(BOTH 'J' FROM x.title) = 'D' SELECT x FROM Magazine x WHERE LOWER(x.title) = 'jdj' SELECT x FROM Magazine x WHERE UPPER(x.title) = 'JAVAPRO' SELECT x FROM Magazine x WHERE LENGTH(x.title) = 3 SELECT x FROM Magazine x WHERE LOCATE('D', x.title) = 2 SELECT x FROM Magazine x WHERE ABS(x.price) >= 5.00 SELECT x FROM Magazine x WHERE SQRT(x.price) >= 1.00 SELECT x FROM Magazine x WHERE MOD(x.price, 10) = 0
6.1.5 Polymorphic Queries
JPQL from子句中的entity class不仅包含这个类本身,而且还包含这个类及其子类。以下是个关于polymorphic query的简单例子:
@Entity @Inheritance(strategy=InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name="Class", discriminatorType=DiscriminatorType.STRING) public abstract class BankingAccount { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) protected int id; } @Entity @DiscriminatorValue("CC") public class CreditCard extends BankingAccount { @Basic private BigInteger limitAmount; public String toString() { StringBuffer sb = new StringBuffer(); sb.append("credit card, limit amount: ").append(limitAmount); return sb.toString(); } } @Entity @DiscriminatorValue("DC") public class DebitCard extends BankingAccount { @Basic private BigInteger balanceAmount; public String toString() { StringBuffer sb = new StringBuffer(); sb.append("debit card, balance amount: ").append(balanceAmount); return sb.toString(); } }
假设目前数据库中的数据如下:
select * from bankingaccount; +----+-------+-------------+---------------+ | id | Class | limitAmount | balanceAmount | +----+-------+-------------+---------------+ | 5 | CC | 1000 | NULL | | 6 | DC | NULL | 2000 | +----+-------+-------------+---------------+
EntityManager em = entityManagerFactory.createEntityManager(); Query q1 = em.createQuery("SELECT x FROM BankingAccount x"); List<BankingAccount> r1 = (List<BankingAccount>)q1.getResultList(); for(Iterator<BankingAccount> iter = r1.iterator(); iter.hasNext(); ) { System.out.println(iter.next().toString()); } em.close();
以上代码的执行结果如下:
credit card, limit amount: 1000
debit card, balance amount: 2000
6.1.6 Query Parameters
JPQL支持两种类型的query参数:named parameters 或 positional parameters。在一个JPQL query中不能同时使用两种类型的参数。以下是两个简单的例子:
Query q = em.createQuery("SELECT x FROM Magazine x WHERE x.title = ?1 and x.price > ?2"); q.setParameter(1, "JDJ").setParameter(2, 5.0); List<Magazine> results = (List<Magazine>) q.getResultList(); Query q = em.createQuery("SELECT x FROM Magazine x WHERE x.title = :titleParam and x.price > :priceParam"); q.setParameter("titleParam", "JDJ").setParameter("priceParam", 5.0); List<Magazine> results = (List<Magazine>) q.getResultList();
6.1.7 Query Hints
JPQL支持通过name/value对来指定query hints。例如:
Query q = em.createQuery("select m from Magazine m where ... "); q.setHint("openjpa.hint.OptimizeResultCount", new Integer(2)); q.setHint("openjpa.FetchPlan.ReadLockMode","WRITE"); List r = q.getResultList();
6.1.8 Ordering
JPQL支持根据一个或者多个字段对查询结果进行排序,例如:
SELECT x FROM Magazine x order by x.title asc, x.price desc
6.1.9 Aggregates
JPQL支持min、max、avg和count等聚集函数(也被称为列函数)。以下是一些例子:
Query q = em.createQuery("SELECT AVG(x.price) FROM Magazine x"); Query q = em.createQuery("SELECT SUM(DISTINCT x.price) FROM Magazine x"); Query q = em.createQuery("SELECT MAX(x.price) FROM Magazine x WHERE x.title = 'JDJ'");
6.1.10 Named Queries
JPQL支持通过NamedQuery 和NamedQueries 这两个annotation来声明命名query。以下是一个例子:
@Entity @NamedQueries({ @NamedQuery(name="magsOverPrice", query="SELECT x FROM Magazine x WHERE x.price > ?1"), @NamedQuery(name="magsByTitle", query="SELECT x FROM Magazine x WHERE x.title = :titleParam") }) public class Magazine { ... } Query q = em.createNamedQuery("magsOverPrice"); q.setParameter(1, 5.0f); List<Magazine> results = (List<Magazine>) q.getResultList(); Query q = em.createNamedQuery("magsByTitle"); q.setParameter("titleParam", "JDJ"); List<Magazine> results = (List<Magazine>) q.getResultList();
6.1.11 Delete By Query
Query可以用来高效地删除对象(不必将每个对象查询之后再进行删除,而是直接进行批量删除)。以下是个简单的例子:
Query q = em.createQuery("DELETE FROM Subscription s WHERE s.subscriptionDate < :today"); q.setParameter("today", new Date()); int deleted = q.executeUpdate();
executeUpdate方法的返回值是删除对象的个数。
6.1.12 Update By Query
跟delete类似,Query也可以用来高效地更新对象。以下是个简单的例子:
Query q = em.createQuery("UPDATE Subscription s SET s.paid = :paid WHERE s.subscriptionDate < :today"); q.setParameter("today", new Date()); q.setParameter("paid", true); int updated = q.executeUpdate();
6.1.13 Subquery
目前JPA规范支持在WHERE子句和HAVING子句中使用子查询,未来可能会支持FROM子句中使用子查询。以下是一些例子:
SELECT DISTINCT auth FROM Author auth WHERE EXISTS (SELECT spouseAuthor FROM Author spouseAuthor WHERE spouseAuthor = auth.spouse) SELECT auth FROM Author auth WHERE auth.salary >= ALL(SELECT a.salary FROM Author a WHERE a.magazine = auth.magazine) SELECT goodPublisher FROM Publisher goodPublisher WHERE goodPublisher.revenue < (SELECT AVG(p.revenue) FROM Publisher p) SELECT mag FROM Magazine mag WHERE (SELECT COUNT(art) FROM mag.articles art) > 10
6.1.14 JPQL Constructor Expressions
在SELECT子句中可以通过使用constructor来返回一个或多个实例。指定的类不必是entity class,例如:
SELECT NEW com.company.PublisherInfo(pub.id, pub.revenue, mag.price) FROM Publisher pub JOIN pub.magazines mag WHERE mag.price > 5.00
6.2 SQL Queries
JPA支持通过Query接口的以下两个方法使用SQL查询:
public Query createNativeQuery(String sqlString, Class resultClass); public Query createNativeQuery(String sqlString, String resultSetMapping);
OpenJPA也支持使用存储过程。OpenJPA假定任何不以SELECT开头的SQL为存储过程的调用。
在指定resultClass的情况下,sqlString必须查询指定resultClass的 primary key 列、 discriminator 列 (如果存在) 和version column (如果存在)。JPA使用以上三个列的信息来判断object identity、区分查询子类和检查并发修改。 以下是个简单的例子:
Query query = em.createNativeQuery("SELECT isbn, title, price, vers FROM Magazine WHERE price > 5 AND price < 10", Magazine.class); List<Magazine> results = (List<Magazine>) query.getResultList(); for (Magazine mag : results) processMagazine(mag);
在指定resultSetMapping的情况下,resultSetMapping引用一个定义好的SqlResultSetMapping,例如:
@Entity @SqlResultSetMapping(name="srsm1", entities={@EntityResult(entityClass=Publisher.class), @EntityResult(entityClass=Magazine.class)} ) public class Publisher { … } EntityManager em = entityManagerFactory.createEntityManager(); Query q13 = em.createNativeQuery("SELECT p.id, p.name, m.isbn, m.title FROM Publisher AS p, Magazine as m WHERE p.id = 1 AND p.id = m.publisherId", "srsm1"); List r13 = q13.getResultList(); em.close(); for(Iterator iter = r13.iterator(); iter.hasNext(); ) { Object objects[] = (Object[])iter.next(); System.out.println("publisher: " + objects[0] + ", magazine: " + objects[1]); }
当查询结果不仅包含entity,而且包含value type的时候,可以在SqlResultSetMapping中指定@ColumnResult,例如:
@Entity @SqlResultSetMapping(name="srsm2", entities={@EntityResult(entityClass=Publisher.class)}, columns={@ColumnResult(name="count")} ) public class Publisher { … } EntityManager em = entityManagerFactory.createEntityManager(); Query q14 = em.createNativeQuery("SELECT p.id, count(*) AS count FROM Publisher AS p LEFT JOIN Magazine as m ON p.id = m.publisherId GROUP BY p.id", "srsm2"); List r14 = q14.getResultList(); em.close(); for(Iterator iter = r14.iterator(); iter.hasNext(); ) { Object objects[] = (Object[])iter.next(); System.out.println("publisher: " + objects[0] + ", count: " + objects[1]); }
评论
应该是更新的语句必须是基本类型及包装器类.
也就是说你的set子句不要是Entity类型.目前经过测试只发现这么多,具体原因还不清楚.
这是openjpa抛出异常的相关代码
// set the actual field in the instance int set = OpenJPAStateManager.SET_USER; switch (fmd.getDeclaredTypeCode()) { case JavaTypes.BOOLEAN: sm.settingBooleanField(into, i, sm.fetchBooleanField(i), val == null ? false : ((Boolean) val).booleanValue(), set); break; case JavaTypes.BYTE: sm.settingByteField(into, i, sm.fetchByteField(i), val == null ? 0 : ((Number) val).byteValue(), set); break; case JavaTypes.CHAR: sm.settingCharField(into, i, sm.fetchCharField(i), val == null ? 0 : val.toString().charAt(0), set); break; case JavaTypes.DOUBLE: sm.settingDoubleField(into, i, sm.fetchDoubleField(i), val == null ? 0 : ((Number) val).doubleValue(), set); break; case JavaTypes.FLOAT: sm.settingFloatField(into, i, sm.fetchFloatField(i), val == null ? 0 : ((Number) val).floatValue(), set); break; case JavaTypes.INT: sm.settingIntField(into, i, sm.fetchIntField(i), val == null ? 0 : ((Number) val).intValue(), set); break; case JavaTypes.LONG: sm.settingLongField(into, i, sm.fetchLongField(i), val == null ? 0 : ((Number) val).longValue(), set); break; case JavaTypes.SHORT: sm.settingShortField(into, i, sm.fetchShortField(i), val == null ? 0 : ((Number) val).shortValue(), set); break; case JavaTypes.STRING: sm.settingStringField(into, i, sm.fetchStringField(i), val == null ? null : val.toString(), set); break; case JavaTypes.DATE: case JavaTypes.NUMBER: case JavaTypes.BOOLEAN_OBJ: case JavaTypes.BYTE_OBJ: case JavaTypes.CHAR_OBJ: case JavaTypes.DOUBLE_OBJ: case JavaTypes.FLOAT_OBJ: case JavaTypes.INT_OBJ: case JavaTypes.LONG_OBJ: case JavaTypes.SHORT_OBJ: case JavaTypes.BIGDECIMAL: case JavaTypes.BIGINTEGER: case JavaTypes.LOCALE: case JavaTypes.OBJECT: case JavaTypes.OID: sm.settingObjectField(into, i, sm.fetchObjectField(i), val, set); break; default: throw new UserException(_loc.get("only-update-primitives")); }
发表评论
-
Terracotta in Action (3)
2009-03-25 09:20 51443 Inside Terracotta 3.1 Core T ... -
Terracotta in Action (2)
2009-03-21 21:09 47022. Terracotta Eclipse Plugin ... -
Terracotta in Action (1)
2009-03-19 21:52 62861. Introduction Terraco ... -
OpenEJB (4)
2008-05-11 09:05 3186本文部分内容节选自Enterprise JavaBeans 3 ... -
OpenEJB (3)
2008-05-11 09:04 2727本文部分内容节选自Enterprise JavaBeans 3 ... -
OpenEJB (2)
2008-05-11 09:03 3320本文部分内容节选自Enterprise JavaBeans 3 ... -
OpenEJB (1)
2008-05-10 22:39 5110本文部分内容节选自Enterprise JavaBeans 3 ... -
OpenJPA (7)
2008-03-25 21:56 357410 Miscellaneous Features 10 ... -
OpenJPA (6)
2008-03-23 21:33 63428 Object Locking 8.1 Configu ... -
OpenJPA (5)
2008-03-18 22:38 50527 Inheritance 对象使用引用以便关联到其 ... -
OpenJPA (3)
2008-03-09 23:09 52554 EntityManagerFactory 4.1 Ove ... -
OpenJPA (2)
2008-03-05 23:59 72993 Metadata 通过javax.persist ... -
OpenJPA (1)
2008-03-04 23:11 68811 Overview Apache OpenJPA是 ... -
ActiveMQ in Action (7)
2008-02-27 14:33 126792.6.7 Wildcards Wil ... -
ActiveMQ in Action (6)
2008-02-26 15:22 137982.6 Features ActiveMQ包含了很多 ... -
ActiveMQ in Action (5)
2008-02-26 00:35 136012.5 Clustering ActiveMQ从多种 ... -
ActiveMQ in Action (4)
2008-02-26 00:21 112782.4 Security ActiveMQ ... -
ActiveMQ in Action (3)
2008-02-26 00:16 106382.3 Persistence 2.3.1 AMQ Mess ... -
ActiveMQ in Action (2)
2008-02-25 23:58 132782.2 Transport ActiveMQ目前支持 ... -
ActiveMQ in Action (1)
2008-02-25 23:18 238811 JMS 在介绍ActiveMQ ...
相关推荐
4. **数据访问层**:创建DAO(Data Access Object)接口和实现,如`UserService.java`,通过OpenJPA的API进行CRUD操作。 5. **配置文件**:在`persistence.xml`文件中配置OpenJPA,包括数据源、实体管理工厂、实体...
默认情况下,当应用程序第一次获取实体标识时,OpenJPA 框架从数据库中一次性获取 50 个连续的实体标识缓存起来,当下一次应用程序需要获取实体标识时,OpenJPA 将首先检测缓存中是否存在实体标识,如果存在,Open...
OpenJPA OpenJPA 是 Apache 组织提供的开源项目,它实现了 EJB 3.0 中的 JPA 标准,为开发者提供功能强大、使用简单的持久化数据管理框架。OpenJPA 封装了和关系型数据库交互的操作,让开发者把注意力集中在编写...
OpenJPA,全称Open Java Persistence API,是Apache软件基金会的一个开源项目,它实现了Java持久化API(Java Persistence API,JPA),为Java开发者提供了一种标准的方式来管理和持久化应用程序中的对象。...
**Spring和OpenJPA集成详解** 在Java世界中,Spring框架和OpenJPA(Open Java Persistence)是两个非常重要的组件。Spring作为一个全面的轻量级应用框架,提供了大量的功能,包括依赖注入、AOP(面向切面编程)、...
OpenJPA2是一个开源的对象关系映射(ORM)框架,它是Java Persistence API(JPA)规范的实现。在这个“Open JPA2 employee简单例子”中,我们将深入理解如何使用OpenJPA2来处理数据库中的员工数据。这个示例将帮助...
OpenJPA(Java Persistence API)则是Java平台上的一个ORM(对象关系映射)工具,它实现了JSR-317规范,使得开发者可以方便地在Java应用程序中操作数据库。本篇将详细讲解如何在Spring项目中集成并使用OpenJPA。 ...
OpenJPA(Open Java Persistence API)是Apache软件基金会下的一个开源项目,它是Java持久层标准JPA(Java Persistence API)的一个实现。JPA是Java EE平台中的一个重要组件,用于管理和处理应用程序中的对象-关系...
**JSF与OpenJPA整合** 涉及到在JSF应用中使用OpenJPA进行数据访问。这通常包括配置OpenJPA的数据源、实体管理器工厂,以及在JSF Managed Beans中注入实体管理器,以便在处理用户请求时执行CRUD操作。JSF的事件驱动...
4. **缓存机制**:OpenJPA提供了本地缓存和第二级缓存功能,以提高数据访问性能。本地缓存存储了最近访问过的实体,而第二级缓存则可以在多个数据源之间共享数据,减少对数据库的访问。 5. **元数据源**:OpenJPA...
为了调试和优化,OpenJPA提供了详细的日志功能,可以通过配置log4j.properties文件来控制日志级别和输出。这对于理解和优化OpenJPA的行为非常有帮助。 最后,记得在部署应用到WebSphere之前,进行适当的测试。可以...
### OpenJPA官方手册知识点概览 #### 一、引言 - **OpenJPA**:作为Apache项目的一部分,OpenJPA是一个开源的Java持久化框架(Java Persistence Framework),它支持Java Persistence API (JPA) 的规范。OpenJPA...
Spring MVC和OpenJPA是Java开发中常用的两个框架,它们分别在Web应用和持久层处理上发挥着重要作用。Spring MVC是Spring框架的一部分,用于构建高效、灵活的Web应用程序,而OpenJPA则是一个实现了Java Persistence ...
OpenJPA API 文档 chm格式
### Apache OpenJPA 2.1 用户指南:Java Persistence API 的深入解析 #### 一、简介 Apache OpenJPA 2.1 是基于 Sun Microsystems 的 Java Persistence 2.0 API (JSR-317 JPA 2.0) 规范实现的一种透明持久化 Java ...
Apache OpenJPA-自述文件 前言 感谢您下载此版本的Apache OpenJPA。 Apache OpenJPA是Java Persistence API规范的实现。 执照 此存储库的内容已根据Apache License 2.0 许可 更多信息 可以在openjpa-project子目录...
### OpenJPA-Manual 关键知识点解析 #### 一、OpenJPA介绍 **1.1 关于本文档** 本文档旨在提供一个全面且深入的指南,帮助开发人员理解和掌握Java Persistence API(JPA)的核心概念及其在Apache OpenJPA中的实现...
Openjpa2.2+Mysql+Maven+Servlet+JSP 博客源码: http://blog.csdn.net/shenhonglei1234/article/details/10394379
4. **事务管理**:OpenJPA集成了Java EE的事务管理机制,可以自动处理事务的开始、提交、回滚等操作。 5. **查询语言JPA QL(Java Persistence Query Language)**:OpenJPA支持一种类似SQL的查询语言,用于检索、...