2020.7.24、(1)PreparedStatement的学习JDBC的标准使用、(2)JDBC事务管理
(1)PreparedStatement的学习JDBC的标准使用
昨天学习的登录程序竟然出问题了,输入别的密码竟然能登录
请输入用户名:
dfgdf
请输入密码:
a’ or ‘a’ ='a
登录成功
就是上面这个
原来这是因为查询语句的问题
原来的查询语句是这样的:String sql="select *from user where username='"+username+"' and password = '"+password+"'";
现在如果输入进这个
dfgdf和a’ or ‘a’ ='a
那么查询语句变成这样的:
select *from user where username='dfgdf'and password='a'or'a'='a';
//后面变成了or 意味着一直都是查询正确了 这就出错了 这个问题就大了
所以说这个问题怎么改?
1、涉及到sql语句的注入问题:在拼接sql时,有一些sql的特殊关键字参与字符串的拼接。会造成安全性的问题,就像上边说的那样!
2、这个问题的解决方法:专门有一个对象PrepareStatement来解决这个问题,这是一个Statement子接口(这里查了一下接口和接口之间只能有继承关系,涉及到接口就要想到多态的问题)。顾名思义这个是个预编译!!
为什么需要预编译呢,这个和Statement有什么不同呢,因为这个Statement执行的都是静态的sql,所有的参数在生成sql的时候都是拼接好的!像上边那样!!
而预编译的sql语句!SQL语句已预编译并存储在PreparedStatement对象中。 然后可以使用该对象多次有效地执行此语句。
注意:setter方法( setShort , setString用于设置IN参数值必须指定与所定义的SQL类型的输入参数的兼容的类型,等等)。 例如,如果IN参数具有SQL类型INTEGER ,则应使用方法setInt 。
如果需要任意参数类型转换,方法setObject应与目标SQL类型一起使用。
在设定的参数的以下示例中, con表示一个活动连接:
PreparedStatement pstmt = con.prepareStatement(“UPDATE EMPLOYEES
SET SALARY = ? WHERE ID = ?”);
pstmt.setBigDecimal(1, 153833.00)
pstmt.setInt(2, 110592)
里面使用了问号占位符替代,?作为参数占位符
然后执行的时候给问号赋值就行!
使用步骤:
1、导入驱动
2、注册驱动
3、获取连接相对应的数据库
4、定义sql:注意了,问号作为占位符
如:select *from user where username=? and password=?;
这里创建之后sql字符串之后怎么办呢!对于以前定义好的完整的sql来说直接下面即可!
//3 获取执行的对象
stmt = conn.createStatement();
//4执行查询
rs = stmt.executeQuery(sql);//结果集
现在呢!因为里面还有问号站位符呢,所以肯定不能直接执行的!
所以得先把这个sql传进去再说,利用的是Connection接口中的一个方法:
PreparedStatement preparedStatement(String sql)
创建一个 PreparedStatement对象,用于将参数化的SQL语句发送到数据库。
好了现在把语句传到预编译对象里面了,下面得先修改赋值语句然后才能发送到数据库!
- 给?赋值,怎么搞呢,这么搞?
- 方法 setXxx(参数1,参数2),在PreparedStatement找这个方法,注意这个参数别误会啊,这个参数1的意思是第几个?占位符,从1开始编号,参数2才是这个传递的值。
- 最后执行无参的方法即可
下面代码实现一下
/*
* 登录方法
*
* */
public boolean login(String username,String password){
if(username==null||password==null){
return false;
}
PreparedStatement ps=null;//之所以可以这么干应该还是因为是接口的原因
Connection conn=null;
ResultSet rs=null;
//连接数据库判断是否登陆成功语句
//1 获取连接
try {
conn= JDBCUtils.