接上篇:java.sql.SQLSyntaxErrorException: Unknown column ‘xxx‘ in ‘where clause‘问题解决及防止SQL注入
演示业务中必须使用Statement完成字符串的拼接.
1、需求:
输入desc,对表中的数据按名字降序排序;
输入asc,对表中的数据按名字升序排序。
2、代码:
2.1 尝试用PreparedStatement完成
package com.sunny;
import java.sql.*;
import java.util.Scanner;
/**
* 尝试用PreparedStatement完成:输入desc,对表中的数据按名字降序排序
* 输入asc,对表中的数据按名字升序排序
*/
public class JDBCTest08 {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
Scanner scanner = new Scanner(System.in);
System.out.println("输入关键字:asc升序输出,desc降序输出");
String kw = scanner.nextLine();
try {
//注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//获取连接
conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/mytest?serverTimezone=Asia/Shanghai","root","123456");
//获取预编译的数据库操作对象
String sql = "select * from user order by username ?";
ps = conn.prepareStatement(sql);
//传值
ps.setString(1, kw);
//执行sql
rs = ps.executeQuery();
while (rs.next()){
System.out.println(rs.getInt("id") + "--"
+ rs.getString("username") + "--"
+ rs.getString("password"));
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}finally {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (ps != null) {
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
运行结果:
D:\Java\jdk1.8.0_202\bin\java.exe...
输入关键字:asc升序输出,desc降序输出
asc
java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''asc'' at line 1
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:120)
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:953)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeQuery(ClientPreparedStatement.java:1003)
at com.sunny.JDBCTest08.main(JDBCTest08.java:30)
Process finished with exit code 0
2.2 结论
通过上面可以发现:
用PreparedStatement无法完成的,因为用?的话会以字符串的形式传入desc/asc,导致拼接的sql语句出现语法问题,所以报错。
2.3 改用Statement
package com.sunny;
import java.sql.*;
import java.util.Scanner;
/**
* 利用Statement完成:输入desc,对表中的数据按名字降序排序
* 输入asc,对表中的数据按名字升序排序
*/
public class JDBCTest08 {
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
Scanner scanner = new Scanner(System.in);
System.out.println("输入关键字:asc升序输出,desc降序输出");
String kw = scanner.nextLine();
try {
//注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//获取连接
conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/mytest?serverTimezone=Asia/Shanghai","root","123456");
//获取预编译的数据库操作对象
String sql = "select * from user order by username " + kw ; //进行字符串拼接
//执行sql
stmt = conn.createStatement();
rs = stmt.executeQuery(sql);
while (rs.next()){
System.out.println(rs.getInt("id") + "--"
+ rs.getString("username") + "--"
+ rs.getString("password"));
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}finally {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
运行结果: