【JDBC练习】使用用户名和密码登录

前言

需求:
  1. 通过键盘录入用户名和密码
  2. 判断用户是否登录成功

分析:
  使用sql语句:select * from user where username = “ “ and password = “ “,如果这个sql有查询结果,则成功;反之,则失败。

步骤

  1. 首先创建数据库表user,添加两个用户名及密码作为已注册用户。
    1
    2
    3
    4
    5
    6
    7
    CREATE TABLE USER(
    id INT PRIMARY KEY AUTO_INCREMENT,-- id 主键 自增长
    username VARCHAR(32),
    PASSWORD VARCHAR(32)
    );
    INSERT INTO USER VALUES(NULL, 'zhangsan', '123');
    INSERT INTO USER VALUES(NULL, '1isi', '234');

使用SQLyog查看表,如下图所示。

  1. 创建配置文件,增加程序拓展性

    1
    2
    3
    4
    url=jdbc:mysql:///db4
    user=root
    password=4719
    driver=com.mysql.jdbc.Driver
  2. 创建工具类JDBCUtils,简化代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    package cn.imcyc.util;

    import java.io.FileReader;
    import java.io.IOException;
    import java.sql.*;
    import java.util.Properties;

    /**
    * JDBC工具类
    */
    public class JDBCUtils {
    private static String url;
    private static String user;
    private static String password;
    private static String driver;

    /**
    * 静态代码块:随着类的加载而加载,只执行一次。用来读取配置文件的信息
    */
    static {
    try {
    //创建Properties集合类对象
    Properties pro = new Properties();
    //获取src路径下的文件的方式--->classLoader类加载器
    //classLoader可以加载字节码文件进内存,并且可以获取资源路径
    //通过类JDBCUtils获得JDBCUtils的类加载器,再通过getResource获得配置文件的资源路径(非配置文件存储路径)
    String path = JDBCUtils.class.getClassLoader().getResource("jdbc.properties").getPath();
    //System.out.println(path);
    //加载配置文件
    pro.load(new FileReader(path));
    //获取数据,并赋值
    url = pro.getProperty("url");
    user = pro.getProperty("user");
    password = pro.getProperty("password");
    driver = pro.getProperty("driver");
    //注册驱动
    Class.forName(driver);
    } catch (IOException e) {
    e.printStackTrace();
    } catch (ClassNotFoundException e) {
    e.printStackTrace();
    }
    }

    /**
    * 获取连接
    * @return 连接对象
    */
    public static Connection getConnection() throws SQLException {
    return DriverManager.getConnection(url, user, password);
    }

    /**
    * 释放资源
    * @param stmt
    * @param conn
    */
    public static void close(Statement stmt, Connection conn){
    if(stmt!=null){
    try {
    stmt.close();
    } catch (SQLException e) {
    e.printStackTrace();
    }
    }
    if(conn!=null){
    try {
    conn.close();
    } catch (SQLException e) {
    e.printStackTrace();
    }
    }
    }

    public static void close(ResultSet rs, Statement stmt, Connection conn){
    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();
    }
    }
    }
    }
  3. 创建JdbcDemo06,代码为:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    package cn.imcyc.jdbc;

    import cn.imcyc.util.JDBCUtils;

    import java.sql.Connection;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.util.Scanner;

    /**
    * 需求:
    * 1.通过键盘录入用户名和密码
    * 2.判断用户是否登录成功
    */
    public class JdbcDemo06 {
    public static void main(String[] args) {
    //1.键盘录入,接受用户名和密码
    Scanner sc = new Scanner(System.in);
    System.out.println("请输入用户名:");
    String username = sc.nextLine();
    System.out.println("请输入密码:");
    String password = sc.nextLine();
    //2.调用方法
    boolean flag = new JdbcDemo06().login(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 conn = null;
    Statement stmt = null;
    ResultSet rs = null;
    try {
    //使用工具类注册驱动、获取链接
    conn = JDBCUtils.getConnection();//把配置文件修改为db4
    //定义sql
    String sql = "select * from user where username = '" + username + "' and password = '" + password + "'";
    //获取执行sql的对象
    stmt = conn.createStatement();
    //执行查询
    rs = stmt.executeQuery(sql);
    //判断
    return rs.next();//因为上面的sql语句查询出来的就只有一行数据(或无),所以rs.next()为真则代表有下一行,即查询成功
    } catch (SQLException e) {
    e.printStackTrace();
    } finally {
    JDBCUtils.close(rs, stmt, conn);
    }

    return false;
    }
    }

执行JdbcDemo06,输入用户名和密码验证登录是否成功,效果如下图。

安全性问题(SQL注入问题)

  SQL注入问题:在拼接sql时,有一些sql的特殊关键字参与字符串的拼接,会造成安全性问题。例如输入任意用户名,输入密码:a’ or ‘a’ = ‘a,使得sql语句变成

1
select * from user where username = 'fhdsjkf' and password = 'a' or 'a' = 'a'

就能登陆成功,这显然是非常严重的安全问题。

  解决SQL注入问题:使用Preparedstatement对象来解决,将上面主程序代码修改为(或创建一个新Demo):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
package cn.imcyc.jdbc;

import cn.imcyc.util.JDBCUtils;

import java.sql.*;
import java.util.Scanner;

public class JdbcDemo07 {
public static void main(String[] args) {
//1.键盘录入,接受用户名和密码
Scanner sc = new Scanner(System.in);
System.out.println("请输入用户名:");
String username = sc.nextLine();
System.out.println("请输入密码:");
String password = sc.nextLine();
//2.调用方法
boolean flag = new JdbcDemo07().login(username, password);
//3.判断结果,输出不同语句
if (flag) {
System.out.println("登录成功!");
} else {
System.out.println("用户名或密码错误!");
}
}

/**
* 登录方法,使用PreparedStatement实现
*/
public boolean login(String username, String password) {
if (username == null || password == null) {
return false;
}
//连接数据库判断登录是否成功
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
//使用工具类注册驱动、获取链接
conn = JDBCUtils.getConnection();//把配置文件修改为db4
//定义sql
String sql = "select * from user where username = ? and password = ?";
//获取执行sql的对象
pstmt = conn.prepareStatement(sql);
//给 ? 赋值
pstmt.setString(1,username);
pstmt.setString(2,password);
//执行查询(不需要传递sql)
rs = pstmt.executeQuery();
//判断
return rs.next();//因为上面的sql语句查询出来的就只有一行数据(或无),所以rs.next()为真则代表有下一行,即查询成功
} catch (SQLException e) {
e.printStackTrace();
} finally {
JDBCUtils.close(rs, pstmt, conn);
}

return false;
}
}

注意:

  1. sql的参数使用 ?作为占位符。如:select * from user where username = ? and password = ?;
  2. 给 ?赋值:
    方法:setXxx(参数1, 参数2)
    参数1:?的位置编号从1开始
    参数2:?的值

  后期都会使用PreparedStatement来完成增删改查的所有操作,因为:1. 可以防止SQL注入;2. 效率更高。

相关文章推荐

  【JDBC练习】查看表的方法——表的数据封装成对象并装载成集合
  【JDBC】使用_不使用数据库连接池获取连接对比

————————— 本文结束 感谢您的阅读 —————————
谢谢你请我喝咖啡ლↂ‿‿ↂლ(支付宝扫一扫即可领红包, 消费时可抵现! 你省钱, 我赚钱, 多谢支持~)