JDO 2.0查询语言的特点(2)

    组操作(Grouping)

  统计功能可用于一个分组操作中。JDO2.0提供类似SQL中的GROUP BY和HAVING子句。Query方法:


  void setGrouping(String groupSpec)


  用于指定分组的原则。groupSpec参数包含一个或多个以逗号分隔的分组表达式,还可以跟上一个以“having ”开头的过滤条件。调用此方法后,setResult()参数的每个结果表达式项必须是groupSpec中的一项,或者是groupSpec中的一项或多项的运算结果。所有groupSpec项的值均相同的结果被归在同一组中(同一条结果记录)。having子句的过滤条件可以包含boolean结果的判断语句或者是对分组表达式的统计运算。与SQL一样,having子句用于对分组后的结果集进行条件过滤。

  唯一性(Uniqueness)

  很多人一直奇怪为什么Query的执行(execute)结果是一个Object类型的对象,因为这样给开发人员造成必须手工强制将结果转换成Collection的不便。JDO1.0中查询结果一般有多个元素,但JDO专家组计划在JDO2.0中加入对返回单值结果的查询的支持,于是将Query的执行结果定义为Object类型。

  你有时会执行一个你确定结果只会有一条的查询(比如统计总数或者按具有唯一索引的会员帐号查找对象等等),在JDO2.0中,你可以调用Query方法来声明:


  void setUnique(boolean unique)


  当你传入“true”后,Query执行的结果将是一个单独的值对象,如果无任何结果返回,则结果是null。如果JDO发现查询结果返回了多条记录,则会扔出一个异常。

  限制返回结果的大小

  设计用户界面的时候,我们常常会显示结果集的某一部分子集(比如分页显示或只显示前十条之类)。为了性能和效率,你多半会需要限制返回结果的范围。Query的方法可以完成这一点:


  void setRange(int fromInclusive, int toExclusive)


  该方法返回的结果集只包含原结果集的第fromInclusive条到第toExclusive-1条。

  新的过滤条件操作符

  一些新的操作符被加到JDOQL中,以便执行针对引用、Map、字符串和数字的操作。instanceof操作符返回一个boolean值,可以让你过滤某个指定类的对象;同样返回boolean值的containsKey(Object)函数和containsValue(Object)用于访问Map元素。

  字符串处理方面加入了很多函数,toLowerCase()和toUpperCase()分别完成大小写转换,另外还有下列函数用于查找子串位置和获得子串:


  int indexOf(String)
  int indexOf(String, int) String substring(int) String substring(int,int)


  另外,String的方法:


  boolean matches(String pattern)


  用于执行正则式匹配。目前只能提供有限的匹配功能。“.”和“.*”可表示通配符,而“(?i)”表示匹配不区分大小写。

  对数字型的字段,JDO2.0增加了两个函数:


  Math.abs(numeric) Math.sqrt(numeric)


  预定义查询(Named Queries)

  你可以在JDO描述符(metadata)中声明常用的JDOQL查询语句,这样就不用将查询嵌入到Java源代码中。这样可以提供一些灵活性,比如将查询语句写到一个配置好的文本文件中,而需要修改时可以直接改该文件,而不用更改Java源码。描述符中的每个查询都有一个名字,而要执行某个查询时,可以使用下面的方法来创建查询:

  Query newNamedQuery(Class cls, String queryName)

  JDO将会搜索描述符来找到对应的预定义查询语句并生成相应的Query对象。

  访问静态字段(static fields)

  你将可以在JDOQL中访问数据类中以public static final方式声明的常量。比如

  public static final int FEMALE = 0;
  public static final int MALE = 1;
  public static final int UNKNOWN = 2;


  而在查询中使用类似“salary > 5000.0 && gender == MALE”的过滤条件。

  批量删除(Deletion by Query)

  在JDO1.0中,要删除一个对象,必须先将其载入内存,再删除,然而很多情况下,你在删除之前并不需要访问该对象,这样的做法比较低效。在JDO2.0中,提供了Query的几个方法来删除符合查询条件的一组对象:

  Object deletePersistentAll(Object[] parameters) Object deletePersistentAll(Map parameters) Object deletePersistentAll()

  此查询结果的对象会被全部从数据库删除。这些方法返回被删除对象的集合。你的程序可以决定是否需要对被删除的对象逐个访问。如果你不访问这些对象,Query执行的性能将不会受到任何影响,换句话说,这些对象将不会在内存中生成。
  
  厂商扩展的查询特性

  JDO厂商可以给JDOQL提供各种各样的特殊查询功能。每个厂商可以定义一组属于该厂商自己的扩展功能。如果你需要使用其中的功能,你需要将该厂商的扩展加到程序运行环境中。每个扩展有一个名字和一个可选的值。你可以单独设置每个扩展,或者一次性设置多个扩展。Query的下列方法用于设置厂商扩展特性:

  void setExtensions(Map extensions) void addExtension(String key, Object value)

  SQL直接访问

  如果JDO2.0的查询功能不能满足需要,并且以下条件都满足:

  你的应用运行在关系数据库上
  
  你需要的查询有SQL语句可以实现

  你知道从你的类模型到数据库的映射细节

  你就可以创建一个SQL查询,方法是调用PersistentManger的方法:

  Query newQuery(String language, Object query)
  
  每一个参数需要设置为“javax.jdo.query.SQL”,而query是一个具体的SQL语句。如果你的查询需要返回类的实例,则这个SQL语句必须返回该类的相应主键字段。使用直接的SQL时,JDOQL提供的函数将不能被使用,否则将会扔出异常JDOUserException,比如,你不能对该Query设置过滤条件字符串、排序声明或变量声明。使用SQL查询时,参数都是未指定类型的,在SQL语句中以“?”表示,并且按出现的顺序被绑定。

  结束语

  各位读者已经看到,JDO2.0对查询语句增加了很多新的功能和特性,我认为其中的查询结果定义是最大的改进。正如我在文章开头说的,这一部分变化目前来说是JDO2.0中最稳定的部分,不会有大的变化。厂商可以开始提供很多这样的功能,不用考虑专家组还在讨论的JDO2.0其余部分将如何变化。

  在JDO2.0提供标准的对象/关系映射的前提下,这里描述的查询功能和一个用于多层结构的JDO应用的脱钩/挂钩(detach/attach)机制,将使JDO占领更多的市场。对这一点有深切体会的厂商将不遗余力地争取率先推出稳定、完整、高效的JDO2.0产品。JDO将是基于数据库存储和管理的应用开发的首先API,开发人员们将享受面向对象的模型设计和高效的数据存储管理系统。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wzxzwd.html