JDBC代码案例
创建Maven项目,导入如下依赖:
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.26</version>
</dependency>
JDBC编程模型
准备数据集
create database huan;
use huan;
CREATE TABLE t_user(
id INT PRIMARY KEY AUTO_INCREMENT COMMENT '用户主键',
account VARCHAR(20) NOT NULL UNIQUE COMMENT '账号',
password VARCHAR(64) NOT NULL COMMENT '密码',
nickname VARCHAR(20) NOT NULL COMMENT '昵称');
INSERT INTO t_user(account,password,nickname) VALUES
('root','123456','经理'),('admin','666666','管理员');
基于statement演示查询
import java.sql.*;
/**
* @author : Aurora
* @Date : 2023/1/3
* @Describe : 使用statement查询t_user表下全部的数据
*/
public class StatementQueryPart {
/**
* DriverManager : 驱动
* Connection : url连接接口
* Statement :
* Result :
*
* @param args
*/
public static void main(String[] args) throws SQLException {
//注册驱动
//如果驱动版本是8+ : 则驱动 com.mysql.cj.jdbc.Driver
//如果驱动版本是5+ : 则驱动 com.mysql.jdbc.Driver
DriverManager.registerDriver(new com.mysql.cj.jdbc.Driver());
//获取连接
//Java和数据库创建连接,肯定调用某个方法,而这个方法也要填入数据库的基本信息
/**
* ip地址:localhost
* 端口号(port):13306
* 账号:root
* 密码:123456
* 连接数据库的名称:huan
*/
String url = "jdbc:mysql://localhost:13306/huan";
String user = "root";
String pass = "123456";
/**
* 参数1:url -> jdbc:数据库厂商名://ip地址:port//数据库名
* 参数2:username -> 数据库软件账号
* 参数3:password -> 数据库软件密码
*/
Connection conn = DriverManager.getConnection(url, user, pass);
//创建Statement
Statement statement = conn.createStatement();
//发送sql语句,并且返回结果
String sql = "select * from t_user";
//执行查询语句的方法
ResultSet resultSet = statement.executeQuery(sql);
//进行结果集解析
//看是否有下一行数据,有的话就可以获取,
while (resultSet.next()) {
int id = resultSet.getInt("id");
String account = resultSet.getString("account");
String password = resultSet.getString("password");
String nickname = resultSet.getString("nickname");
System.out.println(id + "--" + account + "--" + password + "--" + nickname);
}
//关闭资源
resultSet.close();
statement.close();
conn.close();
}
}
引出的问题
- 明确jdbc流程和详细讲解使用(注册驱动,获取连接,发送语句,结果解析)
- 发现问题,引出preparedstatement
案例
模拟登录,控制台输入账号和密码,判断是否登陆成功成功
import com.mysql.cj.jdbc.Driver;
import java.sql.*;
import java.util.Properties;
import java.util.Scanner;
/**
* @author : Aurora
* @Date : 2023/1/4
* @Describe : 模拟用户登录
* 步骤:
* 1,输入账号和密码
* 2,进行数据库信息查询(t_user)
* 3,反馈数据库登录成功还是失败
* 思路:
* 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());
* 问题:会注册两个驱动,
* 1,第一个驱动是方法本身,DriverManager.registerDriver()
* 2,第二个驱动是调用这个类的时候直接进入静态代码块中调用Driver.static{ DriverManager.registerDriver() }
*
* 解决:直想注册一个驱动,只触发静态代码块即可!Driver
* 触发静态代码块:类加载机制:类加载的时刻,会触发静态代码块!
* 加载[class->jvm虚拟机的class对象],
* 连接[验证(检查文件类型)->准备(静态变量默认值)->解析(触发静态代码块)],
* 初始化(静态属性赋真实值)
*
* 触发类加载:
* 1,new 关键字
* 2,调用静态方法
* 3,调用静态属性
* 4,接口1.8 default默认实现
* 5,反射
* 6,子类触发父类
* 7,程序的入口admin
*
*/
//方案一:
//DriverManager.registerDriver(new Driver());
//方案二:注册驱动,固定写法,mysql新版本驱动 | 换成oracle | 还要修改代码
//new Driver();
//方案三:反射
//字符串 -> 提取到外部的配置文件 -> 可以在不改变代码的情况下,完成数据库驱动的切换
Class.forName("com.mysql.cj.jdbc.Driver");//触发类加载,触发静态代码块的调用
//2,获取数据库连接
/**
* 允许开发者,用不同的形式传入数据库连接的核心参数!
*
* 核心属性:
* 1,数据库软件所在的主机IP地址:localhost | 127.0.0.1
* 2,数据库软件所在的主机的端口号:13306
* 3,连接的具体数据库:huan
* 4,连接的账号:root
* 5,连接的密码:123456
* 6,可选的信息(暂时无)
*
*
* 三个参数:
* String url -> jdbc:数据库名称[mysql|oracle]://ip地址:端口号/数据库名称
* String user -> root
* String password -> 123456
*
* 二个参数:
* String url
* Properties info: 存储账号和密码
* 类似于Map 只不过 key = value 都是字符串形式
* key user:账号信息
* key password:密码信息
*
* 一个参数:String url
* jdbc:mysql://localhost:13306/huan?user=root&password=123456
*
* 可选属性:8.0.25版本之后,自动识别地区
* serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=true
*
*/
String url = "jdbc:mysql://localhost:13306/huan";
String user = "root";
String pass = "123456";
//方案一:
Connection connection = DriverManager.getConnection(url, user, pass);
//方案二:
// Properties properties = new Properties();
// properties.setProperty("user","root");
// properties.setProperty("password","123456");
// DriverManager.getConnection(url,properties);
//方案三:忽略
//3.创建发送sql语句的statement对象
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返回影响的行数,例如:删除了三条数据,return 3;插入了两条数据 return 2 ; 修改了0条数据 return 0;
* 情况2:非DML return 0;
* int row = executeUpdate(sql)
*
* 参数:sql DQL
* 返回:resultSet结果封装对象
* ResultSet resultSet = statement.executeQuery(sql);
*
* Java是一种面向对象思维,将结果查询封装成了resultSet对象,我们应该理解,内部一定也是有行和列的。
* resultSet -> 逐行获取数据,行 -> 行的列的数据
*
* 想要进行数据解析,我们需要进行两件事情,1.移动游标指定获取数据行,2.获取指定数据行的列数据即可
*
* 1.游标移动问题
* resultSet内部包含一个游标,指定当前行数据!
* 默认游标指定的是第一行数据之前
* 我们可以调用next方法向后移动一行游标!
* 如果我们有很多行数据,我们可以使用while(next){获取每一行数据}
*
* boolean = next()
* true:有更多行数据,并且向下移动一行
* false:没有更多行数据,不一定!
*
* TODO:移动光标的方法有很多,记住next即可,配合while循环获取全部数据!
*
* 2.获取列的数据问题(获取光标指定的行的列的数据)
*
* resultSet.get类型(String columnLabel | int columnIndex);
* columnLabel:列名 如果有别名 写别名 select * | (id,account,password,nickname) select id as aid ,account as ac from ..
* columnIndex:列的下角标 由左向右,从1开始
*
*
*
*
*/
//int i = statement.executeUpdate(sql);
ResultSet resultSet = statement.executeQuery(sql);
//5.查询结果集解析 resultSet
// 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("登陆失败");
}
//关闭资源
resultSet.close();
statement.close();
connection.close();
}
}
大量笔记都记录在代码中,可细心观看,对敲一遍必然弄会。