在JDBC应用中,如果你已经是稍有水平开发者,你就应该始终以PreparedStatement代替Statement.也就是说,在任何时候都不要使用Statement.
基于以下的原因:
一.代码的可读性和可维护性.
虽然用PreparedStatement来代替Statement会使代码多出几行,但这样的代码无论从可读性还是可维护性上来说.都比直接用Statement的代码高很多档次:
stmt.executeUpdate("insert into tb_name (col1,col2,col2,col4) values ('"+var1+"','"+var2+"',"+var3+",'"+var4+"')");
perstmt = con.prepareStatement("insert into tb_name (col1,col2,col2,col4) values (?,?,?,?)");
perstmt.setString(1,var1);
perstmt.setString(2,var2);
perstmt.setString(3,var3);
perstmt.setString(4,var4);
perstmt.executeUpdate();
不用我多说,对于第一种方法.别说其他人去读你的代码,就是你自己过一段时间再去读,都会觉得伤心.
二.PreparedStatement尽最大可能提高性能.
每一种数据库都会尽最大努力对预编译语句提供最大的性能优化.因为预编译语句有可能被重复调用.所以语句在被DB的编译器编译后的执行代码被缓存下来,那么下次调用时只要是相同的预编译语句就不需要编译,只要将参数直接传入编译过的语句执行代码中(相当于一个涵数)就会得到执行.这并不是说只有一个Connection中多次执行的预编译语句被缓存,而是对于整个DB中,只要预编译的语句语法和缓存中匹配.那么在任何时候就可以不需要再次编译而可以直接执行.而statement的语句中,即使是相同一操作,而由于每次操作的数据不同所以使整个语句相匹配的机会极小,几乎不太可能匹配.比如:
insert into tb_name (col1,col2) values ('11','22');
insert into tb_name (col1,col2) values ('11','23');
即使是相同操作但因为数据内容不一样,所以整个个语句本身不能匹配,没有缓存语句的意义.事实是没有数据库会对普通语句编译后的执行代码缓存.
当然并不是所以预编译语句都一定会被缓存,数据库本身会用一种策略,比如使用频度等因素来决定什么时候不再缓存已有的预编译结果.以保存有更多的空间存储新的预编译语句.
三.最重要的一点是极大地提高了安全性.
即使到目前为止,仍有一些人连基本的恶义SQL语法都不知道.
String sql = "select * from tb_name where name= '"+varname+"' and passwd='"+varpasswd+"'";
如果我们把[' or '1' = '1]作为varpasswd传入进来.用户名随意,看看会成为什么?
select * from tb_name = '随意' and passwd = '' or '1' = '1';
因为'1'='1'肯定成立,所以可以任何通过验证.更有甚者:
把[';drop table tb_name;]作为varpasswd传入进来,则:
select * from tb_name = '随意' and passwd = '';drop table tb_name;有些数据库是不会让你成功的,但也有很多数据库就可以使这些语句得到执行.
而如果你使用预编译语句.你传入的任何内容就不会和原来的语句发生任何匹配的关系.只要全使用预编译语句,你就用不着对传入的数据做任何过虑.而如果使用普通的statement,有可能要对drop,;等做费尽心机的判断和过虑.
分享到:
相关推荐
PreparedStatement对象相比Statement对象具有更多的优点,因此在实际开发中,建议使用PreparedStatement对象来代替Statement对象。 知识点: 1. Statement对象和PreparedStatement对象的区别 2. PreparedStatement...
3. 为什么要始终使用 PreparedStatement 代替 Statement 使用 PreparedStatement 可以防止 SQL 注入攻击,并且可以提高查询性能。因为 PreparedStatement 可以预编译 SQL 语句,从而提高查询速度。 WebLogic 1. ...
- **为什么要始终使用PreparedStatement代替Statement**:PreparedStatement提供预编译的SQL语句,能防止SQL注入攻击,提高性能,并允许参数化查询,提高代码可读性。 2. **线程调度与字符集**: - **一个利己...
在实际开发中,为了提高效率和安全性,我们通常会使用PreparedStatement接口来代替Statement接口。 1. **PreparedStatement简介** PreparedStatement是Statement的一个子接口,它的主要优势在于预编译。预编译的...
在描述中提到的基本查询和更新场景中,我们可以使用PreparedStatement的`setXXX()`方法设置参数,其中XXX代表参数类型,如`setString()`、`setInt()`等。例如,查询用户ID为1的数据,可以这样写: ```java String ...
- 使用PreparedStatement代替Statement,提高安全性和性能。 - 通过使用连接池管理数据库连接,避免频繁创建和关闭连接。 - 在操作完毕后,立即关闭ResultSet、Statement和Connection,释放资源。 - 捕获并正确...
1. 使用PreparedStatement代替Statement,减少SQL解析时间。 2. 数据库连接池:通过数据源实现连接池,复用数据库连接,降低连接创建和释放的开销。 3. 分页查询:避免一次性获取大量数据,使用LIMIT或OFFSET等分页...
- 使用PreparedStatement代替Statement以防止SQL注入。 - 适当使用批处理,优化大量数据的插入和更新。 - 使用连接池管理数据库连接,提高系统性能。 - 在处理完结果集后立即关闭,避免内存泄漏。 - 使用try-with-...
### 为什么使用问号参数 1. **防止SQL注入**:问号参数化能有效防止SQL注入攻击。因为它确保了用户输入的数据不会被解析为SQL代码,而是作为原始数据处理。即使用户尝试插入恶意SQL,数据库也会将它们视为普通字符串...
在实际开发中,为了提高性能和防止SQL注入,通常会使用PreparedStatement代替Statement,因为PreparedStatement允许预编译SQL,并能接受参数。此外,现代JavaEE应用更倾向于使用ORM(Object-Relational Mapping)...
1. 使用PreparedStatement代替Statement,防止SQL注入。 2. 使用连接池(如C3P0、DBCP、HikariCP等)管理数据库连接,提高性能。 3. 使用批处理(Batch Processing)处理批量数据操作,减少与数据库的交互次数。 ...
1. 使用PreparedStatement代替Statement,减少解析时间,提高效率。 2. 使用连接池:例如C3P0、DBCP、HikariCP等,避免频繁创建和销毁数据库连接。 3. 批量处理:尽量将多条SQL语句一起执行,减少网络往返次数。 ...
- 使用PreparedStatement代替Statement,提高性能和安全性。 - 在可能的情况下,关闭自动提交,手动提交事务以增强数据一致性。 - 使用连接池(如C3P0、HikariCP等)管理数据库连接,避免频繁创建和销毁连接。 - ...
- 尽管性能通常优于 Statement,但如果 SQL 语句只执行一次,初始化 PreparedStatement 的开销可能高于直接使用 Statement。 3. CallableStatement CallableStatement 用于执行存储过程。它的特点包括: 优点: - ...
1. 使用PreparedStatement代替Statement,提高效率并防止SQL注入。 2. 合理设置批处理大小,平衡网络传输和内存占用。 3. 使用连接池,控制并发和连接生命周期。 4. 使用预编译和参数化查询,提升查询速度。 5. 适当...
优化主要包括使用PreparedStatement代替Statement,以及使用数据库连接池管理数据库连接。 【数据库连接池】 数据库连接池是管理数据库连接的组件,如Apache的Commons DBCP、C3P0、HikariCP等,它们可以提高性能,...
在实际应用中,为了提高代码的可读性和安全性,通常会使用PreparedStatement代替Statement,因为前者能防止SQL注入攻击。同时,事务管理也是数据库操作中不可忽视的部分,确保数据的一致性。 总结起来,MyEclipse...
2. **使用PreparedStatement代替Statement**: 预编译的SQL语句能避免SQL注入,同时执行效率更高。 3. **结果集的迭代优化**: 使用`ResultSet.next()`逐行读取,而不是一次性加载所有数据。 4. **连接池**: 使用...
3. 使用PreparedStatement代替Statement:PreparedStatement提供了预编译的SQL语句,并使用占位符来接受参数,这样可以保证SQL语句的结构不会被恶意输入所改变。当执行PreparedStatement时,参数的值会被自动转义,...