??xml version="1.0" encoding="utf-8" standalone="yes"?>日日摸夜夜添夜夜添国产精品 ,x88av蜜桃臀一区二区,久久精品色欧美aⅴ一区二区http://www.aygfsteel.com/simie/category/23714.htmlzh-cnThu, 05 Jul 2007 10:05:48 GMTThu, 05 Jul 2007 10:05:48 GMT60对一个简单的 JDBC 包装器的扩展及应?http://www.aygfsteel.com/simie/archive/2007/07/03/127905.html和田?/dc:creator>和田?/author>Tue, 03 Jul 2007 09:22:00 GMThttp://www.aygfsteel.com/simie/archive/2007/07/03/127905.htmlhttp://www.aygfsteel.com/simie/comments/127905.htmlhttp://www.aygfsteel.com/simie/archive/2007/07/03/127905.html#Feedback0http://www.aygfsteel.com/simie/comments/commentRss/127905.htmlhttp://www.aygfsteel.com/simie/services/trackbacks/127905.html

对一个简单的 JDBC 包装器的扩展及应?/h1> developerWorks
文档选项
此作为电子邮件发?src="http://www.ibm.com/i/v14/icons/em.gif"

此作为电子邮件发?/font>

未显C需?JavaScript 的文档选项



U别: 初

宗锋 (zong_feng@263.net)西北大学计算机系士

2001 q?12 ?16 ?/p>

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

最q看?《一个简单的 JDBC 包装器?/font>Q觉得这文章很有应用h|我便在自q开发中使用了它Q不q这个包装器也存在一些不I于是我对它进行了一些扩展。首先原文中的Tablecȝ删除功能,我便增加了删除功能。代码如下:
public void delRow(Row row) throws SQLException {
                        String ss="";
                        ss = "delete from "+name+" where ";
                        for (int i=0; i<row.length(); ++i) {
                        String k = row.getKey( i );
                        String v = row.get( i );
                        ss += k+"='"+v+"'";
                        if (i != row.length()-1)
                        ss += " and ";
                        }
                        Connection con = database.getConnection();
                        Statement st = con.createStatement();
                        st.executeUpdate( ss );
                        }
                        public void delRow(String conditions)throws SQLException {
                        String ss="";
                        ss = "delete from "+name+" where ";
                        ss +=conditions;
                        Connection con = database.getConnection();
                        Statement st = con.createStatement();
                        st.executeUpdate( ss );
                        }

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

CZ如下Q?
//Ҏ一
                        Row e = table.getRow( "id=2001" );
                        table.delRow(e);
                        //Ҏ?
                        table.delRow("id=2001");
                        

另外q个包装器没有对查询l果为NULL的情况作处理Q我通过修改Tablecȝexecute函数和RowSetcȝget函数对这U情况作了处理。具体代码见附g?/p>

下面谈谈利用q个JDBC包装器实现对数据库的装Q假定我们有一个表:studentQ创的Sql语句如下Q?
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
                        )

我们对这个表q行装Q下面是Studentcȝ主要代码Q?
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表示限制条gQ如果ؓI,则插入新记录Q否则更新记?
                        */
                        public void save(String conditions) throws SQLException{
                        if(conditions==null)
                        {getTable().putRow(r);}
                        else
                        getTable().putRow(r,conditions);
                        }
                        /**
                        *׃id作ؓd键字Q所以我们用字W串为参数的delRow()函数
                        */
                        public void delete()throws SQLException{
                        //getTable().delRow(this.r);
                        String conditions="";
                        conditions = "id=" + "'"+getId()+"'";
                        getTable().delRow(conditions);
                        }
                        }

下面q个cL相应的一个查询类的主要代码:
public class StudentFactory{
                        public static Student findStudentById(String id)
                        throws SQLException{
                        Row r=getTable().getRow("id="+id);
                        if(r==null)
                        return nullQ?
                        else
                        return new Student(r);
                        }
                        public static Student[] findAllStudents()
                        throws SQLException{
                        RowSet rs=getTable().getRows("1>0");
                        if (rs==null)
                        return null;
                        else
                        Student[] stu=null;
                        stu=new Student[rs.length()];
                        for(int i=0;i<rs.length(); i++){
                        stu[i]=new Student(rs.get(i));
                        }
                        return stu;
                        }
                        }

我用javabean来实现很多功能,q样可以减少在jsp中的java代码量,方便我们对界面的改进。我们要实现的功能ؓ对学生的~辑Q添加,删除和列表。这些功能定义在两个javabean中:下面是两个jsp文g的主要代码:
<%-- student.jsp --%>
                        <%@ page contentType="text/html;charset=GB2312" %>
                        <%@ page import="org.gjt.mm.mysql.*,manger.bean.*,manger.tools.*,manger.business.*" %>
                        <html>
                        <head>
                        <SCRIPT TYPE="text/javascript" LANGUAGE="JavaScript" >
                        <!--
                        function doDelete()
                        {
                        if(confirm('你确定删除吗?')) {
                        document.EditForm.event.value='delete';
                        document.EditForm.submit();
                        }
                        }
                        function doEdit()
                        {
                        if(confirm('你确定编辑吗?')) {
                        document.EditForm.event.value='showEdit';
                        document.EditForm.submit();
                        }
                        }
                        function showAddPage()
                        {
                        document.location='editstudent.jsp?event=showAdd';
                        }
                        </SCRIPT>
                        </head>
                        <body bgcolor="#FFFFFF" text="#000000">
                        <%
                        try {
                        Class.forName("org.gjt.mm.mysql.Driver").newInstance();
                        }
                        catch (Exception E) {
                        out.println("Unable to load driver.");
                        } %>
                        <jsp:useBean id="table" scope="page" class="manger.bean.ListStudentBean" />
                        <%
                        Student[] student=table.getStudent(pageContext);
                        int total=0;
                        int currPage=table.getCurPage();
                        int pageCount=table.getPageCount();
                        if(student!=null)
                        {total=student.length;}%>
                        <FORM NAME="EditForm" ACTION="editstudent.jsp">
                        <INPUT TYPE="HIDDEN" NAME="event" VALUE="">
                        <table width="75%" border="1">
                        <tr>
                        <td colspan="5">学生列表</td>
                        </tr>
                        <tr>
                        <td>学号</td>
                        <td>姓名</td>
                        <td>班</td>
                        <td>备注一</td>
                        <td>选择</td>
                        </tr>
                        <%for (int i=0;i<total;i++){
                        Student current=student[i];%>
                        <tr>
                        <td><%=current.getId()%></td>
                        <td><%=current.getName()%></td>
                        <td><%=current.getDepart()%></td>
                        <td><%=current.getSex() %></td>
                        <td>
                        <input type="checkbox" name="id" value=<%=current.getId()%>>
                        </td>
                        <% } %>
                        </tr><tr>
                        <td colspan="5">
                        <INPUT TYPE="BUTTON" onclick="doEdit();" VALUE="~辑">
                        <INPUT TYPE="BUTTON" onclick="showAddPage()" VALUE="增加">
                        <INPUT TYPE="BUTTON" onclick="doDelete();" VALUE="删除">
                        </td>
                        </tr>
                        </table>
                        </form>
                        </html>

