对一个简单的 JDBC 包装器的扩展及应用

<script type="text/javascript"> google_ad_client = "pub-8800625213955058"; /* 336x280, 创建于 07-11-21 */ google_ad_slot = "0989131976"; google_ad_width = 336; google_ad_height = 280; // </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>

宗锋 (zong_feng@263.net)
西北大学计算机系硕士
2001 年 12 月

本文将对 《一个简单的 JDBC 包装器》中的JDBC包装器进行一些扩展,然后介绍一下其在jsp javabean开发模式中的应用。

最近看了《一个简单的 JDBC 包装器》,觉得这篇文章很有应用价值,我便在自己的开发中使用了它,不过这个包装器也存在一些不足,于是我对它进行了一些扩展。首先原文中的Table类缺少删除功能,我便增加了删除功能。代码如下:



public void delRow(Row row) throws SQLException {

String ss="";



ss = "delete from " name " where ";



for (int i=0; i<row.length();   i) {

String k = row.getKey( i );

String v = row.get( i );

ss  = k "='" v "'";

if (i != row.length()-1)

ss  = " and ";

}

Connection con = database.getConnection();

Statement st = con.createStatement();

st.executeUpdate( ss );

}

public void delRow(String conditions)throws SQLException {

String ss="";

ss = "delete from " name " where ";

ss  =conditions;

Connection con = database.getConnection();

Statement st = con.createStatement();

st.executeUpdate( ss );

}

这两个函数分别用于删除一个Row和满足一定条件的记录。对于具有主关键字的表,我们可以用下面代码中的方法二来进行删除,如果没有主关键字,我们可以用方法一删除。

示例如下:



//方法一

Row e = table.getRow( "id=2001" );

table.delRow(e);

//方法二

table.delRow("id=2001");

另外这个包装器没有对查询结果为NULL的情况作处理,我通过修改Table类的execute函数和RowSet类的get函数对这种情况作了处理。具体代码见附件。

下面谈谈利用这个JDBC包装器实现对数据库的封装,假定我们有一个表:student,创建表的Sql语句如下:



create table student(

id varchar(10) not null primary key,

name varchar(16) not null,

sex char(2) not null,

password varchar(16) not null,

department varchar(32) not null

)

我们对这个表进行封装,下面是Student类的主要代码:



public class Student{



private Row r;



public Student() {

r=new Row();

}

public Student(Row row) {

this.r=row;

}

private Table getTable() {

Database db =

new Database( "jdbc:mysql://localhost:3306/manger",

"zf", "zf" );

return db.getTable("student");

}



public void setName(String name){

r.put("name",name);

}

public void setPassword(String pass){

r.put("password",pass);

}

public void setId(String number){

r.put("id",number);

}

public void setDepart(String depart){

r.put("department",depart);

}

public void setSex(String sex){

r.put("sex",sex);

}

public String getName(){

return r.get("name");

}

public String getPassword(){

return r.get("password");

}

public String getId(){

return r.get("id");

}

public String getDepart(){

return r.get("department");

}

public String getSex(){

return r.get("sex");

}

/**

 *condition表示限制条件,如果为空,则插入新记录,否则更新记录

 */

public void save(String conditions) throws SQLException{

if(conditions==null)

{getTable().putRow(r);}

else

getTable().putRow(r,conditions);



}

/**

 *由于id作为主关键字,所以我们使用字符串为参数的delRow()函数

 */

public void delete()throws SQLException{

//getTable().delRow(this.r);

String conditions="";

conditions = "id="   "'" getId() "'";

getTable().delRow(conditions);

}

}

下面这个类是相应的一个查询类的主要代码:



public class StudentFactory{

public static Student findStudentById(String id)

throws SQLException{

Row r=getTable().getRow("id=" id);

if(r==null)

  return null;

else

return new Student(r);

}

public static Student[] findAllStudents()

throws SQLException{

RowSet rs=getTable().getRows("1>0");

if (rs==null)

return null;

else

Student[] stu=null;

stu=new Student[rs.length()];

for(int i=0;i<rs.length(); i  ){

stu[i]=new Student(rs.get(i));

}

return stu;

}

}

我使用javabean来实现很多功能,这样可以减少在jsp中的java代码量,方便我们对界面的改进。我们要实现的功能为对学生的编辑,添加,删除和列表。这些功能定义在两个javabean中:下面是两个jsp文件的主要代码:



<%-- student.jsp --%>

<%@ page contentType="text/html;charset=GB2312" %>

<%@ page import="org.gjt.mm.mysql.*,manger.bean.*,manger.tools.*,manger.business.*" %>

<html>

<head>

<SCRIPT TYPE="text/javascript" LANGUAGE="JavaScript" >

<!--

function doDelete()

{

if(confirm('你确定删除吗?')) {

document.EditForm.event.value='delete';

document.EditForm.submit();

}

}

function doEdit()

{

if(confirm('你确定编辑吗?')) {

document.EditForm.event.value='showEdit';

document.EditForm.submit();

}

}

function showAddPage()

{

document.location='editstudent.jsp?event=showAdd';

}

</SCRIPT>

</head>

<body bgcolor="#FFFFFF" text="#000000">

<%

try {

Class.forName("org.gjt.mm.mysql.Driver").newInstance();

}

catch (Exception E) {

out.println("Unable to load driver.");

} %>

<jsp:useBean id="table" scope="page" class="manger.bean.ListStudentBean" />

<%

Student[] student=table.getStudent(pageContext);

int total=0;

int currPage=table.getCurPage();

int pageCount=table.getPageCount();

if(student!=null)

{total=student.length;}%>

<FORM NAME="EditForm" ACTION="editstudent.jsp">

<INPUT TYPE="HIDDEN" NAME="event" VALUE="">

