一、JDBCUtils类
注释非常详细
/**
* JDBC工具类
*/
public class JDBCUtils {
// 为什么是静态的呢,因为只有静态的变量才能被静态代码块所访问,被静态方法所访问
private static String url;
private static String user;
private static String password;
private static String driver;
/**
* 文件的读取,只需要读取一次即可拿到这些值。 使用静态代码块
*/
static {
// 读取资源文件,获取值。
try {
// 1. 创建Properties集合类
Properties properties = new Properties();
//获取src路径下的文件的方式--->ClassLoader 类加载器 加载字节码文件进内存
ClassLoader classLoader = JDBCUtils.class.getClassLoader();
URL resource = classLoader.getResource("jdbc.properties");//获取这个文件的路径
String path = resource.getPath();//获取文件路径的字符串
// System.out.println(path);
// 2. 加载文件
// properties.load(new FileReader("src/jdbc.properties"));
properties.load(new FileReader(path));
// 3. 获取数据,赋值
url = properties.getProperty("url");
user = properties.getProperty("user");
password = properties.getProperty("password");
driver = properties.getProperty("driver");
// 4. 注册驱动
Class.forName(driver);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 获取连接
* @return 连接对象
*/
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url,user,password);
}
/**
* 释放资源 两个参数
* @param statement
* @param connection
*/
public static void close(Statement statement, Connection connection){
if(statement != null){
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(connection != null){
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
/**
* 释放资源 三个参数
* @param resultSet
* @param statement
* @param connection
*/
public static void close(ResultSet resultSet, Statement statement, Connection connection){
if(resultSet != null){
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(statement != null){
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(connection != null){
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
二、jdbc.properties配置文件
# 这里的IP地址和端口号都省略了,因为默认就是 localhost:8080
# 用户名和密码修改成自己数据库的用户名和密码
url=jdbc:mysql:///jdbc?characterEncoding=utf-8
user=root
password=123
driver=com.mysql.jdbc.Driver
三、登录类(内含解决SQL注入的解决方案)
/**
* 1. 通过键盘录入用户名和密码
* 2. 判断用户是否登录成功
*/
public class JDBCLoginDemo {
public static void main(String[] args) {
// 1. 键盘录入,接受用户名和密码
Scanner scanner = new Scanner(System.in);
System.out.println("请输入用户名:");
String username = scanner.nextLine();
System.out.println("请输入密码:");
String password = scanner.nextLine();
// 2. 调用方法
boolean flag = new JDBCLoginDemo().login2(username, password);
// 3. 判断结果,输出不同的语句
if(flag){
//登录成功
System.out.println("登录成功!");
}else{
//登录失败
System.out.println("用户名或密码错误!");
}
}
/**
* 登录方法
*/
public boolean login(String username,String password){
if(username == null || password == null){
return false;
}
//连接数据库判断是否登录成功
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
// 1. 获取连接
try {
connection = JDBCUtils.getConnection();
// 2. 定义sql 这样拼接的SQL存在SQL注入问题
String sql = "select * from user where username = '"+username+"' and password = '"+password+"'";
System.out.println(sql);
// 3. 获取执行sql的对象
statement = connection.createStatement();
// 4. 执行查询
resultSet = statement.executeQuery(sql);
// 这样写太繁琐,直接返回resultSet.next() 就可以
/* if(resultSet.next()){ //如果有下一行,则返回true
return true;
}else{
return false;
}*/
return resultSet.next();
} catch (SQLException e) {
e.printStackTrace();
}finally {
JDBCUtils.close(resultSet,statement,connection);
}
return false;
}
/**
* 登录方法,使用 PreparedStatement 实现 解决SQL注入问题
*/
public boolean login2(String username,String password){
if(username == null || password == null){
return false;
}
//连接数据库判断是否登录成功
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
// 1. 获取连接
try {
connection = JDBCUtils.getConnection();
// 2. 定义sql
String sql = "select * from user where username = ? and password = ?";
// System.out.println(sql);
// 3. 获取执行sql的对象
// statement = connection.createStatement();
preparedStatement = connection.prepareStatement(sql);
// 给 ? 赋值
preparedStatement.setString(1,username);
preparedStatement.setString(2,password);
// 4. 执行查询,不需要传递sql
// resultSet = statement.executeQuery(sql);
ResultSet resultSet1 = preparedStatement.executeQuery();
return resultSet1.next();
} catch (SQLException e) {
e.printStackTrace();
}finally {
JDBCUtils.close(resultSet,preparedStatement,connection);
}
return false;
}
}
四、示例
1.使用login方法的SQL注入问题:
2.使用login2方法解决SQL注入问题: