关于statement用户登录一些常见问题

表依旧还是上一张表

代码:

/**
 * TODO
 *      1、明确jdbc的使用流程 和 详细讲解内部设计api方法
 *      2、发现问题,引出prepareStatement
 *
 * TODO
 *      输入账号密码
 *      进行数据库信息查询(t_user)
 *      反馈登录成功还是登录失败
 *
 * TODO
 *      1、键盘输入事件,收集账号和密码信息
 *      2、注册驱动
 *      3、获取连接
 *      4、创建Statement
 *      5、发送查询SQL语句,并获取返回结果
 *      6、结果判断,显示成功还是失败
 *      7、关闭资源
 */
public class StatementUserLoginPart {
    public static void main(String[] args) throws SQLException, ClassNotFoundException {
        //1、获取用户输入信息
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入账号:");
        String account= scanner.nextLine();
        System.out.println("请输入密码:");
        String password= scanner.nextLine();
​
        //2、注册驱动
        /**
         * 方案1:
         *      DriverManager.registerDriver(new com.mysql.cj.jdbc.Driver());
         *      注意:8+ com.mysql.cj.jdbc.Driver
         *           5+ com.mysql.jdbc.Driver
         *      问题:会注册两次驱动,导致性能消耗
         *          1. DriverManager.registerDriver() 方法本身会注册一次;
         *          2. Driver.static{DriverManager.registerDriver()} 静态代码块也会注册一次。
         *      解决:只想注册一次驱动
         *           只触发静态代码块即可:Driver
         *      触发静态代码块:
         *          类加载机制:类加载的时候,会触发静态代码块。
         *                    加载 [class文件 -> jvm虚拟机的class对象]
         *                    连接 [验证(检查文件类型) -> 准备(静态变量默认值) -> 解析(触发静态代码块)]
         *                    初始化(静态属性赋真实值)
         *      触发类加载:
         *           1、new关键字
         *           2、调用静态方法
         *           3、调用静态属性
         *           4、接口 1.8 default默认实现
         *           5、反射  【Class.forName() 类名.class】
         *           6、子类触发父类
         *           7、程序的入口mian
         */
​
        //方案1:
        //DriverManager.registerDriver(new Driver());
​
        //方案2:mysql新版的驱动,不够灵活,不方便改成其他的数据库软件如Oracle
        //new Driver();
​
        //方案3:字符串 -> 提取到外部的配置文件 -> 可以引导外部的配置文件,只需修改配置文件 -> xx.properties -> Oracle -> 配置文件
        Class.forName("com.mysql.cj.jdbc.Driver");
​
        //2.获取数据库连接
        /**
         * getConnection(1,2,3)方法,是一个重载方法;
         * 允许开发者,用不同的形式传入数据库连接的核心参数;
         *
         * 核心属性:
         *     1、数据库软件所在主机的IP地址:localhost | 127.0.0.1
         *     2、数据库软件所在的主机端口号:3306(默认为3306)
         *     3、连接的具体库:jdbc_study
         *     4、账号:root
         *     5、密码:mysql
         *     6、可选信息:无
         *
         * 三个参数:
         *    String url        数据库软件所在的信息,连接的具体库,以及其他可选信息
         *                      语法:jdbc:数据库管理软件名称[mysql,Oracle]://ip地址 | 主机名(localhost): 端口号/数据库名?key=value
         *                           &key=value 可选信息
         *                      具体:jdbc:mysql://localhost:3306/jdbc_study
         *                           jdbc:mysql://127.0.0.1:3306/jdbc_study
         *                      本机的省略写法:如歌你的数据库软件安装到本机,可以进行一些省略
         *                            jdbc:mysql:///jdbc_study
         *                            省略了【本机地址】和【3306端口号】
         *                            强调:必须是本机,且端口号为3306才可省略
         *
         *    String user       数据库的账号 root
         *    String password   数据库的密码 mysql
         *
         * 两个参数:
         *    String url        : 此url和三个参数的url作用一致
         *    Properties info : 存储账号和密码
         *                      Properties 类似于 Map 只不过 key = value 都是字符串形式
         *                      key user:账号信息
         *                      key password:密码信息
         *
         * 一个参数:
         * String url :         数据库ip,端口号,具体的数据库    可选信息(账号密码)
         *                      jdbc: 数据库软件名://ip:port/数据库名?key=value&key=value
         *
         *                      jdbc:mysql://localhost:3306/jdbc_study?user=root&password=mysql
         *                      携带固定的参数名 user password 传递账号和密码信息
         *
         * url的路径属性可选信息
         *      url?user=账号&password=密码
         */
        //推荐使用第一种
        Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc_study", "root", "mysql");
​
        Properties info=new Properties();
        info.put("user","root");
        info.put("password","mysql");
        Connection connection1 = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc_study", info);
​
        Connection connection2 = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc_study?user=root&password=mysql");
​
        //3、创建发生SQL语句的statement对象
        //statement 可以发送SQL语句到数据库,并且获取返回结果
        Statement statement = connection.createStatement();
​
        //4、发送SQL语句(1、编写SQL语句;2、发送SQL语句)
        String sql="select * from t_user where account='"+account+"'and password=+'"+password+"';";
​
        /**
         * SQL分类:DDL(容器创建,修改,删除);DML(数据的插入,修改,删除);DQL(数据查询);DCL(权限控制);TPL(事务控制语言)
         *
         * 参数:sql 非DQL
         * 返回:int
         *          情况1:DML 返回影响的行数,例如 删除3条数据。return 3;
         *          情况2:非DML return 0;
         * int row=executeUpdate(sql);
         *
         * 参数:sql DQL
         * 返回:resultSet 结果封装对象(返回结果集)
         * ResultSet resultSet=executeQuery(sql);
         */
​
        //登录属于查询语句,选择第二种
        ResultSet resultSet = statement.executeQuery(sql);
​
        //5、查询结果集解析 resultSet
​
        /**
         *java是一种面向对象的思维,将查询结果封装成了resultSet对象,我们应该理解内部一定也是有行和有列的
         *
         * resultSet -> 逐行获取数据,行 -> 行的列的数据
         *
         * 1、获取列数据问题
         *      resultSet.get数据类型(String columnLabel | int conlumnIndex);
         *              columnLabel:列名 如果有别名  写别名   select * | (id等等)
         *                                                 select id as aid(别名) from...
         *              conlumnIndex:列的下角标获取 从左向右 从1开始,数据库全是从1开始!
         */
​
         // 如果有多行数据
//        while(resultSet.next()){
//            指定当前行
//            int id = resultSet.getInt(1);
//            String account1 = resultSet.getString("account");
//            String password1 = resultSet.getString(3);
//            String nickname = resultSet.getString("nickname");
//            System.out.println("["+id+"]---["+account1+"]---["+password1+"]---["+nickname+"]");
//        }
​
        //移动一次光标,只要有数据,就代表登录成功
        if(resultSet.next()){
            System.out.println("登录成功!");
        }else {
            System.out.println("登录失败!");
        }
​
        //6、关闭资源
        resultSet.close();
        statement.close();
        connection.close();
    }
}

