谁给我讲一下EJB2。0的查询语言?

tdg2002 2002-11-27 09:39:05
如题:
尤其是SELECT FROM WHERE从句
50不够再加
...全文
41 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
kexsong 2002-11-27
  • 打赏
  • 举报
回复
再补充一点:ejb-ql查询语句的编写,任何两个元素之间都要有空格,比较符也不例外,例如:c.id = getID,等号两边都留空格吧。保证不出错啊
松耦合紧内聚 2002-11-27
  • 打赏
  • 举报
回复
好像挺好看的!
lun2001 2002-11-27
  • 打赏
  • 举报
回复
说得好
收藏
kexsong 2002-11-27
  • 打赏
  • 举报
回复
接上文:
三、WHERE子句
WHERE子句定义了选择结果中的对象或值必须满足的条件表达式。下面是WHERE子句的语法:
WHERE子句 ::= WHERE 条件表达式
在EJB QL查询语言中,WHERE子句中的所有符号变量必需在FROM子句中声明。查找器方法和select方法的输入参数也在这里传入。输入参数由一个问号(“?”)前缀指示,问号的后面加上方法声明中参数的序号(例如:?1,?2,等等)。
public abstract class OrderBean implements javax.ejb.EntityBean {
...
//method-a
public abstract java.util.Collection ejbSelectLineItems(int quantity)
throws FinderException;
...
//method-b
public abstract java.util.Collection ejbSelectAllProducts(String product_type, double price)
throws FinderException;
}
例如,对应上面method-a的select方法的查询是:
SELECT OBJECT (o) FROM Order AS o IN (o.lineItems) li
WHERE li.quantity = ?1
类似地,对于第二个根据名字和价格选择所有产品的method-b,相应的查询是:
SELECT OBJECT (o) FROM Order AS o IN(o.lineItems) li
WHERE li.product.product_type=?1 AND li.product.price=?2
在部署描述器中,为method-a定义查询的形式如下:
method description
ejbSelectLineItems
int
Local
SELECT OBJECT (o) FROM Order AS o IN (o.lineItems) li
WHERE li.quantity = ?1
在EJB QL查询中,输入参数的数量必须与查找器方法或select方法的输入参数数量相同。尽管如此,EJB QL查询不必一定要用到查找器方法或select方法的全部输入参数。
下面,我们来看看各种可以在WHEER子句中使用的比较操作符。除了支持前面查询例子中的导航操作符(“.”),EJB QL还支持所有算术运算(即:一元操作符,乘法和除法,加法和减法),比较操作符(即:=,>,>=,<,<=,<>),以及逻辑操作符(即:NOT,OR,AND)。
EJB QL查询还支持BETWEEN和NOT BETWEEN比较操作符。例如,下面的查询选择出所有quantity在100到200之间的lineItem:
SELECT OBJECT (li) FROM lineItems AS li
WHERE li.quantity BETWEEN 100 and 200
如果使用“>=”和“<=”比较操作符,则上述查询的WHERE子句可以改写为:
li.quantity >= 100 AND li.quantity <= 200
下面两个查询选择出所有quantity小于100或大于200的lineItem:
查询1:
SELECT OBJECT (li) FROM lineItems AS li
WHERE li.quantity NOT BETWEEN 100 and 200
查询2:
SELECT OBJECT (li) FROM lineItems AS li
WHERE li.quantity < 100 AND li.quantity > 200
EJB QL还支持IN和LIKE表达式。例如,要选择出在各个城市的办公室地址,WHERE子句的查询表达式可以是:
address.city IN ('北京', '上海', '杭州')
当city等于“北京”或者“杭州”,上面的表达式为true;当city等于“纽约”,上面的表达式为false。NOT IN操作符的含义恰好和IN操作符相反:
address.city NOT IN ('北京', '上海', '杭州')
当city等于“北京”或者“杭州”,上面的表达式为false;当city等于“纽约”,上面的表达式为true。对于IN操作符,在括号内用逗号分隔的字符串列表中,至少必须存在一个字符串。
在WHERE子句中,利用[NOT] LIKE操作符可以选择出符合特定模式的值。LIKE表达式的语法如下:
single_valued_path_expression [NOT] LIKE pattern-value [ESCAPE escape-character]
single_valued_path_expression的值必须是一个字符串值。pattern-value可以是任何字符串文本,其中下划线(“_”)表示任意单个字符,百分号(“%”)表示任意字符序列,包括空的字符序列。escape-character是一个单字符的字符串,用来转义pattern-value中下划线和百分号的特殊含义。
例如,下面的查询选择出所有名字以“王”开头的雇员:
SELECT OBJECT (emp) FROM employee as emp
WHERE emp.name LIKE '王%'
又如,下面的查询选择出所有名字不以“王”开头的雇员:
SELECT OBJECT (emp) FROM employee as emp
WHERE emp.name NOT LIKE '王%'
如果在上面的表达式中,emp.name的值是NULL,则整个表达式的值是未知的。为避免出现这种情况,我们可以用IS NULL操作符检查single_valued_path_expression的值是否是NULL。在下面的表达式中,如果雇员的名字是NULL,返回值将是true:
emp.name IS NULL
EJB QL查询语言还提供了IS EMPTY比较操作符,用来检查查询命令返回的集合对象是否包含空值。另外,EJB QL提供了MEMBER [OF]符号来检查single_valued_path表达式的值是否是某个集合的成员。注意在EJB QL查询中,任何带有NULL或未知值的比较或算术运算的结果是一个未知的值。
四、SELECT子句
SELECT子句指定了查询的返回结果。用BNF形式表示的SELECT子句的语法如下:
SELECT [DISTINCT] {single_valued_path_expression | OBJECT (identification_variable)
在EJB QL中,DISTINCT作用和它在SQL中的作用相同,用来从查询结果选择出唯一值。
要限定返回值只包含唯一值,我们还可以把查找器和select方法的返回类型声明为java.util.Set。由于java.util.Set不允许包含重复值,当返回类型是java.util.Set时,容器在内部自动地为查询加上了DISTINCT。因此,查询命令中不一定要显式地加上DISTINCT符号。然而,如果返回值类型是java.util.Collection,要获得唯一的查询结果就要在查询表达式中显式地指定DISTINCT符号。
SELECT子句指定了查询返回值的类型。例如,要获取所有的订单,查询命令的SELECT子句为:
SELECT OBJECT(o) FROM order o
在上面的例子中,order是OrderEJB的抽象模式名字。类似地,要获得与lineItem关联的所有的产品,SELECT子句为:
SELECT li.product FROM Order As o, IN(o.lineItems) li
现在,我们来看看下面这个查询。这个查询用来获取与一个订单有关的所有lineItem:
SELECT o.lineItems FROM Order As o
请仔细观察上面这个查询。实际上,这个查询不能正常工作,因为查询的返回类型不是一个单值的表达式。前面用来获取与lineItem关联的所有产品的查询能够正常工作,这是因为lineItem与Product的关系是一对一的关系,而订单和lineItem的关系是一对多的关系。
EJB QL还提供了一些内建的函数,用于对String类型的对象和各种Java基本类型的数据进行简单的操作。具体地说,EJB QL提供了下列内建函数:
字符串函数:
CONCAT (String, String):该函数返回连结后的字符串值。
SUBSTRING (String, start, length):该函数返回指定字符串的一个子串。
LOCATE (String, String [, start]):该方法的返回值是int。
LENGTH (String):该方法返回参数中指定的字符串的长度。
数值函数:
ABS (number):返回绝对值。
SQRT (double):返回平方根。
五、EJB QL的优点与局限
EJB QL主要有如下优点:
EJB QL为定义实体Bean的查询提供了一种标准的方式。EJB QL查询可以在不同的应用服务器之间移植,如果实体Bean用EJB QL定义它的查找器方法和select方法,则该Bean可以移植到任何遵从EJB 2.0规范的EJB容器上。
在部署实体Bean之前,EJB容器将分析和验证EJB QL查询的合法性。
局限:
SQL中一些有用的功能仍未在EJB QL中提供。例如,当应用变得原来越庞大和复杂时,ORDER BY能够带来不少方便,但是EJB QL查询语言仍不能支持ORDER BY子句。部分应用服务器可能提供这方面的功能,然而,使用这些功能将对应用在不同服务器之间的可移植性带来影响。
日期和时间值必须用Java基本数据类型long以毫秒的形式传递。
在数值表达式中,EJB QL不支持定点数比较。
字符串和Boolean值的比较局限于等于(“=”)和不等于(“<>”)。但内建的函数(CONCAT,SUBSTRING,等等)可用来执行其他类型的字符串操作。
EJB QL不支持注释。
【结束语】EJB 2.0规范新增的EJB QL满足了分布式组件体系对查询定义标准的需求。EJB QL能够使应用具有更好的可移植性。可以相信,未来的EJB QL版本将提供对更多内建函数以及其他SQL功能(比如ORDER BY)的支持。在EJB 2.0规范中,CMP的数据模型当前还不支持继承,因此,我们不能对不同类型的对象或值进行比较,这个问题可望在EJB QL的未来版本中得到解决。
kexsong 2002-11-27
  • 打赏
  • 举报
回复
EJB查询语言

一、EJB查询语言
EJB 1.1规范没有为CMP实体Bean(容器管理持久化的实体Bean)的查找器方法提供一种定义查询的标准,因此,各个EJB容器厂商分别为实体Bean的查找器方法定义了各自的查询语法。例如,BEA的WebLogic Application Server v5.1定义了一种称为WLQL的查询语言。 由于这个原因,当应用从一个厂商的应用服务器移植到另一个厂商的应用服务器时,开发者必须重新为查找器方法定义查询。显然,这限制了带有CMP实体Bean的应用的可移植性。
另外,EJB 1.1规范也没有为CMP实体Bean在各种不同的代码上下文、关系或关联条件下与其它实体Bean的交互提供标准的方法,没有一种合适的机制可以用来定义那些从一个实体Bean导航到它所依赖的类以及这些类的成员变量的查询。
EJB 2.0规范通过定义EJB查询语言(EJB Query Language)来解决这些问题。EJB QL以SQL-92规范为基础,用来为CMP实体Bean定义各种查找器方法和select方法的查询。EJB QL查询语句由三个子句构成:SELECT子句,FROM子句,WHERE子句。EJB QL的用途之一是,通过在部署描述器中引入抽象模式类型和关系,它为定义实体Bean以及依赖类之间的关系提供了一种标准化的方法。另外,EJB QL还能够用抽象模式名字和关系为导航操作定义查询。
下面是EJB QL查询的基本语法格式:
EJB QL查询 ::= SELECT子句 FROM子句 [WHERE子句]
EJB QL查询必须包含SELECT和FROM子句,但WHERE子句是可选的。FROM子句声明了基于抽象模式名字的符号变量,SELECT子句利用这些符号变量定义查询的返回值类型,而WHERE子句则定义了查询的条件。
查找器方法或select方法的名字在元素中指定,参数在元素中指定。元素指定了返回值类型,可以包含本地值或远程值。查询字符串在元素中声明。查找器方法和select方法用EJB QL定义查询,所以下面我将简略地介绍一下这两个概念。EJB 2.0规范定义了实体Bean的查找器方法和select方法,其中select方法是该规范新增的内容。
查找器方法(Finder Method):查找器方法通过关系数据库系统从持久性存储系统中提取出一个实体Bean的实例,或者一个实体Bean实例的集合。这些方法将在实体Bean的Home接口列出,因此,客户程序可以看到它们。Home接口既可以是远程的EJBHome,也可以是本地的EJBLocalHome。在远程Home接口中,查找器方法的返回类型或者是实体Bean的远程接口,或者是一个实现实体Bean远程接口的对象的集合。在本地Home接口中,查找器方法的返回值类型或者是实体Bean的本地接口,或者是一个实现实体Bean本地接口的对象的集合。例如:
// 远程Home接口
public interface OrderHome extends javax.ejb.EJBHome {
...
public Order findByPrimaryKey(int orderId) throws FinderException,RemoteException;
public Order findByBiggestOrder() throws FinderException,RemoteException;
public java.util.Collection findAllOrders(String supplierName) throws FinderException,RemoteException;
}
// 本地Home接口
public interface OrderHome extends javax.ejb.EJBLocalHome {
...
public Order findByPrimaryKey(int orderId) throws FinderException;
public Order findBiggestOrder() throws FinderException;
public java.util.Collection findAllOrders(String supplierName) throws FinderException;
}
select方法(Select Method):在实体Bean中,select方法作为一种特殊类型的查寻方法存在。这些方法不在Home接口中声明,因此客户程序不能直接访问它们。对于访问cmp-field或者在cmr-field中定义的任何远程接口实例来说,查找器方法不是很有用。利用select方法,实体Bean可返回cmp-field类型的实例,或由cmr-field描述的远程接口。
select方法通常有下面两种类型:
ejbSelect
ejbSelectInEntity
例如:
public abstract class OrderBean implements javax.ejb.EntityBean {
...
public abstract java.util.Collection ejbSelectAllOrderedProducts(Date date)
throws FinderException;
...
public abstract java.util.Collection ejbSelectAllOrderedProductsInEntity(Date date)
throws FinderException;
}
ejbSelect不关联到实体Bean的特定实例。因此,在上面的例子中,ejbSelectAllOrderedProducts方法返回一个集合,其中包含与所有订单关联的所有产品。ejbSelectInEntity面向特定的实体Bean实例执行,前面例子中的ejbSelectAllOrderProductsInEntity方法返回与该OrderBean实例关联的所有产品。
我们将以订单处理应用为例,详细介绍EJB QL查询的各个子句。图一显示了OrderEJB、LineItemEJB、ProductEJB和AddressEJB之间的关系:

在部署描述器中,上述关系的定义如下:
Order-LineItem
order-has-lineitems
One
OrderEJB
lineItems
java.util.Collection
lineitem-belongsto-order
Many
LineItemEJB
order
Product-LineItem
product-has-lineitems
One
ProductEJB
lineitem-for-product
Many
LineItemEJB
product
二、FROM子句
FROM子句通过声明符号变量,定义了查询的范围。符号变量不能在SELECT子句和WHERE子句中声明,SELECT子句和WHERE子句只能使用FROM子句中定义的符号变量。一个FROM子句中可以定义多个符号变量。
任何合法的标识符都可以用作符号变量,但也存在一些限制。例如,符号变量的名字不能与抽象模式名字或EJB名字相同。另外,符号变量名字不应该是保留的符号,保留的符号包括:SELECT,FROM,WHERE,DISTINCT,OBJECT,NULL,TRUE,FALSE,NOT,AND,OR,BETWEEN,LIKE,IN,AS,UNKNOWN,EMPTY,MEMBER,OF以及IS。符号变量的名字是大小写敏感的。
符号变量声明包括范围变量声明和集合成员变量声明。下面,我们将分析一个简单的查询命令,它的FROM子句既包括范围变量声明,也包括集合变量声明。要选择出所有包含“Floppy Drive”产品的订单,查询是:
SELECT OBJECT(o) FROM Order o, IN (o.lineItems) li
WHERE li.product.product_type='Floppy Drive'
在这个例子中,FROM子句把“o”标识符声明为一个范围变量,把标识符“li”声明为一个集合成员变量。范围变量声明了抽象模式类型。声明集合成员变量要用到: 保留符号“IN”,范围变量的抽象模式类型,以及 关联的实体Bean的抽象模式类型。 范围变量“o”指示了抽象模式类型Order。类似地,符号变量“li”是LineItem抽象模式类型,li.product是Product抽象模式类型。WHERE子句中的li.product.product_type是java.lang.String类型。在EJB QL查询语言中,所有子句的分析和计算都是从左到右进行,因此,符号变量“li”利用了前面声明的“o”。在SELECT子句中的OBJECT符号是必须的,因为要用OBJECT操作符来限定和修饰SELECT子句中的所有独立的符号变量。
范围变量还可以使用可选的符号AS声明。也就是说,上面例子中的FROM子句也可以改写成:
FROM Order AS o, IN (o.lineItems) li
另外,一个FROM子句可以定义一个以上的范围变量。例如:
FROM Order AS o, IN (o.lineItems) li, Product p

67,515

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