JDBC Update操做返回值和Insert操做返回主键

JDBC Update操做返回值

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

JDBC API

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

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。sql

JDBC Update操做的几个例子

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

JDBC Connection Properties:api

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

JDBC DDL:oracle

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: 1url

JDBC正确的Update操做,注意这里,咱们重复执行2次:code

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);
}
相关文章
相关标签/搜索