JPA查询语言(4)

时间:2022-09-22 09:46:28

SECLECT函数

SELECT 语句标识查询结果。SELECT 语句包含一个或多个下列元素。

  • 一个路径表达式或是标识变量:表明返回一个实体。

  • 一个单值路径表达式:指定返回一个字段或实体。

  • 一个统计SELECT表达式:表明返回计算结果(如,COUNT(*) )。

  • 一个构造器表达式:允许你从选择的条目中返回一个对象。

SELECT 语句允许查询各种实体,计算结果,投影值,非实体类。你可以在SELECT 语句中使用集合值的路径表达式,然而,下面表达是非法的。

 

SELECT f.topics FROM Forum f			

前面已经提供,一些JPA 的实现允许这类的查询。为了保持移植性,你应该使用下面的语句替换(参看Joins 一节)。

 

SELECT t FROM Forum f JOIN f.topics t			

查询的结果可以是一个抽象模型类型,一个状态字段(实体的字段或属性),一个统计函数的结果,由NEW 操 作符创建的对象,或任何它们可能的组合。如果你查询一个抽象模型类型或是构建一个新的对象,查询结果会是实体类型的对象组成的列表或一个新对象。如果你使 用了统计函数,查询状态字段,或是不同的类型,返回结果是一个数组(Object[])实例的列表。数组中对象的位置与你在查询语句中指定的位置一致。例 如。

 

SELECT t.subject, t.content FROM Topic t		

这个查询返回一个数组(Object[])实例组成的列表。这个列表中每个项目包含两个String 对象,第一项目(index 0)是标题,第二个(index 1)是主题的内容。

构造器函数(CONSTRUCTOR EXPRESSION)

你可以创建一个新的对象作为查询结果。这个对象不要求是实体,但要有一个构造器,它的顺序与类型与SELECT 语句一致。下面是一个封装用户统计数据的临时对象。

				public class UserStatistics {

private String username;

private Integer userId;

private long postCount;



public UserStatistics(String username, Integer userId, long postCount) {

super();

this.username = username;

this.userId = userId;

this.postCount = postCount;

}

// getter methods removed for readability

}

下面的查询语句会计算系统中每个用户的发帖数量,并将结果,用户名,用户ID保存到一个临时对象UserStatistics 中。

Query q = em.createQuery("SELECT NEW com.sourcebeat.jpa.model.UserStatistics("

+"u.username, u.id, COUNT(p)) “

+ “FROM Post p JOIN p.createdByUser u "

+ "WHERE p.parent IS NOT NULL GROUP BY u");

List results = q.getResultList();

统计函数(AGGREGATE FUNCTIONS)

SELECT 语句中可以使用以下统计函数(在一个路径表达式上应用)。

AVG

计算查询结果返回的数值型参数的平均值,并返回一个Double 整型。

SELECT AVG(f.forumPostCount) FROM Forum f				

COUNT

计算所找到的实体的总和,并返回一个Long 整型。如果没有找到实体,COUNT 返回0。

SELECT COUNT(f) FROM Forum f				

MAX

计算查询结果作为参数的最大值,返回类型与参数类型一致。MAX 函数可以应用到任何可排序的状态字段上,包括数字类型,字符串,字符类型,或日期。

SELECT MAX(f.forumPostCount) FROM Forum f				

MIN

计算查询结果作为参数的最小值,返回类型与参数类型一致。MIN 函数可以应用到任何可排序的状态字段上,包括数字类型,字符串,字符类型,或日期。

SELECT MIN(f.dateCreated) FROM Forum f				

SUM

计算查询结果作为数值型参数的总和,当参数是浮点类型时返回一个Double 类型,当使用BigInteger 返回一个BigInteger ,当参数为BigDecimal 时返回BigDecimal

SELECT SUM(f.forumPostCount) FROM Forum f				

使用法则(RULES OF USAGE)

COUNT 外,这些函数必须用在以状态字段结尾的路径表达式上。你可以用一个状态字段,关联字段,或是一个标志符号变量作为参数用在COUNT 函数。

如果SUM, AVG, MIN,和MAX计算的值不存在时,返回一个NULL

为了避免使用统计函数查询结果的重复,请使用DISTINCT 操作符。但是在MAX 和MIN使用DISTINCT 是非法的。另外,在函数计算结果之前已经剔除了NULL 值,不管你是否使用了DISTINCT

当使用一个构造器表达式组成的SELECT 语句,函数的返回类型应该注意。UserAverages 对象的postCount 属性是一个Long 对象。最初,使用一个int ,查询语句运行时,Hibernate 会一个IllegalArgumentException 异常,表明UserStatistics 与构造器不相符。我意识到COUNT 返回的是一个Long 类型对象,更新一下UserStatistics ,查询语句就可以正确的运行。