Java -- JDBC学习笔记3、PreparedStatement
1、SQL注入问题
1.1、什么是SQL注入?
用户输入的数据中有SQL关键字或用法并且参与了SQl语句的编译,导致SQL语句编译后的条件含义为true,一直得到正确的结果,这种现象称为SQL注入。
1.2、如何避免SQL注入?
由于编写的SQl语句是在用户输入数据,整合后再进行编译。所以、为了避免SQL注入问题,要提前将SQl语句进行编译,参数位置使用占位符,编译完成后,再对占位符填充对应的数据。
2、PreparedStatement
PreparedStatement继承了Statement接口,执行SQl语句的方法无异
2.1、PreparedStatement的应用
- 作用
- 预编译SQL语句,效率高
- 安全,避免SQl注入
- 可以动态填充数据,执行多个同构的SQL语句(SQL语句相同,参数值不同)
2.1.1、参数标记
String querySql = "SELECT Name,LoginName FROM Students where id=?";
PreparedStatement ps = conn.prepareStatement(querySql);
- 注意:JDBC中所有占位符符号都用 ? 表示,为指定参数下标绑定值,赋值的时候编号从1开始,1代表的就是第一个占位符,2就是第二个。
2.1.2、动态参数绑定
- ps.setXxx(1,1)
- 第一个参数是下标
- 第二个参数是需要填入的值
String querySql = "SELECT Name,LoginName FROM Students where id=?";
PreparedStatement ps = conn.prepareStatement(querySql);
ps.setInt(1, 1);
- 这样,id = ? 中,? 就会替换为 1
2.1.3、执行SQL
执行编译后的SQl查询语句使用ResultSet rs = ps.executeQuery();
- 注意:括号里边没有SQL语句,因为SQL语句事先已经编译过了
2.1.4、遍历集合
while (rs.next())
{
//通过列名获取
String name1 = rs.getString("Name");
String loginName1 = rs.getString("LoginName");
System.out.println("姓名:" + name1 + ",登录名:" + loginName1);
}
- 和statement一样。
2.1.5、整合代码
try
{
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
String url = "jdbc:sqlserver://localhost:1433;databaseName=StudentManage";
Connection conn = DriverManager.getConnection(url, "sa", "sql2012");
String querySql = "SELECT Name,LoginName FROM Students where id=?";
PreparedStatement ps = conn.prepareStatement(querySql);
ps.setInt(1, 1);
ResultSet rs = ps.executeQuery();
while (rs.next())
{
//通过列名获取
String name1 = rs.getString("Name");
String loginName1 = rs.getString("LoginName");
System.out.println("姓名:" + name1 + ",登录名:" + loginName1);
}
rs.close();
ps.close();
conn.close();
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
catch (SQLException sqlException)
{
sqlException.printStackTrace();
}