本文使用的数据库,里面存放了一些用户名与密码

目录
- public class User {
-
- private String user;
- private String password;
-
- public User() {
- }
-
- public User(String user, String password) {
- super();
- this.user = user;
- this.password = password;
- }
-
- @Override
- public String toString() {
- return "User [user=" + user + ", password=" + password + "]";
- }
-
- public String getUser() {
- return user;
- }
-
- public void setUser(String user) {
- this.user = user;
- }
-
- public String getPassword() {
- return password;
- }
-
- public void setPassword(String password) {
- this.password = password;
- }
-
- }

- import java.io.InputStream;
- import java.lang.reflect.Field;
- import java.sql.Connection;
- import java.sql.DriverManager;
- import java.sql.ResultSet;
- import java.sql.ResultSetMetaData;
- import java.sql.SQLException;
- import java.sql.Statement;
- import java.util.Properties;
- import java.util.Scanner;
- import org.junit.Test;
-
- public class StatementTest {
-
- // 使用Statement的弊端:需要拼写sql语句,并且存在SQL注入的问题
- @Test
- public void testLogin() {
- Scanner scan = new Scanner(System.in);
-
- System.out.print("用户名:");
- String userName = scan.nextLine();
- System.out.print("密 码:");
- String password = scan.nextLine();
-
- String sql = "SELECT user,password FROM user_table WHERE USER = '" + userName + "' AND PASSWORD = '" + password+ "'";
- User user = get(sql, User.class);
- if (user != null) {
- System.out.println("登陆成功!");
- } else {
- System.out.println("用户名或密码错误!");
- }
- }
-
- // 使用Statement实现对数据表的查询操作
- public <T> T get(String sql, Class<T> clazz) {
- T t = null;
-
- Connection conn = null;
- Statement st = null;
- ResultSet rs = null;
- try {
- // 1.加载配置文件
- InputStream is = StatementTest.class.getClassLoader().getResourceAsStream("jdbc.properties");
- Properties pros = new Properties();
- pros.load(is);
-
- // 2.读取配置信息
- String user = pros.getProperty("user");
- String password = pros.getProperty("password");
- String url = pros.getProperty("url");
- String driverClass = pros.getProperty("driverClass");
-
- // 3.加载驱动
- Class.forName(driverClass);
-
- // 4.获取连接
- conn = DriverManager.getConnection(url, user, password);
-
- st = conn.createStatement();
-
- rs = st.executeQuery(sql);
-
- // 获取结果集的元数据
- ResultSetMetaData rsmd = rs.getMetaData();
-
- // 获取结果集的列数
- int columnCount = rsmd.getColumnCount();
-
- if (rs.next()) {
-
- t = clazz.newInstance();
-
- for (int i = 0; i < columnCount; i++) {
- // //1. 获取列的名称
- // String columnName = rsmd.getColumnName(i+1);
-
- // 1. 获取列的别名
- String columnName = rsmd.getColumnLabel(i + 1);
-
- // 2. 根据列名获取对应数据表中的数据
- Object columnVal = rs.getObject(columnName);
-
- // 3. 将数据表中得到的数据,封装进对象
- Field field = clazz.getDeclaredField(columnName);
- field.setAccessible(true);
- field.set(t, columnVal);
- }
- return t;
- }
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- // 关闭资源
- if (rs != null) {
- try {
- rs.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- if (st != null) {
- try {
- st.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
-
- if (conn != null) {
- try {
- conn.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- }
-
- return null;
- }
- }
使用 Statement 我们可以实现登录的操作,但是使用 Statement 也存在一些弊端
1. 需要拼写 SQL 语句
2. 存在 SQL 注入的问题
什么是 SQL 注入?比如我们可以把本文的 SQL 语句修改一下
SELECT user,password FROM user_table WHERE USER = '1' or ' AND PASSWORD = '='1' or '1' = '1';
'1' = '1' 是恒成立的,所以我们输入任意用户名和密码都可以登录成功,这样就存了在安全隐患
如何解决呢?
我们可以使用 PreparedStatement 来实现数据库操作来避免这个问题