mysql的预定义语句_sql使用预定义语句

本文介绍了数据库程序优化技术,强调了使用PreparedStatement类的重要性。预编译的SQL语句可以提高查询效率,尤其是在连接池中,能够复用已编译的查询。此外,PreparedStatement还能有效防止SQL注入攻击,确保用户输入不被解释为SQL代码,增强了系统的安全性。在处理用户输入时,避免直接拼接SQL,而是使用预定义语句设置参数,可以避免潜在的安全风险。
摘要由CSDN通过智能技术生成

JDBC程序的一个常用优化技术是使用PrepareStatement类。如果代码多次发出同类查询,则使用预定义语句来加快执行数据库操作。比如查找用户密码,则需要重复发出表单查询:SELECT passwd FROM Credentials WHERE username=...

预定义语句要求数据库预编译查询——也就是说,解析SQL语句并且计算查询策略。信息是使用预定义语句保持的,并且在重新发出查询时重复使用。

使用Connection类的prepareStation方法创建预定义语句。为每个参数使用“?”字符:

PreparedStatement stat=conn.prepareStatement("SELECT password FROM Credentials WHERE username=?");

当准备发出预定义语句时,首先设置参数值:

stat.setString(1,name);

注意索引值1表示第一个参数。然后以通常的方式发出语句:

ResultSet result = stat.executeQuery();

乍一看,好像预定义语句在Web应用程序中没有什么好处。毕竟,当完成一个用户请求时,就关闭连接。预定义语句与数据库连接相关,当数据库的物理连接终止时,建立它的所有工作都将丢失。

但如果物理数据库连接保持在一个连接中,那么当检索连接时,预定义语句仍然很可能可供用。许多连接池实现将缓冲预定义语句。

当调用prepareStatement时,连接池将首先查看语句缓冲内部,使用查询字符串作为键。如果发现了预定义语句,那么重用它。否则创建新的预定义语句并且添加到缓存中。

所以这些活动对于应用程序编程人员而言都是透明的。你请求PrepareStatement对象,并且希望至少在一段时间内,连接池能够为给定的查询检索现有对象。

警告:不能在一个请求作用域之外保持和重用PreparedStatement对象。一旦关闭连接池中的连接,所有相关的PrepareStatement对象也归还到连接池中。因此,在当前请求之外,不应该保持PrepareStatement对象。替代的方法是,使用同一查询字符串来调用prepareStatement方法,并有可能会得到一个缓冲的语句对象。

注意:即使你并不关注性能,也有另一个使用预定义语句的正当理由:防止SQL注入攻击。当查询有连接的SQL代码和用户输入形成时,恶意用户可以在输入中提供能修改查询含义的SQL代码。使用预定义语句,用户输入将永远不会被解释为SQL。

》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》

PS:什么是SQL注入及实例说明:

例如:String sql="select * from usert where name='"+usernameInput+"' and password='"+pwdinput+"'";

这句是判断当uesrname和password条件都成立时,才会显示结果。

就是用如下的字符串拼接而成

String sql="select * from usert where username='"

+usernameInput

+"' and password='"

+pwdinput

+"'";

在输入用户名hh,密码输入下面的代码,

pwd' or '1'='1

在数据库报务器相当于执行这样的SQL语句:

select * from usert where name='hh' and password='pwd' or '1'='1' ; --这个语句不管前面的条件是否成立,后面的语句总是为真,因此where 条件语句总是成立。

所以就可以跳过前面用户名和密码的判段。

这样就不安全

//正常的SQL查询语句

String sql="select * from usert where name='"+userinput+"' and password='"+pwdinput+"'";

//userinput用户输入的字符串

String userinput="hh";

//pwdinput接收用户输入的字符串

String pwdinput="pwd' or '1'='1";

这种不安全的情况是在SQL语句在拼接的情况下发生

为了主防范这样”SQL注入安全“可以用预编译解决:

String sql= "insert into userlogin values(?,?)";

try {

PreparedStatement ps=conn.prepareStatement(sql);

for(int i=1;i<100;i++){

ps.setInt(1, i);

ps.setInt(2, 8888);

ps.executeUpdate();

}

ps.close();

conn.close();

} catch (SQLException e) {

e.printStackTrace();

}

这样,不管用户输入是什么,数据库服务器总认为是一个值,而SQL语句是相同的不会重复编译,也不会编译新的SQL语句,所以不管用户怎么输入,都不会产生"SQL注入安全"

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值