EJB-QL 语言参考(推荐)

    技术2022-05-11  63

    本文描述EJB-QL 语言

    EJB-QL 语言

    EJB-QL 用来在CMP类型的EJB中描述 finders和select 方法。设计这种语言的目的是严格的描绘内存对象的查询,而不是数据库的查询。 但是EJB-QL的语法与 SQL非常相似。 他有三个基本语句: SELECT, FROM, WHERE.。通过这几个语句可以实现各种各样的组合。本文的目的不是解释 EJB-QL的各种用法。我们会给出几种语法,并用几个例子来描述它。

    <ejb-ql> 标记

    EJB-QL不能单独使用,必须定义在ejb-jar.xml文件中的 <ejb-ql> 标记中。这个标记属于 <query> 标记, <query>定义EJB中的查询(finder或者 select方法)。EJB容器可以将查询转化为 finder或者 select方法的具体实现。. 下面是一个<ejb-ql> 标记的例子。.

    <ejb-jar> <enterprise-beans> <entity> <ejb-name>hotelEJB</ejb-name> ... <abstract-schema-name>hotelSchemaName</abstract-schema-name> <cmp-field>... ... <query> <query-method> <method-name>findByCity</method-name> <method-params> <method-param>java.lang.String</method-param> </method-params> </query-method> <ejb-ql> <![CDATA[SELECT OBJECT(h) FROM hotelSchemaName AS h WHERE h.city = ?1]]> </ejb-ql> </query> </entity> ... </enterprise-beans> ... </ejb-jar>

    蓝色的为EJB-QL 查询,红色的为 <![CDATA[...]]> 为特定的 XML符号,注意必须一直用这种表示方法。

    常用语法

    SELECT OBJECT(variable) FROM abstractSchemaName [AS] variable [WHERE value comparison value]

    上面是最常用的语法,后面我们会看到更多的语法要素。在这个语法中,可以在FROM 中声明一个或者多变量(variables), 在SELECT 和 WHERE 中引用。 注意 abstractSchemaName,,它与 ejb-jar.xml中 entity 标记中声明的一致。

    value 可以是一个参数( parameter), 数字(numeric或者字符( string),变量( variable), 变量中的成员( member inside this variable),或者常量(例如 ''Pleasant Inn'', 23, TRUE).。每个查询有一个返回类型( return type)。 Values and return types can be of 6 different data types.

    SELECT OBJECT(h) FROM hotelSchemaName AS h返回所有的 hotels.SELECT OBJECT(h) FROM hotelSchemaName AS h WHERE h.city = ''San Diego''返回在 San Diego的 hotels .

    在 SELECT语句中,关键字DISTINCT 可以避免查询出现重复的值。事实上,对于finder方法,由于其返回实体Bean,而实体Bean本身不会重复(因为其主关键字不同)。 但是对于 select 方法,可能就会有重复。

    Select 方法的语法

    当处理一个select方法时,返回类型 ( SELECT语句) 可以不用是 OBJECT(x)。 可以为任意类型的任意值。示例如下:

    SELECT [DISTINCT] value FROM abstractSchemaName [AS] variable [WHERE ...]

    保留关键字

    EJB-QL保留关键字如下: SELECT FROM WHEREOBJECT AS INNOT AND ORLIKE ESCAPE BETWEEN IS NULL EMPTY MEMBER OFTRUE FALSELENGTH LOCATE CONCAT SUBSTRING ABS SQRT

    返回类型

    所有的查询必须返回下面中的一种: 与 SELECT 语句中定义的对象一致的类型(type) 一个包含这种类型的Collection (当不使用SELECT DISTINCT时允许重复) 一个包含这种类型的 Set (不允许重复,必须用 SELECT DISTINCT) 选择什么取决于你,下面是相应的一些示例: SELECT OBJECT(h) FROM hotelSchemaName AS h WHERE h.id = ?1finder 方法如下: abstract public Hotel findByHotelID(String hotelID); (其实这个例子没有必要,因为findByPrimaryKey 完成的是同样的功能)SELECT OBJECT(h) FROM hotelSchemaName AS h WHERE h.city = ?1 (允许重复) or SELECT DISTINCT OBJECT(h) FROM hotelSchemaName AS h WHERE h.city = ?1 (不重复)finder 方法如下: abstract public Collection findByCity(String city);SELECT OBJECT(h) FROM hotelSchemaName AS h WHERE h.capacity >= ?1finder 方法如下: abstract public Set findByCapacity(integer numberOfPeople);

    变量

    变量在 FROM中声明,表示一个 EJB对象。可以在 SELECT 和 WHERE 语句中声明。变量的类型在 ejb-jar.xml中的 abstract schema name 中声明。

    后边我们会讨论 range variables

    成员操作

    通过点(".")你可以说明一个成员属于一个对象,通过点(".")你可以说明任意的 cmp-field 名字,或者是一个单值的 cmr-field 的名字。你可以通过(".")操作单值对象(包括数据成员和关系链)。下面是一些示例: SELECT OBJECT(h) FROM hotelSchemaName h WHERE ...... h.capacity > 100 ... h.owner = ?1 ... h.owner.name = ''Harry'' ... h.owner.hotel = h ... h.rooms = ?1 (这里的 cmp-field 名为 ''city'') (这里的 cmr-field ''owner'' 包含一个唯一的Owner对象) (这里的owner包含一个 cmp-field ''name'') (这里owner 包含 cmr-field ''hotel''; 这个条件总为真) (语法错误 – 不能使用一个 Collection cmr-field – 应该使用 range变量语法替代 )

    Range Variable Syntax

    当一个变量的成员是一个 Collection时,你不能通过点(".")操作它。你必须指定一个新的变量 ,这个变量回迭代(iterate)Collection中的每一个记录。下面是语法

    SELECT [DISTINCT] OBJECT(variable) FROM abstractSchemaName [AS] variable, IN (variable.collectionMember) [AS] variable2 [WHERE ...]

    (注意这里的IN操作与WHERE中的不同),你可以在WHERE中 使用新定义的变量 ,就像一般的变量一样。

    SELECT DISTINCT OBJECT(h) FROM hotelSchemaName AS h, IN (h.rooms) AS r WHERE r.smoking = TRUE (返回所有不吸烟的房间)

    WebLogic Server 6.1 : range变量语法 在WLS是不同的。下面是一个例子 : SELECT DISTINCT OBJECT(h) FROM hotelSchemaName AS h, r IN h.rooms WHERE r.smoking = TRUE

    参数

    当finder或者select方法有一个或者多个参数时,可以用"?n"来表示第n个参数,下面是一个 finder方法的例子:

    abstract public Hotel findByCityAndState(String city, String state);

    你可以用?1表示参数city, ?2表示state,EJB-QL如下所示:

    SELECT OBJECT(h) FROM hotelSchemaName AS h WHERE h.city = ?1 AND h.state = ?2

    条件操作符

    条件操作符是很多的,可以通过括号 ( )来区分优先级,,通过 AND或者 OR合并,例如下面的例子:

    ... WHERE (h.owner.name = ''Harry'' AND h.capacity > 100) OR (h.owner.name = ''Joe'' AND h.capacity > 200)

    下面是这些操作符的详细列表

    NOT

    颠倒当前的条件

    ... WHERE NOT (h.capacity > 100) 等价于: ... WHERE (h.capacity <= 100)

    [NOT] LIKE

    对字符串进行模式匹配,模式可以包含统配符: % 表示任意字符串, _ 表示单个字符串。统配符可以通过使用 ESCAPE后面跟一个换码符置换掉。

    ... WHERE h.state LIKE ''K%'' (将返回在 Kentucky 或者 Kansas的hotel)

    ... WHERE h.owner.name LIKE ''J__'' (两个下划线 ''_'') (将返回 Joe拥有的hotel)

    ... WHERE h.id LIKE ''A_1%'' ESCAPE '''' (将返回以 "A_1"开头的hotel。这里下划线 "_" 被反斜杠 ""置换掉)

    [NOT] BETWEEN x AND y

    检查是否在两个数值的范围中

    ... WHERE h.capacity BETWEEN 100 AND 200

    IS [NOT] NULL

    检查对象是否为 ''null''.

    ... WHERE h.owner IS NULL (返回owner为空的hotel)

    [NOT] IN listOfStrings

    在 WHERE中,检查一个字符串是否在一系列的字符串之中。 这与 FROM中的IN操作不同。

    ... WHERE h.state IN (''Ohio'', ''Texas'', ?1)

    [NOT] MEMBER [OF]

    检查一个值是否在一个集合中

    ... WHERE ?1 MEMBER OF h.rooms (返回包含某一个的房间的 hotel )

    =, <>

    检查是否相等

    ... WHERE h.owner.name = ''Harry'' ... WHERE h.owner.name <> ''Joe''

    <, >, <=, >=

    数字间的比较,对数字和日期有效

    ... WHERE h.capacity >= 100

    IS [NOT] EMPTY

    检查一个集合Collection中是否有元素

    ... WHERE h.rooms IS EMPTY (返回没有房间的 hotels)

    数据类型

    EJB-QL中共有6中数据类型,它们可以用于返回值,参数,常量,变量。

    Objects

    它是一个一般的 Java object.。这样的一个object可以直接被映射为一个 abstract schema name,,或者其它 object的成员

    SELECT OBJECT(h) FROM hotelSchemaName h WHERE h.owner = ?1 (这里的object 为 h, h.owner 和 ?1)

    Collections

    可以表示为 range变量, 一个object的成员, 或者使用select方法时,返回值为 Collection

    SELECT OBJECT(h) FROM hotelSchemaName h WHERE ?1 MEMBER OF h.rooms (Collection 为 h.rooms)

    SELECT OBJECT(h) FROM hotelSchemaName h, IN h.rooms AS r WHERE r = ?1 ( Collections 为 r 和 h.rooms)

    SELECT h FROM hotelSchemaName (返回所有hotel的Collection )

    Strings

    可以用作字符 参数,成员变量 ,或者单引号 ''中定义的常量。

    ... WHERE h.owner.name = ''Harry'' (String为 h.owner.name (变量) 和 ''Harry'' (常量))

    ... WHERE h.owner.name = ''O''''Sullivan'' (常量)

    Numbers

    可以用作数字 参数,成员变量 ,常量。 number 可以为负数 (加 -) 或者小数 (加.),甚至是科学计数法。 integer 转换为 float是自动完成的 。

    13 -16 17.2 1.98E4 45 + 12.1 (自动转换为 float)

    Dates

    日期其实是另一种形式的数字。如果用常量来表示, 就是从 01/01/1970 00:00:00 GMT后以秒为单位的一个数字。如果是 参数或者成员变量, 必须是一个 Date对象。

    ... WHERE reservation.arrivalDate = ?1 (这里的 date是成员变量 arrivalDate 和参数)

    ... WHERE reservation.arrivalDate < ??????? (这里的值需要计算)

    Booleans

    布尔型 参数 或者成员变量,或者常量TRUE 或者 FALSE

    ... WHERE room.smoking = TRUE

    字符串函数

    LENGTH(s)

    返回字符串的长度

    ... WHERE LENGTH(h.owner.name) > 3

    LOCATE(s, substr [, startPosition])

    返回以各子串在字符串中的位置。 当指定起始点后,子串的搜索从起始点开始。

    ... WHERE LOCATE(h.owner.name, ''rr'') = 2 (Harry''s hotel 会被返回)

    ... WHERE LOCATE(h.owner.name, ''rr'', 3) >= 0 (从位置 3开始, Harry''s hotel 将不会被返回)

    CONCAT(s1, s2)

    连接两个字符串为新的字符串

    SELECT CONCAT (CONCAT( h.owner.name, '', the owner of ''), h.name) FROM hotelSchemaName AS h (select方法返回所有的hotel的所有owner,返回值为一个字符类型的集合)

    SUBSTRING(s, startPosition, length)

    根据指定位置,指定的字符串数从字符串中得到一个字串。

    ... WHERE SUBSTRING(h.owner.name, 0, 2) = ''Jo'' (将会返回Joseph, Joe, 等, 等价于h.owner.name LIKE ''Jo%'')

    数字函数和操作

    ABS(n)

    返回一个数字的绝对值

    SELECT ABS(a.balance) FROM accountSchemaName AS a WHERE a.balance < 0 (select方法将会返回所有的资产为负的记录,但返回值为正的)

    SQRT(n)

    返回数字的平方根

    SELECT OBJECT(a) FROM accountSchemaName AS a WHERE SQRT(a.balance) = 2 (返回资产为4的账号)

    +, -, *, /

    加,减,乘,除操作 SELECT ABS(a.balance) FROM accountSchemaName AS a WHERE a.balance + 1 = 5 (返回资产为4的账号)

    SELECT OBJECT(h) FROM hotelSchemaName AS h WHERE h.capacity / 2 >= ?1 SELECT OBJECT(h) FROM hotelSchemaName AS h WHERE h.capacity >= ?1 * 2 (上面的两个查询都是返回指定容量双倍的hotel)

    SELECT h.capacity - 10 FROM hotelSchemaName AS h (返回 hotel的容量 ,返回值会减去10)

     

    最新回复(0)