表依旧还是上一张表
代码:
/** * 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语句结构,影响了原有的查询结果!