作者: 欢迎观看我的文章, 注定了我们今生有缘分! 我已从事Java开发教育十多年, 怀着教书育人的情怀, 正在让更多的同学们少走弯路, 改变千万IT人的命运!
期待同学动动你的小手给'霈哥'点赞、加关注、分享给更多的朋友共同学习交流, 每天持续更新离不开你的支持! 3Q
欢迎关注我的B站,可观看本文章配套视频~~~
欢迎关注我的公众号,获取更多资料~~~
学习目标
- 能够理解JDBC的概念
- 能够使用DriverManager类
- 能够使用Connection接口
- 能够使用Statement接口
- 能够使用ResultSet接口
第一章 JDBC
1.1 JDBC概述
JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API。JDBC是Java访问数据库的标准规范,可以为不同的关系型数据库提供统一访问,它由一组用Java语言编写的接口和类组成。
JDBC需要连接驱动,驱动是两个设备要进行通信,满足一定通信数据格式,数据格式由设备提供商规定,设备提供商为设备提供驱动软件,通过软件可以与该设备进行通信。
今天我们使用的是mysql的驱动mysql-connector-java-8.0.15.jar
JDBC规范(掌握四个核心对象):
- DriverManager:用于注册驱动
- Connection: 表示与数据库创建的连接
- Statement: 操作数据库sql语句的对象
- ResultSet: 结果集或一张虚拟表
1.2 JDBC原理
Java提供访问数据库规范称为JDBC,而生产厂商提供规范的实现类称为驱动。
JDBC是接口,驱动是接口的实现,没有驱动将无法完成数据库连接,从而不能操作数据库!每个数据库厂商都需要提供自己的驱动,用来连接自己公司的数据库,也就是说驱动一般都由数据库生成厂商提供。
1.3 JDBC入门案例
准备数据
之前我们学习了sql语句的使用,并创建的分类表category及 用户表users,今天我们将使用JDBC对分类表进行增删改查操作。
#创建分类表
create table category(
cid int PRIMARY KEY AUTO_INCREMENT,
cname varchar(100)
);
#初始化数据
insert into category (cname) values('家电');
insert into category (cname) values('服饰');
insert into category (cname) values('化妆品');
#创建用户表
create table users(
uid int PRIMARY KEY AUTO_INCREMENT,
username varchar(100),
`password` varchar(100)
);
#初始化数据
insert into users (username, password) values('admin','1234');
insert into users (username, password) values('jack','1234');
insert into users (username, password) values('rose','1234
导入驱动jar包
创建lib目录,存放mysql的驱动mysql-connector-java-8.0.15.jar
选中mysql的jar包,右键选择“ Add as Library...” 完成jar导入
开发步骤
- 注册驱动.
- 获得连接.
- 获得执行sql语句的对象
- 执行sql语句,并返回结果
- 处理结果
- 释放资源.
案例实现
/**
* 通过JDBC 完成对 数据库表 的 增删改查操作
*/
public class JDBCDemo {
@Test
public void testJDBC() throws ClassNotFoundException, SQLException {
//1.注册驱动, 就是把 Driver.class 文件 加载到内存
Class.forName("com.mysql.jdbc.Driver");
/**
* 2.获得连接
* 参数 url : 需要连接数据库的地址 jdbc:mysql://IP地址:端口号/要连接的数据库名称
* 参数 user : 连接数据库 使用的用户名
* 参数 password: 连接数据库 使用的密码
*/
String url = "jdbc:mysql://localhost:3306/mydb";
Connection conn = DriverManager.getConnection(url, "root", "root");
System.out.println("conn = " + conn);
//3.获取执行sql语句的对象
Statement stat = conn.createStatement();
//4.执行sql语句, 并返回结果
String sql = "select * from category";
ResultSet rs = stat.executeQuery(sql);
System.out.println("rs = " + rs);
//5.处理结果
while (rs.next()) {
//int cid = rs.getInt(1); // 通过列的位置 获取值
//int cid2 = rs.getInt("cid"); //通过列的名称 获取值
int cid = rs.getInt("cid");
String cname = rs.getString("cname");
System.out.println("cid = " + cid + ", cname = " + cname);
}
//6.释放资源
rs.close();
stat.close();
conn.close();
}
}
1.4 API详解
API详解:注册驱动
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
不建议使用,原因有2个:
- 导致驱动被注册2次
- 强烈依赖数据库的驱动jar
解决办法:
Class.forName("com.mysql.jdbc.Driver");
API详解:获得链接
static Connection getConnection(String url, String user, String password)
:试图建立到给定数据库 URL 的连接。
- 参数说明:
- url 需要连接数据库的位置(网址)
- user用户名
- password 密码
- 例如:
getConnection("jdbc:mysql://localhost:3306/mydb", "root", "root");
扩展:
URL: SUN公司与数据库厂商之间的一种协议。
jdbc:mysql://localhost:3306/mydb
协议子协议 IP :端口号数据库 mysql数据库: jdbc:mysql://localhost:3306/mydb 或者 jdbc:mysql:///mydb(默认本机连接) oracle数据库: jdbc:oracle:thin:@localhost:1521:sid
API详解:java.sql.Connection接口:一个连接
接口的实现在数据库驱动中。所有与数据库交互都是基于连接对象的。
Statement createStatement();
//创建操作sql语句的对象
API详解:java.sql.Statement接口: 操作sql语句,并返回相应结果
String sql = "某SQL语句";
获取Statement语句执行平台:Statement stmt =con.createStatement();
常用方法:
-
int executeUpdate(String sql);
--执行insert update delete语句. -
ResultSet executeQuery(String sql);
--执行select语句. -
boolean execute(String sql);
--仅当执行select并且有结果时才返回true,执行其他的语句返回false.
API详解:处理结果集(注:执行insert、update、delete无需处理)
ResultSet实际上就是一张二维的表格,我们可以调用其boolean next()
方法指向某行记录,当第一次调用next()
方法时,便指向第一行记录的位置,这时就可以使用ResultSet提供的getXXX(int col)
方法来获取指定列的数据:(与数组索引从0开始不同,这里索引从1开始)
rs.next();//指向第一行
rs.getInt(1);//获取第一行第一列的数据
常用方法:
-
Object getObject(int index)
/Object getObject(String name)
获得任意对象 -
String getString(int index)
/String getString(String name)
获得字符串 -
int getInt(int index)
/int getInt(String name)
获得整形 -
double getDouble(int index)
/double getDouble(String name)
获得双精度浮点型
API详解:释放资源
与IO流一样,使用后的东西都需要关闭!关闭的顺序是先得到的后关闭,后得到的先关闭。
rs.close();
stmt.close();
con.close();
1.5 JDBC增删改查操作
插入
@Test
public void testJDBC2() throws SQLException, ClassNotFoundException {
/**
* JDBC 完成 记录的插入
* 1.注册驱动
* 2.获得连接
* 3.获得执行sql语句的对象
* 4.执行sql语句, 并返回结果
* 5.处理结果
* 6.释放资源
* 注意: 若插入中文出现乱码, 请设置编码
jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
*/
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai";
Connection conn = DriverManager.getConnection(url, "root", "root");
Statement stat = conn.createStatement();
String sql = "insert into category(cname) values('测试')";
int result = stat.executeUpdate(sql);
System.out.println("result = " + result);
stat.close();
conn.close();
}
修改
@Test
public void testJDBC3() throws SQLException, ClassNotFoundException {
/**
* JDBC 完成 记录的更新
* 1.注册驱动
* 2.获得连接
* 3.获得执行sql语句的对象
* 4.执行sql语句, 并返回结果
* 5.处理结果
* 6.释放资源
*/
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai";
Connection conn = DriverManager.getConnection(url, "root", "root");
Statement stat = conn.createStatement();
String sql = "update category set cname='测试2' where cid=4";
int result = stat.executeUpdate(sql);
System.out.println("result = " + result);
stat.close();
conn.close();
}
删除
@Test
public void testJDBC4() throws SQLException, ClassNotFoundException {
/**
* JDBC 完成 记录的删除
* 1.注册驱动
* 2.获得连接
* 3.获得执行sql语句的对象
* 4.执行sql语句, 并返回结果
* 5.处理结果
* 6.释放资源
*/
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai";
Connection conn = DriverManager.getConnection(url, "root", "root");
Statement stat = conn.createStatement();
String sql = "delete from category where cid=4";
int result = stat.executeUpdate(sql);
System.out.println("result = " + result);
stat.close();
conn.close();
}
查询
@Test
public void testJDBC5() throws SQLException, ClassNotFoundException {
/**
* JDBC 完成 基于ID的查询
* 1.注册驱动
* 2.获得连接
* 3.获得执行sql语句的对象
* 4.执行sql语句, 并返回结果
* 5.处理结果
* 6.释放资源
*/
// 通过id 查询数据
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai";
Connection conn = DriverManager.getConnection(url, "root", "root");
Statement stat = conn.createStatement();
String sql = "select * from category where cid = 3";
ResultSet rs = stat.executeQuery(sql);
if (rs.next()) {
int cid = rs.getInt("cid");
String cname = rs.getString("cname");
System.out.println("cid = " + cid + ",cname = " +cname);
} else {
System.out.println("数据没有查到");
}
rs.close();
stat.close();
conn.close();
}
1.6 JDBC工具类
“获得数据库连接”操作,将在以后的增删改查所有功能中都存在,可以封装工具类JDBCUtils。提供获取连接对象的方法,从而达到代码的重复利用。
该工具类提供方法:public static Connection getConnection()
。代码如下:
- jdbc.properties文件
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
jdbc.user=root
jdbc.password=root
- JDBC工具类
public class JDBCUtils {
private static String driver;
private static String url;
private static String user;
private static String password;
static {
try {
//使用类加载器, 读取配置文件
InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
Properties prop = new Properties();
prop.load(is);
driver = prop.getProperty("jdbc.driver");
url = prop.getProperty("jdbc.url");
user = prop.getProperty("jdbc.user");
password = prop.getProperty("jdbc.password");
//注册驱动
Class.forName(driver);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 返回连接对象 Connection
*/
public static Connection getConnection() throws SQLException {
Connection conn = DriverManager.getConnection(url, user, password);
return conn;
}
/**
* 释放资源
*/
public static void close(ResultSet rs, Statement stat, Connection conn) throws SQLException {
if (rs != null) {
rs.close();
}
if (stat != null) {
stat.close();
}
//看Connection来自哪里, 如果Connection是从连接池里面获得的, close()方法其实是归还; 如果Connection是创建的, 就是销毁
if (conn != null) {
conn.close();
}
}
}
- 使用JDBC工具类 完成查询
@Test
public void testJDBC6() throws SQLException {
/**
* 使用JDBC工具类, 完成查询所有分类
* 1.通过JDBC工具类, 获得连接
* 2.获得执行sql语句的对象
* 3.执行sql语句, 并返回结果
* 4.处理结果
* 5.释放资源
*/
Connection conn = JDBCUtils.getConnection();
Statement stat = conn.createStatement();
ResultSet rs = stat.executeQuery("select * from category");
while (rs.next()) {
int cid = rs.getInt("cid");
String cname = rs.getString("cname");
System.out.println("cid = " + cid + ",cname = " + cname);
}
JDBCUtils.close(rs, stat, conn);
}