<%-- studentedit.jsp --%>
                        <jsp:useBean id="table" scope="page" class="manger.bean.EditStudentBean" />
                        <%table.processRequest(pageContext);%>
                        <p>_lt;/p>
                        <form name="EditForm" action="editstudent.jsp">
                        <INPUT TYPE="hidden" NAME="event" VALUE="<%=table.getEvent()%>" >
                        <table width="75%" border="1">
                        <tr>
                        <td colspan="2">
                        <div align="center"><b>~辑学生信息</b></div>
                        </td>
                        </tr>
                        <tr>
                        <td width="40%">学号Q?lt;/td>
                        <td width="60%">
                        <input type="text" name="id" value="<%=table.getStudent().getId()%>">
                        </td>
                        </tr>
                        <%--下面的一些学生信息我们省略了--%>
                        <tr>
                        <td colspan="2">
                        <input type="submit" name="Submit" value="定">
                        </td>
                        </tr>
                        </table>
                        </form>
                        

我的x是在student.jsp中显C学生列表,从这个页面可以{到增加和~辑面Q也可以在这个页面中删除学生Q这三个功能都是由editstudent.jsp完成的。在editstudent.jsp中非常关键的一行代码就?lt;%table.processRequest(pageContext);%>Q这会调用EditStudentBeancȝprocessRequestҎQ下面是EditStudentBeancprocessRequestҎ和addStudentҎ的代?
public void processRequest (PageContext pageContext)
                        throws SQLException,ServletException,IOException{
                        this.student.setId("");
                        this.student.setName("");
                        this.student.setPassword("");
                        this.student.setDepart("");
                        this.student.setSex("");
                        HttpServletRequest request=(HttpServletRequest)pageContext.getRequest();
                        String event=request.getParameter("event");
                        //this.event=event;
                        if(event==null || event.equals("")||event.equals("showAdd"))
                        {this.event="add";
                        }
                        else if(event.equals("showEdit"))
                        {this.event="edit";
                        String id=request.getParameter("id");
                        Student stu=StudentFactory.findStudentById(id);
                        this.student=stu;
                        }
                        else if(event.equals("add"))
                        {this.addStudent(pageContext);
                        }
                        else if(event.equals("delete"))
                        {this.deleteStudent(pageContext);
                        }
                        else if(event.equals("edit"))
                        {this.editStudent(pageContext);
                        }
                        }
                        public void addStudent(PageContext page)
                        throws SQLException,ServletException,IOException{
                        HttpServletRequest request=(HttpServletRequest)page.getRequest();
                        HttpServletResponse response=(HttpServletResponse)page.getResponse();
                        JspWriter out=page.getOut();
                        String id=request.getParameter("id");
                        String name=request.getParameter("name");
                        String sex=request.getParameter("sex");
                        String pass=request.getParameter("password");
                        String depart=request.getParameter("depart");
                        if (id!=null&&name!=null&&sex!=null&&pass!=null&&depart!=null
                        &&!id.equals("")&&!name.equals("")&&!sex.equals("")&&!pass.equals("")&&!depart.equals(""))
                        {Student s=new Student();
                        s.setId(id);
                        s.setName(name);
                        s.setSex(sex);
                        s.setPassword(pass);
                        s.setDepart(depart);
                        s.save(null);
                        response.sendRedirect("student.jsp");
                        }
                        else
                        {out.print("h完所有信?);
                        }
                        }

processRequestҎ的功能主要ؓ获取提交leditstudent.jsp的event的|Ҏ不同的event调用不同的函数。例如event=addQ则调用addStudent函数?/p>

注意Q在讄Student对象的各个属性值时Q一定要按照?见上面的SQL语句)中顺序来讄Q例如在表中,id字段在name字段的前面,所以setIdҎ在setNameҎ前面Q这主要是由于TablecM的putRow函数中执行插入操作的SQL语句有缺陗在那个SQL语句中,它是按各属性在Row中的序来执行插入操作的。如q你不愿意按表中字段的顺序来讄Student的属性,可以对putRow函数更改如下Q?
String ss = "";
                        if (conditions==null) {
                        ss = "INSERT INTO "+name+'(";
                        for (int i=0;i<row.length();++i) {
                        String k = row.getKey( i );
                        ss += k;
                        if (i != row.length()-1)
                        ss += ", ";
                        }
                        ss +=") VALUES (";
                        for (int j=0; j<row.length(); ++j) {
                        String v = row.get( j );
                        ss += "'"+v+"'";
                        if (j != row.length()-1)
                        ss += ", ";
                        }
                        ss += ")";
                        }

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

MQ我改进之后的这个JDBC装器还是比较有效的Q它能满一般地需要,当然你也可以Ҏ你的情况对其q行扩充Q以更好地适应你的开发?/p>

代码在Tomcat4.01+mysql3.23.43下测试通过?/p>

关于作?/span>

 

宗锋Q男Q西北大学计机pȝ士。兴主要集中在QjavaQlinuxQenhydraQbarracuda。希望能与有共同爱好的朋友进行交。E-mail: zong_feng@263.net.



]]>一个简单的 JDBC 包装?http://www.aygfsteel.com/simie/archive/2007/07/03/127902.html和田?/dc:creator>和田?/author>Tue, 03 Jul 2007 09:16:00 GMThttp://www.aygfsteel.com/simie/archive/2007/07/03/127902.htmlhttp://www.aygfsteel.com/simie/comments/127902.htmlhttp://www.aygfsteel.com/simie/archive/2007/07/03/127902.html#Feedback0http://www.aygfsteel.com/simie/comments/commentRss/127902.htmlhttp://www.aygfsteel.com/simie/services/trackbacks/127902.html

一个简单的 JDBC 包装?/h1>

一U简单程序的快速数据访问解x?/p> developerWorks
文档选项
此作为电子邮件发?src="http://www.ibm.com/i/v14/icons/em.gif"

此作为电子邮件发?/font>

未显C需?JavaScript 的文档选项



U别: 初

Greg Travis (mito@panix.com), 自由E序?br>

2001 q?8 ?04 ?/p>

JDBC 提供了一U强大、全面的接口用来?Java E序讉K数据库。对于较的目来说Q?JDBC g是理所当然的,它一些程序员避免了一起用数据库。本文描qC一U简单的包装器库Q它让用简单的数据库易如反掌。您会发现您已经开始想在编写的每一个程序中都?JDBC?/blockquote>

事情发生得很H然。您正在修改一个程序,您原以ؓ它是个小E序Q不料竟发现它已l迅速增长成Z个庞大的东西 ?一??而现在您已到了需要保存一些数据的时候了?

问题是,您ƈ不是有意让程序发展到q种E度的?您只是不pd做了一部分修攏V您q没有真正准备要存储或装入。而且Q您的程序是?appletQ?applet 是无法存储或装入的?/p>

可以存储或装入它们吗Q?/p>

