 |
級別: 初級
宗鋒 (zong_feng@263.net)西北大學計算機系碩士
2001 年 12 月 16 日
本文將對 《一個簡單的 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>_lt;/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.
|
|