日期:2014-05-16  浏览次数:20476 次

Inside JDBC(三)


??? ??? 在上一篇Inside JDBC(二)中,介绍了Connection接口的功能,以及DatabaseMetaData接口。本篇主要介绍
SQL语句对象及结果集。
??? ??? 数据库连接建立好之后,我们就可以与数据库进行交互了,这种交互主要体现为执行各种SQL语句。SQL
语句的执行需要Statement对象来完成。为了讲述SQL语句对象的具体用法,先给大家介绍结果集(ResultSet)
??? ??? 结果集由java.sql.ResultSet接口定义,接口起到定义规范(标准)的作用,就是说任何JDBC驱动都需要
实现ResultSet接口,提供封装查询结果的功能,从而符合JDBC规范。在Connector/J中,实现ResultSet接口的
类是com.mysql.jdbc.ResultSetImpl类。
??? ??? 我们可以简单把结果集理解成执行Select语句之后符合条件的数据从数据库传输到内存中形成的一张内存
数据表,此表具有表头、列索引、行索引以及定位用的行指示器。行、列索引都是从1开始计数行指示器停留
在当前行,但是对于刚刚产生的结果集,行指示器停留在第一行之前。那么如何来移动行指示器呢?大家肯定
能猜到了ResultSet定义了用于移动行指示器的方法,但是别急,移动行指示器是有前提的,就是要看结果集的
类型。结果集类型的指定用以下代码:

Statement stmt = con.createStatement(
                                      ResultSet.TYPE_SCROLL_INSENSITIVE,
                                      ResultSet.CONCUR_UPDATABLE);
    ResultSet rs = stmt.executeQuery("SELECT a, b FROM TABLE2");
?

这里只关心ResultSet内部定义的几个静态常量,其他的稍后会说明,
ResultSet.TYPE_SCROLL_INSENSITIVE
说明结果集的行指示器可向前、向后移动,甚至绝对定位;同时此结果集忽略其他数据库事务对数据库中在当前
结果集中已选定数据的更新。
ResultSet.TYPE_FORWARD_ONLY
说明结果集的行指示器只可向前移动,直到结束。
ResultSet.TYPE_SCROLL_SENSITIVE
说明结果集的行指示器可向前、向后移动,甚至绝对定位;同时此结果集显示其他数据库事务对数据库中在当前
结果集中已选定数据的更新。
ResultSet.CONCUR_UPDATABLE
说明结果集是可更新的,并使对应数据库中数据更新。
ResultSet.CONCUR_READ_ONLY???????
说明结果集是不可可更新的,不能使用对结果集数据的更新来更新数据库中数据。
ResultSet.CLOSE_CURSORS_AT_COMMIT
说明使用Connection.commit()提交事务时,结果集关闭。
ResultSet.HOLD_CURSORS_OVER_COMMIT
说明使用Connection.commit()提交事务时,结果集保留。

??? ??? 接下来看一个具体的实例,已知MySQL的test数据库中有一表(station)数据如下:
+-----------+----------+---------+---------+---------+-----------+
| stationId | trainNum | station | outTime | dayTime | sitePrice |
+-----------+----------+---------+---------+---------+-----------+
|???????? 1 | k339???? | 北京??? | 12:37?? |?????? 1 |????? 0.00 |
|???????? 2 | k339???? | 秦皇岛? | 17:06?? |?????? 1 |???? 44.00 |
|???????? 3 | k339???? | 沈阳??? | 22:30?? |?????? 1 |???? 99.00 |
|???????? 4 | k339???? | 哈尔滨? | 04:37?? |?????? 2 |??? 154.00 |
+-----------+----------+---------+---------+---------+-----------+
字段定义如下:(此处只用于演示,不考虑表设计是否优良)
+-----------+--------------+------+-----+---------+----------------+
| Field???? | Type???????? | Null | Key | Default | Extra????????? |
+-----------+--------------+------+-----+---------+----------------+
| stationId | int(11)????? | NO?? | PRI | NULL??? | auto_increment |
| trainNum? | varchar(20)? | NO?? |???? | NULL??? |??????????????? |
| station?? | varchar(20)? | NO?? |???? | NULL??? |??????????????? |
| outTime?? | varchar(5)?? | NO?? |???? | NULL??? |??????????????? |
| dayTime?? | int(11)????? | NO?? |???? | NULL??? |??????????????? |
| sitePrice | decimal(6,2) | YES? |???? | NULL??? |??????????????? |
+-----------+--------------+------+-----+---------+----------------+

代码如下:

package com.wwei.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class ResultSetType {

    public static void main(String[] args) {
        Connection con = getConnection();
        String sql = "select stationId,trainNum,station,outTime,dayTime,sitePrice from station where trainNum='k339'";
        if(con != null){
            handleData(getData(sql, con));
            releaseConnection(con);
        }
    }

    private static Connection getConnection() {
        try {
            Class.forName("com.mysql.jdbc.Driver");
            return DriverManager.getConnection("jdbc:mysql://localhost/test",
                    "root", "wwei");
        } catch (ClassNotFoundException e) {
            System.err.println("类路径中没有MySQL驱动jar库文件");
        } catch (SQLException e) {