在Beehive PageFlow Tutorial中有过一些关于Beehive Data control的介绍,这里将通过一个例子,具体说明如何运用Beehive build-in的数据控制机制来完成数据库的相关操作。
1. 首先,需要对数据库连接进行配置。
Beehive内置的数据库是derby。如果你希望使用其他数据库,就需要修改一些源码,该文件位于BEEHIVE_HOME/samples/controls-db/src/dbControl/下面。在文件DatabaseControlImpl.jcs中可以重新设置数据库的URL,例如要使用SQL Server 就可以做如下修改:
Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
也可以按需求修改其他源文件。然后利用Ant工具重新编译并打包成dbControl.jar,放到web应用的相应位置(一般为WEB-INF/lib下面)即可。
2. 定义数据库操作。
我们需要创建一个jcx文件来定义所需的数据库相关操作,下面通过一个例子来说明如何完成该操作。
圆圈代表action,方块代表page
在该例中,我们在首页点击相应链接跳转到displaydata.jsp,在这里将数据库操作的结果展示出来。因此show action是核心,由它进行一系列的数据库操作并将结果输出给下个页面。Beehive使用自己的机制封装了数据库操作的具体实现,因此在show方法中,相关的代码量很少。这个例子中我们需要创建如下文件:
l Project_home/WEB-INF/src/dbcontroller/ MyFirstDBControl.jcx
l Project_home/WEB-INF/src/forms/Employee.java
l Project_home/Controller.jpf
l Project_home/*.jsp
注意:src目录下面可以根据自己的需要建立包结构,与import相对应就可以。
MyFirstDBControl.jcx
package dbcontroller; import java.sql.SQLException; import java.io.Serializable; import java.util.Iterator; import java.util.HashMap; import javax.sql.RowSet;
import org.apache.beehive.controls.api.bean.ControlExtension; import dbControl.DatabaseControl; import dbControl.DatabaseControl.ConnectionDataSource; import dbControl.DatabaseControl.SQL;
import forms.Employee;
@ControlExtension @ConnectionDataSource(jndiName="jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=Test;user=sa;password=sa") public interface MyFirstDBControl extends DatabaseControl { @SQL(statement="CREATE TABLE Employee (id INT PRIMARY KEY NOT NULL, " + "name VARCHAR(50), age INT)") public void createTable() throws SQLException;
@SQL(statement="DROP TABLE Employee") public void dropTable() throws SQLException;
@SQL(statement="INSERT INTO Employee " + "(id, name, age) " + "VALUES ({u.id}, {u.name}, {u.age})") public void insertEmployee(Employee u) throws SQLException;
@SQL(statement="UPDATE Employee SET age = {age} WHERE id = {id}") public void changeTitle(int id, String title) throws SQLException;
@SQL(statement="DELETE FROM Employee WHERE id = {id}") public void deleteEmployee(int id) throws SQLException;
@SQL(statement="SELECT name FROM Employee") public String[] selectAllName() throws SQLException;
@SQL(statement="SELECT * FROM Employee WHERE id={id}") public Employee selectEmployee(int id) throws SQLException;
@SQL(statement="SELECT * FROM Employee ORDER BY id") public Employee[] selectEmployees() throws SQLException;
@SQL(statement="SELECT * FROM Employee ORDER BY id", iteratorElementType=Employee.class) public Iterator selectEmployeesWithIterator() throws SQLException;
@SQL(statement="SELECT * FROM Employee ORDER BY id") public HashMap selectEmployeeWithHashMap() throws SQLException;
@SQL(statement="SELECT * FROM Employee ORDER BY id", maxRows=1) public Employee[] selectOneEmployee() throws SQLException;
@SQL(statement="select count(*) from Employee") public Integer getCount() throws SQLException; //返回int型的一定要定义返回类型为Integer } |
|
MyFirstDBControl首先定义了数据库连接的JNDI属性,接口主体则定义了能够完成的数据库操作。注意要引入相应的数据库表的持久类,即操作对象。这里分别定义了建表,删表,以及对记录的增删查改操作。对于查询,可以定义不同的返回类型以符合需求。还可以在@SQL里增加maxRows属性,控制返回的记录个数。
Employee是这个例子中用到的数据表,它有三个字段,id、name和age。我们需要创建该表对应的持久类forms/Employee.java,注意到beehive需要将该类的成员变量声明为public的。
Employee.java
package forms; public class Employee { public Integer id; public String name; public int age;
public Employee(Integer id, String name, int age) { this.id = id; this.name = name; this.age = age; } public Employee(Integer id) { this.id = id; } public Integer getId() { return this.id; }
public void setId(Integer id) { this.id = id; }
public String getName() { return this.name; }
public void setName(String name) { this.name = name; }
public int getAge() { return this.age; }
public void setAge(int age) { this.age = age; } } |
|
3. 在Controller中调用数据库操作。
有了上面两个文件的支持,我们就可以编辑page Flow里的核心文件Controller.jpf了。
Controller.jpf
import javax.servlet.http.HttpSession; import org.apache.beehive.netui.pageflow.Forward; import org.apache.beehive.netui.pageflow.PageFlowController; import org.apache.beehive.netui.pageflow.annotations.Jpf; import forms.Employee; //应用中所需的持久类 import dbcontroller.MyFirstDBControl; //应用中所需的数据库操作的定义文件 import org.apache.beehive.controls.api.bean.Control; //用来解释@Control,将MyFirstDBControl接口实现成bean,并完成实例化工作。
|
@Control public MyFirstDBControl myControl; public Employee u; @Jpf.Action( forwards={ @Jpf.Forward(name="success", path="index.jsp") } ) protected Forward begin() { return new Forward("success"); } @Jpf.Action( forwards={ @Jpf.Forward(name="success", path="displaydata.jsp") } ) protected Forward show() throws java.sql.SQLException{ u = myControl.selectEmployee(1); getRequest().setAttribute("data",u); return new Forward(“success”); } |
可以看到,在show方法中我们调用了selectEmployee方法,查询id为1的用户,返回值为Employee类型。然后将结果赋给一个request的变量,在页面中便可以使用该变量引用查询结果,如下所示:
<p>Name:<netui:span value="${requestScope.data.name}"/>
<p>Age:<netui:span value="${requestScope.data.age}"/>
这里,查询结果是一条记录,返回类型为对应的持久类。如果是多条记录,我们可以用Vector来作为查询结果的容器,并将之传给页面显示。代码如下:
………….. @Control public MyFirstDBControl myControl; public Vector u; …………..
protected Forward show() throws java.sql.SQLException{ u = new Vector(); Employee[] es = myControl.selectEmployees(); for(int i=0;i<es.length;i++) { u.add(es[i]); } return new Forward(“success”); } |
|
相应地,页面也需要做些修改来展示多条记录。可以直接使用Beehive提供的标签<netui-data:repeater>,它专门用于显示以集合形式存储的数据,可以是数组,或者Vector等。
displaydata.jsp
<netui-data:repeater dataSource="pageFlow.u"> <netui-data:repeaterHeader> <table border="1"> <tr> <td><b>id</b></td> <td><b>name</b></td> <td><b>age</b></td> </tr> </netui-data:repeaterHeader> <netui-data:repeaterItem> <tr> <td> <netui:label value="${container.item.id}" /> </td> <td> <netui:label value="${container.item.name}" /> </td> <td> <netui:label value="${container.item.age}" /> </td> </tr> </netui-data:repeaterItem> <netui-data:repeaterFooter> </table> </netui-data:repeaterFooter> </netui-data:repeater> |
|
displaydata页面将以表格的形式显示Employee表中所有的记录,如下图所示:
id name age 1 candy 23 2 nick 24 3 keller 25