﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-Java Tools-随笔分类-JDBC</title><link>http://www.blogjava.net/simie/category/23714.html</link><description /><language>zh-cn</language><lastBuildDate>Thu, 05 Jul 2007 10:05:48 GMT</lastBuildDate><pubDate>Thu, 05 Jul 2007 10:05:48 GMT</pubDate><ttl>60</ttl><item><title>对一个简单的 JDBC 包装器的扩展及应用 </title><link>http://www.blogjava.net/simie/archive/2007/07/03/127905.html</link><dc:creator>和田雨</dc:creator><author>和田雨</author><pubDate>Tue, 03 Jul 2007 09:22:00 GMT</pubDate><guid>http://www.blogjava.net/simie/archive/2007/07/03/127905.html</guid><wfw:comment>http://www.blogjava.net/simie/comments/127905.html</wfw:comment><comments>http://www.blogjava.net/simie/archive/2007/07/03/127905.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/simie/comments/commentRss/127905.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/simie/services/trackbacks/127905.html</trackback:ping><description><![CDATA[<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr vAlign=top>
            <td width="100%">
            <h1>对一个简单的 JDBC 包装器的扩展及应用</h1>
            <img class=display-img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=1></td>
            <td class=no-print width=192><img height=18 alt=developerWorks src="http://www.ibm.com/developerworks/cn/i/dw.gif" width=192></td>
        </tr>
    </tbody>
</table>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr vAlign=top>
            <td width=10><img height=1 alt="" src="http://www.ibm.com/i/c.gif" width=10></td>
            <td width="100%">
            <table class=no-print cellSpacing=0 cellPadding=0 width=160 align=right border=0>
                <tbody>
                    <tr>
                        <td width=10><img height=1 alt="" src="http://www.ibm.com/i/c.gif" width=10></td>
                        <td>
                        <table cellSpacing=0 cellPadding=0 width=150 border=0>
                            <tbody>
                                <tr>
                                    <td class=v14-header-1-small>文档选项</td>
                                </tr>
                            </tbody>
                        </table>
                        <table class=v14-gray-table-border cellSpacing=0 cellPadding=0 border=0>
                            <tbody>
                                <tr>
                                    <td class=no-padding width=150>
                                    <table cellSpacing=0 cellPadding=0 width=143 border=0>
                                        <img height=1 alt="" src="http://www.ibm.com/i/c.gif" width=8>
                                        <form name=email action=https://www.ibm.com/developerworks/secure/email-it.jsp>
                                            <input type=hidden value="本文将对《一个简单的 JDBC 包装器》中的JDBC包装器进行一些扩展，然后介绍一下其在jsp+javabean开发模式中的应用。" name=body><input type=hidden value="对一个简单的 JDBC 包装器的扩展及应用" name=subject><input type=hidden value=cn name=lang>
                                            <script language=JavaScript type=text/javascript>
                                            <!--
                                            document.write('
                                            <tr valign="top">
                                                <td width="8"><img src="//www.ibm.com/i/c.gif" width="8" height="1" alt=""/></td>
                                                <td width="16"><img src="//www.ibm.com/i/v14/icons/em.gif" height="16" width="16" vspace="3" alt="将此页作为电子邮件发送" /></td>
                                                <td width="122">
                                                <p><a class="smallplainlink" href="javascript:document.email.submit();"><strong>将此页作为电子邮件发送</strong></a></p>
                                                </td>
                                            </tr>
                                            ');
                                            //-->
                                            </script>
                                            <tbody>
                                                <tr vAlign=top>
                                                    <td width=8><img height=1 alt="" src="http://www.ibm.com/i/c.gif" width=8></td>
                                                    <td width=16><img height=16 alt=将此页作为电子邮件发送 src="http://www.ibm.com/i/v14/icons/em.gif" width=16 vspace=3></td>
                                                    <td width=122>
                                                    <p><a class=smallplainlink href="javascript:document.email.submit();"><strong><font color=#996699 size=2>将此页作为电子邮件发送</font></strong></a></p>
                                                    </td>
                                                </tr>
                                                <noscript>
                                                <tr valign="top">
                                                    <td width="8"><img alt="" height="1" width="8" src="//www.ibm.com/i/c.gif"/></td>
                                                    <td width="16"><img alt="" width="16" height="16" src="//www.ibm.com/i/c.gif"/></td>
                                                    <td class="small" width="122">
                                                    <p><span class="ast">未显示需要 JavaScript 的文档选项</span></p>
                                                    </td>
                                                </tr>
                                                </noscript>
                                            </form>
                                        </tbody>
                                    </table>
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                        <!--start RESERVED FOR FUTURE USE INCLUDE FILES--><!-- this content will be automatically generated across all content areas --><br><!--end RESERVED FOR FUTURE USE INCLUDE FILES--><br></td>
                    </tr>
                </tbody>
            </table>
            <p>级别: 初级</p>
            <p><a href="http://www.ibm.com/developerworks/cn/java/l-jdbcwrap/index.html#author"><font color=#996699>宗锋</font></a> (<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#122;&#111;&#110;&#103;&#95;&#102;&#101;&#110;&#103;&#64;&#50;&#54;&#51;&#46;&#110;&#101;&#116;&#63;&#115;&#117;&#98;&#106;&#101;&#99;&#116;&#61;&#23545;&#19968;&#20010;&#31616;&#21333;&#30340;&#32;&#74;&#68;&#66;&#67;&#32;&#21253;&#35013;&#22120;&#30340;&#25193;&#23637;&#21450;&#24212;&#29992;&#38;&#97;&#109;&#112;&#59;&#99;&#99;&#61;&#122;&#111;&#110;&#103;&#95;&#102;&#101;&#110;&#103;&#64;&#50;&#54;&#51;&#46;&#110;&#101;&#116;"><font color=#5c81a7>zong_feng@263.net</font></a>)西北大学计算机系硕士<br></p>
            <p>2001 年 12 月 16 日</p>
            <blockquote>本文将对 <a href="http://www.ibm.com/developerworks/cn/java/j-jdbcwrap/index.html"><font color=#996699>《一个简单的 JDBC 包装器》</font></a>中的JDBC包装器进行一些扩展，然后介绍一下其在jsp+javabean开发模式中的应用。 </blockquote><!--start RESERVED FOR FUTURE USE INCLUDE FILES--><!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters --><!--end RESERVED FOR FUTURE USE INCLUDE FILES-->
            <p>最近看了 <a href="http://www.ibm.com/developerworks/cn/java/j-jdbcwrap/index.html"><font color=#996699>《一个简单的 JDBC 包装器》</font></a>，觉得这篇文章很有应用价值，我便在自己的开发中使用了它，不过这个包装器也存在一些不足，于是我对它进行了一些扩展。首先原文中的Table类缺少删除功能，我便增加了删除功能。代码如下：
            <table cellSpacing=0 cellPadding=0 width=550 border=0>
                <tbody>
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>public void delRow(Row row) throws SQLException {
                        String ss="";
                        ss = "delete from "+name+" where ";
                        for (int i=0; i&lt;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 );
                        }</pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br></p>
            <p>这两个函数分别用于删除一个Row和满足一定条件的记录。对于具有主关键字的表，我们可以用下面代码中的方法二来进行删除，如果没有主关键字，我们可以用方法一删除。</p>
            <p>示例如下：
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>//方法一
                        Row e = table.getRow( "id=2001" );
                        table.delRow(e);
                        //方法二
                        table.delRow("id=2001");
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br></p>
            <p>另外这个包装器没有对查询结果为NULL的情况作处理，我通过修改Table类的execute函数和RowSet类的get函数对这种情况作了处理。具体代码见附件。</p>
            <p>下面谈谈利用这个JDBC包装器实现对数据库的封装，假定我们有一个表:student，创建表的Sql语句如下：
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>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
                        )</pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br></p>
            <p>我们对这个表进行封装，下面是Student类的主要代码：
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>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);
                        }
                        }</pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br></p>
            <p>下面这个类是相应的一个查询类的主要代码：
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>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&gt;0");
                        if (rs==null)
                        return null;
                        else
                        Student[] stu=null;
                        stu=new Student[rs.length()];
                        for(int i=0;i&lt;rs.length(); i++){
                        stu[i]=new Student(rs.get(i));
                        }
                        return stu;
                        }
                        }</pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br></p>
            <p>我使用javabean来实现很多功能，这样可以减少在jsp中的java代码量，方便我们对界面的改进。我们要实现的功能为对学生的编辑，添加，删除和列表。这些功能定义在两个javabean中：下面是两个jsp文件的主要代码：
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>&lt;%-- student.jsp --%&gt;
                        &lt;%@ page contentType="text/html;charset=GB2312" %&gt;
                        &lt;%@ page import="org.gjt.mm.mysql.*,manger.bean.*,manger.tools.*,manger.business.*" %&gt;
                        &lt;html&gt;
                        &lt;head&gt;
                        &lt;SCRIPT TYPE="text/javascript" LANGUAGE="JavaScript" &gt;
                        &lt;!--
                        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';
                        }
                        &lt;/SCRIPT&gt;
                        &lt;/head&gt;
                        &lt;body bgcolor="#FFFFFF" text="#000000"&gt;
                        &lt;%
                        try {
                        Class.forName("org.gjt.mm.mysql.Driver").newInstance();
                        }
                        catch (Exception E) {
                        out.println("Unable to load driver.");
                        } %&gt;
                        &lt;jsp:useBean id="table" scope="page" class="manger.bean.ListStudentBean" /&gt;
                        &lt;%
                        Student[] student=table.getStudent(pageContext);
                        int total=0;
                        int currPage=table.getCurPage();
                        int pageCount=table.getPageCount();
                        if(student!=null)
                        {total=student.length;}%&gt;
                        &lt;FORM NAME="EditForm" ACTION="editstudent.jsp"&gt;
                        &lt;INPUT TYPE="HIDDEN" NAME="event" VALUE=""&gt;
                        &lt;table width="75%" border="1"&gt;
                        &lt;tr&gt;
                        &lt;td colspan="5"&gt;学生列表&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                        &lt;td&gt;学号&lt;/td&gt;
                        &lt;td&gt;姓名&lt;/td&gt;
                        &lt;td&gt;班级&lt;/td&gt;
                        &lt;td&gt;备注一&lt;/td&gt;
                        &lt;td&gt;选择&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;%for (int i=0;i&lt;total;i++){
                        Student current=student[i];%&gt;
                        &lt;tr&gt;
                        &lt;td&gt;&lt;%=current.getId()%&gt;&lt;/td&gt;
                        &lt;td&gt;&lt;%=current.getName()%&gt;&lt;/td&gt;
                        &lt;td&gt;&lt;%=current.getDepart()%&gt;&lt;/td&gt;
                        &lt;td&gt;&lt;%=current.getSex() %&gt;&lt;/td&gt;
                        &lt;td&gt;
                        &lt;input type="checkbox" name="id" value=&lt;%=current.getId()%&gt;&gt;
                        &lt;/td&gt;
                        &lt;% } %&gt;
                        &lt;/tr&gt;&lt;tr&gt;
                        &lt;td colspan="5"&gt;
                        &lt;INPUT TYPE="BUTTON" onclick="doEdit();" VALUE="编辑"&gt;
                        &lt;INPUT TYPE="BUTTON" onclick="showAddPage()" VALUE="增加"&gt;
                        &lt;INPUT TYPE="BUTTON" onclick="doDelete();" VALUE="删除"&gt;
                        &lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;/table&gt;
                        &lt;/form&gt;
                        &lt;/html&gt;</pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br></p>
            <p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>&lt;%-- studentedit.jsp --%&gt;
                        &lt;jsp:useBean id="table" scope="page" class="manger.bean.EditStudentBean" /&gt;
                        &lt;%table.processRequest(pageContext);%&gt;
                        &lt;p&gt;_lt;/p&gt;
                        &lt;form name="EditForm" action="editstudent.jsp"&gt;
                        &lt;INPUT TYPE="hidden" NAME="event" VALUE="&lt;%=table.getEvent()%&gt;" &gt;
                        &lt;table width="75%" border="1"&gt;
                        &lt;tr&gt;
                        &lt;td colspan="2"&gt;
                        &lt;div align="center"&gt;&lt;b&gt;编辑学生信息&lt;/b&gt;&lt;/div&gt;
                        &lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                        &lt;td width="40%"&gt;学号：&lt;/td&gt;
                        &lt;td width="60%"&gt;
                        &lt;input type="text" name="id" value="&lt;%=table.getStudent().getId()%&gt;"&gt;
                        &lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;%--下面的一些学生信息我们省略了--%&gt;
                        &lt;tr&gt;
                        &lt;td colspan="2"&gt;
                        &lt;input type="submit" name="Submit" value="确定"&gt;
                        &lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;/table&gt;
                        &lt;/form&gt;
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br></p>
            <p>我的想法是在student.jsp中显示学生列表，从这个页面可以转到增加和编辑页面，也可以在这个页面中删除学生，这三个功能都是由editstudent.jsp完成的。在editstudent.jsp中非常关键的一行代码就是&lt;%table.processRequest(pageContext);%&gt;，这会调用EditStudentBean类的processRequest方法：下面是EditStudentBean类processRequest方法和addStudent方法的代码:
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>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&amp;&amp;name!=null&amp;&amp;sex!=null&amp;&amp;pass!=null&amp;&amp;depart!=null
                        &amp;&amp;!id.equals("")&amp;&amp;!name.equals("")&amp;&amp;!sex.equals("")&amp;&amp;!pass.equals("")&amp;&amp;!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("请添完所有信息");
                        }
                        }</pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br></p>
            <p>processRequest方法的功能主要为获取提交给editstudent.jsp的event的值，根据不同的event调用不同的函数。例如event=add，则调用addStudent函数。</p>
            <p>注意：在设置Student对象的各个属性值时，一定要按照表(见上面的SQL语句)中顺序来设置，例如在表中,id字段在name字段的前面，所以setId方法在setName方法前面，这主要是由于Table类中的putRow函数中执行插入操作的SQL语句有缺陷。在那个SQL语句中，它是按各属性在Row中的顺序来执行插入操作的。如过你不愿意按表中字段的顺序来设置Student的属性，可以对putRow函数更改如下：
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>String ss = "";
                        if (conditions==null) {
                        ss = "INSERT INTO "+name+'(";
                        for (int i=0;i&lt;row.length();++i) {
                        String k = row.getKey( i );
                        ss += k;
                        if (i != row.length()-1)
                        ss += ", ";
                        }
                        ss +=") VALUES (";
                        for (int j=0; j&lt;row.length(); ++j) {
                        String v = row.get( j );
                        ss += "'"+v+"'";
                        if (j != row.length()-1)
                        ss += ", ";
                        }
                        ss += ")";
                        }</pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br></p>
            <p>限于篇幅，我省略了student.jsp文件中的一些内容，对这个jsp文件进行处理的bean为ListStudentBean，这个类主要实现一个函数getStudent，这个函数主要通过StudentFactory查寻到所有的学生，由于我在此函数中进行了分页处理，因此此函数只返回当前页需要的Student数组。具体的代码参看 <a href="http://www.ibm.com/developerworks/cn/java/l-jdbcwrap/jdbc.zip"><font color=#5c81a7>附件</font></a>。 </p>
            <p>总之，我改进之后的这个JDBC封装器还是比较有效的，它能满足一般地需要，当然你也可以根据你的情况对其进行扩充，以更好地适应你的开发。</p>
            <p>代码在Tomcat4.01+mysql3.23.43下测试通过。</p>
            <br><br>
            <p><a name=author><span class=atitle>关于作者</span></a></p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td colSpan=3><img height=5 alt="" src="http://www.ibm.com/i/c.gif" width="100%"></td>
                    </tr>
                    <tr vAlign=top align=left>
                        <td>
                        <p>&#160;</p>
                        </td>
                        <td><img height=5 alt="" src="http://www.ibm.com/i/c.gif" width=4></td>
                        <td width="100%">
                        <p>宗锋，男，西北大学计算机系硕士。兴趣主要集中在：java，linux，enhydra，barracuda。希望能与有共同爱好的朋友进行交流。E-mail: <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#122;&#111;&#110;&#103;&#95;&#102;&#101;&#110;&#103;&#64;&#50;&#54;&#51;&#46;&#110;&#101;&#116;&#63;&#99;&#99;&#61;&#122;&#111;&#110;&#103;&#95;&#102;&#101;&#110;&#103;&#64;&#50;&#54;&#51;&#46;&#110;&#101;&#116;"><font color=#5c81a7>zong_feng@263.net</font></a>. </p>
                        </td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<img src ="http://www.blogjava.net/simie/aggbug/127905.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/simie/" target="_blank">和田雨</a> 2007-07-03 17:22 <a href="http://www.blogjava.net/simie/archive/2007/07/03/127905.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一个简单的 JDBC 包装器 </title><link>http://www.blogjava.net/simie/archive/2007/07/03/127902.html</link><dc:creator>和田雨</dc:creator><author>和田雨</author><pubDate>Tue, 03 Jul 2007 09:16:00 GMT</pubDate><guid>http://www.blogjava.net/simie/archive/2007/07/03/127902.html</guid><wfw:comment>http://www.blogjava.net/simie/comments/127902.html</wfw:comment><comments>http://www.blogjava.net/simie/archive/2007/07/03/127902.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/simie/comments/commentRss/127902.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/simie/services/trackbacks/127902.html</trackback:ping><description><![CDATA[<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr vAlign=top>
            <td width="100%">
            <h1>一个简单的 JDBC 包装器</h1>
            <p id=subtitle>一种简单程序的快速数据访问解决方案</p>
            <img class=display-img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=1></td>
            <td class=no-print width=192><img height=18 alt=developerWorks src="http://www.ibm.com/developerworks/cn/i/dw.gif" width=192></td>
        </tr>
    </tbody>
