服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

enterprise javabeans查询语言(1)

enterprise javabeans查询语言(ejb ql)定义了容器管理持续化的finder方法和select方法的查询。作为sql92的一个子集,ejb ql进行了扩展,它可以使用entity bean的抽象模式中定义的关联。一个ejb ql查询可以跨越封装在同一个ejb jar文件中的所有相关的entity bean的抽象模式。

你可以在entity bean中部署描述中定义ejb ql查询。典型的情况是,一个工具会将这些查询转换成低层数据存储所使用的查询语言。因为这种转换的存在,使用容器管理持续化的entity bean具有可移植性--它们的代码不受具体的数据存储的类型的影响。

术语

下面列出了本章中用到的一些术语的定义。

1、abstract schema--抽象模式:一个entity bean的部署描述的一部分,它定义了bean的持续化字段和关联关系。

2、abstract schema name--抽象模式名:在ejb ql查询中引用的一个逻辑命名。你需要为每个容器管理持续化的entity bean指定一个抽象模式名。

3、abstract schema type--抽象模式类型:所有的ejb ql表达式都对应一个类型。如果表达式是一个抽象模式名,那么它的类型默认是定义了这个抽象模式名的entity bean的local接口。

4、backus-naur form (bnf)--巴科斯-诺尔范式:一种描述高级语言语法的一种表示法。这一章的语法图表使用了bnf表示法。

5、navigation--跨越:在一个ejb ql表达式中对关联关系的使用。跨越操作符是一个句点。

6、path expression--路径表达式:一个跨越到相关entity bean的表达式。

7、persistent field--持续化字段:一个容器管理持续化的entity bean中的一个虚拟字段;它存储在一个数据库中。

8、relationship field--关联字段:一个容器管理持续化的entity bean中的一个虚拟字段;它确定了一个相关的entity bean。

简单的语法

这里简要地描述了ejb ql的语法,这样你可以快速进入下面查询示例的学习。如果你要对此进行更深入的学习,请阅读完整的语法。

一个ejb ql查询由三个子句组成:select子句、from子句和where子句,select子句和from子句是必选的,而where子句是可选的。下面是一个ejb ql查询的简单bnf定义:

ejb ql :: = select_clause from_clause [where_clause]

elect子句定义了对象的类型或查询的返回值。返回类型可是一个local接口、一个remote接口或是一个持续化字段。

from子句通过声明一个或多个标识变量定义了查询的范围,这些标识变量可能会在select子句和where子句中被引用。一个标识变量反映了下列元素之一:

1、一个entity bean的抽象模式名

2、一个集合的一个成员,这个集合是一个一对多关系中的多端

where子句是一个限制查询找到的对象或数值的条件表达式。尽管它是可选的,但是绝大多数查询都会有一个where子句。

查询示例

下面的查询来自于rosterapp j2ee应用程序的playerejb entity bean,在第六章中我们对这个应用程序作了介绍。rosterapp中bean之间的关联关系,请参看图6-1。

简单的finder查询

如果你对ejb ql不熟悉,这些简单的查询将有助于你尽快入门。

示例 1

select object(p)

from player p

获得的数据:所有队员。

finder方法: findall()

说明:from子句声明了一个名为p的标识变量,其中省略了可选的as关键字。如果使用了as关键字,这个子句将是这样的:

from player as p

player元素是playerejb entity bean的抽象模式名。因为bean在localplayerhome接口中定义了findall方法,所以这个查询返回的对象具有localplayer类型。

参见: 标识变量

示例 2

select distinct object(p)

from player p

where p.position = ?1

获得的数据:由finder方法的参数指定位置的队员。

finder方法: findbyposition(string position)

说明:在一个select子句中,在例如p这样的独立的标识变量前面要加object关键字。distinct关键字排除了重复的数据。

where子句通过检查队员的position这个playerejb entity bean的持续化字段对获得的队员进行了限制。?1元素表示了了findbyposition方法中的输入参数。

参见: 输入参数, distinct关键字和object关键字

示例 3

select distinct object(p)

from player p

where p.position = ?1 and p.name = ?2

获得的数据:指定位置和姓名的队员。

finder方法: findbypositionandname(string position, string name)