<table width="75%" border="1">

<tr>

<td colspan="5">学生列表</td>

</tr>

<tr>

<td>学号</td>

<td>姓名</td>

<td>班级</td>

<td>备注一</td>

<td>选择</td>

</tr>

<%for (int i=0;i<total;i  ){

Student current=student[i];%>

<tr>

<td><%=current.getId()%></td>

<td><%=current.getName()%></td>

<td><%=current.getDepart()%></td>

<td><%=current.getSex() %></td>

<td>

<input type="checkbox" name="id" value=<%=current.getId()%>>

</td>

<% } %>

</tr><tr>

<td colspan="5">

<INPUT TYPE="BUTTON" onclick="doEdit();" VALUE="编辑">

<INPUT TYPE="BUTTON" onclick="showAddPage()" VALUE="增加">

<INPUT TYPE="BUTTON" onclick="doDelete();" VALUE="删除">

</td>

</tr>

</table>

</form>

</html>



<%-- studentedit.jsp --%>

<jsp:useBean id="table" scope="page" class="manger.bean.EditStudentBean" />

<%table.processRequest(pageContext);%>

<p> </p>

<form name="EditForm" action="editstudent.jsp">

<INPUT TYPE="hidden" NAME="event" VALUE="<%=table.getEvent()%>" >

<table width="75%" border="1">

<tr> 

<td colspan="2"> 

<div align="center"><b>编辑学生信息</b></div>

</td>

</tr>

<tr> 

<td width="40%">学号:</td>

<td width="60%"> 

<input type="text" name="id" value="<%=table.getStudent().getId()%>">

</td>

</tr>

<%--下面的一些学生信息我们省略了--%> 

<tr> 

<td colspan="2">

<input type="submit" name="Submit" value="确定">

</td>

</tr>

</table>

</form>

我的想法是在student.jsp中显示学生列表,从这个页面可以转到增加和编辑页面,也可以在这个页面中删除学生,这三个功能都是由editstudent.jsp完成的。在editstudent.jsp中非常关键的一行代码就是<%table.processRequest(pageContext);%>,这会调用EditStudentBean类的processRequest方法:下面是EditStudentBean类processRequest方法和addStudent方法的代码:



public void processRequest (PageContext pageContext) 

throws SQLException,ServletException,IOException{

this.student.setId("");

this.student.setName("");

this.student.setPassword("");

this.student.setDepart("");

this.student.setSex("");

HttpServletRequest request=(HttpServletRequest)pageContext.getRequest();

String event=request.getParameter("event");

//this.event=event;

if(event==null || event.equals("")||event.equals("showAdd"))

{this.event="add";

}

else if(event.equals("showEdit"))

{this.event="edit";

String id=request.getParameter("id");

Student stu=StudentFactory.findStudentById(id);

this.student=stu;

}

else if(event.equals("add"))

{this.addStudent(pageContext);

} 

else if(event.equals("delete"))

{this.deleteStudent(pageContext);

} 

else if(event.equals("edit"))

{this.editStudent(pageContext);

} 

}



public void addStudent(PageContext page)

throws SQLException,ServletException,IOException{

HttpServletRequest request=(HttpServletRequest)page.getRequest();

HttpServletResponse response=(HttpServletResponse)page.getResponse();

JspWriter out=page.getOut();

String id=request.getParameter("id");

String name=request.getParameter("name");

String sex=request.getParameter("sex");

String pass=request.getParameter("password");

String depart=request.getParameter("depart");

if (id!=null&&name!=null&&sex!=null&&pass!=null&&depart!=null

&&!id.equals("")&&!name.equals("")&&!sex.equals("")&&!pass.equals("")&&!depart.equals(""))

{Student s=new Student();

s.setId(id);

s.setName(name);

s.setSex(sex);

s.setPassword(pass);

s.setDepart(depart);

s.save(null); 

response.sendRedirect("student.jsp"); 

}

else

{out.print("请添完所有信息");

}

}

processRequest方法的功能主要为获取提交给editstudent.jsp的event的值,根据不同的event调用不同的函数。例如event=add,则调用addStudent函数。

注意:在设置Student对象的各个属性值时,一定要按照表(见上面的SQL语句)中顺序来设置,例如在表中,id字段在name字段的前面,所以setId方法在setName方法前面,这主要是由于Table类中的putRow函数中执行插入操作的SQL语句有缺陷。在那个SQL语句中,它是按各属性在Row中的顺序来执行插入操作的。如过你不愿意按表中字段的顺序来设置Student的属性,可以对putRow函数更改如下:



String ss = "";

if (conditions==null) {

ss = "INSERT INTO " name "(";

for (int i=0;i<row.length();  i) {

String k = row.getKey( i );

ss  = k;

if (i != row.length()-1)

ss  = ", ";

}



ss  =") VALUES (";

for (int j=0; j<row.length();   j) { 

String v = row.get( j );

ss  = "'" v "'";

if (j != row.length()-1)

ss  = ", ";

}

ss  = ")";

}

限于篇幅,我省略了student.jsp文件中的一些内容,对这个jsp文件进行处理的bean为ListStudentBean,这个类主要实现一个函数getStudent,这个函数主要通过StudentFactory查寻到所有的学生,由于我在此函数中进行了分页处理,因此此函数只返回当前页需要的Student数组。具体的代码参看附件

总之,我改进之后的这个JDBC封装器还是比较有效的,它能满足一般地需要,当然你也可以根据你的情况对其进行扩充,以更好地适应你的开发。

代码在Tomcat4.01 mysql3.23.43下测试通过。

关于作者
宗锋,男,西北大学计算机系硕士。兴趣主要集中在:java,linux,enhydra,barracuda。希望能与有共同爱好的朋友进行交流。E-mail: zong_feng@263.net.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值