zoukankan      html  css  js  c++  java
  • 数据库程序接口——JDBC——API解读第三篇——处理结果集的核心对象

    核心对象                                                  

          处理结果集的核心对象有ResultSet和RowSet。其中ResultSet指定关系型数据库的结果集,RowSet更为抽象,凡是由行列组成的数据都可以。

    ResultSet    

          ResultSet对象的主要作用是获取数据库中的查询结果。它主要由三部分组成,查询结果与结果集对象的关系,结果集对象的类型,结果集对象的操作。

    关系

          每个结果集与查询结果一一对应的关系,结果集包含查询结果中的全部列,但只包含查询结果中的某些行。如果查询结果是跨表的,那么结果集也是跨表的,这种类型的结果集无法进行更新,插入操作。

          要获取结果集中的对象,如果了解查询结果的列名称以及该列的数据类型,可以通过名称来获取数据的值,如果了解查询结果中列的顺序以及每列对应的数据类型,可以通过索引来获取数据的值。 如果不了解查询结果的结构,可以通过获取ResultSetMetaData对象来获取查询结果中的相关信息。

    ResultSetMetaData

     ResultSetMetaData包含查询结果的相关信息,大体可以分为四类。

    数据库

    // 一个catalog包含多个schema,一个schema包含多张table,查询结果集可以来自多张表
    System.out.println("查询结果第" + i + "列的Catalog名称:" + rsMetaData.getCatalogName(i));
    System.out.println("查询结果第" + i + "列的shcema名称:" + rsMetaData.getSchemaName(i));
    System.out.println("查询结果第" + i + "列的table名称:" + rsMetaData.getTableName(i));

    列的信息

    // 列信息,获取列的名称,类型
    System.out.println("查询结果第" + i + "列名:" + rsMetaData.getColumnName(i));
    System.out.println("查询结果第" + i + "列label:" + rsMetaData.getColumnLabel(i));
    System.out.println("查询结果第" + i + "列的type名称:" + rsMetaData.getColumnType(i));
    System.out.println("查询结果第" + i + "列的数据库数据类型:" + rsMetaData.getColumnTypeName(i));
    System.out.println(
            "查询结果第" + i + "列的columnDisplaySize:" + rsMetaData.getColumnDisplaySize(i));
    System.out.println("查询结果第" + i + "列对应的java数据类型:" + rsMetaData.getColumnClassName(i));

    列的特性

    // 列的特性,例如是否为null.
    System.out.println("查询结果第" + i + "列是否允许空值:" + rsMetaData.isNullable(i));
    System.out.println("查询结果第" + i + "列是否为货币:" + booleanToStr(rsMetaData.isCurrency(i)));
    System.out.println(
        "查询结果第" + i + "列是否是自增列:" + booleanToStr(rsMetaData.isAutoIncrement(i)));
    System.out.println(
        "查询结果第" + i + "列是否是大小写敏感:" + booleanToStr(rsMetaData.isCaseSensitive(i)));

    权限

    // 列的权限
    System.out.println(
            "查询结果第" + i + "列是否拥有写权限:" + booleanToStr(rsMetaData.isDefinitelyWritable(i)));
    System.out.println("查询结果第" + i + "列是否只读权限:" + booleanToStr(rsMetaData.isReadOnly(i)));
    System.out.println("查询结果第" + i + "列是否允许搜索:" + booleanToStr(rsMetaData.isSearchable(i)));

    类型

    结果集的类型可以通过设置其同步方式,遍历方式,关闭方式来指定。

    /**
     * 打印结果集类型相关信息,设置结果集类型信息是在创建Statement相关对象时指定。ResultSet本身并没有这些方法
     * 输出结果需要参考Java API Constant Field Values
     * @param rs
     * @throws SQLException
     */
    public static void printResultTypeInfo(ResultSet rs) throws SQLException {
        System.out.println("-------------------结果集的类型相关信息-------------------");
        System.out.println("结果集的遍历类型:" + rs.getType());
        System.out.println("结果集的同步类型:" + rs.getConcurrency());
        System.out.println("结果集的关闭方式:" + rs.getHoldability());
    }

     同步方式

    1. CONCUR_READONLY:结果集是只读的,只能进行遍历操作。用户读数据时会获取read锁,这也是默认的方式
    2. CONCUR_UPDATABLE:结果集是可以更新的,用户读取数据时会获取read-write锁,当对数据库进行插入,更新,删除操作时,存在两种锁机制,悲观锁和乐观锁。悲观锁只允许单个用户访问数据,只有当前用户释放锁之后,其他用户才可以进行访问。乐观锁允许多个用户同时对数据进行访问,当发生冲突时,会回滚之后造成冲突的事务,以此来保证数据的完整性。

    遍历方式

    1. FORWARD_ONLY:只能从前往后遍历1
    2. TYPE_SCROLL_SENSITIVE:结果集是可滚动的,可以从前到后,也可以从后到前遍历,也可以指定从任意的位置开始遍历,但是结果集中的数据在创建时已经指定,如果查询结果发生改变,结果集中的数据不会感应改变。
    3. TYPE_SCROLL_INSENSITIVE:结果集是可以滚动的,遍历方式是任意的,查询结果发生改变时,结果集中会包含新的查询结果。

     关闭方式

    1. CLOSE_CURSORS_AT_COMMIT:当事务提交时,会关闭结果集对象
    2. HOLD_CURSORS_OVER_COMMIT:当事务提交时,不会关闭结果集对象。

    操作

     遍历

          结果集遍历的方式有四种,从前到后,从后到前,指定绝对位置,相对位置。默认的结果集是FORWARD_ONLY类型,只能从前到后遍历,其他遍历方式需要将结果集设置为TYPE_SCROLL_SENSITIVE或TYPE_SCROLL_INSENSITIVE。

    从前到后

    /**
     * 遍历结果集对象从前到后
     * 
     * @param rs
     * @throws SQLException
     */
    private static void printTopToBottom(ResultSet rs) throws SQLException {
        rs.beforeFirst();
        while (rs.next()) {
            System.out.print("学生的姓名为:" + rs.getString(1) + "	");
            System.out.print("学生的学号为:" + rs.getInt(2) + "	");
            System.out.print("学生的班级为: " + rs.getString(3) + "	");
            System.out.print("学生的课程为:" + rs.getString(4) + "	");
            System.out.println("学生的生日为:" + rs.getDate(5) + "	");
        }
    }

    从后到前

    /**
     * 遍历结果集对象,从后到前
     * 
     * @param rs
     * @throws SQLException
     */
    private static void printBottomToTop(ResultSet rs) throws SQLException {
        rs.afterLast();
        while (rs.previous()) {
            System.out.print("学生的姓名为:" + rs.getString(1) + "	");
            System.out.print("学生的学号为:" + rs.getInt(2) + "	");
            System.out.print("学生的班级为: " + rs.getString(3) + "	");
            System.out.print("学生的课程为:" + rs.getString(4) + "	");
            System.out.println("学生的生日为:" + rs.getDate(5) + "	");
        }
    }

    绝对位置

    /**
     * 遍历结果集,使用绝对方式
     * 
     * @param rs
     * @param pos 从第几行开始,起始值为1
     * @throws SQLException
     */
    private static void printByAbsolutePos(ResultSet rs, int pos) throws SQLException {
        rs.absolute(pos);
        while (rs.next()) {
            System.out.print("学生的姓名为:" + rs.getString(1) + "	");
            System.out.print("学生的学号为:" + rs.getInt(2) + "	");
            System.out.print("学生的班级为: " + rs.getString(3) + "	");
            System.out.print("学生的课程为:" + rs.getString(4) + "	");
            System.out.println("学生的生日为:" + rs.getDate(5) + "	");
        }
    }

    相对位置

    /**
     * 遍历结果集,使用相对位置
     * 
     * @param rs
     * @param pos
     * @throws SQLException
     */
    private static void printByRelativePos(ResultSet rs, int pos) throws SQLException {
        // 指定到最后一行
        rs.last();
        // 结果集条数
        int total = rs.getRow();
        // 指定到第一行
        rs.beforeFirst();
        while (rs.next()) {
            // 判断当前行从前或从后移动pos位置后没有超过越界
            if (rs.getRow() + pos < total) {
                rs.relative(pos);
            }
            System.out.print("学生的姓名为:" + rs.getString(1) + "	");
            System.out.print("学生的学号为:" + rs.getInt(2) + "	");
            System.out.print("学生的班级为: " + rs.getString(3) + "	");
            System.out.print("学生的课程为:" + rs.getString(4) + "	");
            System.out.println("学生的生日为:" + rs.getDate(5) + "	");
        }
    }

    更新

    结果集更新数据同步到数据库中需要如下前提条件:

    1. 结果集的类型为CONCUR_UPDATEABLE。
    2. 结果集包含的数据是单张表中的数据
    3. 结果集对应的查询语句不能包含join,group by 和* 号
    4. 结果集中包含主键字段
    /**
     * 结果集中更新数据,同步到数据库当中。
     * 前提条件:
     * 1.结果集类型为CONCUR_UPDATABLE
     * 2.结果集中的对象是单表,
     * 3.结果集对应的查询不包含join和group by 语句,不能包含*号
     * 4.结果集中包含主键字段
     * 
     * @param rs
     * @throws SQLException 
     */
    public static void updateData(ResultSet rs) throws SQLException
    {
        // 演示更新最后一条数据
        rs.last();
        // 更新姓名
        rs.updateString(1, "更新之后的名称");
        // 更新学号
        rs.updateInt(2, 500);
        // 更新班级
        rs.updateString(3, "更新之后的班级");
        // 更新课程
        rs.updateString(4, "更新之后的课程");
        // 更新生日
        rs.updateDate(5, new Date(2017, 11, 12));
        // 更新结果集和数据库
        rs.updateRow();
    }

    插入

    结果集插入数据除了需要满足更新时的条件外,还需要满足如下条件

    1. 用户对该表拥有权限
    2. 结果集包含所有插入时不为null值的列
    /**
     * 结果集插入数据,同步到数据库当中。
     * 在更新操作的前提下,还有额外的要求
     * 1.用户对该表有读写的权限
     * 2.结果集中包含所有不允许非空的列
    * @param rs
     * @throws SQLException 
     */
    public static void insertData(ResultSet rs) throws SQLException
    {
        // 准备插入一条数据
        rs.moveToInsertRow();
        // 插入姓名
        rs.updateString(1, "插入的名称");
        // 插入学号
        rs.updateInt(2, 501);
        // 插入班级
        rs.updateString(3, "插入的班级");
        // 插入课程
        rs.updateString(4, "插入的课程");
        // 插入生日
        rs.updateDate(5,new Date(2017,11,12));
        // 插入数据,因为达到了最大条数限制,所以结果集中不包含刚插入的数据,但是从数据库中可以查询得到
        rs.insertRow();
    }

    删除

    /**
     * 结果集中删除某一行
     * @param rs
     * @throws SQLException
     */
    public static void deleteData(ResultSet rs) throws SQLException
    {
        // 删除结果集
        rs.last();
        rs.deleteRow();
    }

    ROWSET

    TODO

  • 相关阅读:
    oracle中add_months()函数总结
    Oracle总结之plsql编程(基础九)
    Oracle总结之plsql编程(基础八)
    java调用存储过程
    Oracle总结之plsql编程(基础七)
    Python 變量 Variable 動態綁定
    Python 類和對象 Class vs Object
    Python 元組 Tuple
    Python 字典 Dictionary
    Python 列表 List
  • 原文地址:https://www.cnblogs.com/rain144576/p/6979519.html
Copyright © 2011-2022 走看看