当前位置: 首页 > wzjs >正文

网站建设开发语言360网站收录提交

网站建设开发语言,360网站收录提交,辽宁建设工程信息网官网新网站如何进入,网站开发岗位实际情况JDBC 获取新增行主键值详解 在数据库操作中,获取新插入行的主键值是一个常见需求。以下是几种常用方法及其实现细节: 一、标准 JDBC 方法 1. 使用 Statement.RETURN_GENERATED_KEYS try (Connection conn dataSource.getConnection();PreparedStatement…

JDBC 获取新增行主键值详解

在数据库操作中,获取新插入行的主键值是一个常见需求。以下是几种常用方法及其实现细节:

一、标准 JDBC 方法

1. 使用 Statement.RETURN_GENERATED_KEYS

try (Connection conn = dataSource.getConnection();PreparedStatement pstmt = conn.prepareStatement("INSERT INTO users (username, email) VALUES (?, ?)", Statement.RETURN_GENERATED_KEYS)) {pstmt.setString(1, "john_doe");pstmt.setString(2, "john@example.com");int affectedRows = pstmt.executeUpdate();if (affectedRows > 0) {try (ResultSet generatedKeys = pstmt.getGeneratedKeys()) {if (generatedKeys.next()) {long userId = generatedKeys.getLong(1);System.out.println("新用户ID: " + userId);}}}
}

2. 指定需要返回的主键列名

// 明确指定需要返回的主键列
String[] keyColumns = {"id"};
try (PreparedStatement pstmt = conn.prepareStatement("INSERT INTO orders (customer_id, total) VALUES (?, ?)", keyColumns)) {pstmt.setInt(1, 1001);pstmt.setBigDecimal(2, new BigDecimal("99.99"));pstmt.executeUpdate();try (ResultSet keys = pstmt.getGeneratedKeys()) {if (keys.next()) {long orderId = keys.getLong(1);}}
}

二、数据库特定方法

1. MySQL (使用 LAST_INSERT_ID())

try (Statement stmt = conn.createStatement()) {stmt.executeUpdate("INSERT INTO products (name, price) VALUES ('Laptop', 1200.00)");try (ResultSet rs = stmt.executeQuery("SELECT LAST_INSERT_ID()")) {if (rs.next()) {long productId = rs.getLong(1);}}
}

2. PostgreSQL (使用 RETURNING 子句)

try (PreparedStatement pstmt = conn.prepareStatement("INSERT INTO employees (name, position) VALUES (?, ?) RETURNING id")) {pstmt.setString(1, "Alice Smith");pstmt.setString(2, "Developer");try (ResultSet rs = pstmt.executeQuery()) {if (rs.next()) {long empId = rs.getLong("id");}}
}

3. SQL Server (使用 OUTPUT 子句)

try (PreparedStatement pstmt = conn.prepareStatement("INSERT INTO invoices (customer_id, amount) OUTPUT INSERTED.id VALUES (?, ?)")) {pstmt.setInt(1, 2001);pstmt.setBigDecimal(2, new BigDecimal("499.95"));try (ResultSet rs = pstmt.executeQuery()) {if (rs.next()) {long invoiceId = rs.getLong("id");}}
}

4. Oracle (使用 RETURNING INTO)

try (CallableStatement cstmt = conn.prepareCall("DECLARE new_id NUMBER; " +"BEGIN " +"  INSERT INTO departments (name) VALUES (?) " +"  RETURNING id INTO new_id; " +"  ? := new_id; " +"END;")) {cstmt.setString(1, "Engineering");cstmt.registerOutParameter(2, Types.NUMERIC);cstmt.execute();long deptId = cstmt.getLong(2);
}

三、跨数据库兼容方案

public Long insertAndGetKey(String sql, Object... params) throws SQLException {try (Connection conn = dataSource.getConnection();PreparedStatement pstmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {for (int i = 0; i < params.length; i++) {pstmt.setObject(i + 1, params[i]);}int affectedRows = pstmt.executeUpdate();if (affectedRows == 0) {throw new SQLException("插入失败,无记录受影响");}try (ResultSet generatedKeys = pstmt.getGeneratedKeys()) {if (generatedKeys.next()) {return generatedKeys.getLong(1);} else {throw new SQLException("插入失败,未获取到主键");}}}
}// 使用示例
Long newId = insertAndGetKey("INSERT INTO customers (name, email) VALUES (?, ?)", "Bob Johnson", "bob@example.com");

四、最佳实践与注意事项

1. 事务管理

conn.setAutoCommit(false);
try {Long newId = insertAndGetKey(...);// 使用新ID进行后续操作insertRelatedRecords(newId);conn.commit();
} catch (SQLException e) {conn.rollback();throw e;
}

2. 处理复合主键

try (ResultSet keys = pstmt.getGeneratedKeys()) {if (keys.next()) {long id1 = keys.getLong(1);String id2 = keys.getString(2);// 处理复合主键}
}

3. 性能优化

  • 使用批量插入时获取主键:
pstmt.addBatch();
// 添加多个批次...
int[] counts = pstmt.executeBatch();try (ResultSet keys = pstmt.getGeneratedKeys()) {List<Long> generatedIds = new ArrayList<>();while (keys.next()) {generatedIds.add(keys.getLong(1));}
}

4. 常见问题解决

问题: 返回多个结果集
解决: 确保只插入一行或处理多个键

try (ResultSet keys = pstmt.getGeneratedKeys()) {while (keys.next()) {System.out.println("生成ID: " + keys.getLong(1));}
}

问题: 获取非自增主键
解决: 使用数据库特定函数或序列

// Oracle序列示例
PreparedStatement pstmt = conn.prepareStatement("INSERT INTO items (id, name) VALUES (item_seq.NEXTVAL, ?)");

五、各数据库驱动支持情况

数据库标准方法支持推荐方法注意事项
MySQLRETURN_GENERATED_KEYS需要InnoDB引擎
PostgreSQLRETURNING子句更高效
OracleRETURNING INTO必须使用CallableStatement
SQL ServerOUTPUT子句兼容性好
SQLitelast_insert_rowid()使用SELECT last_insert_rowid()
DB2IDENTITY_VAL_LOCAL()需在插入后单独查询

六、完整示例(跨数据库)

public class KeyGenerator {private final DataSource dataSource;public KeyGenerator(DataSource dataSource) {this.dataSource = dataSource;}public long insertUser(String username, String email) throws SQLException {String sql = "INSERT INTO users (username, email) VALUES (?, ?)";try (Connection conn = dataSource.getConnection();PreparedStatement pstmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {pstmt.setString(1, username);pstmt.setString(2, email);int affectedRows = pstmt.executeUpdate();if (affectedRows == 0) {throw new SQLException("创建用户失败");}try (ResultSet generatedKeys = pstmt.getGeneratedKeys()) {if (generatedKeys.next()) {return generatedKeys.getLong(1);} else {// 回退到数据库特定方法return fallbackGetKey(conn, "users", "id");}}}}private long fallbackGetKey(Connection conn, String table, String pkColumn) throws SQLException {String database = conn.getMetaData().getDatabaseProductName();String query = "";switch (database) {case "MySQL":query = "SELECT LAST_INSERT_ID()";break;case "PostgreSQL":query = "SELECT lastval()";break;case "Microsoft SQL Server":query = "SELECT SCOPE_IDENTITY()";break;case "Oracle":// Oracle需要更复杂的处理throw new SQLException("Oracle需要显式使用序列");default:query = "SELECT MAX(" + pkColumn + ") FROM " + table;}try (Statement stmt = conn.createStatement();ResultSet rs = stmt.executeQuery(query)) {if (rs.next()) {return rs.getLong(1);}}throw new SQLException("无法获取生成的主键");}
}

总结

获取新增行主键值的最佳实践:

  1. 优先使用标准JDBC方法Statement.RETURN_GENERATED_KEYS
  2. 对于复杂场景:使用数据库特定语法(如RETURNING, OUTPUT
  3. 事务管理:确保获取主键操作在同一个事务中
  4. 错误处理:总是检查返回结果和受影响行数
  5. 兼容性考虑:为不同数据库提供后备方案

通过合理选择方法,您可以高效可靠地获取新插入行的主键值,为后续的关联操作提供基础。

http://www.dtcms.com/wzjs/469384.html

相关文章:

  • 做问卷调查哪个网站好福州关键词排名软件
  • 最专业的网站建设seo优化服务公司企业策划咨询公司
  • web网站开发环境淘宝怎么提高关键词搜索排名
  • 自己 做网站站长工具排名查询
  • 一级a做爰精免费网站制作一个网站步骤
  • 创世网站建设 优帮云百度商家入驻怎么做
  • baidu网站建设做个网站
  • 免费网站建设3602024年1月新冠高峰
  • 什么平台可以做网站浙江企业seo推广
  • 做一个手机网站多少钱网上国网推广
  • 东莞企业网站价格企业网站优化外包
  • 有哪些做婚品的网站泰州seo外包
  • 太原本地网站如何做游戏推广
  • 视频网站开发 价格百度官网首页登录入口
  • 专业的营销型网站建设百度问答怎么赚钱
  • java做网站教程免费开源网站
  • 做推广的网站微信号百度资源搜索平台官网
  • 供应邢台wap网站建设网络营销有什么岗位
  • 福田皇岗社区网站建设国内推广平台有哪些
  • 网站开发要会英语吗品牌推广与传播方案
  • 东莞企业网站建设制作如何让百度搜索到自己的网站
  • 厦门官方网站建设关键词云图
  • 公司网站如何注册上海高端网站定制
  • 开通网站的会计科目怎么做宁德市人力资源和社会保障局
  • 通州城乡建设委房管局官方网站谷歌关键词排名查询工具
  • 自己做的相册网站百度关键词快速排名
  • 深圳宝安区深圳网站建设 骏域网络怎么做公司网页
  • 网站开发总体功能设计杭州网络
  • iis添加网站建设中中国国家培训网官网入口
  • 做网站可以用海外空间吗济源网络推广