Statement

本文详细解读Statements缓存机制,如何通过减少重复操作优化性能,并提供设置指南与注意事项,确保资源利用高效且避免常见问题。

Statements 缓存通过缓存能重复使用的statements提高性能,使程序员不必明确的生命重复使用的statements。

Statement缓存减少重复指针创建,重复的statement解析和创建,应用服务器和数据库服务器的通讯,数据库负荷。

Statement特征

Statement缓存和重用对应用是透明的。每一个statement缓存和一个物理连接关联,每一个连接有自己的statement缓存。

statement匹配严格遵守:

       在statement中的SQL 字符串在缓存中必须是唯一的(大小写敏感)。

       statement的类型必须是相同的(准备的或者可调用的)

       statement产生的结果集的滑动类型必须是相同的(单向前或滑动的)

       Statements 缓存的最大数目

数据源JDBCStatement缓存容量设置

一个JDBC statement缓存和一个数据源维护的物理连接关联,所以不能跨物理连接共享。JDBC statement在中间层维护,不是数据库。

程序员能够通过编程方式,使用connection对象的setStmtCacheSize() 方法动态的启用和禁用statement缓存。

在数据源配置中使用num-cached-statements属性配置 JDBC statement 缓存 ,设置缓存大小。不设置此属性,或设置为0,禁用缓存。

Eg:

<data-source>

   ...

  num-cached-statements="200"

  </data-source>

设置num-cached-statements属性,首先要确定应用发起到数据库不同statements有多少种,然后再设置相应的缓存容量。如果不知道确切的数量,可以使用JDBC性能测量工具帮助确定。OC4j使用statement度量需要将JAVA属性oracle.jdbc.DMSStatementMetrics设置为true。

Statement缓存大小与资源问题

每个连接维护自己的statement cache,Statement Cache会持有数据库资源,绑定在连接上的Statement Cache持有的连接数很有可能会超过最大的数据库连接数,可以通过减小num-cached-statements 的值或者增加数据库最大连接限制避免此问题。

 

托管数据源的satement代理

 

所有java.sql.*接口的实现都被OC4J用一个代理对象做了包装,包括statement对象。

有些情况下,连接代理会被重新绑定到一个新的物理连接上。比如:一个连接被用来跨事务使用时,此时,任何通过此连接代理获取的statement对象不再有效,因为它们是旧的物理连接创建的。因此,在通过物理连接获取的statement对象前放置一个代理是同样的。这些Statement代理和连接代理关联,通过连接代理监控代理和物理连接的关联,如果Statement代理确认与连接代理关联的物理连接改变了,将从连接代理获取一个新的物理Statement。


### 关于 `Statement` 的详细介绍 `Statement` 是 Java JDBC API 提供的一个接口,主要用于执行静态 SQL 语句并返回生成的结果。它是数据库操作的基础工具之一,允许开发者通过它来发送 SQL 查询到数据库服务器[^4]。 以下是关于 `Statement` 的一些核心特性: #### 创建 `Statement` 对象 在使用 `Statement` 前,需要先创建它的实例。通常情况下,这一步是在建立了数据库连接之后完成的: ```java Connection conn = DriverManager.getConnection(url, username, password); Statement stmt = conn.createStatement(); ``` #### 执行查询 `Statement` 支持多种类型的 SQL 操作,包括但不限于查询 (`SELECT`)、更新 (`INSERT`, `UPDATE`, `DELETE`) 等。对于数据修改类的操作,可以使用 `executeUpdate()` 方法: ```java String sql = "INSERT INTO user(name, age) VALUES('John Doe', 30)"; int rowsAffected = stmt.executeUpdate(sql); if (rowsAffected > 0) { System.out.println("插入成功!"); } ``` 上述代码片段展示了如何通过 `Statement` 插入一条记录,并验证是否成功[^3]。 #### 静态 SQL 的局限性 尽管 `Statement` 使用简单,但它存在明显的不足之处。由于其设计仅支持静态 SQL 语句,这意味着所有的参数都需要手动拼接成字符串形式后再传递给数据库。这种方式不仅降低了代码的可读性和可维护性,还容易引发安全问题,比如 **SQL 注入**。 #### 安全隐患:SQL 注入 如果应用程序未对用户输入的内容进行严格的校验,则可能被恶意攻击者利用,向系统注入非法的 SQL 片段。例如: ```java String userInput = "' OR '1'='1"; String query = "SELECT * FROM users WHERE name='" + userInput + "'"; stmt.executeQuery(query); ``` 在这种场景下,攻击者的输入会破坏原始查询逻辑,从而绕过身份验证或其他保护机制。 为了避免此类风险,推荐改用 `PreparedStatement` 来替代传统的 `Statement` 接口[^2]。 --- ### 总结 虽然 `Statement` 能够满足基本的需求,但由于缺乏安全性保障以及较差的灵活性,在现代开发实践中已逐渐被淘汰。取而代之的是功能更强大且更加安全的 `PreparedStatement` 或其他高级选项。 ```java // 示例对比:使用 PreparedStatement 替代 Statement String sql = "INSERT INTO user(name, age) VALUES(?, ?)"; PreparedStatement pstmt = conn.prepareStatement(sql); pstmt.setString(1, "Jane Smith"); pstmt.setInt(2, 28); int result = pstmt.executeUpdate(); if (result > 0) { System.out.println("插入成功!"); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值