业务案例:
用户在控制台输入desc让结果集降序,输入asc就是升序
先用PreparedStatement编写程序:
package com.hyqwsq.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Scanner;
public class jdbcTest09 {
public static void main(String[] args) {
//用户在控制台输入desc就是降序,输入asc就是升序
Scanner s = new Scanner(System.in);
System.out.println("输入desc或asc,desc表示降序,asc表示升序");
System.out.println("请输入");
String keyWord = s.nextLine();
//执行SQL
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try{
//注册驱动
Class.forName("com.mysql.jdbc.Driver");
//获取连接
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/hyqwsq","root","333");
//获取预编译的数据库操作对象
String sql = "select ename from emp order by ename ?";//先写框架
ps = conn.prepareStatement(sql);//再进行编译
ps.setString(1,keyWord);//最后传值
//执行SQL
rs = ps.executeQuery();
//处理结果集,遍历
System.out.println(rs.getString("ename"));
}catch(Exception e){
e.printStackTrace();
}finally{
if(rs != null){
try{
rs.close();
}catch(Exception e){
e.printStackTrace();
}
}
if(ps != null){
try{
ps.close();
}catch(Exception e){
e.printStackTrace();
}
}
if(conn != null){
try{
conn.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
}
}
占位符?调用 getString()方法给?传值desc,他会把?变成 单引号desc 即 ‘desc’
所以以上代码经过 getString() 方法将 desc 或者 asc 传给编译后的SQL语句后SQL语句会变成这样:
select ename from emp order by ename 'desc'
很明显sql语句报错:
正是因为getString()方法会给传进去的值加上 ’ ',所以报错
所以此业务把必须支持SQL注入,使传进去的值必须没有单引号,所以就要用Statement
使用Statement:
//用户在控制台输入desc就是降序,输入asc就是升序
Scanner s = new Scanner(System.in);
System.out.println("输入desc或asc,desc表示降序,asc表示升序");
System.out.println("请输入");
String keyWord = s.nextLine();
//执行SQL
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try{
//注册驱动
Class.forName("com.mysql.jdbc.Driver");
//获取连接
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/hyqwsq","root","333");
// //获取预编译的数据库操作对象
// String sql = "select ename from emp order by ename ?";//先写框架
// ps = conn.prepareStatement(sql);//再进行编译
// ps.setString(1,keyWord);//最后传值
// //执行SQL
// rs = ps.executeQuery();
// //处理结果集,遍历
// System.out.println(rs.getString("ename"));
//获取数据库操作对象
stmt = conn.createStatement();
//执行SQL
String sql = "select ename from emp order by ename " + keyWord;
rs = stmt.executeQuery(sql);
//处理结果集,遍历
while(rs.next()){
System.out.println(rs.getString("ename"));
}
}catch(Exception e){
e.printStackTrace();
}finally{
if(rs != null){
try{
rs.close();
}catch(Exception e){
e.printStackTrace();
}
}
if(stmt != null){
try{
stmt.close();
}catch(Exception e){
e.printStackTrace();
}
}
if(conn != null){
try{
conn.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
输出:
总结:Statement支持SQL注入,凡是业务方面要求是需要进行SQL语句拼接的,必须使用过Statement,如果只是单纯给SQL语句传值必须用PrepareStatement