使用 EJB 查询
Enterprise JavaBeans (EJB) 查询语言用于指定容器管理的实体 Bean 上的查询。该语言类似于结构化查询语言 (SQL)。EJB 查询与 Bean 到持久性存储的映射无关。
关于此任务
在三种情况下使用 EJB 查询:
- 要定义 EJB 实体 Bean 的 finder 方法。
- 要定义 EJB 实体 Bean 的 select 方法。
- 要使用 executeQuery 方法动态 API 动态指定查询。
产品 EJB 查询语言符合 Sun EJB 2.1、EJB 3.0 和 EJB 3.1 规范中定义的 EJB QL,并具有在“EJB 规范和 WebSphere® 查询语言的比较”主题中列示的其他功能。
过程
示例:查询 EJB
以下是一个示例 Enterprise JavaBeans (EJB) 模式,后跟一组示例查询。
EJB 模式 | 示例查询 |
---|---|
实体 Bean 名称(EJB 名称) | DeptEJB(不用于查询) |
抽象模式名称 | DeptBean |
实现类 | com.acme.hr.deptBean(不用于查询) |
持久属性(cmp 字段) |
|
关系 |
|
EJB 模式 | 示例查询 |
---|---|
实体 Bean 名称(EJB 名称) | EmpEJB(不用于查询) |
抽象模式名称 | EmpBean |
实现类 | com.acme.hr.empBean(不用于查询) |
持久属性(cmp 字段) |
|
关系 |
|
地址是作为 EmpBean 中的 cmp 字段使用的可串行的对象。地址的定义按如下所示:
public class com.acme.hr.Address extends Object implements Serializable {
public String street;
public String state;
public String city;
public Integer zip;
public double distance (String start_location) { ... } ;
public String format ( ) { ... } ;
}
以下查询返回所有部门:
SELECT OBJECT(d) FROM DeptBean d
以下查询返回一些部门,其名称都是以字母“Web”开头的。按名称排序结果:
SELECT OBJECT(d) FROM DeptBean d WHERE d.name LIKE 'Web%' ORDER BY d.name
关键字 SELECT 和 FROM 在示例中是以大写显示的,但它们不区分大小写。如果查询中使用的名称是保留字,那么名称必须加上双引号以在查询中使用。您可以在EJB 查询:保留字中查找保留字的列表。包含在双引号中的标识区分大小写。本示例显示如何使用是保留字的 cmp 字段:
SELECT OBJECT(d) FROM DeptBean d WHERE d."select" > 5
以下查询返回所有由 Bob 管理的职员。本示例显示如何使用路径表达式浏览关系:
SELECT OBJECT (e) FROM EmpBean e WHERE e.dept.mgr.name='Bob'
查询可以包含参数,此参数指 finder 方法或 select 方法的相应值。查询参数是以 1 开始编号的:
SELECT OBJECT (e) FROM EmpBean e WHERE e.dept.mgr.name= ?1
本查询显示多值关系的导航并返回所有收入在 50000 至 90000 之间的职员所在的部门:
SELECT OBJECT(d) FROM DeptBean d, IN (d.emps) AS e
WHERE e.salary BETWEEN 50000 and 90000
此查询中包含了每个部门对象和其相关职员集合之间的连接操作。如果部门没有职员,那么该部门不在结果中出现。如果一个部门有多个职员的收入大于 50000,那么该部门在结果中多次出现。
以下查询消去重复的部门:
SELECT DISTINCT OBJECT(d) from DeptBean d, IN (d.emps) AS e WHERE e.salary > 50000
查找奖金大于其薪水 40% 的职员:
SELECT OBJECT(e) FROM EmpBean e where e.bonus > 0.40 * e.salary
查找部门,该部门职员的薪水和奖金总和超过了部门的预算:
SELECT OBJECT(d) FROM DeptBean d where d.budget <
( SELECT SUM(e.salary+e.bonus) FROM IN(d.emps) AS e )
查询可以包含 DB2® 样式日期时间算术表达式,如果您使用 java.sql.* 数据类型作为 CMP 字段并且您的数据存储是 DB2 的话。查找所有到 2000-01-01 时为止已工作至少 20 年的职员:
SELECT OBJECT(e) FROM EmpBean e where year( '2000-01-01' - e.hireDate ) >= 20
如果数据存储不是 DB2 或者如果您更愿意使用 java.util.Calendar 作为 CMP 字段,那么您可以在查询中使用 Java 毫秒值。下列查询查找所有在 1990-01-01 之前出生的职员:
SELECT OBJECT(e) FROM EmpBean e WHERE e.birthDate < 631180800232
查找没有职员的部门:
SELECT OBJECT(d) from DeptBean d where d.emps IS EMPTY
查找所有收入多于 Bob 的职员:
SELECT OBJECT(e) FROM EmpBean e, EmpBean b
WHERE b.name = 'Bob' AND e.salary + e.bonus > b.salary + b.bonus
查找奖金最多的职员:
SELECT OBJECT(e) from EmpBean e WHERE e.bonus =
(SELECT MAX(e1.bonus) from EmpBean e1)
上面列出的查询全都返回 EJB 对象。finder 方法查询必须总是返回 EJB 对象给归属。select 方法查询还可以返回 CMP 字段或其他不属于归属的 EJB 对象。
以下是对于 EmpBean 的有效的 select 方法查询。返回每个部门的经理:
SELECT d.mgr FROM DeptBean d
返回部门 42 经理的姓名:
SELECT d.mgr.name FROM DeptBean d WHERE d.deptno = 42
返回部门 42 中的职员的姓名:
SELECT e.name FROM EmpBean e WHERE e.dept.deptno=42
另一种写相同查询的方法是:
SELECT e.name from DeptBean d, IN (d.emps) AS e WHERE d.deptno=42
finder 方法和 select 查询在 SELECT 子句中仅允许单个 CMP 字段或 EJBObject。select 查询可以使用 SUM、MIN、MAX、AVG 和 COUNT 返回 Enterprise JavaBeans 2.1 中的聚集值。
SELECT max(e.salary) FROM EmpBean e WHERE e.dept.deptno=42
动态查询 API 允许在 SELECT 子句中有多个表达式。以下查询将是有效的动态查询
,但不是有效的 select 或 finder 方法查询:
SELECT e.name, e.salary+e.bonus as total_pay , object(e), e.dept.mgr
FROM EmpBean e
ORDER BY 2
以下动态查询返回每个部门中的职员数:
SELECT e.dept.deptno as department_number , count(*) as employee_count
FROM EmpBean e
GROUP BY by e.dept.deptno
ORDER BY 1
动态查询 API 允许包含 bean 或值对象方法的查询:
SELECT object(e), e.address.format( )
FROM EmpBean e EmpBean e