2、当中重点

2.1、注册驱动时,减少性能消耗,采用反射的方法( Class.forName() )

//方案3:字符串 -> 提取到外部的配置文件 -> 可以引导外部的配置文件,只需修改配置文件 -> xx.properties -> Oracle -> 配置文件
Class.forName("com.mysql.cj.jdbc.Driver");

2.2、获取数据库连接

* getConnection(1,2,3)方法,是一个重载方法;
* 允许开发者,用不同的形式传入数据库连接的核心参数;
*
* 核心属性:
*     1、数据库软件所在主机的IP地址:localhost | 127.0.0.1
*     2、数据库软件所在的主机端口号:3306(默认为3306)
*     3、连接的具体库:jdbc_study
*     4、账号:root
*     5、密码:mysql(自己的数据库密码)
*     6、可选信息:无
//推荐使用第一种
Connection connection = DriverManager.getConnection
("jdbc:mysql://localhost:3306/jdbc_study", "root", "mysql");
​

2.3、发送SQL语句

/**
 * SQL分类:DDL(容器创建,修改,删除);DML(数据的插入,修改,删除);
           DQL(数据查询);DCL(权限控制);TPL(事务控制语言)
 *
 * 参数:sql 非DQL
 * 返回:int
 *          情况1:DML 返回影响的行数,例如 删除3条数据。return 3;
 *          情况2:非DML return 0;
 * int row=executeUpdate(sql);
 *
 * 参数:sql DQL
 * 返回:resultSet 结果封装对象(返回结果集)
 * ResultSet resultSet=executeQuery(sql);
 */

2.4、查询结果集解析

获取列数据问题
*      resultSet.get数据类型(String columnLabel | int conlumnIndex);
*              columnLabel:列名 如果有别名  写别名   select * | (id等等)
*                                                 select id as aid(别名) from...
*              conlumnIndex:列的下角标获取 从左向右 从1开始,数据库全是从1开始!
*/
​
// 如果有多行数据
//        while(resultSet.next()){
//            指定当前行
//            int id = resultSet.getInt(1);
//            String account1 = resultSet.getString("account");
//            String password1 = resultSet.getString(3);
//            String nickname = resultSet.getString("nickname");
//            System.out.println("["+id+"]---["+account1+"]---["+password1+"]---["+nickname+"]");
//        }
​
        //移动一次光标,只要有数据,就代表登录成功
        if(resultSet.next()){
            System.out.println("登录成功!");
        }else {
            System.out.println("登录失败!");
        }

3、存在的问题

3.1、SQL语句需要字符串拼接,比较麻烦

3.2、只能拼接字符串类型,其他的数据库类型无法处理

3.3、可能发生注入攻击,动态值充当了SQL语句结构,影响了原有的查询结果!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值