用EJB-QL语言FIND 实体BEAN

很多应用(程序)需要使用特定的条件在数据库中查找实体BEANS。借助EJB-QL查询语言,实体BEANS可以在HOME接口中定义Find方法,通过实体BEAN的属性来查询。
加一个FIND方法需要做2步:
  在HOME接口加一个FIND方法
  在BEAN的部署描途中加入EJB-QL查询。
Resin-CMP使用EJB2.0规范的EJB-QL查询语言。EJB-QL类似SQL,为了适合于操作实体BEAN,EJB-QL与SQL相比,EJB-QL增加了一些限制和扩展。例如,EJB-QL扩展了SQL,直接支持关联和方法参数。

下而的例子,学校的校长需要知道当前有哪门课程正在上课和任课老师是谁。

Database Schema
        Courses.sql
CREATE TABLE find_courses (
 course_id VARCHAR(250) NOT NULL,
 instructor VARCHAR(250),

 PRIMARY KEY(course_id)
);
lEJB-QL
在findall  和 findByInstructor 方法中,使用EJB-QL从数据库中选取一个教师。EJB-QL类似于一个有一定限制的SQL,加入对关联和方法参数的直接支持。
findall方法查数据库所有的课程,schema 名字course 来自abctract-schena-ame。字段courseId是cmp-field 名字,这些名字不必与SQL的表名和列名一致。如果在部署配置中改变了SQL的表名和列名,EJB-QL仍然引用相同的abstract名字。
SELECT  o  FROM  course o

findByInstructor 使用带参数instructor的方法查找课程,因为instructor是一个参数,它必须在查询中指定。EJB-QL使用参数的方法是?n。n是参数的序号,从1开始。
SELECT o FROM courses o WHERE o.instructor = ?1

Client Serverlet
在下面的例子中,我们列举三种find方法
1.通常使用的findByPriaryKey
2.返回集合 findAll
3.带一个instructor参数的findByInstructor
成对出现的本地对象和它的Home接口符合Home接口在Factory模式(设计模式中的工厂模式)中的角色(远程Home的Find方法永远返回远程接口或者远程接口的集合)
如果应用程序需要返回其它的值,包括本地Beans,需要调用ejbSelect方法。
findAll方法返回包含所有课程的集合。Client端在课程的集合上进行迭代遍历。

Findall Courses
...

Collection c = home.findAll();
Iterator iter = c.iterator();

while (iter.hasNext()) {
 Course course = (Course) iter.next();

 out.println(course.getCourseId() + " is taught by " +
             course.getInstructor() + "<br>");
}

...
结果类似于下面:
Potions is taught by Severus Snape
Transfiguration is taught by Minerva McGonagall
Defense Against the Dark Arts is taught by Remus Lupin
上例中带参数instructor的findByInstructor方法返回一个教师所教授的课程,单值查找方法期望返回一个且只有一个结果。如果没有查找到结果,findByInstructor抛出一个ObjectNotFoundException异常。如果返回值多于一个,它将抛出一个FinderException(异常)。

Finding a Course by its Instructor
...

Course course = home.findByInstructor(teacher);

out.println(course.getCourseId() + " is taught by " +
           course.getInstructor() + "<br>");

...
返加结果类似:
Potions is taught by Severus Snape

实体BEAN类

CourseHome接口定义了findAll和findByInstructor方法,同时有一个findByPrimaryKey方法,实现该接口的类中并不实现该方法,Resin-CMP会自动生成它的代码。


CourseHome.java
   
package example.cmp.find;

import java.util.*;
import javax.ejb.*;

public interface CourseHome extends EJBLocalHome {
 Course findByPrimaryKey(String name)
   throws FinderException;

 Collection findAll()
   throws FinderException;

 Course findByInstructor(String instructor)
   throws FinderException;
}

Course.java

package example.cmp.find;

import javax.ejb.*;

public interface Course extends EJBLocalObject {
 String getCourseId();

 String getInstructor();
}

CourseBean.java
package example.cmp.find;

abstract public class CourseBean
 extends com.caucho.ejb.AbstractEntityBean {
 abstract public String getCourseId();

 abstract public String getInstructor();
}

Deployment Descriptor
Deployment Descriptor新特点是<query>节,虽然我们已经在sql-table和sql-column元素中定义了对象与数据库之间的映射,但查询用的是abstract 名字。

WEB-INF/cmp-find.ejb
<ejb-jar>
<enterprise-beans>
 <entity>
   <ejb-name>find_CourseBean</ejb-name>
   <local-home>example.cmp.find.CourseHome</local-home>
   <local>example.cmp.find.Course</local>
   <ejb-class>example.cmp.find.CourseBean</ejb-class>
   <persistence-type>Container</persistence-type>
   <reentrant>True</reentrant>

   <abstract-schema-name>courses</abstract-schema-name>
   <sql-table>find_courses</sql-table>

   <primkey-field>name</primkey-field>
   <prim-key-class>String</prim-key-class>

   <cmp-field><field-name>courseId</field-name></cmp-field>
   <cmp-field>
     <field-name>instructor</field-name>
     <sql-column>teacher</sql-column>
   </cmp-field>

   <query>
     <query-method>
       <method-name>findAll</method-name>
     </query-method>
     <ejb-ql>SELECT o FROM courses o</ejb-ql>
   </query>

   <query>
     <query-method>
       <method-name>findByInstructor</method-name>
     </query-method>
     <ejb-ql>SELECT o FROM courses o WHERE o.instructor=?1</ejb-ql>
   </query>
 </entity>
</enterprise-beans>
</ejb-jar>

Tag               Meaning
Query             Contains the query information for a find method
Query-method      The method descriptor
Method-name       The method name
Ejb-ql              The query for the find method

阅读更多

没有更多推荐了,返回首页