实际上,JDBC API 允许M Java E序 ?甚至?applet ?q接到关pd数据库(RDBMSQ上?不幸的是QJDBC Ҏ的小E序来说可能有一点头重脚M。毕竟,如果您希望做的只是存储一点点数据的话QRDBMS 是一个强大、复杂的pȝ?/p>

在本文中Q我们将分析一个简单的使用 JDBC 的抽象层。对于简单的应用E序来说Q它可以让您只用几行代码实现存储和装入l构化数据。它不会处理复杂?RDBMS 使用Q但那正是我们要避免的,不是吗?

JDBC 的复杂?/span>

JDBC 使用h可能是一个复杂的 API。它不仅必须支持整个强大?SQL 标准Q还必须很好地隐藏不同数据库引擎之间的区别?/p>

JDBC 的复杂还在于关系型数据库是基?SQL 构徏的,?SQL 是要lh用的Q而不是给E序用的。直接?JDBC 有点象同时用两种语言~程?/p>

虽然 JDBC 的这些方面ƈ不是什么坏事,但它们确实与我们的目??快速地存储量数据相冲H?/p>



回页?/font>


化的抽象

我们创Z个简单的抽象层,让您不必虑所有繁琐的l节问题来直接?JDBC。如果您早已熟悉 JDBC 或关pd数据库了Q那您一眼看到我们的cd表应该是很熟悉的Q?/p>

  • Database
  • Table
  • RowSet
  • Row

我们q里不是在作M实质性的事情Q我们的数据模型本质上和关系型模型是一LQ但L了烦人的l节Q同时去掉了强大的功能)。每一个类映射C个基本的 RDBMS 概念上,同时也映到一?JDBC cM。就是这U映让我们?API 可以在保持易用性的同时保留它的相关Ҏ?/p>

q种 API 的设计是ZҎ们的数据存储需要的设想。如果您发现自己的程序需要一点不同的地方Q您可以随意地改变这U抽象以适应您的情况?q些cd以被认ؓ是一U简化您工作的模式,而不是一成不变的规则?/p>

如果您不熟悉 SQL 或?RDBMS 技术,不必x?下面的四节中Q每一节都会帮助您熟悉我们的一个类Q还有这些类映射到的 RDBMS 功能?/p>

Database c?/font>

