CMP Bean’s EJB QL
Introduction:
考虑
customer-order-orderDetails
的数据库表的一般的情况,下面是关于这
3
张表他们彼此之间的关系
:
Tables 1: Customers Table 2: Order Table 3: orderDetails
customerId
|
CompanyName
|
Address
|
City
|
Region
|
OrderID
|
customerId
|
orderDate
|
Shipment
|
shipmentAdd
|
orderID
|
productId
|
Quantity
|
Price
|
问题:
1.
找出所有住在
“New York”
的客户。
2.
找出所有以
“ER”
开头的客户的名字。
3.
找出定单编号是‘
1832
’的客户。
4.
找出所有在
’12/12/2001’
和
‘3/12/2002’.
之间发出定单的客户。
5.
找出所有订购了
’XYZ’
产品的客户。
l
CustomersEJB
表示
Customers CMP
实体
bean
的类名
.
.
l
Customers
在
CustomersEJB CMP
的实体
bean
里面是表示一个抽象的表名
.
.
.
1.
find all customers who are living in “New York” city
按
SQL
语法的写法:
Select customer.companyName from customer where customer.city =’New York’
CMP
实体
Bean
我们使用
EJB QL
语言的写法:
SELECT OBJECT(C) FROM Customers AS c WHERE c.city =’New York’
.
FROM
子句
:
l
所有别名必须定义在
FROM
字句里,并且在
SELECT
和
WHERE
字句里使用。
l
别名不能是标识符或者是下面的类型的名字:
•
abstract-schema-name
•
ejb-name
reserved identifiers are:
SELEC
T, FROM, WHERE, DISTINCT, OBJECT,NULL, TRUE, FALSE, NOT, AND, OR, BETWEEN, LIKE, IN, AS, UNKNOWN [18] , EMPTY, MEMBER, OF and IS.
WHERE
子句 :
l
WHEREe
字句必须使用在
FROM
字句里面定义的别名
l
WHERE
字句能够使用输入的参数,因而你能够写出
QL
的查询像这样:
SELECT OBJECT(c) FROM Customers AS c WHERE c.city = ?1
?
1
表示输入的第一个参数
SELECT
子句
:
SELECT
字句表示一个查询结果。他包含一个范围变量,这个范围变量在一个实体
Bean
上面是一个抽象的表的类型,或者是一个表达式。
在
ejb-jar
文件里怎么定义一个
abstract-schema-name
:
下面
abstract-schema-name
用黑体表示出来了
<ejb-jar>
<enterprise-beans>
<entity>
<display-name>CustomersEJB</display-name>
<ejb-name>CustomersEJB</ejb-name>
<home>com.bharat.ejbql.CustomersEJBRemoteHome</home>
<remote>com.bharat.ejbql.CustomersEJBRemote</remote>
<ejb-class>com.bharat.ejbql.CustomersEJBBean</ejb-class>
<persistence-type>Container</persistence-type>
表示是一个由容器管理的
CMP
的实体
Bean
<prim-key-class>java.lang.String</prim-key-class>
<reentrant>False</reentrant>
<cmp-version>2.x</cmp-version>
<abstract-schema-name>Customers</abstract-schema-name>
<cmp-field>
<field-name>customerName</field-name>
</cmp-field>
<cmp-field>
<field-name>city</field-name>
</cmp-field>
………..
others table fields
………..
在
QL
中我们要怎么使用
abstract-schema-name
l
在我们定义的实体
Bean
的
finder
方法中,它不是一个唯一被使用的
abstract-schema-name
,
在
ejb-jar
文件中你能够使用所有已经定义了的实体
Bean
的
abstract-schema-name
l
finder
方法的返回值必须是我们已经定义的实体
Bean
的类型
l
接下来让我们为一个实体
Bean
定义一个
finder()
或者是一个
select(),
请注意下面几点
:
l
Finder()
都定义在
home
接口里面,因而它们能够暴露在客户端被
Bean
调用
l
Select()
都被定义在
bean
的里面,所以他们只能在
bean
的内部使用
l
定义一个
finder()
的语法
:
find<METHOD-NAME>
因而
finder()
可以像这样子定义
:
Public
java.util.Collection findByCity(java.lang.String city) throws RemoteException , FinderException.
要注意的两点
:
l
我们的
finder()
接收
String
类型的参数并且抛出
RemoteException and FinderException
l
方法的返回值是
java.util.Collection
.
完成上面的
QL
:
<query>
<query-method>
<method-name>findByCity</method-name>
<method-params>
<method-param>java.lang.String</method-param>
</method-params>
</query-method>
<result-type-mapping>Local</result-type-mapping>
<ejb-ql>
SELECT OBJECT(c) FROM Customers AS c WHERE c.city = ?1
</ejb-ql>
</query>
到目前为止我们已经完成了我们第一个查询。在下面的查询中,你可以参考我们已经完成的查询的配置信息。我们不会重复这些配置信息,让我们开始进入第
2
个问题。
2
.
Find all customers whose companyName start with “ER”.
EJB QL
:
SELECT OBJECT(c) Customers AS c WHERE c.companyName LIKE ‘ER%’.
类似的你也可以使用
NOT LIKE
:
SELECT OBJECT(c) Customers AS c WHERE c.companyName NOT LIKE ‘ER%’.
3 . find customer with orderID ‘1832’ .
.
(
一对多关系的配置
)
先让我们定义
ejb-jar
的配置信息
,
它绑定了
CustomersEJB
和
OrdersEJB
:
<relationships>
<ejb-relation>
<ejb-relation-name>customersEJB-ordersEJB</ejb-relation-name>
<ejb-relationship-role>
(
customersEJB
的关系配置
)
<description>customersEJB</description>
<ejb-relationship-role-name>
CustomersEJBRelationshipRole
</ejb-relationship-role-name>
<multiplicity>One</multiplicity>
<relationship-role-source>
<description>customersEJB</description>
<ejb-name>CustomersEJB</ejb-name>
</relationship-role-source>
<cmr-field>
<description>ordersEJB</description>
<cmr-field-name>ordersEJB</cmr-field-name>
<cmr-field-type>java.util.Collection</cmr-field-type>
</cmr-field>
</ejb-relationship-role>
要注意的地方:
:
l
在
Customers-Orders CMP beans.
中我们配置了一个一对多关系。
这样我们就可以写出关联
2
个表的
QL
语句了:
SELECT OBJECT(c) FROM Customers AS c , IN(c.ordersEJB) o WHERE o.orderid = ?1
4. Find all customers who have given order between ’12/12/2001’ and ‘3/12/2002’ .
我们使用相同的关系映射在
Customers-Orders
获得查询结果。这里我们将在
WHERE
字句中使用
BETWEEN
操作符:
SELECT OBJECT(c) FROM Customers AS c , IN(c.ordersEJB) o WHERE o.orderDate BETWEEN ?1 AND ?2
在这个
QL
语句中返回的类型是一个集合的类型,它包含所有的在过去的这个事段中发出
orders
(定单)的
customers
(客户)的信息,但是在这个时段中可能有相同的
customers
发出了
orders
。我们能够限制结果不包含相同的
customers
:
l
在下面的
SELECT
子句中使用
DISTINCT
:
SELECT DISTINCT c FROM Customers AS c WHERE c.ordersEJB.orderid = ?1
l
定义一个
finder()
的返回值为
java.util.Set
代替
java.util.Collection
:
Public java.util.Set findByDateDiff(java.sql.Date start, java.sql.Date end) throws RemoteException , FinderException
如果你想返回的结果是不在那个时段发出
orders
的
Customers
的信息。我们可以使用
NOT BETWEEN
代替
BETWEEN
。
如果你没有使用上面的操作符,可以对照这些操作符的使用:
> , < , >= ,<= ,<>
5
. Find all customers who give order for product with productID of ?.
在这个例子中查询
Customers
的时候
3
张表都被调用了,所以在这个查询语句中,我们在使用了
Order-Customer
表的关系映射中同样要加入
Orders
和
OrderDetails
表的关系映射:
SELECT OBJECT(c) FROM Customers AS c , IN(c.ordersEJB) l , IN(l.orderDetailsEJB) od WHERE od.productid = ?1
这里的
orderDetailsEJB
已经在
cmr-frield
中关联了
Orders
和
OrderDetails
表。