zoukankan      html  css  js  c++  java
  • JDBC Update操作返回值和Insert操作返回主键

    JDBC Update操作返回值

    在操作数据库时,update操作会返回数据库更新行数,但是在JDBC默认情况下则不会返回数据库更新行数,这一点有所不同,在实际操作中可能会出现意想不到的结果。在使用ORM框架时,例如Mybatis、Hibernate时由于其底层同样使用JDBC API,所以同样会出现上诉问题。

    JDBC API

    首先,我们看一下JDBC API中是对update操作返回值得定义,主要涉及要Statement.executeUpdate()和PreparedStatement.executeUpdate()两个操作,其返回值定义一样:

    either (1) the row count for SQL Data Manipulation Language (DML) statements or (2) 0 for SQL statements that return nothing
    

    也就是说DDL语句返回值为0,而DML语句返回值只是说返回Row Count,而没有说返回Affect Count。

    JDBC Update操作的几个例子

    我们来编写几个例子,实际来看看JDBC Update的返回值。注:这里使用的是Mysq数据库进行测试:

    JDBC Connection Properties:

    driver=com.mysql.jdbc.Driver
    url=jdbc:mysql://120.55.59.65:3306/study_jdbc?characterEncoding=utf8
    username=root
    password=********
    

    JDBC DDL:

    Connection connection = DriverUtils.getConnection();
    String sql1 = "DROP TABLE IF EXISTS `update_return_value`;";
    String Sql2 = " CREATE TABLE `update_return_value`"
        + "(`id` bigint(20) PRIMARY KEY NOT NULL AUTO_INCREMENT, `name` varchar(255))"
        + "ENGINE=InnoDB AUTO_INCREMENT=1;";
    PreparedStatement preparedStatement = connection.prepareStatement(sql1);
    preparedStatement.executeUpdate();
    PreparedStatement statement = connection.prepareStatement(Sql2);
    int updateValue = statement.executeUpdate();
    System.out.println("Update Return Value: " + updateValue);
    

    控制台输出:Update Return Value: 0

    JDBC Insert:

    Connection connection = DriverUtils.getConnection();
    String sql = "INSERT INTO update_return_value(name) VALUES (?)";
    PreparedStatement preparedStatement = connection.prepareStatement(sql);
    preparedStatement.setString(1, "2222");
    int updateValue = preparedStatement.executeUpdate();
    System.out.println("Update Return Value: " + updateValue);
    

    控制台输出:Update Return Value: 1

    JDBC正确的Update操作,注意这里,我们重复执行2次:

    Connection connection = DriverUtils.getConnection();
    String sql = "UPDATE update_return_value SET name = ? WHERE id = ?";
    PreparedStatement preparedStatement = connection.prepareStatement(sql);
    preparedStatement.setString(1, "11111");
    preparedStatement.setLong(2, 1L);
    int updateValue = preparedStatement.executeUpdate();
    System.out.println("Update Return Value: " + updateValue);
    

    控制台输出:Update Return Value: 1 /n Update Return Value: 1

    JDBC不正确的Update操作:

    Connection connection = DriverUtils.getConnection();
    String sql = "UPDATE update_return_value SET name = ? WHERE id = ?";
    PreparedStatement preparedStatement = connection.prepareStatement(sql);
    preparedStatement.setString(1, "11111");
    preparedStatement.setLong(2, 2L);
    int updateValue = preparedStatement.executeUpdate();
    System.out.println("Update Return Value: " + updateValue);
    

    控制台输出:Update Return Value: 0

    从上面我们可以看出,出乎意料的是在正确update更新操作执行2次结果都是1,如果是返回值是行影响数目则第二次应该为0,因为第二次更新时数据库并没有变化。然后我们把JDBC Properties中的url变为一下,然后重新执行就会出现第二次更新返回值为0

    driver=com.mysql.jdbc.Driver
    url=jdbc:mysql://120.55.59.65:3306/study_jdbc?characterEncoding=utf8&useAffectedRows=true
    username=root
    password=*********
    

    总结

    JDBC Update操作DML语句默认情况下返回Rows-Matches数目,而不是Rows-Affect数目,可以在url中加入userAffectedRows=true 则会返回Rows-Affect数目

    JDBC Insert操作返回主键

    JDBC通过创建PreparedStatement时指定返回主键,然后通过getGenerateKeys()方法进行查询返回主键。注:这里主键必须是Auto Increment

    大多数数据库返回主键方式,例如Mysql

    Connection connection = DriverUtils.getConnection();
    String sql = "INSERT INTO insert_return_key(name) VALUES (?)";
    PreparedStatement preparedStatement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
    preparedStatement.setString(1, "3333");
    preparedStatement.executeUpdate();
    ResultSet generatedKeys = preparedStatement.getGeneratedKeys();
    while (generatedKeys.next()) {
        long generateKey = generatedKeys.getLong(1);
    }
    

    Oracle方式返回主键,当然也可以用于mysql等数据库

    由于Oracle生成主键的方式比较特别,所以上面的方式并不适用于Oracle

    Connection connection = DriverUtils.getConnection();
    String sql = "INSERT INTO insert_return_key(name) VALUES (?)";
    String[] keysName = {"id"};
    PreparedStatement preparedStatement = connection.prepareStatement(sql, keysName);
    preparedStatement.setString(1, "3333");
    preparedStatement.executeUpdate();
    ResultSet generatedKeys = preparedStatement.getGeneratedKeys();
    while (generatedKeys.next()) {
          long generateKey = generatedKeys.getLong(1);
    }
    
  • 相关阅读:
    如何阅读论文
    我的算法学习之路
    blazor wasm访问非本地的restful service
    ionic + asp.net core webapi + keycloak实现前后端用户认证和自动生成客户端代码
    在ef core中使用postgres数据库的全文检索功能实战之中文支持
    在ef core中使用postgres数据库的全文检索功能实战
    .net core grpc单元测试
    asp.net core + entity framework core 多数据库类型支持实战
    asp.net core计划任务探索之hangfire+redis+cluster
    Keycloak & Asp.net core webapi 整合跳坑之旅
  • 原文地址:https://www.cnblogs.com/maying3010/p/8714836.html
Copyright © 2011-2022 走看看