当?JDBC 与数据库建立q接Ӟ您必d?JDBC 在何处可以找到实际的数据?因ؓ不同的数据库引擎有不同的讉KҎ和描q这些方法的不同语法Q所以有不止一U方法来指定数据源??JDBC 中,l一资源标识W(Uniform Resource IdentifierQURIQ字W串是用来指定数据源的,而这个字W串的结构是依赖于数据库的?/p>

Database cȝ主要目的是装q个字符Ԍq有建立q接操作时可能需要的M用户名/密码信息?

下面是如何创Z?Database 对象的方法:

  Database db =
                        new Database( "jdbc:postgresql://localhost/mito",
                        "mito", "" );
                        

构造函数的W一个参数是数据源的 URI?在这个示例中Q我使用?PostgreSQL数据库引擎,而且在本Z讉K了一个名?mito 的数据库?另外Q我指定我的用户?mito 和一个空的密码分别作为第二个和第三个参数?

一旦您创徏?Database 对象Q您可以用它来访问数据,如我们在下一章可以看到的一栗?

Table c?/font>

我们?API 中对化的一个设惛_是,当您从表的一行读取数据时Q您会得到整行的数据。换句话_表的一行是作ؓd单独一块数据的最单位。这q不十分有效Q但效率不是我们Ҏ中所首要考虑的?/p>

Talbe c让您可以读写这些行对象。您必须做的W一步是创徏一个表对象Q它单得只要知道它的名称卛_Q?

  Table table = db.getTable( "employee" );
                        

创徏 Table 对象的操作实际上q没有做M事,只是让对象记住自q名称。要做一些实际的事,我们需要实际地使用q个 Table 对象了。在q里Q我们从表中d一行?

  Row row = table.getRow( "id=101");
                        

注意Q我们已l指定了我们只需要那?#8216;id’D定ؓ‘101’的行。通过使用 getRow() ҎQ我们假定只有一行符合这个条件。在另外的情况下Q我们可能需要多个行Q那h们就需要这样?getRows() ҎQ?

  RowSet rows = table.getRows( "id<103" );
                        

在这U情况下,q回的值是一?RowSet Q而不是一?Row?RowSet 是 Row 的一个集合?

在接下来的两节里Q我们将讨论 Row ?RowSet cR?

Row c?/font>

在我们的抽象中, Row 是在 RDBMS 中表C中一行的名称Q值对的集合。不同于 RDBMS 值可以是不同的类型, Row 仅包含一U类型,卛_W串cd?q还是ؓ了让事情单一??我们假定您不需要字W串cd提供的Q何更强大的功能?

一旦您有了一?Row Q就很容易从其中取出一个|正如我们在清?1 中看见的一栗?



L清单 1. ?Row 中获取?
  Row e = table.getRow( "id=100" );
                        String name = e.get( "name" );
                        System.out.println( "Employee name: "+name );
                        

q要注意的是 Row 是排序的Q这h可以通过索引来取出名Uͼ值的寏V清?2 中给Zq样的一个示例?



清单 2. q代整个 Row
  Row e = table.getRow( "id=100" );
                        for (int i=0; i<e.length(); ++i) {
                        String key = e.getKey( i );
                        String value = e.get( i );
                        System.out.println( key+" = "+value );
                        }
                        

当然Q您q可以改?Row 中的倹{这是在数据库中更改数据所必需??E后我们会看到这一炏V?

RowSet c?/font>

C有一些查询可以返回多?Row Q这L话您׃得到一?RowSet ?RowSet 有一点不同于Z Vector 的包装器。你可以L地P?RowSet 中所有的 Row Q在清单 3 中可以看到这一炏V?



清单 3. q代整个 RowSet
  RowSet rs = table.get( "id<104" );
                        for (int i=0; i<rs.length(); ++i) {
                        Row row = rs.get( i );
                        // do something with the row....
                        }
                        

一个完整的CZ

现在我们已经看过了所有的c,让我们来看一个完整的CZ吧。在清单 4 中,我们抽取出W合特定条g的一套记录,然后打印出它们的倹{?/p>

清单 4. 一个读取数据的完整CZ
    // First, get all rows meeting the criterion
                        RowSet rs = table.getRows( "id<103" );
                        // Iterate through the set
                        for (int i=0; i<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 );
                        }
                        

如此ҎQ在下一节中Q我们将看看怎样向数据库写入数据?/p>



回页?/font>


修改数据

正如前面所提到的,使用我们?API d数据是以整个 ?/em>为单位的。ؓ了向数据库写入数据,您必d建(或修改) Row 对象Q然后向数据库写入那?Row 对象?

向数据库写入数据是通过使用 Table 中的 putRow Ҏ。这U方法有两种变体Q?

  • public void putRow( Row row )
  • public void putRow( Row row, String conditions )

q两U变体分别对应于 SQL 中的 INSERT ?UPDATE 命o?

在第一个变体中Q写一行意味着一个全新的行插入表中?/p>

在第二个变体中,写一行意味着修改一个现有的行?conditions 参数使您能够指定您想要修改的是哪一行(哪些行)?

让我们来看看每种Ҏ的一个示例?/p>

插入一个新?/font>

插入一个新行很单,因ؓ您不必指定要修改的行Q一行或多行Q。您只是单地把行插入Q?/p>
  table.putRow( row );
                        

您可以重新创Z?Row Q如清单 5 所C?



清单 5. 重新创徏一?Row
  // Create an empty row object
                        Row row = new Row();
                        // Fill it up with data
                        row.put( "id", "200" );
                        row.put( "name", "Joey Capellino" );
                        

或者,您可以修改一个以前曾l从数据库中d的一个现有的行,如清?6 所C?/p>

清单 6. 修改现有?Row
  // Grab a row from the database
                        Row row = table.getRow( someConditions );
                        // Change some or all of the fields
                        row.put( "name", "Joey Capellino" );
                        

虽然通常是在插入旉新创?Row Q更新时使用现有?Row Q实际上您可以用M方式来进行?

更新现有的行

正如前面的部分提到的Q对于您如何 创徏用来更新?Row 是没有限制的?但是Q通常您是使用一个刚从数据库中读出的 Row ?

Z详细描述q一点,我们用一个示例(在该例子中我们读Z个员工的姓名Q,改变q个名字Q然后将更改后的l果写回数据库,如清?7 所C?/p>

清单 7. 通过修改 Row q行更新
    Row row = table.getRow( "id=104" );
                        row.put( "name", newName );
                        table.putRow( row, "id=104" );
                        

注意我们必须在调?putRow() 中指定条件。这h会调用成ؓ 更新Q而不?插入?

注意Q这个调用将更新 所?/em>W合条g的行Q而不是其中的一行?





回页?/font>


l论

在本文中Q我们初步认识了一U通过 JDBC 包提供一U简化的通往关系型数据库接口?API。这U抽象保留了 JDBC 接口的很多基本关pd功能Q但对其q行了简化,从而让使用非常地方ѝ这U简化是以效率ؓ代h的,但当目标是简单性时Q这q不是一个o人惊奇的l果?/p>

参考资?



关于作?/span>

 

Greg Travis 是居住在U约的一个自q序员。他对计机的兴可能是源于“ Bionic Woman”中的一D|?Q?Jamie 四处奔跑Q试N离一所灯光和门都被邪恶的h工智能所控制的房子,人工q通过扬声器嘲W她。他是一个传l观늚虔诚信徒 Q?如果一个计机E序能够工作Q那完全是个巧合。可以通过 mito@panix.com与他联系?



]]>Java SE 6中的JDBC 4.0增强http://www.aygfsteel.com/simie/archive/2007/07/02/127660.html和田?/dc:creator>和田?/author>Mon, 02 Jul 2007 11:39:00 GMThttp://www.aygfsteel.com/simie/archive/2007/07/02/127660.htmlhttp://www.aygfsteel.com/simie/comments/127660.htmlhttp://www.aygfsteel.com/simie/archive/2007/07/02/127660.html#Feedback0http://www.aygfsteel.com/simie/comments/commentRss/127660.htmlhttp://www.aygfsteel.com/simie/services/trackbacks/127660.htmlJava SE 6中的JDBC 4.0增强

旉Q?006-10-25
作者:Srini Penchikala
览ơ数Q? 5760
本文关键字:JDOJDBCSQLJJavaSrini Penchikalajdbcmustangjava se 6RowIDdriverannotation驱动E序注释
文章工具
推荐l朋?src="http://dev2dev.bea.com.cn/images/letter001.gif" 推荐l朋?/font>
打印文章 打印文章

   Java Platform, Standard EditionQJava SEQ版?Q代码名U?a >MustangQ现在已l推ZW二?a >beta版本Qƈ计划于今q十月䆾交付使用。Java SE 6包括几处?a >Java Database Connectivity Q?a target=_blank>JDBCQAPI的增强。这些增强将被发布ؓJDBC 4.0版本。新JDBC功能的主要目标是提供更ؓ单的设计方式和更好的开发h员体验。本文概要说明了JDBC 4.0增强Q以及它们给企业Java开发h员带来的好处。我们将借助一个用Apache Derby作ؓ后端数据库而构建的h处理CZ应用E序Q对新的JDBC功能q行探讨?/p>

Java SE 6.0

  Java SE 6.0版本的主要目标是提供兼容性、稳定性和高质量。这个版本中有几处有的增强Q尤其是在监控与理QJMXQ、Web service、脚本语a支持Q用Rhino脚本引擎JSR 223JavaScript技术与Java源代码集成在一P、数据库q接?/font>、注释支持和安全性方面。JDBC API中还增加了几个新功能Q从新的RowId支持到更多的SQLException子类?/p>

JDBC 4.0功能

  借助Mustang中包含的Java SE Service Provider机制QJava开发h员不再需要用像Class.forName()q样的代码显式地加蝲JDBC驱动E序Q就能注册JDBC驱动E序。通过在调用DriverManager.getConnection()Ҏ时自动定位合适的驱动E序QDriverManagercd以做到这一炏V这个功能是向后兼容的,所以无需修改现有的JDBC代码?/p>

   在访问关pL据库的Java应用E序中,通过最化我们需要编写的“模板”代码QJDBC 4.0q改善了开发h员体验。它q提供实用程序类Q以改进JDBC驱动E序的注册和卸蝲机制Q以及管理数据源和连接对象?/p>

   借助JDBC 4.0QJava开发h员现在可以用Annotations指定SQL查询Q从而利用Java SE 5.0Q?a >TigerQ版本中提供的元数据支持。基于注释的SQL查询允许在Java代码中用Annotation关键字指定SQL查询字符丌Ӏ这P我们׃必在两个不同文g中查看JDBC代码以及q些代码中调用的数据库查询了。例如,如果有一个叫做getActiveLoans()的方法,用于获取h处理数据库中的当前贷ƾ,可以使用@Query(sql="SELECT * FROM LoanApplicationDetails WHERE LoanStatus = 'A'")注释来修饰它?/p>

   此外QJava SE 6开发工具包QJDK 6Q的最后版本——与q行时环境(JRE 6Q相反——将会有一个基于与它绑定在一LApache Derby的数据库。这帮助开发h员理解新的JDBC功能Q而不必单独下载、安装和配置数据库品?/p>

   JDBC 4.0中加入的主要功能包括Q?/p>

  • 自动加蝲JDBC驱动E序cR?
  • q接理增强?
  • 支持RowId SQL cd?
  • 使用Annotations的DataSet SQL实现?
  • 处理增强的SQL异常?
  • 支持SQL XML?

  q存在其他功能,比如对大对象QBLOB/CLOBQ的改进支持和National Character Set Support。接下来的内容将会详l分析这些功能?/p>

自动加蝲JDBC驱动E序

  在JDBC 4.0中,调用getConnectionҎӞ不再需要用Class.forName()昑ּ地加载JDBC驱动E序Q因为DriverManager会试着从初始化时加载的以及使用与当前应用程序相同的cd载器昑ּ加蝲的JDBC驱动E序中,扑և合适的驱动E序来?/p>

   DriverManagerҎgetConnection和getDrivers已经增强为支持Java SE Service Provider机制QSPMQ。根据SPMQ服务被定义Zl众所周知的接口和抽象c,而服务提供程序则是服务的特定实现。它q指定在META-INF/services目录中保存服务提供程序配|文件。JDBC 4.0驱动E序必须包含文gMETA-INF/services/java.sql.Driver。这个文件包含JDBC驱动E序的java.sql.Driver实现的名U。例如,要加载JDBC驱动E序以连接到Apache Derby数据库,META-INF/services/java.sql.Driver文gp包含以下:

   org.apache.derby.jdbc.EmbeddedDriver

   让我们尽快了解如何用这Ҏ功能加蝲JDBC驱动E序理器。下面的列表昄了加载JDBC驱动E序通常使用的示例代码。我们假定需要连接到一个Apache Derby数据库,因ؓ我们在文章后面提到的CZ应用E序中将使用q个数据库:

 Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
Connection conn

=DriverManager.getConnection(jdbcUrl, jdbcUser, jdbcPassword);

  但是在JDBC 4.0中,我们不需要Class.forName()q一行。我们只要调用getConnection()可以获得数据库q接?/p>

   注意Q这仅适用于在单机模式中获得数据库q接。如果用某U数据库q接池来理q接Q代码将会有所区别?/p>

q接理

  在JDBC 4.0之前Q我们依赖于JDBC URL来定义数据源q接。现在有了JDBC 4.0Q我们只要提供一l参敎ͼ比如L名称和端口号Q给标准的连接工厂机Ӟp获得CQ意数据源的连接。Connection和Statement接口中加入了新的ҎQ以便在理池环境中的Statement对象时可以支持连接状态跟t改q和更大的灵zL。元数据工具Q?a >JSR-175Q用于管理活动连接。我们还可以获得元数据信息,比如zdq接的状态,q可以把q接指定为标准的QConnectionQ用于单机应用程序)、池化的QPooledConnectionQ或者甚x用于XA事务的分布式q接QXAConnectionQ。注意,我们没有直接使用XAConnection。它是由诸如WebLogic、WebSphere或JBossq样的Java EE应用服务器内部的事务理器来使用的?/p>

RowId支持

  RowID接口被添加到JDBC 4.0中以支持ROWID数据cdQOracle和DB2{数据库也支持这U数据类型。当有多条记录没有惟一标识W列Q而且需要在不允许复制的CollectionQ比如HashtableQ中保存查询输出ӞRowId很有用。我们可以用ResultSet的getRowId()Ҏ来获得RowIdQƈ使用PreparedStatement的setRowId()Ҏ在查询中使用RowId?/p>

   关于RowId对象要记住的一仉要事情是Q分别在PreparedStatement和ResultSet中用set或updateҎӞRowId对象的值无法在数据源之间移植,可以认ؓ它是特定于数据源的。所以,止在不同的Connection和ResultSet对象之间׃n它?/p>

   DatabaseMetaData中的getRowIdLifetime()Ҏ可用于确定RowId对象的生存期有效性。表1中列Zq回值或行id可能取的倹{?/p>
RowId ?/th> 描述
ROWID_UNSUPPORTED 不支持ROWID数据cd?/td>
ROWID_VALID_OTHER RowID的生存期依赖于数据库厂商实现?/td>
ROWID_VALID_TRANSACTION 只要在数据库表中行未被删除,RowID的生存期在当前的事务中?/td>
ROWID_VALID_SESSION 只要在数据库表中行未被删除,RowID的生存期在当前会话的持箋旉中?/td>
ROWID_VALID_FOREVER 只要在数据库表中行未被删除,RowID的生存期是无限的?/td>

Z注释的SQL查询

  JDBC 4.0规范利用注释QJava SE 5中加入)允许开发h员把SQL查询与Javacd联在一P同时不用~写大量的代码。此外,通过使用GenericsQ?a >JSR 014Q和元数据(JSR 175QAPIQ我们可以把SQL查询与Java对象兌在一P从而指定查询输入和输出参数。我们还可以把查询结果绑定到Javac,以加速对查询输出的处理。我们无需~写通常用于把查询结果填充到Java对象中的所有代码。在Java代码中指定SQL查询Ӟ?U主要的注释QSelect和Update?/p>

Select注释

  Select注释用于在JavacM指定选择查询Q以便用getҎ从数据库表中获取数据。表2昄了Select注释的各U属性以及它们的用法?/p>
名称 cd 描述
sql String SQL Select查询字符丌Ӏ?/td>
value String 与sql属性相同?/td>
tableName String 在其上调用sql的数据库表的名称?/td>
readOnly、connected?scrollable Boolean 标志Q分别用于指C回的DataSet是只ȝq是可更新的Q是否连接到后端数据库,在connected模式中用时是否可以滚动?/td>
allColumnsMapped Boolean 标志Q用于指Csql注释元素中的列名是否一对一地映到DataSet中的字段?/td>

  下面是Select注释的一个例子,用于从贷ƾ数据库获得所有当前贷ƾ:

interface LoanAppDetailsQuery extends BaseQuery {
@Select("SELECT * FROM LoanDetais where LoanStatus = 'A'")
DataSet<LoanApplication> getAllActiveLoans();
}

  sql注释也支持I/O参数Q参数标记由一个问号后面跟一个整数来表示Q。下面是参数化sql查询的一个例子:

interface LoanAppDetailsQuery extends BaseQuery {
@Select(sql="SELECT * from LoanDetails
where borrowerFirstName= 1 and borrowerLastName= 2")
DataSet<LoanApplication> getLoanDetailsByBorrowerName(String borrFirstName,
String borrLastName);
}

Update注释

  Update注释用于修饰Query接口ҎQ用于更新数据库表中的一条或多条记录。每个Update注释都必d含一个sql注释cd的元素。下面是Update注释的一个例子:

interface LoanAppDetailsQuery extends BaseQuery {
@Update(sql="update LoanDetails set LoanStatus = 1
where loanId = 2")
boolean updateLoanStatus(String loanStatus, int loanId);
}

处理增强的SQL异常

  异常处理是Java~程的一个重要组成部分,特别是当q接到后端关pL据库或在后端关系数据库上q行查询的时候。我们一直用SQLExceptioncL指示与数据库相关的错误?a target=_blank>JDBC 4.0在SQLException处理斚w有几处增强。下面是JDBC 4.0版本中的一些增强,在处理SQLExceptions时它们可以ؓ开发h员带来更好的体验Q?/p>

  • 新的SQLException子类
  • 支持因果关系
  • 支持增强的for-each循环

新的SQLExceptionc?

  JDBC 4.0中创ZSQLException的新子类Q以便ؓJavaE序员提供一U编写更多可UL错误处理代码的手DcJDBC 4.0中引入了2cL的SQLExceptionQ?/p>

  • SQL非瞬时异?
  • SQL瞬时异常

  非瞬时异常:同一Ҏ作重试失败时抛出此异常,直到SQLException的原因得到纠正ؓ止。表3昄了JDBC 4.0中加入的新异常类Q它们都是SQLNonTransientException的子c(SQLStatecd定义在SQL 2003规范中。)Q?/p>
异常c?/th> SQLState?/th>
SQLFeatureNotSupportedException 0A
SQLNonTransientConnectionException 08
SQLDataException 22
SQLIntegrityConstraintViolationException 23
SQLInvalidAuthorizationException 28
SQLSyntaxErrorException 42

  瞬时异常Q?/strong>当操作在没有M应用E序U功能进行干涉的情况下重试,前面p|的JDBC操作能够成功时抛出此异常。表4中列Z对SQLTransientExceptionq行扩展的新异常?/p>
异常c?/th> SQLState?/th>
SQLTransientConnectionException 08
SQLTransactionRollbackException 40
SQLTimeoutException None

因果关系

  现在QSQLExceptioncL持配备有异常机制Q也UCؓCause工具Q的Java SEQ这U机制让我们能够处理JDBC操作中抛出的多种异常Q如果后端数据库支持多异常功能)。这U场景发生在执行一条可能抛出多个SQLException的语句时?/p>

   我们可以使用SQLException中的getNextException()ҎQ通过异常链进行P代。下面给Z些用于处理SQLException因果关系的示例代码:

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();
}
}

增强的For-Each循环

  SQLExceptioncdCIterable接口QؓJava SE 5中加入的for-each循环功能提供支持。@环的D遍历SQLException及其原因。下面给Z个代码片D,对SQLException中加入的for-each循环q行了说明?/p>

catch(SQLException ex) {
for(Throwable e : ex ) {
LOG.error("Error occurred: " + e);
}
}

对国家字W集转换的支?/h3>

  下面列出了处理国家字W集QNational Character SetQ时JDBCcM所做的增强Q?/p>

  • JDBC数据cdQ加入了新的JDBC数据cdQ比如NCHAR、NVARCHAR、LONGNVARCHAR和NCLOB?
  • PreparedStatementQ加入了新方法setNString、setNCharacterStream和setNClob?
  • CallableStatementQ加入了新方法getNClob、getNString和getNCharacterStream?
  • ResultSetQ接口加入了新方法updateNClob、updateNString和updateNCharacterStream?

对大对象QBLOB和CLOBQ的增强支持

  下面列出了JDBC 4.0中对处理LOB所做的增强Q?/p>

  • ConnectionQ加入了新方法(createBlob()、createClob()和createNClob()Q以创徏BLOB、CLOB和NCLOB对象的新实例?
  • PreparedStatementQ加入了新方法setBlob()、setClob()和setNClob()Q以便用InputStream对象插入BLOB对象Q以及用Reader对象插入CLOB和NCLOB对象?
  • LOBQBlob、Clob和NClob接口中加入了新方法(free()Q,以便释放q些对象占用的资源?

  现在Q让我们看一看java.sql和javax.jdbc包中加入的一些新c,以及它们提供了哪些服务?/p>

JDBC 4.0 APIQ新c?/h3>

RowId (java.sql)

  正如前面提过的那Pq个接口代表着数据库中的一个SQL ROWID倹{ROWID是一个内|的SQL数据cdQ用于识别数据库表中的特定数据行。ROWID通常用在q样的查询中Q该查询从输没有惟一ID列的表中q回行?/p>

   CallableStatement、PreparedStatement和ResultSet接口中的ҎQ比如getRowId和setRowIdQ允许程序员讉KSQL ROWID倹{接口还提供一个方法(叫做getBytes()Q把ROWID的D回ؓ字节数组。DatabaseMetaData接口有一个叫做getRowIdLifetime的新ҎQ可用于定RowId对象的生存期。RowId的作用域可以是下?U类型之一Q?/p>

  • 在其中创建RowId的数据库事务的持l时间?
  • 在其中创建RowId的会话的持箋旉?
  • 数据库表中的标识行,只要它尚未被删除?

DataSet (java.sql)

  DataSet接口Z执行SQL查询q回的数据提供类型安全的视图。DataSet可以在已q接或未q接模式中进行操作。当在已q接模式中用时Q其功能cM于ResultSet。而在未连接模式中使用ӞDataSet的功能则cM于CachedRowSet。因为DataSet扩展了List接口Q我们可以遍历查询返回的行?/p>

   现有的类中还加入了几个新ҎQ比如ConnectionQcreateSQLXML、isValidQ和ResultSetQgetRowIdQ?/p>

CZ应用E序

  本文中用的CZ应用E序是一个贷Ƒ֤理应用程序,它包含一个贷ƾ查N面,用户可以在这个页面上输入一个贷ƾID以获得有兌Ƅ详细信息Q然后提交表单。贷ƾ查N面调用一个控制器对象Q而此控制器对象又调用DAO对象来访问后端数据库Q从而获得有兌Ƅ详细信息。这些详l信息包括借款人姓名、贷N额和h到期旉Q它们均会显C在一个贷ƾ详l信息页面上。在后端数据库中Q我们用一个叫做LoanApplicationDetails的表来保存贷Ƒֺ用程序的详细信息?/p>

   CZ应用E序的用例是获得特定hID的贷ƾ详l信息。在注册hqҎg品和利率锁定它之后,可以获得这些贷ƾ详l信息了。贷Ƒ֤理应用程序的目l节如表5所C?/p>
名称 ?/th>
Project Name JdbcApp
Project Directory c:\dev\projects\JdbcApp
DB Directory c:\dev\dbservers\apache\derby
JDK Directory c:\dev\java\jdk_1.6.0
IDE Directory c:\dev\tools\eclipse
Database Apache Derby 10.1.2.1
JDK 6.0 (beta 2 release)
IDE Eclipse 3.1
Unit Testing JUnit 4
Build Ant 1.6.5

  下表列出了连接贷ƾ详l信息Apache Derby数据库时需要用到的JDBC参数。这些参数都保存在一个叫?em>derby.properties的文本文件中Q该文g位于目基目录下?em>etc/jdbc目录中(参见?Q?/p>
名称 ?/th>
JDBC Driver File LoanApp\META-INF\services\java.sql.driver
Driver org.apache.derby.ClientDriver
URL jdbc:derby:derbyDB
User Id user1
Password user1

  注意QApache Derby数据库提?cJDBC驱动E序QEmbedded DriverQorg.apache.derby.jdbc.EmbeddedDriverQ和Client/Server DriverQorg.apache.derby.jdbc.ClientDriverQ。在CZ应用E序中我使用的是Client/Server Driver版本?/p>

   下面l出用于启动Derby数据库服务器和用ij工具创徏新数据库的命令?/p>

   要启动Derby Network ServerQ打开一个命令提C,然后q行以下命oQ修改DERBY_INSTALL和JAVA_HOME环境变量Q从而媄响本地环境)?/p>

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

  要连接到数据库服务器和创建测试数据库Q打开另一个命令提C,然后q行以下命o。确保修改了DERBY_INSTALL和JAVA_HOME环境变量Q以适应环境?/p>

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';

  用于~译Java源代码的classpath讄应该包含位于目ȝ录下lib目录中的derby.jar?em>junit4.jar文g。我们还需要在classpath中包?em>etc?em>etc/jdbc?em>etc/log4j目录Q这样应用程序就能访问JDBC属性和Log4J配置文g。我创徏了一个Ant~译脚本Q位?em>JdbcApp/build目录中)Q以自动化编译和打包Java代码的Q务?/p>

   用于试h详细信息数据讉K对象的测试类叫做LoanAppDetailsDAOTest。我们传入参敎ͼ比如hID和借款人姓名)以获得贷ƾ详l信息?/p>

   下面的内容给Z一些代码示例,q些代码是关于JDBC 4.0规范的JDBC驱动E序自动加蝲和给予注释的SQL查询功能的?/p>

自动加蝲JDBC驱动E序

  BaseDAO抽象cL一个叫做getConnection的方法,用于获得一个数据库q接。下面的代码片段昄了这个方法(注意Q我们不必注册JDBC驱动E序Q。只?em>java.sql.Driver文g中存在正的驱动E序名称Qorg.apache.derby.jdbc.ClientDriverQ,可以自动加载JDBC驱动E序?/p>

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;
}

SQL注释

  LoanAppDetailsQuery接口有带有注释的SQL查询Q用于获得当前贷ƾ(条g是loanstatus="A"Q的列表和基于贷ƾh姓名的贷ƾ详l信息(在一个贷ƾh借贷多笔N的情况下Q。我们在本文的前面部分曾见过q些SQL注释。下面给出的CZ代码说明了如何调用用Annotation定义的SQL查询?/p>

public DataSet<LoanAppDetails> getAllActiveLoans() throws Exception {
// Get Connection
Connection conn = getConnection();
LoanAppDetailsQuery query = null;
DataSet<LoanAppDetails> loanDetails = null;
query = QueryObjectFactory.createQueryObject(
LoanAppDetailsQuery.class, conn);
loanDetails = query.getAllActiveLoans();
return loanDetails;
}
public DataSet<LoanAppDetails> getLoanDetailsByBorrowerName(
String borrFirstName, String borrLastName) throws Exception {
// Get Connection
Connection conn = getConnection();
LoanAppDetailsQuery query = null;
DataSet<LoanAppDetails> loanDetails = null;
query = QueryObjectFactory.createQueryObject(
LoanAppDetailsQuery.class, conn);
loanDetails = query.getLoanDetailsByBorrowerName(
borrFirstName,borrLastName);
return loanDetails;
}

l束?/h3>

  在用SQLӞJDBC 4.0可以提供开发的便性ƈ改善开发h员体验。JDBC 4.0的另一个目标是提供企业U的JDBC功能Q把API公开l涵盖范围更q的工具集,以便更好地管理JDBC资源。此外,JDBC 4.0 API为JDBC驱动E序提供了一条迁U\径,从而与J2EE Connector架构QJCAQ保持兼宏V这使得JDBC厂商能够l箋实现JDBC技术Connector API。当在企业面向服务架构QService Oriented ArchitectureQSOAQ应用程序中使用JDBC数据源时Q这一点很重要Q因为在企业USOA应用E序中,可以把JDBC数据源部|ؓ企业服务ȝQEnterprise Service BusQESBQ架构中的另一个适配器,而不必ؓJDBC数据源编写ESB特定实现代码?/p>

   在本文中Q我们讨ZJDBC 4.0中的增强Q比如RowId支持、JDBC驱动E序加蝲和基于Annotations的SQL。JDBC 4.0中还加入其他功能,以便在未来支持SQL 2003规范。要了解有关JDBC 4.0规范的更多信息,请参?a >规范文档?/p>

参考资?/h3>
 作者简?/span>
Srini Penchikala 是一位在Flagstar银行工作的信息系l学U问题专家?/td>


]]>数据库连接池+JavaBean+JSP+SQL Server+JDBC3.0的数据库分页技?/title><link>http://www.aygfsteel.com/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.aygfsteel.com/simie/archive/2007/07/02/127656.html</guid><wfw:comment>http://www.aygfsteel.com/simie/comments/127656.html</wfw:comment><comments>http://www.aygfsteel.com/simie/archive/2007/07/02/127656.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/simie/comments/commentRss/127656.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/simie/services/trackbacks/127656.html</trackback:ping><description><![CDATA[<pre>主要特色Q? 1.使用最新的JDBC3.0数据库驱动? 2.大幅度减化了JSP的反复调用JavaBean,可以直接写SQL,无须再用连接数据库q接池? 3.大量的工作交给JavaBean?JSP负责面控制? 4.最大特色是极其?E序~写也极其简?非常适合初学者? 5.使用的是tomcat数据库连接池,方便快速? h供E_mail,为大家分享,如有高手Q请指点不是? 本hE_mailQc841@163.com,望多提意见? ****************************************文g名《page.jsp?****************************************************************** 文g名《page.jsp? <%@ page language="java" import="java.sql.*, my.*" %> <%@ page contentType="text/html; charset=gb2312" %> <jsp:useBean id="pagi" scope="page" class="my.Pagi"/> <html> <body> <table align="center" border=1> <% String CountQuery="select count(*) from 商品资料"; String query = "select * from 商品资料"; ResultSet rs = pagi.querySql(CountQuery,query, request); String footer = pagi.PageFooter(); %> <tr> <td >商品~号</font></td> <td >商品名称</font></td> </tr> <% if (pagi.intPageCount>0) { int i=0; while (rs.next()) { i++; if (i>((pagi.intPage-1)*pagi.intPageSize) &&(i<=pagi.intPage*pagi.intPageSize)) { %> <tr> <td><%=rs.getString(1)%></td> <td><%=rs.getString(2)%></td> </tr> <% } } } out.println("<tr><td colspan=2>"+footer+"</td></tr>"); rs.close(); pagi.close_all(); %> </table> </body> </html> ****************************************文g名《pagi.java?******************************************************** 文g名《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; //主题L public int intPageSize;//每页昄主题? public int intPageCount;//总页? public int intPage=1; //当前| public String nowPage; // int i; public String HttpFile;//初始化当前页intPage变量Q以准确便获取当前页?//当前的地址栏的文g DB db; //定义Linkdbcȝ一个对象? public Pagi()//定义构造器Q初始化每页昄的主题数和数据库的连接? { intPageSize=4; //每页昄的记录数? db = new DB(); } //Countsql:总记录的Query字符丌Ӏ[形式为select count(*) from tablename] //Pagisql :要分늚Query字符丌Ӏ[形式为select * from tablename where ...] //request :参数传递过E中的变量。[用来控制页时的pages变量] public ResultSet querySql(String Countsql,String Pagisql,HttpServletRequest request)throws Exception { HttpFile=request.getRequestURI(); //获取当前文g名? nowPage=request.getParameter("pages"); //获取当前,数D予intPage变量。[分页栏中必须要有pages参数] if (nowPage==null) { intPage=1; } else { intPage=Integer.parseInt(nowPage); if (intPage<1) intPage=1; } CountTopicrs=db.executeQuery(Countsql); //@@@@@@@@@@@@获取总记录数的结果集? if (CountTopicrs.next()) { intCountTopic=CountTopicrs.getInt(1); } intPageCount = (intCountTopic+intPageSize-1)/intPageSize; //获取总页数? if (intPage>intPageCount)//如果当前大于总页敎ͼ则当前页{于总页数? { intPage=intPageCount; } CountTopicrs.close(); //关闭M题数的数据集? db.close_all(); Pagirs=db.executeQuery(Pagisql); //@@@@@@@@@@@@@@@获取执行分页的结果集? return Pagirs; }//end querySql function. public int getCountTopic()//获取记录L? { 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>"+getCountTopic()+"</font>条记?+ " ?lt;font color=red>"+getPageCount()+"</font>?; str +=" W?lt;font color=red>"+getIntPage()+"</font>?"; if(intPage>1) str += " <A href=" + HttpFile + "?pages=1"+">首页</A> "; else str += " 首页 "; if(intPage>1) str += " <A href=" + HttpFile + "?pages=" + prev + ">上一?lt;/A> "; else str += " 上一?"; if(intPage<intPageCount) str += " <A href=" + HttpFile + "?pages=" + next + ">下一?lt;/A> "; else str += " 下一?"; if(intPageCount>1&&intPage!=intPageCount) str += " <A href=" + HttpFile + "?pages=" + intPageCount + ">N</A>"; else str += " N "; return str; } public void close_all() { db.close_all(); } } ************************************************文g名《DB.java?******************************************************* 文g名《DB.java? package my; import java.sql.*; import javax.naming.*; import javax.sql.DataSource; //一个用于查找数据源的工L? 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中的数据库连接池的设|?******************************************************************************* …… …… …… <Context path="/SQL" docBase="D:\SQL_JSP" debug="0" reloadable="true" crossContext="true"> <Resource name="jdbc/bn" auth="Container" type="javax.sql.DataSource"/> <ResourceParams name="jdbc/bn"> <parameter> <name>factory</name> <value>org.apache.commons.dbcp.BasicDataSourceFactory</value> </parameter> <parameter> <name>driverClassName</name> <value>com.microsoft.jdbc.sqlserver.SQLServerDriver</value> </parameter> <parameter> <name>url</name> <value>jdbc:microsoft:sqlserver://127.0.0.1:1433;DatabaseName=jspdev</value> </parameter> <parameter> <name>username</name> <value>cyg</value> </parameter> <parameter> <name>password</name> <value>325345353</value> </parameter> <parameter> <name>maxActive</name> <value>20</value> </parameter> <parameter> <name>maxIdle</name> <value>20</value> </parameter> <parameter> <name>maxWait</name> <value>-1</value> </parameter> </ResourceParams> </Context> </Host> </Engine> </Service> </Server> </pre> <img src ="http://www.aygfsteel.com/simie/aggbug/127656.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/simie/" target="_blank">和田?/a> 2007-07-02 19:23 <a href="http://www.aygfsteel.com/simie/archive/2007/07/02/127656.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>各种数据库的JDBC驱动下蝲及连接字W串URL写法http://www.aygfsteel.com/simie/archive/2007/07/01/127366.html和田?/dc:creator>和田?/author>Sun, 01 Jul 2007 08:09:00 GMThttp://www.aygfsteel.com/simie/archive/2007/07/01/127366.htmlhttp://www.aygfsteel.com/simie/comments/127366.htmlhttp://www.aygfsteel.com/simie/archive/2007/07/01/127366.html#Feedback1http://www.aygfsteel.com/simie/comments/commentRss/127366.htmlhttp://www.aygfsteel.com/simie/services/trackbacks/127366.html 各种数据库的JDBC驱动下蝲及连接字W串URL写法

sun官方|站上的JDBC驱动列表Q?/strong>http://java.sun.com/products/jdbc/reference/industrysupport/index.html

?nbsp;?nbsp;?/font>  ?nbsp;     ?/font> 
MySQL  http://www.mysql.com/products/connector/j/ Shipped. But need to download the latest for MySQL 4.1 or higher. 
Oracle  http://www.oracle.com/technology/software/tech/java/sqlj_jdbc/index.html Included. 
SQL Server by jTDS  http://sourceforge.net/project/showfiles.php?group_id=33291 Included. Support Microsoft SQL Server (6.5, 7, 2000 and 2005) 
Postgres  http://jdbc.postgresql.org/download.html Included 7.3 JDBC 3 
SAP DB  http://www.sapdb.org/sap_db_jdbc.htm Included. 
SyBase by jTDS  http://jtds.sourceforge.net/ Included. Support Sybase (10, 11, 12) 


以下内容来自互联|?br>
1. MySQL(http://www.mysql.com) mysql-connector-java-2.0.14-bin.jar ;
  Class.forName( "org.gjt.mm.mysql.Driver" );
  cn = DriverManager.getConnection( "jdbc:mysql://MyDbComputerNameOrIP:3306/myDatabaseName", sUsr, sPwd ); 
2. PostgreSQL(http://www.de.postgresql.org) pgjdbc2.jar ;
  Class.forName( "org.postgresql.Driver" ); 
  cn = DriverManager.getConnection( "jdbc:postgresql://MyDbComputerNameOrIP/myDatabaseName", sUsr, sPwd ); 
3. Oracle(http://www.oracle.com/ip/deploy/database/oracle9i/) classes12.zip ;
  Class.forName( "oracle.jdbc.driver.OracleDriver" ); 
  cn = DriverManager.getConnection( "jdbc:oracle:thin:@MyDbComputerNameOrIP:1521:ORCL", sUsr, sPwd ); 
4. Sybase(http://jtds.sourceforge.net) jconn2.jar ;
  Class.forName( "com.sybase.jdbc2.jdbc.SybDriver" ); 
  cn = DriverManager.getConnection( "jdbc:sybase:Tds:MyDbComputerNameOrIP:2638", sUsr, sPwd ); 
  //(Default-Username/Password: "dba"/"sql") 
5. Microsoft SQLServer(http://jtds.sourceforge.net) ;
  Class.forName( "net.sourceforge.jtds.jdbc.Driver" ); 
  cn = DriverManager.getConnection( "jdbc:jtds:sqlserver://MyDbComputerNameOrIP:1433/master", sUsr, sPwd ); 
6. Microsoft SQLServer(http://www.microsoft.com) ;
  Class.forName( "com.microsoft.jdbc.sqlserver.SQLServerDriver" ); 
  cn = DriverManager.getConnection( "jdbc:microsoft:sqlserver://MyDbComputerNameOrIP:1433;databaseName=master", sUsr, sPwd ); 
7. ODBC 
  Class.forName( "sun.jdbc.odbc.JdbcOdbcDriver" ); 
  Connection cn = DriverManager.getConnection( "jdbc:odbc:" + sDsn, sUsr, sPwd ); 
8.DB2 Class.forName("com.ibm.db2.jdbc.net.DB2Driver"); 
  String url="jdbc:db2://192.9.200.108:6789/SAMPLE" 
  cn = DriverManager.getConnection( url, sUsr, sPwd ); 
9.access׃accessq不是作ZҎ务运行,所以url的方法对他不适用。access可以通过odbcQ也可以通过服务器映\径的形式扑ֈ.mdb文g,参见http://rmijdbc.objectweb.org/Access/access.html
JDBC API的用方?/font>
(1)登记q加载JDBC驱动E序Q?br>两种ҎQ?br>Class.forName(String drivername);
DriverManager.registerDriver(Driver driver)
(2)建立与SQL数据库的q接Q?br>DriverManager的getConnection()ҎQ?br>Connection getConnection(String url):url表示数据库地址字符Ԍ
Connection getConnection(String url,String user,String pwd)
Connection getConnection(String url,Properties info)
(3)传送一个SQL查询Q?br>Connection的createStatement()ҎQ?br>Statement createStatement();
Statement可以执行SQL语句Q得到SQL查询l果?/div>
(4)获得l果集?br>Statement的执行SQL语句ҎQ?br>ResultSet executeQuery(String sql):执行select语句
int executeUpdate(String sql)Q执行更新语句,如insert,delete,update.
(5)索查询结果?br>ResultSet的方法:
boolean next():没有行时q回false;
String getString(String columnName)Q返回列名对应的倹{?/div>

]]> վ֩ģ壺 ̨| | ν| ʲ| | ˫| | ԣ| | | º| | | Ҷ| ¡| | ȫ| ƽ| | ʡ| | | | ͭ| ĺ| ϴ| ٽ| | | | | | | | ͩ| կ| | Դ| | ƺ| |