Java JDBC 4

作者: 毛小力 | 来源:发表于2019-02-01 14:25 被阅读0次

    ResultSet

    表示数据库查询结果的数据表。

    ResultSet对象有一个光标指向当前数据行。最初,光标位于第一行之前,next方法将光标移动到下一行,没有更多行(最后一行之后)时返回false。

    默认,光标只能向前移动,只能从第一行移动到最后一行,且只能遍历一次。可以生成可滚动的ResultSet。

    ResultSet提供getter方法,通过列号(1起,更高效)或列名(不区分大小写),从当前行获取列值。为可移植性,最好按从左到右的顺序获取列值,且每列只读取一次。

    1. ResultSet属性
    // ResultSetType
    // 返回:
    //     ResultSet.TYPE_FORWARD_ONLY(默认,1003):光标只能向前
    //     ResultSet.TYPE_SCROLL_INSENSITIVE(1004):光标可滚动,对底层数据变化不敏感
    //     ResultSet.TYPE_SCROLL_SENSITIVE(1005):光标可滚动,对底层数据变化敏感
    int getType();
    
    // ResultSetConcurrency
    // 返回:
    //     ResultSet.CONCUR_READ_ONLY(默认,1007):只读
    //     ResultSet.CONCUR_UPDATABLE(1008):可更新
    int getConcurrency();
    
    // ResultSetHoldability
    // 返回:
    //     ResultSet.HOLD_CURSORS_OVER_COMMIT(1):当前事务提交后ResultSet仍打开
    //     ResultSet.CLOSE_CURSORS_AT_COMMIT(2):当前事务提交后ResultSet关闭
    int int getHoldability();
    
    // 光标移动方向
    // 返回:
    //     ResultSet.FETCH_FORWARD(默认,1000)
    //     ResultSet.FETCH_REVERSE(1001)
    //     ResultSet.FETCH_UNKNOWN(1002)
    int getFetchDirection();
    void setFetchDirection(int direction);
    
    // 一次读取的行数,0表示忽略
    int getFetchSize();
    void setFetchSize(int rows);
    
    1. 操作光标
    // 移动到下一行
    // 返回:是否指向有效行
    boolean next();
    // 移动到上一行
    // 返回:是否指向有效行
    boolean previous();
    
    // 移动到第一行之前
    void beforeFirst();
    // 移动到最后一行之后
    void afterLast();
    // 是否在第一行之前
    boolean isBeforeFirst();
    // 是否在最后一行之后
    boolean isAfterLast();
    
    // 移动到第一行
    // 返回:是否指向有效行
    boolean first();
    // 移动到最后一行
    // 返回:是否指向有效行
    boolean last();
    // 是否在第一行
    boolean isFirst();
    // 是否在最后一行
    boolean isLast();
    
    // 当前行号,1起
    int getRow();
    // 移动到第row行
    boolean absolute(int row);
    // rows正:向前移动rows行,等同rows次next(),到最后一行之后为止
    // rows负:向后移动|rows|行,等同|rows|此previous(),到第一行之前为止
    boolean relative(int rows);
    
    1. 获取列信息
    ResultSetMetaData getMetaData();
    

    ResultSetMetaData:

    // 列数
    int getColumnCount();
    
    // 列名,AS之前
    // column,1起
    String getColumnName(int column);
    // 列标,AS之后
    // 若没有使用AS则与列名相同
    String getColumnLabel(int column);
    
    // 列类型,见java.sql.Types
    int getColumnType(int column);
    // 列类型名
    String getColumnTypeName(int column);
    // 列类型映射的Java类型
    String getColumnClassName(int column);
    
    // 自增列
    boolean isAutoIncrement(int column);
    

    实例:

    Connection connection = DriverManager.getConnection(url);
    Statement statement = connection.createStatement();
    String sql = "select *, id as userId from user";
    ResultSet resultSet = statement.executeQuery(sql);
    
    ResultSetMetaData metaData = resultSet.getMetaData();
    int columnCount = metaData.getColumnCount();
    System.out.println("列数:" + columnCount);
    for (int i = 1; i <= columnCount; i++) {
        String label = metaData.getColumnLabel(i);
        String name = metaData.getColumnName(i);
        int type = metaData.getColumnType(i);
        String typeName = metaData.getColumnTypeName(i);
        String className = metaData.getColumnClassName(i);
        boolean isAutoIncrement = metaData.isAutoIncrement(i);
        System.out.println(label + ", " + name + ", " + type + ", " + typeName + ", " + className + ", " + isAutoIncrement);
    }
    
    resultSet.close();
    statement.close();
    connection.close();
    
    
    1. 获取列值
    // 通过列号获取列值
    String getString(int columnIndex);
    boolean getBoolean(int columnIndex);
    ...
    
    // 通过列名获取列值
    String getString(String columnLabel);
    boolean getBoolean(String columnLabel);
    ...
    
    // 列名对应的列号
    int findColumn(String columnLabel);
    

    实例:

    private static Consumer<ResultSet> getRowValue = rs -> {
        try {
            long userId = rs.getLong("id");
            String userName = rs.getString("userName");
            String nickName = rs.getString("nickName");
            Timestamp timestamp = rs.getTimestamp("dbUpdateTime");
            System.out.println(userId + " " + userName + " " + nickName + " " + timestamp);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    };
    
    Connection connection = DriverManager.getConnection(url);
    Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
    String sql = "select *, id as userId from user";
    ResultSet resultSet = statement.executeQuery(sql);
    
    while (resultSet.next()) {
        getRowValue.accept(resultSet);
    }
    System.out.println("isAfterLast: " + resultSet.isAfterLast());
    
    while (resultSet.previous()) {
        getRowValue.accept(resultSet);
    }
    System.out.println("isBeforeFirst: " + resultSet.isBeforeFirst());
    
    if (resultSet.absolute(1)) {
        getRowValue.accept(resultSet);
    }
    System.out.println("currentRow: " + resultSet.getRow());
    
    resultSet.close();
    statement.close();
    connection.close();
    
    
    1. 关闭
    // 是否已关闭
    boolean isClosed();
    void close();
    
    1. 感知更新
    // 当前行是否被更新
    // SQLFeatureNotSupportedException:不支持该方法
    // DatabaseMetaData.updatesAreDetected():查看是否支持
    boolean rowUpdated();
    
    // DatabaseMetaData.insertsAreDetected():查看是否支持
    boolean rowInserted();
    
    // DatabaseMetaData.deletesAreDetected():查看是否支持
    boolean rowDeleted();
    
    // 从DB更新当前行
    void refreshRow();
    
    1. 更新

    有两种方式进行更新:

    1. 更新行
      rs.absolute(5); // 移动到指定行
      rs.updateString("NAME", "AINSWORTH"); // 更新列值
      rs.updateRow(); // 更新行

    2. 插入行
      rs.moveToInsertRow(); // 移动到插入行(构建要插入的行的暂存区)
      rs.updateString(1, "AINSWORTH"); // 设置列值
      rs.insertRow(); // 插入行
      rs.moveToCurrentRow(); // 返回到插入前的数据行

    // 移动到插入行
    void moveToInsertRow();
    
    // 设置当前行列值
    void updateString(int columnIndex, String x);
    void updateBoolean(int columnIndex, boolean x);
    ...
    // 取消当前行列值的设置
    void cancelRowUpdates();
    
    // 将插入行更新到DB
    void insertRow();
    // 返回到插入前的数据行
    void moveToCurrentRow();
    
    // 更新当前行到DB
    void updateRow();
    
    // 删除当前行到DB
    void deleteRow();
    

    实例:

    Connection connection = DriverManager.getConnection(url);
    Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
    String sql = "select *, id as userId from user";
    ResultSet resultSet = statement.executeQuery(sql);
    
    resultSet.moveToInsertRow();
    resultSet.updateString("userName", "lmztest@163.com");
    resultSet.updateString("nickName", "测试插入");
    resultSet.updateInt("status", 0);
    resultSet.updateLong("createTime", System.currentTimeMillis());
    resultSet.updateLong("updateTime", System.currentTimeMillis());
    resultSet.insertRow();
    
    ThreadUtil.sleepSeconds(10);
    
    while (resultSet.next()) {
        String userName = resultSet.getString("userName");
        if (userName.endsWith("lmztest@163.com")) {
            System.out.println("CurrentRow: " + resultSet.getRow());
            break;
        }
    }
    
    resultSet.updateInt("status", 3);
    resultSet.updateRow();
    
    ThreadUtil.sleepSeconds(10);
    
    resultSet.deleteRow();
    
    resultSet.close();
    statement.close();
    connection.close();
    
    
    1. 流式读取(一次一行):MySQL
    • ResultSetType: TYPE_FORWARD_ONLY
    • ResultSetConcurrency: CONCUR_READ_ONLY
    • FetchSize: Integer.MIN_VALUE
    Connection connection = DriverManager.getConnection(MYSQL_URL);
    Statement statement = connection.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
    statement.setFetchSize(Integer.MIN_VALUE);
    //
    // resultSet.rowData为类RowDataDynamic
    ResultSet resultSet = statement.executeQuery("select * from user order by id");
    while (resultSet.next()) {
        getRowValue.accept(resultSet);
    }
    
    resultSet.close();
    statement.close();
    connection.close();
    
    1. 游标读取(一次多行):MySQL
    • useCursorFetch: true
    • ResultSetType: TYPE_FORWARD_ONLY
    • FetchSize: 大于0
    Properties properties = new Properties();
    properties.setProperty("useCursorFetch", "true");
    Connection connection = DriverManager.getConnection(MYSQL_URL, properties);
    Statement statement = connection.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
    statement.setFetchSize(5);
    
    // resultSet.rowData为类RowDataCursor
    ResultSet resultSet = statement.executeQuery("select * from user order by id");
    while (resultSet.next()) {
        getRowValue.accept(resultSet);
    }
    resultSet.close();
    statement.close();
    connection.close();
    

    相关文章

      网友评论

        本文标题:Java JDBC 4

        本文链接:https://www.haomeiwen.com/subject/roirsqtx.html