核心对象

处理结果集的核心对象有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) + "\t");
System.out.print("学生的学号为:" + rs.getInt(2) + "\t");
System.out.print("学生的班级为: " + rs.getString(3) + "\t");
System.out.print("学生的课程为:" + rs.getString(4) + "\t");
System.out.println("学生的生日为:" + rs.getDate(5) + "\t");
}
}

从后到前

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

绝对位置

/**
* 遍历结果集,使用绝对方式
*
* @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) + "\t");
System.out.print("学生的学号为:" + rs.getInt(2) + "\t");
System.out.print("学生的班级为: " + rs.getString(3) + "\t");
System.out.print("学生的课程为:" + rs.getString(4) + "\t");
System.out.println("学生的生日为:" + rs.getDate(5) + "\t");
}
}

相对位置

/**
* 遍历结果集,使用相对位置
*
* @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) + "\t");
System.out.print("学生的学号为:" + rs.getInt(2) + "\t");
System.out.print("学生的班级为: " + rs.getString(3) + "\t");
System.out.print("学生的课程为:" + rs.getString(4) + "\t");
System.out.println("学生的生日为:" + rs.getDate(5) + "\t");
}
}

更新

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

  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

数据库程序接口——JDBC——API解读第三篇——处理结果集的核心对象的更多相关文章

  1. 数据库程序接口——JDBC——API解读第一篇——建立连接的核心对象

    结构图 核心对象 Driver Java通过Driver接口表示驱动,每种类型的数据库通过实现Driver接口提供自己的Driver实现类. Driver由属性,操作,事件三部分组成. 属性 公共属性 ...

  2. 数据库程序接口——JDBC——API解读第二篇——执行SQL的核心对象

    结构图 核心对象 Statement Statement主要用来执行SQL语句.它执行SQL语句的步骤为: 第一步:创建statement对象. 第二步:配置statement对象,此步骤可以忽略. ...

  3. 数据库程序接口——JDBC——初篇——目录

    目录 建立连接 核心对象 Driver DriverManager Connection DataSource 常用功能 第一个程序 C3P0数据源 DBCP数据源 事务之Spring事务 执行SQL ...

  4. 数据库程序接口——JDBC——功能第四篇——事务之Spring事务

    综述 事务的实现方式有三种,JTA,Spring事务,Web Container方式.本篇讲述Spring事务. Spring事务分为两个部分核心对象,Spring事务的实现方式. Spring事务实 ...

  5. 数据库程序接口——JDBC——功能第一篇——第一个程序

    流程图 综述 从零开始搭建JDBC环境.通过创建Java项目,在项目中,通过java程序执行SQL,并处理返回的结果.本文通过执行 select 1 from dual 语句来测试,并输出相结果集.首 ...

  6. 数据库程序接口——JDBC——功能第二篇——数据源之C3P0数据源

    综述 C3P0由三部分内容组成.实例化对象,各配置项的含义,以及加载配置项的方式. 实例化对象的方式有三种,第一种方式直接new ComboPooledDataSource,第二种方式使用工厂类Dat ...

  7. 数据库程序接口——JDBC——功能第五篇——批量处理

    综述 批量处理一般指批量插入,批量更新,删除通过可以指定where条件实现.批量插入的实现方式有三种类型.statement,preparedStatement,callableStatement. ...

  8. 深入理解javascript选择器API系列第三篇——h5新增的3种selector方法

    × 目录 [1]方法 [2]非实时 [3]缺陷 前面的话 尽管DOM作为API已经非常完善了,但是为了实现更多的功能,DOM仍然进行了扩展,其中一个重要的扩展就是对选择器API的扩展.人们对jQuer ...

  9. 深入理解javascript选择器API系列第三篇——HTML5新增的3种selector方法

    前面的话 尽管DOM作为API已经非常完善了,但是为了实现更多的功能,DOM仍然进行了扩展,其中一个重要的扩展就是对选择器API的扩展.人们对jQuery的称赞,很多是由于jQuery方便的元素选择器 ...

随机推荐

  1. caffe+win10+git使用sh文件

    在windows下是否可以执行sh文件呢,搜了一下,可以安装了git就可以执行,当然这不是唯一答案. 然后联想到caffe下有一些.sh文件可以尝试,就用create_mnist.sh尝试把. cre ...

  2. Apache服务:使用 Apache 服务部署静态网站

    1.安装Apache服务 第一步:安装Apache服务程序   yum install httpd 具体流程参考https://www.cnblogs.com/python-wen/p/1016845 ...

  3. B站学习记:贪心与博弈

    贪心 1. poj2287 N匹马的田忌赛马问题 稳稳地赢. 寻找最优的方案. 更优的收益. 有时候,局部最优导致全局最优. 马的能力值. 使得让我赢的局数最多. 对于对方的任何一匹马,如果我的马能打 ...

  4. Oracle11g配置监听

    步骤 1.在windows系统上安装好Oracle后,点击右下角开始菜单Oracle目录下选择Net Manager进行配置,也可以使用Net Configuration Assistant(建议使用 ...

  5. MAC MAMP集成环境安装 PHP 扩展

    MAC MAMP集成环境安装 PHP扩展 开发环境中,对于需要维护很多 WEB 站点,以及可能会使用到很多不同的 PHP 版本,集成环境比较好用,在MAC 上 MAMP 集成环境是比较好用的,但是在安 ...

  6. blob - 二进制文件流下载

    /** * 返回值文件类型为 blob 二进制流文件 * responseType: 'blob' * params 接口所需参数 * 命名文件名:依据时间戳命名文件名 * (导出时需要延迟,否则导出 ...

  7. 0004 继承django系统用户表

    1 创建基础模型 在本项目中,所有表都有两个自动产生的完全相同的字段,即创建时间和更新时间,因此,可以创建一个基础模型,让所有的表都来继承这个模型. 找到工程目录下的PublicMethod目录,创建 ...

  8. loadrunner11破解失败,已解决“ license security violation.Operation is not allowed ”问题

    参考链接https://blog.csdn.net/yongrong/article/details/7891738,亲测可以解决问题 在64位win7系统中安装LR11时,采用普通的方法无法授权.最 ...

  9. [P3806] 【模板】点分治 - 点分治

    辣鸡蒟蒻怎么今天才来敲这个模板题 好像还敲了很久的样子 (大雾) #include <bits/stdc++.h> using namespace std; #define int lon ...

  10. [CF705B] Spider Man - 博弈论

    [CF705B] Description ICG 游戏有若干个环,每次操作将一个环断成非空的两部分,节点数总和不变.集合初态为空,每次向集合中添加一个环,询问当前集合用于游戏的胜负. \(n \le ...