说明:position元素和name元素是playerejb entity bean的持续化字段。where子句将这些字段与findbypositionandname方法的输入参数进行比较。ejb ql使用一个后面带有整数的问号表示输入参数。第一个输入参数中?1,第二个是?2,依此类推。

跨越相关bean的finder查询

ejb ql中,一个表达式可以跨越相关的bean。这些表达式的存在中ejb ql和sql的主要不同点。ejb ql跨越到相关的bean,而sql是使用表的连接。

示例 4

select distinct object(p)

from player p, in (p.teams) as t

where t.city = ?1

获得的数据:属于指定城市的运动队的队员。

finder方法: findbycity(string city)

说明:from子句声明了两个标识变量:p和t。p变量表示playerejb entity bean,而t变量表示相关的teamejb bean。在t的声明中引用了之前声明的p变量。in关键记号表示teams是一个相关bean的集合。p.teams表示式实现了从playerejb bean到它的相关teamejb bean的跨越。p.teams表达式中的句点是跨越操作符。

在where子句中,标识变量city之前的句点是一个分隔符,而不是一个跨越操作符。严格说来,表达式可以跨越到关联字段(相关的bean),而不是持续化字段。要访问一个持续化字段,一个表达式必须使用句点作为分隔符。

表达式不可以对作为集合的关联字段作更进一步的跨越。在一个表达式的语法中,collection-value字段是一个终结符。因为teams字段是一个集合,所以where子句不可以指定 p.teams.city--这是一个非法的表达式。

参见: 路径表达式

示例 5

select distinct object(p)

from player p, in (p.teams) as t

where t.league = ?1

获得的数据:属于指定运动联盟的队员。

finder方法: findbyleague(localleague league)

说明:这个查询中的表达式实现了两个关联关系的跨越。p.teams表达式跨越了playerejb-teamejb关联关系,而t.league表达式跨越了teamejb-leagueejb关系。

在其它示例中,输入参数是string对象,但是在这个示例中参数是一个类型为一个localleague接口的对象。这个类型与where的比较表达式中的league关联字段匹配。

示例 6

select distinct object(p)

from player p, in (p.teams) as t

where t.league.sport = ?1

获得的数据:参与指定运动的队员。

finder方法: findbysport(string sport)

说明:sport持续化字段属于leagueejb bean。要访问sport字段,查询必须首先实现从playerejb bean到teamejb bean的跨越(p.teams),然后实现从teamejb bean到leagueejb bean的跨越(t.league)。因为league关联字段不是一个集合,在它后面可以跟随sport持续化字段。

使用其它条件表达式的finder查询

每一个where子句都必须指定一个条件表达式,这样的条件表达式可以有几种。在之前的示例中,条件表达式是检测是否相等的比较表达式。在下面的例子中,使用了一些其它种类的条件表达式。对于所有条件表达式的介绍,请参看where子句。

示例 7

select object(p)

from player p

where p.teams is empty

获得的数据:所有不属于任何运动队的队员。

finder方法: findnotonteam()

说明:playerejb bean的teams关联字段是一个集合。如果一个队员不属于任何运动队,那么teams集合为空,条件表达式的结果将为true。

参见: 空集合比较表达式

示例 8

select distinct object(p)

from player p

where p.salary between ?1 and ?2

获得的数据:薪水位于指定范围的队员。

finder方法: findbysalaryrange(double low, double high)

说明:between表达式是一个三元表达式:一个持续化字段(p.salary)和两个输入参数(?1和?2)。下面的表达式与之前的between表达式等价:

p.salary 〉= ?1 and p.salary 〈= ?2

参见: between表达式

示例 9

select distinct object(p1)

from player p1, player p2

where p1.salary 〉 p2.salary and p2.name = ?1

获得的数据:所有薪水高于指定姓名的队员薪水的队员。

finder方法: findbyhighersalary(string name)

说明:from子句声明了两个标识变量(p1和p2),这两个标识变量具有同一类型(player)。之所以在这里需要两个标识变量是因为以where子句中将一个队员(p2)的薪水与另一个队员(p1)进行了比较。

参见: 标识变量


select查询

这一部分的查询是select方法所使用的。与finder方法不同,一个select方法可以返回持续化字段或其它entity bean。

示例 10

select distinct t.league

from player p, in (p.teams) a

扫描关注微信公众号