</table>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr vAlign=top>
            <td width=10><img height=1 alt="" src="http://www.ibm.com/i/c.gif" width=10></td>
            <td width="100%">
            <table class=no-print cellSpacing=0 cellPadding=0 width=160 align=right border=0>
                <tbody>
                    <tr>
                        <td width=10><img height=1 alt="" src="http://www.ibm.com/i/c.gif" width=10></td>
                        <td>
                        <table cellSpacing=0 cellPadding=0 width=150 border=0>
                            <tbody>
                                <tr>
                                    <td class=v14-header-1-small>文档选项</td>
                                </tr>
                            </tbody>
                        </table>
                        <table class=v14-gray-table-border cellSpacing=0 cellPadding=0 border=0>
                            <tbody>
                                <tr>
                                    <td class=no-padding width=150>
                                    <table cellSpacing=0 cellPadding=0 width=143 border=0>
                                        <img height=1 alt="" src="http://www.ibm.com/i/c.gif" width=8>
                                        <form name=email action=https://www.ibm.com/developerworks/secure/email-it.jsp>
                                            <input type=hidden value="JDBC 提供了一种强大、全面的接口用来从 Java 程序访问数据库。对于较小的项目来说，使用 JDBC 似乎是理所当然的，它使一些程序员避免了一起使用数据库。本文描述了一种简单的包装器库，它让使用简单的数据库易如反掌。您会发现您已经开始想在编写的每一个程序中都使用 JDBC。" name=body><input type=hidden value="一个简单的 JDBC 包装器" name=subject><input type=hidden value=cn name=lang>
                                            <script language=JavaScript type=text/javascript>
                                            <!--
                                            document.write('
                                            <tr valign="top">
                                                <td width="8"><img src="//www.ibm.com/i/c.gif" width="8" height="1" alt=""/></td>
                                                <td width="16"><img src="//www.ibm.com/i/v14/icons/em.gif" height="16" width="16" vspace="3" alt="将此页作为电子邮件发送" /></td>
                                                <td width="122">
                                                <p><a class="smallplainlink" href="javascript:document.email.submit();"><strong>将此页作为电子邮件发送</strong></a></p>
                                                </td>
                                            </tr>
                                            ');
                                            //-->
                                            </script>
                                            <tbody>
                                                <tr vAlign=top>
                                                    <td width=8><img height=1 alt="" src="http://www.ibm.com/i/c.gif" width=8></td>
                                                    <td width=16><img height=16 alt=将此页作为电子邮件发送 src="http://www.ibm.com/i/v14/icons/em.gif" width=16 vspace=3></td>
                                                    <td width=122>
                                                    <p><a class=smallplainlink href="javascript:document.email.submit();"><strong><font color=#996699 size=2>将此页作为电子邮件发送</font></strong></a></p>
                                                    </td>
                                                </tr>
                                                <noscript>
                                                <tr valign="top">
                                                    <td width="8"><img alt="" height="1" width="8" src="//www.ibm.com/i/c.gif"/></td>
                                                    <td width="16"><img alt="" width="16" height="16" src="//www.ibm.com/i/c.gif"/></td>
                                                    <td class="small" width="122">
                                                    <p><span class="ast">未显示需要 JavaScript 的文档选项</span></p>
                                                    </td>
                                                </tr>
                                                </noscript>
                                            </form>
                                        </tbody>
                                    </table>
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                        <!--start RESERVED FOR FUTURE USE INCLUDE FILES--><!-- this content will be automatically generated across all content areas --><br><!--end RESERVED FOR FUTURE USE INCLUDE FILES--><br></td>
                    </tr>
                </tbody>
            </table>
            <p>级别: 初级</p>
            <p><a href="http://www.ibm.com/developerworks/cn/java/j-jdbcwrap/index.html#author"><u><font color=#996699>Greg Travis</font></u></a> (<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#109;&#105;&#116;&#111;&#64;&#112;&#97;&#110;&#105;&#120;&#46;&#99;&#111;&#109;&#63;&#115;&#117;&#98;&#106;&#101;&#99;&#116;&#61;&#19968;&#20010;&#31616;&#21333;&#30340;&#32;&#74;&#68;&#66;&#67;&#32;&#21253;&#35013;&#22120;&#38;&#97;&#109;&#112;&#59;&#99;&#99;&#61;&#109;&#105;&#116;&#111;&#64;&#112;&#97;&#110;&#105;&#120;&#46;&#99;&#111;&#109;"><u><font color=#5c81a7>mito@panix.com</font></u></a>), 自由程序员<br></p>
            <p>2001 年 8 月 04 日</p>
            <blockquote>JDBC 提供了一种强大、全面的接口用来从 Java 程序访问数据库。对于较小的项目来说，使用 JDBC 似乎是理所当然的，它使一些程序员避免了一起使用数据库。本文描述了一种简单的包装器库，它让使用简单的数据库易如反掌。您会发现您已经开始想在编写的每一个程序中都使用 JDBC。</blockquote><!--start RESERVED FOR FUTURE USE INCLUDE FILES--><!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters --><!--end RESERVED FOR FUTURE USE INCLUDE FILES-->
            <p>事情发生得很突然。您正在修改一个程序，您原以为它是个小程序，不料竟发现它已经迅速增长成为一个庞大的东西 ― 一个 <em>项目</em>― 而现在您已到了需要保存一些数据的时候了。 </p>
            <p>问题是，您并不是有意让程序发展到这种程度的。 您只是不由自主地做了一小部分修改。您并没有真正准备要存储或装入。而且，您的程序是个 applet，而 applet 是无法存储或装入的。</p>
            <p>可以存储或装入它们吗？</p>
            <p>实际上，JDBC API 允许任何 Java 程序 ― 甚至是 applet ― 连接到关系型数据库（RDBMS）上。 不幸的是，JDBC 对您的小程序来说可能有一点头重脚轻了。毕竟，如果您希望做的只是存储一点点数据的话，RDBMS 是一个强大、复杂的系统。</p>
            <p>在本文中，我们将分析一个简单的使用 JDBC 的抽象层。对于简单的应用程序来说，它可以让您只用几行代码就实现存储和装入结构化数据。它不会处理复杂的 RDBMS 使用，但那正是我们要避免的，不是吗？</p>
            <a name=complex>
            <p><a name=h4069><span class=atitle>JDBC 的复杂性</span></a></p>
            <p>JDBC 使用起来可能是一个复杂的 API。它不仅必须支持整个强大的 SQL 标准，还必须很好地隐藏不同数据库引擎之间的区别。</p>
            <p>JDBC 的复杂还在于关系型数据库是基于 SQL 构建的，而 SQL 是要给人用的，而不是给程序用的。直接使用 JDBC 有点象同时用两种语言编程。</p>
            <p>虽然 JDBC 的这些方面并不是什么坏事，但它们确实与我们的目标 ― 快速地存储少量数据相冲突。</p>
            <a name=simplify><br>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td><img height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"><br><img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=8 border=0></td>
                    </tr>
                </tbody>
            </table>
            <table class=no-print cellSpacing=0 cellPadding=0 align=right>
                <tbody>
                    <tr align=right>
                        <td><img height=4 alt="" src="http://www.ibm.com/i/c.gif" width="100%"><br>
                        <table cellSpacing=0 cellPadding=0 border=0>
                            <tbody>
                                <tr>
                                    <td vAlign=center><img height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><br></td>
                                    <td vAlign=top align=right><a class=fbox href="http://www.ibm.com/developerworks/cn/java/j-jdbcwrap/index.html#main"><strong><font color=#996699>回页首</font></strong></a></td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br><br>
            <p><a name=h4750><span class=atitle>简化的抽象</span></a></p>
            <p>我们将创建一个简单的抽象层，让您不必顾虑所有繁琐的细节问题来直接使用 JDBC。如果您早已熟悉 JDBC 或关系型数据库了，那您一眼看到我们的类列表应该是很熟悉的：</p>
            <ul>
                <li><code>Database</code>
                <li><code>Table</code>
                <li><code>RowSet</code>
                <li><code>Row</code> </li>
            </ul>
            <p>我们这里不是在作任何实质性的事情；我们的数据模型本质上和关系型模型是一样的，但去掉了烦人的细节（同时去掉了强大的功能）。每一个类映射到一个基本的 RDBMS 概念上，同时也映射到一个 JDBC 类上。就是这种映射让我们的 API 可以在保持易用性的同时保留它的相关特性。</p>
            <p>这种 API 的设计是基于对我们的数据存储需要的设想。如果您发现自己的程序需要一点不同的地方，您可以随意地改变这种抽象以适应您的情况。 这些类可以被认为是一种简化您工作的模式，而不是一成不变的规则。</p>
            <p>如果您不熟悉 SQL 或者 RDBMS 技术，不必害怕。 下面的四节中，每一节都会帮助您熟悉我们的一个类，还有这些类映射到的 RDBMS 功能。</p>
            <p><a name=N10094><span class=smalltitle><strong><font face=Arial>Database 类</font></strong></span></a></p>
            <p>当使用 JDBC 与数据库建立连接时，您必须告诉 JDBC 在何处可以找到实际的数据。 因为不同的数据库引擎有不同的访问方法和描述这些方法的不同语法，所以有不止一种方法来指定数据源。 在 JDBC 中，统一资源标识符（Uniform Resource Identifier，URI）字符串是用来指定数据源的，而这个字符串的结构是依赖于数据库的。</p>
            <p><code>Database</code> 类的主要目的就是封装这个字符串，还有建立连接操作时可能需要的任何用户名／密码信息。 </p>
            <p>下面是如何创建一个 <code>Database</code> 对象的方法： </p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>  Database db =
                        new Database( "jdbc:postgresql://localhost/mito",
                        "mito", "" );
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>构造函数的第一个参数是数据源的 URI。 在这个示例中，我使用了 <em>PostgreSQL</em>数据库引擎，而且在本机上访问了一个名为 mito 的数据库。 另外，我指定我的用户名 mito 和一个空的密码分别作为第二个和第三个参数。 </p>
            <p>一旦您创建了 <code>Database</code> 对象，您就可以使用它来访问数据，如我们在下一章可以看到的一样。 </p>
            <p><a name=N100BC><span class=smalltitle><strong><font face=Arial>Table 类</font></strong></span></a></p>
            <p>我们在 API 中对简化的一个设想就是，当您从表的一行读取数据时，您会得到整行的数据。换句话说，表的一行是作为读写单独一块数据的最小单位。这并不十分有效，但效率不是我们方法中所首要考虑的。</p>
            <p><code>Talbe</code> 类让您可以读写这些行对象。您必须做的第一步是创建一个表对象，它简单得只要知道它的名称即可： </p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>  Table table = db.getTable( "employee" );
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>创建 <code>Table</code> 对象的操作实际上并没有做任何事，只是让对象记住自己的名称。要做一些实际的事，我们就需要实际地使用这个 Table 对象了。在这里，我们从表中读取一行。 </p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>  Row row = table.getRow( "id=101");
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>注意，我们已经指定了我们只需要那些&#8216;id&#8217;值设定为&#8216;101&#8217;的行。通过使用 <code>getRow()</code> 方法，我们假定只有一行符合这个条件。在另外的情况下，我们可能需要多个行，那样我们就需要这样使用 <code>getRows()</code> 方法： </p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>  RowSet rows = table.getRows( "id&lt;103" );
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>在这种情况下,返回的值是一个 <code>RowSet</code> ，而不是一个 Row。 <code>RowSet</code> 就是 Row 的一个集合。 </p>
            <p>在接下来的两节里，我们将讨论 <code>Row</code> 和 <code>RowSet</code> 类。 </p>
            <p><a name=N10100><span class=smalltitle><strong><font face=Arial>Row 类</font></strong></span></a></p>
            <p>在我们的抽象中， <code>Row</code> 是在 RDBMS 中表示表中一行的名称／值对的集合。不同于 RDBMS 值可以是不同的类型， <code>Row</code> 仅包含一种类型，即字符串类型。 这还是为了让事情简单一点 ― 我们假定您不需要字符串类型提供的任何更强大的功能。 </p>
            <p>一旦您有了一个 <code>Row</code> ，就很容易从其中取出一个值，正如我们在清单 1 中看见的一样。 </p>
            <br><br><a name=listing1><strong>L清单 1. 从 Row 中获取值 </strong></a><br>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>  Row e = table.getRow( "id=100" );
                        String name = e.get( "name" );
                        System.out.println( "Employee name: "+name );
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>还要注意的是 <code>Row</code> 是排序的，这样您就可以通过索引来取出名称／值的对。清单 2 中给出了这样的一个示例。 </p>
            <br><br><a name=listing2><strong>清单 2. 迭代整个 Row </strong></a><br>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>  Row e = table.getRow( "id=100" );
                        for (int i=0; i&lt;e.length(); ++i) {
                        String key = e.getKey( i );
                        String value = e.get( i );
                        System.out.println( key+" = "+value );
                        }
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>当然，您还可以改变 <code>Row</code> 中的值。这是在数据库中更改数据所必需的 — 稍后我们会看到这一点。 </p>
            <p><a name=N10142><span class=smalltitle><strong><font face=Arial>RowSet 类</font></strong></span></a></p>
            <p>记住有一些查询可以返回多个 <code>Row</code> ，这样的话您就会得到一个 <code>RowSet</code> 。 <code>RowSet</code> 有一点不同于基于 Vector 的包装器。你可以轻易地迭代 <code>RowSet</code> 中所有的 <code>Row</code> ，在清单 3 中可以看到这一点。 </p>
            <br><br><a name=listing3><strong>清单 3. 迭代整个 RowSet </strong></a><br>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>  RowSet rs = table.get( "id&lt;104" );
                        for (int i=0; i&lt;rs.length(); ++i) {
                        Row row = rs.get( i );
                        // do something with the row....
                        }
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p><a name=N1016D><span class=smalltitle><strong><font face=Arial>一个完整的示例</font></strong></span></a></p>
            <p>现在我们已经看过了所有的类，让我们来看一个完整的示例吧。在清单 4 中，我们将抽取出符合特定条件的一套记录，然后打印出它们的值。</p>
            <br><br><a name=listing4><strong>清单 4. 一个读取数据的完整示例</strong></a><br>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>    // First, get all rows meeting the criterion
                        RowSet rs = table.getRows( "id&lt;103" );
                        // Iterate through the set
                        for (int i=0; i&lt;rs.length(); ++i) {
                        // Grab each row in turn
                        Row row = rs.get( i );
                        // Get and print the value of the "name" field
                        String name = row.get( "name" );
                        System.out.println( "Name: "+name );
                        }
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>如此容易！在下一节中，我们将看看怎样向数据库写入数据。</p>
            <a name=modifying><br>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td><img height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"><br><img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=8 border=0></td>
                    </tr>
                </tbody>
            </table>
            <table class=no-print cellSpacing=0 cellPadding=0 align=right>
                <tbody>
                    <tr align=right>
                        <td><img height=4 alt="" src="http://www.ibm.com/i/c.gif" width="100%"><br>
                        <table cellSpacing=0 cellPadding=0 border=0>
                            <tbody>
                                <tr>
                                    <td vAlign=center><img height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><br></td>
                                    <td vAlign=top align=right><a class=fbox href="http://www.ibm.com/developerworks/cn/java/j-jdbcwrap/index.html#main"><strong><font color=#996699>回页首</font></strong></a></td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br><br>
            <p><a name=h12852><span class=atitle>修改数据</span></a></p>
            <p>正如前面所提到的，使用我们的 API 读写数据是以整个 <em>行</em>为单位的。为了向数据库写入数据，您必须创建（或修改） <code>Row</code> 对象，然后向数据库写入那个 <code>Row</code> 对象。 </p>
            <p>向数据库写入数据是通过使用 <code>Table</code> 中的 <code>putRow</code> 方法。这种方法有两种变体： </p>
            <ul>
                <li><code>public void putRow( Row row )</code>
                <li><code>public void putRow( Row row, String conditions )</code> </li>
            </ul>
            <p>这两种变体分别对应于 SQL 中的 <code>INSERT</code> 和 <code>UPDATE</code> 命令。 </p>
            <p>在第一个变体中，写一行意味着将一个全新的行插入表中。</p>
            <p>在第二个变体中，写一行意味着修改一个现有的行。 <code>conditions</code> 参数使您能够指定您想要修改的是哪一行（哪些行）。 </p>
            <p>让我们来看看每种方法的一个示例。</p>
            <p><a name=N101CE><span class=smalltitle><strong><font face=Arial>插入一个新行</font></strong></span></a></p>
            <p>插入一个新行很简单，因为您不必指定要修改的行（一行或多行）。您只是简单地把行插入：</p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>  table.putRow( row );
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>您可以重新创建一个 <code>Row</code> ，如清单 5 所示。 </p>
            <br><br><a name=listing5><strong>清单 5. 重新创建一个 Row </strong></a><br>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>  // Create an empty row object
                        Row row = new Row();
                        // Fill it up with data
                        row.put( "id", "200" );
                        row.put( "name", "Joey Capellino" );
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>或者，您可以修改一个以前曾经从数据库中读取的一个现有的行，如清单 6 所示。</p>
            <br><br><a name=listing6><strong>清单 6. 修改现有的 Row </strong></a><br>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>  // Grab a row from the database
                        Row row = table.getRow( someConditions );
                        // Change some or all of the fields
                        row.put( "name", "Joey Capellino" );
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>虽然通常是在插入时重新创建 <code>Row</code> ，更新时使用现有的 <code>Row</code> ，实际上您可以用任何方式来进行。 </p>
            <p><a name=N1020C><span class=smalltitle><strong><font face=Arial>更新现有的行</font></strong></span></a></p>
            <p>正如前面的部分提到的，对于您如何 <em>创建</em>用来更新的 <code>Row</code> 是没有限制的。 但是，通常您是使用一个刚从数据库中读出的 <code>Row</code> 。 </p>
            <p>为了详细描述这一点，我们将使用一个示例（在该例子中我们读出一个员工的姓名），改变这个名字，然后将更改后的结果写回数据库，如清单 7 所示。</p>
            <br><br><a name=listing7><strong>清单 7. 通过修改 Row 进行更新 </strong></a><br>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td class=code-outline>
                        <pre class=displaycode>    Row row = table.getRow( "id=104" );
                        row.put( "name", newName );
                        table.putRow( row, "id=104" );
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br>
            <p>注意我们必须在调用 <code>putRow()</code> 中指定条件。这样才会使调用成为 <em>更新</em>，而不是 <em>插入</em>。 </p>
            <p>注意，这个调用将更新 <em>所有</em>符合条件的行，而不是其中的一行。 </p>
            <a name=conclusion><br>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td><img height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"><br><img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=8 border=0></td>
                    </tr>
                </tbody>
            </table>
            <table class=no-print cellSpacing=0 cellPadding=0 align=right>
                <tbody>
                    <tr align=right>
                        <td><img height=4 alt="" src="http://www.ibm.com/i/c.gif" width="100%"><br>
                        <table cellSpacing=0 cellPadding=0 border=0>
                            <tbody>
                                <tr>
                                    <td vAlign=center><img height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><br></td>
                                    <td vAlign=top align=right><a class=fbox href="http://www.ibm.com/developerworks/cn/java/j-jdbcwrap/index.html#main"><strong><font color=#996699>回页首</font></strong></a></td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br><br>
            <p><a name=h16647><span class=atitle>结论</span></a></p>
            <p>在本文中，我们初步认识了一种通过 JDBC 包提供一种简化的通往关系型数据库接口的 API。这种抽象保留了 JDBC 接口的很多基本关系型功能，但对其进行了简化，从而让使用非常地方便。这种简化是以效率为代价的，但当目标是简单性时，这并不是一个令人惊奇的结果。</p>
            <br><br>
            <p><a name=resources><span class=atitle>参考资料 </span></a></p>
            <ul>
                <li>您可以参阅本文在 developerWorks 全球站点上的 <a href="http://www.ibm.com/developerworks/library/j-jdbcwrap/index.html?S_TACT=105AGX52&amp;S_CMP=cn-a-j"><u><font color=#5c81a7>英文原文</font></u></a>. <br><br>
                <li>参加本文的 <a href="javascript:void forumWindow()"><u><font color=#5c81a7>讨论论坛</font></u></a>。 <br><br>
                <li>下载本文中讨论的类的全部资料：
                <ul>
                    <li><a href="http://www.ibm.com/developerworks/cn/java/j-jdbcwrap/sidedatabasejava.html"><u><font color=#996699>Database.java</font></u></a>
                    <li><a href="http://www.ibm.com/developerworks/cn/java/j-jdbcwrap/sidetablejava.html"><u><font color=#5c81a7>Table.java</font></u></a>
                    <li><a href="http://www.ibm.com/developerworks/cn/java/j-jdbcwrap/siderowsetjava.html"><u><font color=#5c81a7>RowSet.java</font></u></a>
                    <li><a href="http://www.ibm.com/developerworks/cn/java/j-jdbcwrap/siderowjava.html"><u><font color=#5c81a7>Row.java</font></u></a> </li>
                </ul>
                <br>
                <li><a href="http://java.sun.com/products/jdbc/learning.html"><u><font color=#5c81a7>JDBC 学习中心</font></u></a>包含许多教程的链接。 <br><br>
                <li>阅读 <a href="http://java.sun.com/j2se/1.3/docs/guide/jdbc/index.html"><u><font color=#5c81a7>JDBC 文档页</font></u></a>可以获得很多有用的文档的链接。 <br><br>
                <li>您可以在 Amazon 购买 <a href="http://www.amazon.com/exec/obidos/ASIN/0201433281/javasoftsunmicroA"><u><font color=#5c81a7>《JDBC API 教程和参考大全》，第 2 版</font></u></a>，或者只是 <a href="http://java.sun.com/docs/books/jdbc/index.html"><u><font color=#5c81a7>阅读它</font></u></a>。 <br><br>
                <li><a href="http://www.iam.unibe.ch/~scg/Archive/Software/FreeDB/FreeDB.list.html"><u><font color=#5c81a7>免费数据库清单</font></u></a>包含许多免费 RDBMS 软件包的链接，您可以在启用 JDBC 的程序的服务器端使用。 <br><br>
                <li>本文中的代码已经在 <a href="http://www.postgresql.org/"><u><font color=#5c81a7>PostgreSQL</font></u></a>数据库引擎上通过了测试。 <br><br>
                <li>在 <a href="http://www.ibm.com/developerworks/cn/java/j-jdbcnew/index.html"><u><font color=#5c81a7>&#8220;JDBC 3.0 中有什么新内容&#8221;</font></u></a>（developerWorks，2001 年 7 月）中，Josh Heidebrecht 向我们介绍了 JDBC 最新的修正情况。 <br><br>
                <li>在 <a href="http://www.ibm.com/developerworks/java/library/j-spejb/index.html?S_TACT=105AGX52&amp;S_CMP=cn-a-j"><u><font color=#5c81a7>&#8220;将 RDBMS 存储过程作为 session EJB 组件的方法来封装&#8221;</font></u></a>（developerWorks，2000 年 10 月）中学习如何通过 Enterprise JavaBeans 来调用旧的存储过程。 <br><br>
                <li>阅读 <a href="http://www.ibm.com/developerworks/java/library/co-tipdiv.html?S_TACT=105AGX52&amp;S_CMP=cn-a-j"><u><font color=#5c81a7>&#8220;对象－数据分离和 EJB&#8221;</font></u></a>（developerWorks，2001 年 4 月），就能知道面向对象和面向数据的开发人员的分离是怎样产生的了。然后阅读接下来的文章 <a href="http://www.ibm.com/developerworks/java/library/co-tipdiv2.html?S_TACT=105AGX52&amp;S_CMP=cn-a-j"><u><font color=#5c81a7>&#8220;在您的 EBJ 项目上克服对象－数据分离&#8221;</font></u></a>（developerWorks，2001 年 4 月），看看您能对它做什么。 <br><br>
                <li>开发人员在选择数据库时应该注重什么功能？这个问题可以参阅 <a href="http://www.ibm.com/developerworks/java/library/z-dbpick.html?S_TACT=105AGX52&amp;S_CMP=cn-a-j"><u><font color=#5c81a7>&#8220;选择数据库管理系统&#8221;</font></u></a>（developerWorks，2001 年 7 月）。 <br><br>
                <li>在 <a href="http://www.ibm.com/developerworks/cn/java/index.html"><u><font color=#5c81a7>developerWorks Java 技术专区</font></u></a>寻找更多 Java 参考资料。 <br></li>
            </ul>
            <br><br>
            <p><a name=author><span class=atitle>关于作者</span></a></p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td colSpan=3><img height=5 alt="" src="http://www.ibm.com/i/c.gif" width="100%"></td>
                    </tr>
                    <tr vAlign=top align=left>
                        <td>
                        <p>&#160;</p>
                        </td>
                        <td><img height=5 alt="" src="http://www.ibm.com/i/c.gif" width=4></td>
                        <td width="100%">
                        <p>Greg Travis 是居住在纽约的一个自由程序员。他对计算机的兴趣可能是源于&#8220; Bionic Woman&#8221;中的一段情节 － Jamie 四处奔跑，试图逃离一所灯光和门都被邪恶的人工智能所控制的房子，人工智能还通过扬声器嘲笑她。他是一个传统观念的虔诚信徒 － 如果一个计算机程序能够工作，那完全是个巧合。可以通过 <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#109;&#105;&#116;&#111;&#64;&#112;&#97;&#110;&#105;&#120;&#46;&#99;&#111;&#109;&#63;&#99;&#99;&#61;&#109;&#105;&#116;&#111;&#64;&#112;&#97;&#110;&#105;&#120;&#46;&#99;&#111;&#109;"><u><font color=#5c81a7>mito@panix.com</font></u></a>与他联系。 </p>
                        </td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<img src ="http://www.blogjava.net/simie/aggbug/127902.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/simie/" target="_blank">和田雨</a> 2007-07-03 17:16 <a href="http://www.blogjava.net/simie/archive/2007/07/03/127902.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java SE 6中的JDBC 4.0增强</title><link>http://www.blogjava.net/simie/archive/2007/07/02/127660.html</link><dc:creator>和田雨</dc:creator><author>和田雨</author><pubDate>Mon, 02 Jul 2007 11:39:00 GMT</pubDate><guid>http://www.blogjava.net/simie/archive/2007/07/02/127660.html</guid><wfw:comment>http://www.blogjava.net/simie/comments/127660.html</wfw:comment><comments>http://www.blogjava.net/simie/archive/2007/07/02/127660.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/simie/comments/commentRss/127660.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/simie/services/trackbacks/127660.html</trackback:ping><description><![CDATA[<span class=h1b>Java SE 6中的JDBC 4.0增强</span><br><br>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td height=64>时间：2006-10-25<br>作者：<a href="http://dev2dev.bea.com.cn/author/499.html"><u><font color=#0000ff>Srini Penchikala</font></u></a><br>浏览次数：
            <script language=JavaScript src="/beadevcount.jsp?d_id=162472" type=text/JavaScript></script>
            5760 <br>本文关键字：<a href="http://dev2dev.bea.com.cn/products/search.jsp?searchtype=keywords&amp;keywords=JDO"><u><font color=#0000ff>JDO</font></u></a>,&nbsp;<a href="http://dev2dev.bea.com.cn/products/search.jsp?searchtype=keywords&amp;keywords=JDBC"><u><font color=#0000ff>JDBC</font></u></a>,&nbsp;<a href="http://dev2dev.bea.com.cn/products/search.jsp?searchtype=keywords&amp;keywords=SQLJ"><u><font color=#0000ff>SQLJ</font></u></a>,&nbsp;<a href="http://dev2dev.bea.com.cn/products/search.jsp?searchtype=keywords&amp;keywords=Java"><u><font color=#0000ff>Java</font></u></a>,&nbsp;<a href="http://dev2dev.bea.com.cn/products/search.jsp?searchtype=keywords&amp;keywords=Srini Penchikala"><u><font color=#0000ff>Srini Penchikala</font></u></a>,&nbsp;<a href="http://dev2dev.bea.com.cn/products/search.jsp?searchtype=keywords&amp;keywords=jdbc"><u><font color=#0000ff>jdbc</font></u></a>,&nbsp;<a href="http://dev2dev.bea.com.cn/products/search.jsp?searchtype=keywords&amp;keywords=mustang"><u><font color=#0000ff>mustang</font></u></a>,&nbsp;<a href="http://dev2dev.bea.com.cn/products/search.jsp?searchtype=keywords&amp;keywords=java se 6"><u><font color=#0000ff>java se 6</font></u></a>,&nbsp;<a href="http://dev2dev.bea.com.cn/products/search.jsp?searchtype=keywords&amp;keywords=RowID"><u><font color=#0000ff>RowID</font></u></a>,&nbsp;<a href="http://dev2dev.bea.com.cn/products/search.jsp?searchtype=keywords&amp;keywords=driver"><u><font color=#0000ff>driver</font></u></a>,&nbsp;<a href="http://dev2dev.bea.com.cn/products/search.jsp?searchtype=keywords&amp;keywords=annotation"><u><font color=#0000ff>annotation</font></u></a>,&nbsp;<a href="http://dev2dev.bea.com.cn/products/search.jsp?searchtype=keywords&amp;keywords=驱动程序"><u><font color=#0000ff>驱动程序</font></u></a>,&nbsp;<a href="http://dev2dev.bea.com.cn/products/search.jsp?searchtype=keywords&amp;keywords=注释"><u><font color=#0000ff>注释</font></u></a></td>
            <td>
            <table class=box_content cellSpacing=0 cellPadding=0 border=0>
                <tbody>
                    <tr>
                        <td><span class=h2b>文章工具</span><br><img height=10 alt=推荐给朋友 src="http://dev2dev.bea.com.cn/images/letter001.gif" width=19 align=absMiddle>&nbsp;<a href="javascript:sendmail()"><u><font color=#0000ff>推荐给朋友</font></u></a><br><u><font color=#0000ff><img height=18 alt=打印文章 src="http://dev2dev.bea.com.cn/images/print001.gif" width=19 align=absMiddle></font></u>&nbsp;<a href="javascript:window.print()"><u><font color=#0000ff>打印文章</font></u></a></td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<!-- 提取技术文章 -->
<div class=beas><u><font color=#0000ff><img height=1 alt="" src="http://dev2dev.bea.com.cn/images/dot6B6B6B.gif" width="100%"></font></u></div>
<p>　　 <a href="http://www.onjava.com/pub/a/onjava/2006/08/02/jjdbc-4-enhancements-in-java-se-6.html##" target=_blank><u><font color=#0000ff>Java</font></u></a> Platform, Standard Edition（Java SE）版本6（代码名称<a href="http://mustang.dev.java.net/"><u><font color=#0000ff>Mustang</font></u></a>）现在已经推出了第二个<a href="http://java.sun.com/javase/6/"><u><font color=#0000ff>beta</font></u></a>版本，并计划于今年十月份交付使用。Java SE 6包括几处对<a href="http://java.sun.com/javase/technologies/database.jsp"><u><font color=#0000ff>Java Database Connectivity</font></u></a> （<a href="http://www.onjava.com/pub/a/onjava/2006/08/02/jjdbc-4-enhancements-in-java-se-6.html##" target=_blank><u><font color=#0000ff>JDBC</font></u></a>）API的增强。这些增强将被发布为JDBC 4.0版本。新JDBC功能的主要目标是提供更为简单的设计方式和更好的开发人员体验。本文概要说明了JDBC 4.0增强，以及它们给企业Java开发人员带来的好处。我们将借助一个使用Apache Derby作为后端数据库而构建的贷款处理示例应用程序，对新的JDBC功能进行探讨。</p>
<h3>Java SE 6.0</h3>
<p>　　Java SE 6.0版本的主要目标是提供兼容性、稳定性和高质量。这个版本中有几处有趣的增强，尤其是在监控与管理（JMX）、Web service、脚本语言支持（使用Rhino脚本引擎<a href="http://www.jcp.org/en/jsr/detail?id=223"><u><font color=#0000ff>JSR 223</font></u></a>将JavaScript技术与Java源代码集成在一起）、数据库<a href="http://www.onjava.com/pub/a/onjava/2006/08/02/jjdbc-4-enhancements-in-java-se-6.html##" target=_blank><u><font color=#0000ff>连接性</font></u></a>、注释支持和安全性方面。JDBC API中还增加了几个新功能，从新的RowId支持到更多的SQLException子类。</p>
<h3>JDBC 4.0功能</h3>
<p>　　借助Mustang中包含的Java SE <em>Service Provider</em>机制，Java开发人员不再需要使用像Class.forName()这样的代码显式地加载JDBC驱动程序，就能注册JDBC驱动程序。通过在调用DriverManager.getConnection()方法时自动定位合适的驱动程序，DriverManager类可以做到这一点。这个功能是向后兼容的，所以无需修改现有的JDBC代码。</p>
<p>　　 在访问关系数据库的Java应用程序中，通过最小化我们需要编写的&#8220;模板&#8221;代码，JDBC 4.0还改善了开发人员体验。它还提供实用程序类，以改进JDBC驱动程序的注册和卸载机制，以及管理数据源和连接对象。</p>
<p>　　 借助JDBC 4.0，Java开发人员现在可以使用Annotations指定SQL查询，从而利用Java SE 5.0（<a href="http://java.sun.com/j2se/1.5.0/docs/index.html"><u><font color=#0000ff>Tiger</font></u></a>）版本中提供的元数据支持。基于注释的SQL查询允许在Java代码中使用Annotation关键字指定SQL查询字符串。这样，我们就不必在两个不同文件中查看JDBC代码以及这些代码中调用的数据库查询了。例如，如果有一个叫做getActiveLoans()的方法，用于获取贷款处理数据库中的当前贷款，可以使用@Query(sql="SELECT * FROM LoanApplicationDetails WHERE LoanStatus = 'A'")注释来修饰它。</p>
<p>　　 此外，Java SE 6开发工具包（JDK 6）的最后版本——与运行时环境（JRE 6）相反——将会有一个基于与它绑定在一起的<a href="http://db.apache.org/derby/"><u><font color=#800080>Apache Derby</font></u></a>的数据库。这将帮助开发人员理解新的JDBC功能，而不必单独下载、安装和配置数据库产品。</p>
<p>　　 JDBC 4.0中加入的主要功能包括：</p>
<ul>
    <li>自动加载JDBC驱动程序类。
    <li>连接管理增强。
    <li>支持RowId SQL 类型。
    <li>使用Annotations的DataSet SQL实现。
    <li>处理增强的SQL异常。
    <li>支持SQL XML。 </li>
</ul>
<p>　　还存在其他功能，比如对大对象（BLOB/CLOB）的改进支持和National Character Set Support。接下来的内容将会详细分析这些功能。</p>
<h3>自动加载JDBC驱动程序</h3>
<p>　　在JDBC 4.0中，调用getConnection方法时，不再需要使用Class.forName()显式地加载JDBC驱动程序，因为DriverManager将会试着从初始化时加载的以及使用与当前应用程序相同的类加载器显式加载的JDBC驱动程序中，找出合适的驱动程序来。</p>
<p>　　 DriverManager方法getConnection和getDrivers已经增强为支持Java SE Service Provider机制（SPM）。根据SPM，服务被定义为一组众所周知的接口和抽象类，而服务提供程序则是服务的特定实现。它还指定在META-INF/services目录中保存服务提供程序配置文件。JDBC 4.0驱动程序必须包含文件META-INF/services/java.sql.Driver。这个文件包含JDBC驱动程序的java.sql.Driver实现的名称。例如，要加载JDBC驱动程序以连接到Apache Derby数据库，META-INF/services/java.sql.Driver文件就要包含以下项：</p>
<p>　　 org.apache.derby.jdbc.EmbeddedDriver</p>
<p>　　 让我们尽快了解如何使用这项新功能加载JDBC驱动程序管理器。下面的列表显示了加载JDBC驱动程序通常使用的示例代码。我们假定需要连接到一个Apache Derby数据库，因为我们在文章后面提到的示例应用程序中将使用这个数据库：</p>
<pre class=code> Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
Connection conn
<br>=DriverManager.getConnection(jdbcUrl, jdbcUser, jdbcPassword);
</pre>
<p>　　但是在JDBC 4.0中，我们不需要Class.forName()这一行。我们只要调用getConnection()就可以获得数据库连接。</p>
<p>　　 注意，这仅适用于在单机模式中获得数据库连接。如果使用某种数据库连接池来管理连接，代码将会有所区别。</p>
<h3>连接管理</h3>
<p>　　在JDBC 4.0之前，我们依赖于JDBC URL来定义数据源连接。现在有了JDBC 4.0，我们只要提供一组参数（比如主机名称和端口号）给标准的连接工厂机制，就能获得到任意数据源的连接。Connection和Statement接口中加入了新的方法，以便在管理池环境中的Statement对象时可以支持连接状态跟踪改进和更大的灵活性。元数据工具（<a href="http://www.jcp.org/en/jsr/detail?id=175"><u><font color=#0000ff>JSR-175</font></u></a>）用于管理活动连接。我们还可以获得元数据信息，比如活动连接的状态，还可以把连接指定为标准的（Connection，用于单机应用程序）、池化的（PooledConnection）或者甚至是用于XA事务的分布式连接（XAConnection）。注意，我们没有直接使用XAConnection。它是由诸如WebLogic、WebSphere或JBoss这样的Java EE应用服务器内部的事务管理器来使用的。</p>
<h3>RowId支持</h3>
<p>　　RowID接口被添加到JDBC 4.0中以支持ROWID数据类型，Oracle和DB2等数据库也支持这种数据类型。当有多条记录没有惟一标识符列，而且需要在不允许复制的Collection（比如Hashtable）中保存查询输出时，RowId很有用。我们可以使用ResultSet的getRowId()方法来获得RowId，并使用PreparedStatement的setRowId()方法在查询中使用RowId。</p>
<p>　　 关于RowId对象要记住的一件重要事情是，分别在PreparedStatement和ResultSet中使用set或update方法时，RowId对象的值无法在数据源之间移植，可以认为它是特定于数据源的。所以，禁止在不同的Connection和ResultSet对象之间共享它。</p>
<p>　　 DatabaseMetaData中的getRowIdLifetime()方法可用于确定RowId对象的生存期有效性。表1中列出了返回值或行id可能取的值。</p>
<table class=tabel-general cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <th class=left>RowId 值</th>
            <th class=right>描述</th>
        </tr>
        <tr>
            <td class=left>ROWID_UNSUPPORTED</td>
            <td class=right>不支持ROWID数据类型。</td>
        </tr>
        <tr>
            <td class=left>ROWID_VALID_OTHER</td>
            <td class=right>RowID的生存期依赖于数据库厂商实现。</td>
        </tr>
        <tr>
            <td class=left>ROWID_VALID_TRANSACTION</td>
            <td class=right>只要在数据库表中行未被删除，RowID的生存期在当前的事务中。</td>
        </tr>
        <tr>
            <td class=left>ROWID_VALID_SESSION</td>
            <td class=right>只要在数据库表中行未被删除，RowID的生存期在当前会话的持续时间中。</td>
        </tr>
        <tr>
            <td class=left>ROWID_VALID_FOREVER</td>
            <td class=right>只要在数据库表中行未被删除，RowID的生存期是无限的。</td>
        </tr>
    </tbody>
</table>
<h3>基于注释的SQL查询</h3>
<p>　　JDBC 4.0规范利用注释（Java SE 5中加入）允许开发人员把SQL查询与Java类关联在一起，同时不用编写大量的代码。此外，通过使用Generics（<a href="http://www.jcp.org/en/jsr/detail?id=014"><u><font color=#0000ff>JSR 014</font></u></a>）和元数据（<a href="http://www.jcp.org/en/jsr/detail?id=175"><u><font color=#0000ff>JSR 175</font></u></a>）API，我们可以把SQL查询与Java对象关联在一起，从而指定查询输入和输出参数。我们还可以把查询结果绑定到Java类，以加速对查询输出的处理。我们无需编写通常用于把查询结果填充到Java对象中的所有代码。在Java代码中指定SQL查询时，有2种主要的注释：Select和Update。</p>
<h4>Select注释 </h4>
<p>　　Select注释用于在Java类中指定选择查询，以便使用get方法从数据库表中获取数据。表2显示了Select注释的各种属性以及它们的用法。</p>
<table class=tabel-general cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <th class=left>名称</th>
            <th class=center>类型</th>
            <th class=right>描述</th>
        </tr>
        <tr>
            <td class=left>sql</td>
            <td class=center>String</td>
            <td class=right>SQL Select查询字符串。</td>
        </tr>
        <tr>
            <td class=left>value</td>
            <td class=center>String</td>
            <td class=right>与sql属性相同。</td>
        </tr>
        <tr>
            <td class=left>tableName</td>
            <td class=center>String</td>
            <td class=right>在其上调用sql的数据库表的名称。</td>
        </tr>
        <tr>
            <td class=left>readOnly、connected、 scrollable</td>
            <td class=center>Boolean</td>
            <td class=right>标志，分别用于指示返回的DataSet是只读的还是可更新的，是否连接到后端数据库，在connected模式中使用时是否可以滚动。</td>
        </tr>
        <tr>
            <td class=left>allColumnsMapped</td>
            <td class=center>Boolean</td>
            <td class=right>标志，用于指示sql注释元素中的列名是否一对一地映射到DataSet中的字段。</td>
        </tr>
    </tbody>
</table>
<p>　　下面是Select注释的一个例子，用于从贷款数据库获得所有当前贷款：</p>
<pre class=code>interface LoanAppDetailsQuery extends BaseQuery {
@Select("SELECT * FROM LoanDetais where LoanStatus = 'A'")
DataSet&lt;LoanApplication&gt; getAllActiveLoans();
}
</pre>
<p>　　sql注释也支持I/O参数（参数标记由一个问号后面跟一个整数来表示）。下面是参数化sql查询的一个例子：</p>
<pre class=code>interface LoanAppDetailsQuery extends BaseQuery {
@Select(sql="SELECT * from LoanDetails
where borrowerFirstName= 1 and borrowerLastName= 2")
DataSet&lt;LoanApplication&gt; getLoanDetailsByBorrowerName(String borrFirstName,
String borrLastName);
}
</pre>
<h4>Update注释 </h4>
<p>　　Update注释用于修饰Query接口方法，用于更新数据库表中的一条或多条记录。每个Update注释都必须包含一个sql注释类型的元素。下面是Update注释的一个例子：</p>
<pre class=code>interface LoanAppDetailsQuery extends BaseQuery {
@Update(sql="update LoanDetails set LoanStatus = 1
where loanId = 2")
boolean updateLoanStatus(String loanStatus, int loanId);
}
</pre>
<h3>处理增强的SQL异常</h3>
<p>　　异常处理是Java编程的一个重要组成部分，特别是当连接到后端关系数据库或在后端关系数据库上运行查询的时候。我们一直使用SQLException类来指示与数据库相关的错误。<a href="http://www.onjava.com/pub/a/onjava/2006/08/02/jjdbc-4-enhancements-in-java-se-6.html?page=2#" target=_blank><u><font color=#0000ff>JDBC</font></u></a> 4.0在SQLException处理方面有几处增强。下面是JDBC 4.0版本中的一些增强，在处理SQLExceptions时它们可以为开发人员带来更好的体验：</p>
<ul>
    <li>新的SQLException子类
    <li>支持因果关系
    <li>支持增强的for-each循环 </li>
</ul>
<h4>新的SQLException类 </h4>
<p>　　JDBC 4.0中创建了SQLException的新子类，以便为Java程序员提供一种编写更多可移植错误处理代码的手段。JDBC 4.0中引入了2类新的SQLException：</p>
<ul type=disc>
    <li>SQL非瞬时异常
    <li>SQL瞬时异常 </li>
</ul>
<p>　　<strong>非瞬时异常：</strong>同一项操作重试失败时抛出此异常，直到SQLException的原因得到纠正为止。表3显示了JDBC 4.0中加入的新异常类，它们都是SQLNonTransientException的子类（SQLState类值定义在SQL 2003规范中。）：</p>
<table class=tabel-general cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <th class=left>异常类</th>
            <th class=right>SQLState值</th>
        </tr>
        <tr>
            <td class=left>SQLFeatureNotSupportedException</td>
            <td class=right>0A</td>
        </tr>
        <tr>
            <td class=left>SQLNonTransientConnectionException</td>
            <td class=right>08</td>
        </tr>
        <tr>
            <td class=left>SQLDataException</td>
            <td class=right>22</td>
        </tr>
        <tr>
            <td class=left>SQLIntegrityConstraintViolationException</td>
            <td class=right>23</td>
        </tr>
        <tr>
            <td class=left>SQLInvalidAuthorizationException</td>
            <td class=right>28</td>
        </tr>
        <tr>
            <td class=left>SQLSyntaxErrorException</td>
            <td class=right>42</td>
        </tr>
    </tbody>
</table>
<p>　　<strong>瞬时异常：</strong>当操作在没有任何应用程序级功能进行干涉的情况下重试，前面失败的JDBC操作能够成功时抛出此异常。表4中列出了对SQLTransientException进行扩展的新异常。</p>
<table class=tabel-general cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <th class=left>异常类</th>
            <th class=right>SQLState值</th>
        </tr>
        <tr>
            <td class=left>SQLTransientConnectionException</td>
            <td class=right>08</td>
        </tr>
        <tr>
            <td class=left>SQLTransactionRollbackException</td>
            <td class=right>40</td>
        </tr>
        <tr>
            <td class=left>SQLTimeoutException</td>
            <td class=right>None</td>
        </tr>
    </tbody>
</table>
<h4>因果关系 </h4>
<p>　　现在，SQLException类支持配备有异常机制（也称为Cause工具）的Java SE，这种机制让我们能够处理JDBC操作中抛出的多种异常（如果后端数据库支持多异常功能）。这种场景发生在执行一条可能抛出多个SQLException的语句时。</p>
<p>　　 我们可以使用SQLException中的getNextException()方法，通过异常链进行迭代。下面给出一些用于处理SQLException因果关系的示例代码：</p>
<pre class=code>catch(SQLException ex) {
while(ex != null) {
LOG.error("SQL State:" + ex.getSQLState());
LOG.error("Error Code:" + ex.getErrorCode());
LOG.error("Message:" + ex.getMessage());
Throwable t = ex.getCause();
while(t != null) {
LOG.error("Cause:" + t);
t = t.getCause();
}
ex = ex.getNextException();
}
}
</pre>
<h4>增强的For-Each循环 </h4>
<p>　　SQLException类实现了Iterable接口，为Java SE 5中加入的for-each循环功能提供支持。循环的导航将遍历SQLException及其原因。下面给出一个代码片段，对SQLException中加入的for-each循环进行了说明。</p>
<pre class=code>catch(SQLException ex) {
for(Throwable e : ex ) {
LOG.error("Error occurred: " + e);
}
}</pre>
<h3>对国家字符集转换的支持</h3>
<p>　　下面列出了处理国家字符集（National Character Set）时JDBC类中所做的增强：</p>
<ul>
    <li>JDBC数据类型：加入了新的JDBC数据类型，比如NCHAR、NVARCHAR、LONGNVARCHAR和NCLOB。
    <li>PreparedStatement：加入了新方法setNString、setNCharacterStream和setNClob。
    <li>CallableStatement：加入了新方法getNClob、getNString和getNCharacterStream。
    <li>ResultSet：接口加入了新方法updateNClob、updateNString和updateNCharacterStream。 </li>
</ul>
<h3>对大对象（BLOB和CLOB）的增强支持</h3>
<p>　　下面列出了JDBC 4.0中对处理LOB所做的增强：</p>
<ul>
    <li>Connection：加入了新方法（createBlob()、createClob()和createNClob()）以创建BLOB、CLOB和NCLOB对象的新实例。
    <li>PreparedStatement：加入了新方法setBlob()、setClob()和setNClob()，以便使用InputStream对象插入BLOB对象，以及使用Reader对象插入CLOB和NCLOB对象。
    <li>LOB：Blob、Clob和NClob接口中加入了新方法（free()），以便释放这些对象占用的资源。 </li>
</ul>
<p>　　现在，让我们看一看java.sql和javax.jdbc包中加入的一些新类，以及它们提供了哪些服务。</p>
<h3>JDBC 4.0 API：新类</h3>
<h4>RowId (java.sql)</h4>
<p>　　正如前面提过的那样，这个接口代表着数据库中的一个SQL ROWID值。ROWID是一个内置的SQL数据类型，用于识别数据库表中的特定数据行。ROWID通常用在这样的查询中：该查询从输出行没有惟一ID列的表中返回行。</p>
<p>　　 CallableStatement、PreparedStatement和ResultSet接口中的方法，比如getRowId和setRowId，允许程序员访问SQL ROWID值。接口还提供一个方法（叫做getBytes()）把ROWID的值返回为字节数组。DatabaseMetaData接口有一个叫做getRowIdLifetime的新方法，可用于确定RowId对象的生存期。RowId的作用域可以是下列3种类型之一：</p>
<ul>
    <li>在其中创建RowId的数据库事务的持续时间。
    <li>在其中创建RowId的会话的持续时间。
    <li>数据库表中的标识行，只要它尚未被删除。 </li>
</ul>
<h4>DataSet (java.sql) </h4>
<p>　　<a href="http://download.java.net/jdk6/docs/api/java/sql/DataSet.html"><u><font color=#0000ff>DataSet</font></u></a>接口为从执行SQL查询返回的数据提供类型安全的视图。DataSet可以在已连接或未连接模式中进行操作。当在已连接模式中使用时，其功能类似于ResultSet。而在未连接模式中使用时，DataSet的功能则类似于CachedRowSet。因为DataSet扩展了List接口，我们可以遍历查询返回的行。</p>
<p>　　 现有的类中还加入了几个新方法，比如Connection（createSQLXML、isValid）和ResultSet（getRowId）。</p>
<h3>示例应用程序</h3>
<p>　　本文中使用的示例应用程序是一个贷款处理应用程序，它包含一个贷款查找页面，用户可以在这个页面上输入一个贷款ID以获得有关贷款的详细信息，然后提交表单。贷款查找页面调用一个控制器对象，而此控制器对象又调用DAO对象来访问后端数据库，从而获得有关贷款的详细信息。这些详细信息包括借款人姓名、贷款金额和贷款到期时间，它们均会显示在一个贷款详细信息页面上。在后端数据库中，我们使用一个叫做LoanApplicationDetails的表来保存贷款应用程序的详细信息。</p>
<p>　　 示例应用程序的用例是获得特定贷款ID的贷款详细信息。在注册贷款并针对抵押产品和利率锁定它之后，就可以获得这些贷款详细信息了。贷款处理应用程序的项目细节如表5所示。</p>
<table class=tabel-general cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <th class=left>名称</th>
            <th class=right>值</th>
        </tr>
        <tr>
            <td class=left>Project Name</td>
            <td class=right>JdbcApp</td>
        </tr>
        <tr>
            <td class=left>Project Directory</td>
            <td class=right>c:\dev\projects\JdbcApp</td>
        </tr>
        <tr>
            <td class=left>DB Directory</td>
            <td class=right>c:\dev\dbservers\apache\derby</td>
        </tr>
        <tr>
            <td class=left>JDK Directory</td>
            <td class=right>c:\dev\java\jdk_1.6.0</td>
        </tr>
        <tr>
            <td class=left>IDE Directory</td>
            <td class=right>c:\dev\tools\eclipse</td>
        </tr>
        <tr>
            <td class=left>Database</td>
            <td class=right>Apache Derby 10.1.2.1</td>
        </tr>
        <tr>
            <td class=left>JDK</td>
            <td class=right>6.0 (beta 2 release)</td>
        </tr>
        <tr>
            <td class=left>IDE</td>
            <td class=right>Eclipse 3.1</td>
        </tr>
        <tr>
            <td class=left>Unit Testing</td>
            <td class=right>JUnit 4</td>
        </tr>
        <tr>
            <td class=left>Build</td>
            <td class=right>Ant 1.6.5</td>
        </tr>
    </tbody>
</table>
<p>　　下表列出了连接贷款详细信息Apache Derby数据库时需要用到的JDBC参数。这些参数都保存在一个叫做<em>derby.properties</em>的文本文件中，该文件位于项目基目录下的<em>etc/jdbc</em>目录中（参见表6）。</p>
<table class=tabel-general cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <th class=left>名称</th>
            <th class=right>值</th>
        </tr>
        <tr>
            <td class=left>JDBC Driver File</td>
            <td class=right>LoanApp\META-INF\services\java.sql.driver</td>
        </tr>
        <tr>
            <td class=left>Driver</td>
            <td class=right>org.apache.derby.ClientDriver</td>
        </tr>
        <tr>
            <td class=left>URL</td>
            <td class=right>jdbc:derby:derbyDB</td>
        </tr>
        <tr>
            <td class=left>User Id</td>
            <td class=right>user1</td>
        </tr>
        <tr>
            <td class=left>Password</td>
            <td class=right>user1</td>
        </tr>
    </tbody>
</table>
<p>　　注意：Apache Derby数据库提供2类JDBC驱动程序：Embedded Driver（org.apache.derby.jdbc.EmbeddedDriver）和Client/Server Driver（org.apache.derby.jdbc.ClientDriver）。在示例应用程序中我使用的是Client/Server Driver版本。</p>
<p>　　 下面给出用于启动Derby<a href="http://www.onjava.com/pub/a/onjava/2006/08/02/jjdbc-4-enhancements-in-java-se-6.html?page=3#" target=_blank><u><font color=#0000ff>数据库服务器</font></u></a>和使用ij工具创建新数据库的命令。</p>
<p>　　 要启动Derby Network Server，打开一个命令提示，然后运行以下命令（修改DERBY_INSTALL和JAVA_HOME环境变量，从而影响本地环境）。</p>
<pre class=code>set DERBY_INSTALL=C:\dev\dbservers\db-derby-10.1.2.1-bin
set JAVA_HOME=C:\dev\java\jdk1.6.0
set DERBY_INSTALL=C:\dev\dbservers\db-derby-10.1.3.1-bin
set CLASSPATH=%CLASSPATH%;%DERBY_INSTALL%\lib\derby.jar;
%DERBY_INSTALL%\lib\derbytools.jar;
%DERBY_INSTALL%\lib\derbynet.jar;
cd %DERBY_INSTALL%\frameworks\ NetworkServer\bin
startNetworkServer.bat
</pre>
<p>　　要连接到数据库服务器和创建测试数据库，打开另一个命令提示，然后运行以下命令。确保修改了DERBY_INSTALL和JAVA_HOME环境变量，以适应环境。</p>
<pre class=code>set JAVA_HOME=C:\dev\java\jdk1.6.0
set DERBY_INSTALL=C:\dev\dbservers\db-derby-10.1.3.1-bin
set CLASSPATH=%DERBY_INSTALL%\lib\derbyclient.jar;
%DERBY_INSTALL%\lib\derbytools.jar;.
%JAVA_HOME%\bin\java org.apache.derby.tools.ij
connect 'jdbc:derby://localhost:1527/LoanDB;create=true';
</pre>
<h3>测试</h3>
<p>　　用于编译Java源代码的classpath设置应该包含位于项目主目录下<em>lib</em>目录中的<em>derby.jar</em>和<em>junit4.jar</em>文件。我们还需要在classpath中包含<em>etc</em>、<em>etc/jdbc</em>和<em>etc/log4j</em>目录，这样应用程序就能访问JDBC属性和Log4J配置文件。我创建了一个Ant编译脚本（位于<em>JdbcApp/build</em>目录中），以自动化编译和打包Java代码的任务。</p>
<p>　　 用于测试贷款详细信息数据访问对象的测试类叫做LoanAppDetailsDAOTest。我们传入参数（比如贷款ID和借款人姓名）以获得贷款详细信息。</p>
<p>　　 下面的内容给出了一些代码示例，这些代码是关于JDBC 4.0规范的JDBC驱动程序自动加载和给予注释的SQL查询功能的。</p>
<h4>自动加载JDBC驱动程序 </h4>
<p>　　BaseDAO抽象类有一个叫做getConnection的方法，用于获得一个数据库连接。下面的代码片段显示了这个方法（注意，我们不必注册JDBC驱动程序）。只要<em>java.sql.Driver</em>文件中存在正确的驱动程序名称（org.apache.derby.jdbc.ClientDriver），就可以自动加载JDBC驱动程序。</p>
<pre class=code>protected Connection getConnection() throws DAOException {
// Load JDBC properties first
if (jdbcUrl == null || jdbcUser == null ||
jdbcPassword == null) {
loadJdbcProperties();
}
// Get Connection
Connection conn = null;
try {
conn = DriverManager.getConnection(jdbcUrl, jdbcUser,
jdbcPassword);
} catch (SQLException sqle) {
throw new DAOException("Error in getting a DB connection.",
sqle);
}
return conn;
}
</pre>
<h4>SQL注释 </h4>
<p>　　LoanAppDetailsQuery接口有带有注释的SQL查询，用于获得当前贷款（条件是loanstatus="A"）的列表和基于贷款人姓名的贷款详细信息（在一个贷款人借贷多笔款项的情况下）。我们在本文的前面部分曾见过这些SQL注释。下面给出的示例代码说明了如何调用使用Annotation定义的SQL查询。</p>
<pre class=code>public DataSet&lt;LoanAppDetails&gt; getAllActiveLoans() throws Exception {
// Get Connection
Connection conn = getConnection();
LoanAppDetailsQuery query = null;
DataSet&lt;LoanAppDetails&gt; loanDetails = null;
query = QueryObjectFactory.createQueryObject(
LoanAppDetailsQuery.class, conn);
loanDetails = query.getAllActiveLoans();
return loanDetails;
}
</pre>
<pre class=code>public DataSet&lt;LoanAppDetails&gt; getLoanDetailsByBorrowerName(
String borrFirstName, String borrLastName) throws Exception {
// Get Connection
Connection conn = getConnection();
LoanAppDetailsQuery query = null;
DataSet&lt;LoanAppDetails&gt; loanDetails = null;
query = QueryObjectFactory.createQueryObject(
LoanAppDetailsQuery.class, conn);
loanDetails = query.getLoanDetailsByBorrowerName(
borrFirstName,borrLastName);
return loanDetails;
}
</pre>
<h3>结束语</h3>
<p>　　在使用SQL时，JDBC 4.0可以提供开发的简便性并改善开发人员体验。JDBC 4.0的另一个目标是提供企业级的JDBC功能，把API公开给涵盖范围更广的工具集，以便更好地管理JDBC资源。此外，JDBC 4.0 API为JDBC驱动程序提供了一条迁移路径，从而与J2EE Connector架构（JCA）保持兼容。这使得JDBC厂商能够继续实现JDBC技术Connector API。当在企业级面向服务架构（Service Oriented Architecture，SOA）应用程序中使用JDBC数据源时，这一点很重要，因为在企业级SOA应用程序中，可以把JDBC数据源部署为企业服务总线（Enterprise Service Bus，ESB）架构中的另一个适配器，而不必为JDBC数据源编写ESB特定实现代码。</p>
<p>　　 在本文中，我们讨论了JDBC 4.0中的增强，比如RowId支持、JDBC驱动程序加载和基于Annotations的SQL。JDBC 4.0中还将加入其他功能，以便在未来支持SQL 2003规范。要了解有关JDBC 4.0规范的更多信息，请参考<a href="http://java.sun.com/products/jdbc/download.html"><u><font color=#800080>规范</font></u></a>文档。</p>
<h3>参考资料</h3>
<ul type=disc>
    <li><a href="http://www.onjava.com/onjava/2006/08/02/examples/jdbc40app.zip"><u><font color=#0000ff>示例应用程序代码</font></u></a>
    <li><a href="http://java.sun.com/javase/6/"><u><font color=#0000ff>Java SE 6主页</font></u></a>
    <li><a href="https://mustang.dev.java.net/"><u><font color=#0000ff>Java SE 6参考实现（Mustang）Web站点</font></u></a>
    <li><a href="http://java.sun.com/javase/6/download.jsp"><u><font color=#0000ff>Java SE 6下载页面</font></u></a>
    <li><a href="http://java.sun.com/javase/6/docs/api/"><u><font color=#0000ff>API规范</font></u></a>
    <li><a href="http://db.apache.org/derby/"><u><font color=#800080>Apache Derby主页</font></u></a>
    <li><a href="http://tomcat.apache.org/"><u><font color=#0000ff>Tomcat 5.5主页</font></u></a> </li>
</ul>
<!--文章其他信息-->
<div class=dot001><img height=1 alt="" src="http://dev2dev.bea.com.cn/images/_.gif" width="100%"></div>
<table cellSpacing=0 cellPadding=3 width="100%" border=0>
    <tbody>
        <tr vAlign=bottom>
            <td colSpan=2 height=20>&nbsp;<span class=h2b>作者简介</span></td>
        </tr>
        <tr>
            <td vAlign=top align=middle width=0></td>
            <td><a href="http://www.onjava.com/pub/au/1418" target=_blank><u><font color=#0000ff>Srini Penchikala</font></u></a> 是一位在Flagstar银行工作的信息系统学科问题专家。</td>
        </tr>
    </tbody>
</table>
<img src ="http://www.blogjava.net/simie/aggbug/127660.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/simie/" target="_blank">和田雨</a> 2007-07-02 19:39 <a href="http://www.blogjava.net/simie/archive/2007/07/02/127660.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>数据库连接池+JavaBean+JSP+SQL Server+JDBC3.0的数据库分页技术</title><link>http://www.blogjava.net/simie/archive/2007/07/02/127656.html</link><dc:creator>和田雨</dc:creator><author>和田雨</author><pubDate>Mon, 02 Jul 2007 11:23:00 GMT</pubDate><guid>http://www.blogjava.net/simie/archive/2007/07/02/127656.html</guid><wfw:comment>http://www.blogjava.net/simie/comments/127656.html</wfw:comment><comments>http://www.blogjava.net/simie/archive/2007/07/02/127656.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/simie/comments/commentRss/127656.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/simie/services/trackbacks/127656.html</trackback:ping><description><![CDATA[<pre>主要特色：
1.使用最新的JDBC3.0数据库驱动。
2.大幅度减化了JSP的反复调用JavaBean,可以直接写SQL,无须再使用连接数据库连接池。
3.将大量的工作交给JavaBean做,JSP负责页面控制。
4.最大特色是极其简单,程序编写也极其简单,非常适合初学者。
5.使用的是tomcat数据库连接池,方便快速。
请提供E_mail,为大家分享，如有高手，请指点不是。
本人E_mail：c841@163.com,望多提意见。
****************************************文件名《page.jsp》*******************************************************************
文件名《page.jsp》
&lt;%@ page language="java" import="java.sql.*, my.*" %&gt;
&lt;%@ page contentType="text/html; charset=gb2312" %&gt;
&lt;jsp:useBean id="pagi" scope="page" class="my.Pagi"/&gt;
&lt;html&gt;
&lt;body&gt;
&lt;table  align="center" border=1&gt;
&lt;%
String CountQuery="select count(*) from 商品资料";
String query = "select * from 商品资料";
ResultSet rs = pagi.querySql(CountQuery,query, request);
String footer = pagi.PageFooter();
%&gt;
&lt;tr&gt;
&lt;td &gt;商品编号&lt;/font&gt;&lt;/td&gt;
&lt;td &gt;商品名称&lt;/font&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;%
if (pagi.intPageCount&gt;0)
{
int i=0;
while (rs.next())
{
i++;
if (i&gt;((pagi.intPage-1)*pagi.intPageSize) &amp;&amp;(i&lt;=pagi.intPage*pagi.intPageSize))
{
%&gt;
&lt;tr&gt;
&lt;td&gt;&lt;%=rs.getString(1)%&gt;&lt;/td&gt;
&lt;td&gt;&lt;%=rs.getString(2)%&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;%
}
}
}
out.println("&lt;tr&gt;&lt;td colspan=2&gt;"+footer+"&lt;/td&gt;&lt;/tr&gt;");
rs.close();
pagi.close_all();
%&gt;
&lt;/table&gt;
&lt;/body&gt;
&lt;/html&gt;
****************************************文件名《pagi.java》*********************************************************
文件名《pagi.java》
package my;
import java.util.*;
import java.sql.*;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import my.DB.*;
public class Pagi
{
ResultSet CountTopicrs=null; //初始化总记录数Rs变量
ResultSet Pagirs=null; //初始化分页时Rs变量
public int intCountTopic=0; //主题总数
public int intPageSize;//每页显示主题数
public int intPageCount;//总页数
public int intPage=1; //当前页数
public String nowPage; // int i;
public String HttpFile;//初始化当前页intPage变量，以准确便获取当前页。 //当前的地址栏的文件
DB db; //定义Linkdb类的一个对象。
public Pagi()//定义构造器，初始化每页显示的主题数和数据库的连接。
{
intPageSize=4;  //每页显示的记录数目
db = new DB();
}
//Countsql:总记录的Query字符串。[形式为select count(*) from tablename]
//Pagisql :要分页的Query字符串。[形式为select * from tablename where ...]
//request :参数传递过程中的变量。[用来控制翻页时的pages变量]
public ResultSet querySql(String Countsql,String Pagisql,HttpServletRequest request)throws Exception
{
HttpFile=request.getRequestURI();  //获取当前文件名。
nowPage=request.getParameter("pages");  //获取当前页，将数值赋予intPage变量。[分页栏中必须要有pages参数]
if (nowPage==null)
{
intPage=1;
}
else
{
intPage=Integer.parseInt(nowPage);
if (intPage&lt;1)
intPage=1;
}
CountTopicrs=db.executeQuery(Countsql); //@@@@@@@@@@@@获取总记录数的结果集。
if (CountTopicrs.next())
{
intCountTopic=CountTopicrs.getInt(1);
}
intPageCount = (intCountTopic+intPageSize-1)/intPageSize;  //获取总页数。
if (intPage&gt;intPageCount)//如果当前页大于总页数，则当前页等于总页数。
{
intPage=intPageCount;
}
CountTopicrs.close();  //关闭总主题数的数据集。
db.close_all();
Pagirs=db.executeQuery(Pagisql);  //@@@@@@@@@@@@@@@获取执行分页的结果集。
return Pagirs;
}//end querySql function.
public int getCountTopic()//获取记录总数。
{
return intCountTopic;
}
public int getPageCount() //获取总页数。
{
return intPageCount;
}
public int getIntPage()  //获取当前页数。
{
return intPage;
}
public String PageFooter()
{
String str = "";
int next, prev;
prev=intPage-1;
next=intPage+1;
str += "查询到&lt;font color=red&gt;"+getCountTopic()+"&lt;/font&gt;条记录"+
"    共&lt;font color=red&gt;"+getPageCount()+"&lt;/font&gt;页";
str +=" 第&lt;font color=red&gt;"+getIntPage()+"&lt;/font&gt;页 ";
if(intPage&gt;1)
str += " &lt;A href=" + HttpFile + "?pages=1"+"&gt;首页&lt;/A&gt; ";
else
str += " 首页 ";
if(intPage&gt;1)
str += " &lt;A href=" + HttpFile + "?pages=" + prev + "&gt;上一页&lt;/A&gt; ";
else
str += " 上一页 ";
if(intPage&lt;intPageCount)
str += " &lt;A href=" + HttpFile + "?pages=" + next + "&gt;下一页&lt;/A&gt; ";
else
str += " 下一页 ";
if(intPageCount&gt;1&amp;&amp;intPage!=intPageCount)
str += " &lt;A href=" + HttpFile + "?pages=" + intPageCount +
"&gt;尾页&lt;/A&gt;";
else
str += " 尾页 ";
return str;
}
public void close_all()
{
db.close_all();
}
}
************************************************文件名《DB.java》********************************************************
文件名《DB.java》
package my;
import java.sql.*;
import javax.naming.*;
import javax.sql.DataSource;
//一个用于查找数据源的工具类。
public class DB {
private Connection con=null;
private Statement stmt=null;
ResultSet rs=null;
public  ResultSet executeQuery(String sql) throws Exception
{
rs=null;
try
{
Context initCtx = new javax.naming.InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
DataSource ds = (DataSource)envCtx.lookup("jdbc/bn");
con=ds.getConnection();
stmt=con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY);
rs=stmt.executeQuery (sql);
}
catch(SQLException e){throw e;}
catch(NamingException e){throw e;}
return rs;
}
//执行Insert,Update语句
public void executeUpdate(String sql) throws Exception
{
stmt = null;
rs=null;
try
{
Context initCtx = new javax.naming.InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
DataSource ds = (DataSource)envCtx.lookup("jdbc/bn");
con=ds.getConnection();
stmt=con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY);
stmt.executeQuery(sql);
stmt.close();
con.close();
}
catch(SQLException ex)
{
System.err.println("执行SQL语句出错: " + ex.getMessage());
}
}
// 关闭stmt和关闭连接
public void close_all()
{
try{
stmt.close();
con.close();
}
catch(SQLException e){e.printStackTrace();}
}
}
***************************************《tomcat中的数据库连接池的设置》********************************************************************************
&#8230;&#8230;
&#8230;&#8230;
&#8230;&#8230;
&lt;Context path="/SQL" docBase="D:\SQL_JSP" debug="0" reloadable="true" crossContext="true"&gt;
&lt;Resource name="jdbc/bn" auth="Container" type="javax.sql.DataSource"/&gt;
&lt;ResourceParams name="jdbc/bn"&gt;
&lt;parameter&gt;
&lt;name&gt;factory&lt;/name&gt;
&lt;value&gt;org.apache.commons.dbcp.BasicDataSourceFactory&lt;/value&gt;
&lt;/parameter&gt;
&lt;parameter&gt;
&lt;name&gt;driverClassName&lt;/name&gt;
&lt;value&gt;com.microsoft.jdbc.sqlserver.SQLServerDriver&lt;/value&gt;
&lt;/parameter&gt;
&lt;parameter&gt;
&lt;name&gt;url&lt;/name&gt;
&lt;value&gt;jdbc:microsoft:sqlserver://127.0.0.1:1433;DatabaseName=jspdev&lt;/value&gt;
&lt;/parameter&gt;
&lt;parameter&gt;
&lt;name&gt;username&lt;/name&gt;
&lt;value&gt;cyg&lt;/value&gt;
&lt;/parameter&gt;
&lt;parameter&gt;
&lt;name&gt;password&lt;/name&gt;
&lt;value&gt;325345353&lt;/value&gt;
&lt;/parameter&gt;
&lt;parameter&gt;
&lt;name&gt;maxActive&lt;/name&gt;
&lt;value&gt;20&lt;/value&gt;
&lt;/parameter&gt;
&lt;parameter&gt;
&lt;name&gt;maxIdle&lt;/name&gt;
&lt;value&gt;20&lt;/value&gt;
&lt;/parameter&gt;
&lt;parameter&gt;
&lt;name&gt;maxWait&lt;/name&gt;
&lt;value&gt;-1&lt;/value&gt;
&lt;/parameter&gt;
&lt;/ResourceParams&gt;
&lt;/Context&gt;
&lt;/Host&gt;
&lt;/Engine&gt;
&lt;/Service&gt;
&lt;/Server&gt;
</pre>
<img src ="http://www.blogjava.net/simie/aggbug/127656.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/simie/" target="_blank">和田雨</a> 2007-07-02 19:23 <a href="http://www.blogjava.net/simie/archive/2007/07/02/127656.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>各种数据库的JDBC驱动下载及连接字符串URL写法</title><link>http://www.blogjava.net/simie/archive/2007/07/01/127366.html</link><dc:creator>和田雨</dc:creator><author>和田雨</author><pubDate>Sun, 01 Jul 2007 08:09:00 GMT</pubDate><guid>http://www.blogjava.net/simie/archive/2007/07/01/127366.html</guid><wfw:comment>http://www.blogjava.net/simie/comments/127366.html</wfw:comment><comments>http://www.blogjava.net/simie/archive/2007/07/01/127366.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/simie/comments/commentRss/127366.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/simie/services/trackbacks/127366.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;<font color=#0000ff size=3><strong>&nbsp;各种数据库的JDBC驱动下载及连接字符串URL写法</strong></font>
<p><font color=#ff00ff size=3><strong>sun官方网站上的JDBC驱动列表：</strong></font><a href="http://java.sun.com/products/jdbc/reference/industrysupport/index.html"><font color=#333399><u>http://java.sun.com/products/jdbc/reference/industrysupport/index.html</u></font></a><br></p>
<table cellSpacing=1 cellPadding=1 border=1>
    <tbody>
        <tr>
            <th><font size=2>数&nbsp;据&nbsp;库</font>&nbsp;</th>
            <th><font size=2>说&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;明</font>&nbsp;</th>
        </tr>
        <tr>
            <td><font size=2>MySQL</font>&nbsp;</td>
            <td><a href="http://www.mysql.com/products/connector/j/"><font size=2><u><font color=#4444cc>http://www.mysql.com/products/connector/j/</font><font color=#800080>&nbsp;</font></u></font></a><font size=2>Shipped.&nbsp;But&nbsp;need&nbsp;to&nbsp;download&nbsp;the&nbsp;latest&nbsp;for&nbsp;MySQL&nbsp;4.1&nbsp;or&nbsp;higher.</font>&nbsp;</td>
        </tr>
        <tr>
            <td><font size=2>Oracle</font>&nbsp;</td>
            <td><a href="http://www.oracle.com/technology/software/tech/java/sqlj_jdbc/index.html"><font size=2><u><font color=#4444cc>http://www.oracle.com/technology/software/tech/java/sqlj_jdbc/index.html</font><font color=#0000ff>&nbsp;</font></u></font></a><font size=2>Included.</font>&nbsp;</td>
        </tr>
        <tr>
            <td><font size=2>SQL&nbsp;Server&nbsp;by&nbsp;jTDS</font>&nbsp;</td>
            <td><font size=2><a href="http://sourceforge.net/project/showfiles.php?group_id=33291"><u><font color=#4444cc>http://sourceforge.net/project/showfiles.php?group_id=33291</font><font color=#800080>&nbsp;</font></u></a></font><font size=2>Included.&nbsp;Support&nbsp;Microsoft&nbsp;SQL&nbsp;Server&nbsp;(6.5,&nbsp;7,&nbsp;2000&nbsp;and&nbsp;2005)</font>&nbsp;</td>
        </tr>
        <tr>
            <td><font size=2>Postgres</font>&nbsp;</td>
            <td><a href="http://jdbc.postgresql.org/download.html"><font size=2><u><font color=#4444cc>http://jdbc.postgresql.org/download.html</font><font color=#0000ff>&nbsp;</font></u></font></a><font size=2>Included&nbsp;7.3&nbsp;JDBC&nbsp;3</font>&nbsp;</td>
        </tr>
        <tr>
            <td><font size=2>SAP&nbsp;DB</font>&nbsp;</td>
            <td><a href="http://www.sapdb.org/sap_db_jdbc.htm"><font size=2><u><font color=#4444cc>http://www.sapdb.org/sap_db_jdbc.htm</font><font color=#0000ff>&nbsp;</font></u></font></a><font size=2>Included.</font>&nbsp;</td>
        </tr>
        <tr>
            <td><font size=2>SyBase&nbsp;by&nbsp;jTDS</font>&nbsp;</td>
            <td><a href="http://jtds.sourceforge.net/"><font size=2><u><font color=#4444cc>http://jtds.sourceforge.net/</font><font color=#0000ff>&nbsp;</font></u></font></a><font size=2>Included.&nbsp;Support&nbsp;Sybase&nbsp;(10,&nbsp;11,&nbsp;12)</font>&nbsp;</td>
        </tr>
    </tbody>
</table>
<div twffan="done"></div>
<div twffan="done"><br><br><font color=#a9a9a9>以下内容来自互联网<br></font><br>1.&nbsp;MySQL(<a href="http://www.mysql.com/"><u><font color=#0000ff>http://www.mysql.com</font></u></a>)&nbsp;mysql-connector-java-2.0.14-bin.jar&nbsp;;<br>&nbsp;&nbsp;Class.forName(&nbsp;"org.gjt.mm.mysql.Driver"&nbsp;);<br>&nbsp;&nbsp;cn&nbsp;=&nbsp;DriverManager.getConnection(&nbsp;"jdbc:mysql://MyDbComputerNameOrIP:3306/myDatabaseName",&nbsp;sUsr,&nbsp;sPwd&nbsp;);&nbsp;<br>2.&nbsp;PostgreSQL(<a href="http://www.de.postgresql.org/"><u><font color=#0000ff>http://www.de.postgresql.org</font></u></a>)&nbsp;pgjdbc2.jar&nbsp;;<br>&nbsp;&nbsp;Class.forName(&nbsp;"org.postgresql.Driver"&nbsp;);&nbsp;<br>&nbsp;&nbsp;cn&nbsp;=&nbsp;DriverManager.getConnection(&nbsp;"jdbc:postgresql://MyDbComputerNameOrIP/myDatabaseName",&nbsp;sUsr,&nbsp;sPwd&nbsp;);&nbsp;<br>3.&nbsp;Oracle(<a href="http://www.oracle.com/ip/deploy/database/oracle9i/"><u><font color=#0000ff>http://www.oracle.com/ip/deploy/database/oracle9i/</font></u></a>)&nbsp;classes12.zip&nbsp;;<br>&nbsp;&nbsp;Class.forName(&nbsp;"oracle.jdbc.driver.OracleDriver"&nbsp;);&nbsp;<br>&nbsp;&nbsp;cn&nbsp;=&nbsp;DriverManager.getConnection(&nbsp;"jdbc:oracle:thin:@MyDbComputerNameOrIP:1521:ORCL",&nbsp;sUsr,&nbsp;sPwd&nbsp;);&nbsp;<br>4.&nbsp;Sybase(<a href="http://jtds.sourceforge.net/"><font color=#000080><u>http://jtds.sourceforge.net</u></font></a>)&nbsp;jconn2.jar&nbsp;;<br>&nbsp;&nbsp;Class.forName(&nbsp;"com.sybase.jdbc2.jdbc.SybDriver"&nbsp;);&nbsp;<br>&nbsp;&nbsp;cn&nbsp;=&nbsp;DriverManager.getConnection(&nbsp;"jdbc:sybase:Tds:MyDbComputerNameOrIP:2638",&nbsp;sUsr,&nbsp;sPwd&nbsp;);&nbsp;<br>&nbsp;&nbsp;//(Default-Username/Password:&nbsp;"dba"/"sql")&nbsp;<br>5.&nbsp;Microsoft&nbsp;SQLServer(<a href="http://jtds.sourceforge.net/"><font color=#000080><u>http://jtds.sourceforge.net</u></font></a>)&nbsp;;<br>&nbsp;&nbsp;Class.forName(&nbsp;"net.sourceforge.jtds.jdbc.Driver"&nbsp;);&nbsp;<br>&nbsp;&nbsp;cn&nbsp;=&nbsp;DriverManager.getConnection(&nbsp;"jdbc:jtds:sqlserver://MyDbComputerNameOrIP:1433/master",&nbsp;sUsr,&nbsp;sPwd&nbsp;);&nbsp;<br>6.&nbsp;Microsoft&nbsp;SQLServer(<a href="http://www.microsoft.com/"><font color=#800080><u>http://www.microsoft.com</u></font></a>)&nbsp;;<br>&nbsp;&nbsp;Class.forName(&nbsp;"com.microsoft.jdbc.sqlserver.SQLServerDriver"&nbsp;);&nbsp;<br>&nbsp;&nbsp;cn&nbsp;=&nbsp;DriverManager.getConnection(&nbsp;"jdbc:microsoft:sqlserver://MyDbComputerNameOrIP:1433;databaseName=master",&nbsp;sUsr,&nbsp;sPwd&nbsp;);&nbsp;<br>7.&nbsp;ODBC&nbsp;<br>&nbsp;&nbsp;Class.forName(&nbsp;"sun.jdbc.odbc.JdbcOdbcDriver"&nbsp;);&nbsp;<br>&nbsp;&nbsp;Connection&nbsp;cn&nbsp;=&nbsp;DriverManager.getConnection(&nbsp;"jdbc:odbc:"&nbsp;+&nbsp;sDsn,&nbsp;sUsr,&nbsp;sPwd&nbsp;);&nbsp;<br>8.DB2&nbsp;Class.forName("com.ibm.db2.jdbc.net.DB2Driver");&nbsp;<br>&nbsp;&nbsp;String&nbsp;url="jdbc:db2://192.9.200.108:6789/SAMPLE"&nbsp;<br>&nbsp;&nbsp;cn&nbsp;=&nbsp;DriverManager.getConnection(&nbsp;url,&nbsp;sUsr,&nbsp;sPwd&nbsp;);&nbsp;<br>9.access由于access并不是作为一项服务运行，所以url的方法对他不适用。access可以通过odbc，也可以通过服务器映射路径的形式找到.mdb文件,参见<a href="http://rmijdbc.objectweb.org/Access/access.html"><font color=#800080><u>http://rmijdbc.objectweb.org/Access/access.html</u></font></a><br></div>
<div twffan="done"><u></u></div>
<div twffan="done"><strong><font color=#0000ff>JDBC&nbsp;API的使用方法</font></strong><br>(1)登记并加载JDBC驱动程序；<br>两种方法：<br>Class.forName(String&nbsp;drivername);<br>DriverManager.registerDriver(Driver&nbsp;driver)</div>
<div twffan="done">(2)建立与SQL数据库的连接；<br>DriverManager的getConnection()方法：<br>Connection&nbsp;getConnection(String&nbsp;url):url表示数据库地址字符串；<br>Connection&nbsp;getConnection(String&nbsp;url,String&nbsp;user,String&nbsp;pwd)<br>Connection&nbsp;getConnection(String&nbsp;url,Properties&nbsp;info)<br>(3)传送一个SQL查询；<br>Connection的createStatement()方法：<br>Statement&nbsp;createStatement();<br>Statement可以执行SQL语句，得到SQL查询结果。</div>
<div twffan="done">(4)获得结果集。<br>Statement的执行SQL语句方法：<br>ResultSet&nbsp;executeQuery(String&nbsp;sql):执行select语句<br>int&nbsp;executeUpdate(String&nbsp;sql)：执行更新语句，如insert,delete,update.</div>
<div twffan="done">(5)检索查询结果。<br>ResultSet的方法：<br>boolean&nbsp;next():没有行时返回false;<br>String&nbsp;getString(String&nbsp;columnName)：返回列名对应的值。</div>
<img src ="http://www.blogjava.net/simie/aggbug/127366.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/simie/" target="_blank">和田雨</a> 2007-07-01 16:09 <a href="http://www.blogjava.net/simie/archive/2007/07/01/127366.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>