JDBC编程规范:PreparedStatement与事务管理

PreparedStatement的使用规范

使用PreparedStatement替代Statement能有效防止SQL注入攻击,提高执行效率。创建PreparedStatement时应使用参数化查询:

java 复制代码
String sql = "SELECT * FROM users WHERE username = ? AND password = ?";
PreparedStatement pstmt = connection.prepareStatement(sql);
pstmt.setString(1, username);
pstmt.setString(2, password);
ResultSet rs = pstmt.executeQuery();

参数索引从1开始,必须为每个参数设置合适的类型(setInt/setString等)。执行后必须关闭资源:

java 复制代码
try (PreparedStatement pstmt = connection.prepareStatement(sql)) {
    // 设置参数并执行
} catch (SQLException e) {
    // 异常处理
}

批处理操作优化

对于批量数据操作,应使用addBatch()和executeBatch()方法:

java 复制代码
PreparedStatement pstmt = connection.prepareStatement("INSERT INTO logs VALUES(?, ?)");
for (Log log : logList) {
    pstmt.setString(1, log.getId());
    pstmt.setTimestamp(2, log.getTime());
    pstmt.addBatch();
}
int[] results = pstmt.executeBatch();

批处理大小建议控制在100-1000条之间,过大的批处理可能导致内存问题。

事务管理基本模式

JDBC事务应遵循ACID原则,默认自动提交需关闭:

java 复制代码
connection.setAutoCommit(false);
try {
    // 执行多个SQL操作
    connection.commit();
} catch (SQLException e) {
    connection.rollback();
} finally {
    connection.setAutoCommit(true);
}

事务隔离级别应根据业务需求设置:

modelscope.cn/learn/70890

modelscope.cn/learn/70889

modelscope.cn/learn/70886

modelscope.cn/learn/70885

modelscope.cn/learn/70882

modelscope.cn/learn/70880

modelscope.cn/learn/70878

modelscope.cn/learn/70876

modelscope.cn/learn/70875

modelscope.cn/learn/70872

modelscope.cn/learn/70870

modelscope.cn/learn/70868

modelscope.cn/learn/70867

modelscope.cn/learn/70864

modelscope.cn/learn/70863

modelscope.cn/learn/70860

modelscope.cn/learn/70859

modelscope.cn/learn/70856

modelscope.cn/learn/70855

modelscope.cn/learn/70852

java 复制代码
connection.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);

事务超时设置

为防止长时间运行的事务,应设置超时时间:

java 复制代码
int timeoutSeconds = 30;
connection.setNetworkTimeout(executor, timeoutSeconds * 1000);

对于分布式系统,需考虑XA事务或使用JTA实现。

连接池与事务关联

从连接池获取连接时,必须确保事务结束后重置连接状态:

java 复制代码
try (Connection conn = dataSource.getConnection()) {
    conn.setAutoCommit(false);
    // 业务操作
    conn.commit();
} catch (Exception e) {
    // 异常时自动回滚
}

连接必须在使用后立即关闭,避免连接泄漏。

异常处理规范

捕获SQLException时应包含详细信息:

java 复制代码
catch (SQLException e) {
    logger.error("SQLState: " + e.getSQLState() 
        + " ErrorCode: " + e.getErrorCode(), e);
    throw new DataAccessException(e);
}

对可恢复错误(如死锁)应实现重试机制。

元数据缓存优化

频繁使用的PreparedStatement可缓存:

java 复制代码
Map<String, PreparedStatement> statementCache = new LRUCache<>(100);
PreparedStatement getCachedStatement(String sql) {
    return statementCache.computeIfAbsent(sql, 
        k -> connection.prepareStatement(k));
}

注意缓存大小需根据应用负载调整,避免内存溢出。

相关推荐
非优秀程序员1 小时前
第02章 杭电的英语老师与一台服务器|《互联网产品恩仇录》
数据库·node.js·代码规范
用户956256254296 小时前
跟做:Firecrawl 单页转 Markdown 再丢进沙箱总结
python·api
SelectDB6 小时前
SelectDB 是哪个公司的?是国产数据库吗?一篇讲清飞轮科技与 Apache Doris 的关系
数据库
威哥爱编程6 小时前
模拟面试智能体开发实战 02:回答等半分钟,谁还愿意练?把服务端和流式输出搭起来
python·agent·harmonyos
这个DBA有点耶6 小时前
库内计算推理:一条SQL背后的算子融合,和外挂方案差了几次网络往返
数据库·人工智能·sql
威哥爱编程6 小时前
模拟面试智能体开发实战 01:面试挂了都不知道挂在哪?用 Python 给自己造一个随叫随到的 AI 面试官
python·agent·harmonyos
2601_967980116 小时前
Python行情API量化 02:顺序拉 20 要 2 秒?并发批量把时间压到 0.5 秒
python·api·限流·并发·量化
伞伞悦读6 小时前
【第81期】特征缩放怎么选:标准化、MinMax 与 Robust 的原理、泄漏对照和完整实验
人工智能·python·深度学习·机器学习
新*7 小时前
从一段 WebSocket 代码聊开:bytes 不是 zlib、binaryType 决定一切,15MB 大消息的零拷贝优化
javascript·python·websocket·性能优化·blob·zlib·arraybuffer
这个DBA有点耶8 小时前
函数索引的“完全一致”有多苛刻:写法、字符集、类型,差一处就失效
数据库·mysql·代码规范