package com.atsyc.api.statement;
import com.mysql.cj.jdbc.Driver;
import java.sql.*;
import java.util.Properties;
import java.util.Scanner;
/*
* TODO:
* 1.明确jdbc的使用流程 和 详细讲解内部设计api方法
* 2.发现问题,引出preparedStatement
*
* 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();
scanner.nextLine();
//2.注册驱动
/*
* 方案1:
* DriverManager.registerDriver(new com.mysql.cj.jdbc.Driver())
* 问题:注册两次驱动()
* 1.DriverManager.registerDriver() 方法本身会注册一次
* 2.Driver.static{ DriverManager.registerDriver() } 静态代码块,会注册一次
* 解决:只想注册一次驱动,只触发静态代码块即可
* 触发静态代码块:类加载的时刻,会触发静态代码块
* 加载:[class文件 -> ivm虚拟机的class对象]
* 连接:[验证(检查文件类型) -> 准备(静态变量默认值) -> 解析(触发静态代码块)]
* 初始化:(静态属性赋真实值)
* 触发类加载:
* 1.new 关键字
* 2.调用静态方法
* 3.调用静态属性
* 4.接口 1.8 default默认实现
* 5.反射
* 6.子类触发父类
* 7.程序的入口main
*/
//方案1
//DriverManager.registerDriver(new Driver());
//方案2:mysql新版本的驱动 | 换成oracle driver | 还需要改代码
new Driver();
// 字符串 -> 提取到外部的配置文件 -> 可以在不改变代码的情况下,完成数据库驱动的切换
Class.forName("com.mysql.cj.jdbc.Driver");//触发类加载,触发静态代码块的调用
//3.获取数据库连接
/*
* getConnection(1,2,3)方法是一个重载方法
* 允许开发者用不同的形式传入数据库连接的核心参数
*
* 核心属性:
* 1.数据库软件所在的主机的ip地址:localhost / 127.0.0.1
* 2.数据库软件所在的主机的端口号:3306
* 3.连接的具体库:atsyc
* 4.连接的账号:root
* 5.连接的密码:Yican030615
* 6.可选的信息:
*
* 三个参数:url,user,password
* String url:
* jdbc:数据库厂商名://ip地址:主机名:port端口号/数据库名?key=value(可选信息)
* 本机省略写法:jdbc:mysql://127.0.0.1:3306/atsyc = jdbc:mysql:///atsyc (省略了本机地址和3306默认端口号)
* String user:数据库账号
* String password:数据库密码
* 两个参数:
* String url:和三个参数的url作用一样
* Properties info:存储账号和密码 (Properties 类似于 Map,只不过key = value 都是字符串形式的)
*
* 一个参数:
* jdbc:mysql://127.0.0.1:3306/atsyc?user=root&password=Yican030615
*
* url的路径可选信息:
* url?user=账号&password=密码
* serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=true
* 8.0.25以后自动识别时区,serverTimezone=Asia/Shanghai 不用添加,8.0.25之前下面一句话要加
* 8版本之后默认使用utf-8,useUnicode=true&characterEncoding=utf8&useSSL=true 都可以省略
*/
Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/atsyc","root","Yican030615");
Properties info = new Properties();
info.put("user","root");
info.put("password","Yican030615");
Connection connection1 = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/atsyc",info);
Connection connection2 = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/atsyc?user=root&password=Yican030615");
//4.创建发送sql语句的statement对象
Statement statement = connection.createStatement();
//5.发送sql语句(先编写sql语句,再发送sql语句)
String sql = "SELECT * FROM t_user WHERE account = '" + account + "' AND PASSWORD = '" + password + "';";
/*
* sql分类:DDL(容器创建,修改,删除)DML(插入,修改,删除)DQL(查询)DCL(权限控制)TPL(事务控制语言)
*
* 参数:sql 非DQL
* 返回:int
* 情况1:DML 返回影响的行数,例如:删除了三条数据 return 3; 插入了两条 return 2; 修改了0条 return 0;
* 情况2:非DML return 0;
*
* int row = executeUpdate(sql)
*
* 参数:sqk DQL
* 返回:resultSet 结果封装对象
* ResultSet resultSet = executeQuery(sql);
*/
//int i = statement.executeUpdate(sql);
ResultSet resultSet = statement.executeQuery(sql);
//6.查询结果集解析 resultSet
/*
* Java是一种面向对象的思维,将查询结果封装成了resultSet对象,我们应该理解,内部一定也是有行和列的,和mysql中的数据是一样的
*
* resultSet -> 逐行获取数据,行 -> 行的列的数据
*
* 想要进行数据解析,需要进行两件事:
* 1.移动游标,指定获取数据行
* resultSet内部包含一个游标,指定当前行数据
* 默认游标指定的是第一行数据之前,可以调用next方法向后移动一行游标
* 如果有很多行数据,可以是有while(next){获取每一行的数据}
*
* boolean = next(resultSet) 返回值:
* true:有更多行数据,并且向下移动一行
* false:没有更多行数据,不一定
* 移动光标方法有很多,只需要记住next,配合while循环获取全部数据
* 如果next不满足需求,是查询条件出问题了
* 2.获取指定数据行的列数据
* 获取方式有两种:列名或下角标
* resultSet.get类型(String columnLabel 或 int columnIndex)
* columnLabel:列名 如果有别名,写别名 select * / (id,account,password,nickname)
* select id as aid , account as ac from
* columnIndex:列的下角标获取 从左向右 从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();
}
}