- 日报 11.11 JDBC
- 学习内容
- JDBC
- JDBC 的核心 API
- DriverManager 类
- Connection 接口 :
- Statement接口:
- PreparedStatemen 接口: 一个 SQL 语句对象,是 `Statement` 的子接口。
- ResultSet 接口: 用于封装数据库查询的结果集,返回给客户端 。
- JDBC 的执行步骤
- 任务内容
- 任务2
- 任务2
JDBC 英文名为:Java Data base Connectivity(Java 数据库连接),官方解释它是独立于数据库的标准的 Java API。
JDBC 是一种规范,它提供一套完整的允许便捷式访问底层数据库的接口,简单来说它就是 Java 与数据库连接的桥梁或者插件,通过它,就能用 Java 代码操作数据库,实现数据库的增删改查、存储过程和事务处理等功能。
JDBC 的核心 API- DriverManager 类
作用:
- 管理和注册驱动
- 创建数据库的连接
类中方法:
Connection getConnection (String url, String user, String password) :通过连接字符串,用户名,密码来得到数据。
库的连接对象
Connection getConnection (String url, Properties info) :通过连接字符串,属性对象来得到连接对象。
- Connection 接口 :
一个连接对象,可用于创建 Statement 和 PreparedStatement 对象。
类中方法:
Statement createStatement() :创建一条 SQL 语句对象。
- Statement接口:
一个 SQL 语句对象,用于将 SQL 语句发送给数据库服务器。
类中方法:
int executeUpdate(String sql) :
- 用于发送 DML 语句,增删改的操作,insert、update、delete
- 参数:SQL 语句
- 返回值:返回对数据库影响的行数
ResultSet executeQuery(String sql) :
- 用于发送 DQL 语句,执行查询的操作。select
- 参数:SQL 语句
- 返回值:查询的结果集
释放资源:
-
需要释放的对象:ResultSet 结果集,Statement 语句,Connection 连接
-
释放原则:先开的后关,后开的先关。ResultSet → Statement → Connection
-
放在哪个代码块中:finally 块
- PreparedStatemen 接口: 一个 SQL 语句对象,是 Statement 的子接口。
- ResultSet 接口: 用于封装数据库查询的结果集,返回给客户端 。
boolean next()
- 游标向下移动 1 行
- 返回 boolean 类型,如果还有下一条记录,返回 true,否则返回 false
数据类型 getXxx()
- 通过字段名,参数是 String 类型。返回不同的类型
- 通过列号,参数是整数,从 1 开始。返回不同的类型
- 还有 boolean 型、Long 型,很多很多
- 注册驱动
- 获取数据库对象
- 定义 SQL 语句
- 获取执行 SQL 的对象
- 执行 SQL 语句
- 处理结果
- 释放资源
1.)使用 JDBC 连接数据库并创建如下数据表:
| 编码 | 部门编码 | 姓名 | 性别 | 年龄 | 入职日期 |
|---|---|---|---|---|---|
| 1 | 1 | 李雷 | 男 | 22 | 2021-01-09 |
| 2 | 1 | 韩梅梅 | 21 | 2020-02-23 | |
| 3 | 2 | 赵男 | 女 | 23 | 2018-05-17 |
| 4 | 3 | 周倩 | 女 | 20 | |
| 5 | 3 | 夏雨 | 男 | 2017-09-29 |
| 编码 | 部门名称 |
|---|---|
| 1 | 研发部 |
| 2 | 产品部 |
| 3 | 运营部 |
| 4 | 财务部 |
答:创建表格
package com.xxm.advanced_camp.mission16_JDBC;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class task1 {
public static void main(String[] args) throws Exception {
//1. 注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取数据库连接对象
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/study", "root", "root");
//3.定义 sql 语句
//创建员工表
String sql1 = "CREATE TABLE employers_table(n" +
"id INTEGER(8) NOT NULL AUTO_INCREMENT,n" +
"department_id INTEGER(8) NOT NULL,n" +
"emp_name CHAr(16) NOT NULL,n" +
"gender CHAr(8),n" +
"age INTEGER(8),n" +
"join_date CHAr(32),n" +
"PRIMARY KEY(id)n" +
");";
//创建部门表
String sql2 = "CREATE TABLE departments_table(n" +
"department_idtINTEGER(4) NOT NULL AUTO_INCREMENT,n" +
"department_nametCHAr(16) NOT NULL,n" +
"PRIMARY KEY(department_id)n" +
");";
//4.获取执行 sql 的对象
Statement stmt = conn.createStatement();
//5.执行 sql 语句
int count1 = stmt.executeUpdate(sql1);
int count2 = stmt.executeUpdate(sql2);
//6.处理结果
System.out.println(count1);
System.out.println(count2);
//7.释放资源
stmt.close();
conn.close();
}
}
任务2
使用 JDBC 完成如下任务:
- 将韩梅梅的性别更新为女,夏雨的年龄更新为 24 岁,并将周倩的入职日期更新为 2019-07-01;
- 查询所有在 2018 年之后入职且年龄大于 22 岁的员工;
- 分别使用内连接、左外连接、右外连接和全连接,实现员工表的部门表的关联查询;
- 利用 SQL 函数求出所有员工的平均年龄,找出年龄最大的员工和最小的员工;
- 将员工表按照年龄排序,将员工表按照入职日期排序;
- 将员工按照性别分组然后统计男女的人数;
- 开启事务,并通过不同的事务隔离级别完成数据更新;
- 给员工表插入十万条数据(员工姓名、年龄、日期都可以随机生成),然后再使用批处理完成同样的功能,比较两种操作的耗时。
答:1-7,由于在 SQL 中做过, 在 JDBC 中就不再做了。
但是要注意几个点:
- JDBC 的执行步骤
- 注册驱动
- 获取数据库对象
- 定义 SQL 语句
- 获取执行 SQL 的对象
- 执行 SQL 语句
- 处理结果
- 释放资源
答:
题中,各个要求不同的点,主要在 第三步,SQL 语句不同。
其中,第 1 个要求,在第 5-6 步的时候,要使用 executeUpdate , 接收结果时使用 int 类型(处理影响的行数);
后面几个要求,要使用 executeQuerey ,接收结果时使用 Result 类的对象,输出时类似这样。
第七步,释放资源时,要先关闭结果集 ResultSet,再关闭 Statement,再关闭 Connection 。
给员工表插入十万条数据(员工姓名、年龄、日期都可以随机生成),然后再使用批处理完成同样的功能,比较两种操作的耗时。
package com.xxm.advanced_camp.mission16_JDBC;
import com.mysql.cj.x.protobuf.MysqlxPrepare;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.Statement;
public class task3 {
public static void main(String[] args) throws Exception {
//开始时间
long startTime = System.currentTimeMillis();
//1. 注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取数据库连接对象
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/study", "root", "root");
//3.定义 sql 语句 ,并执行
//第一行数据,设置主键为1
String sql0 = "INSERT INTO task3 (id,emp_name,age)n" +
"VALUESn" +
"(1,SUBSTRINg(MD5(RAND()),1,20),FLOOR(RAND()*80));";
Statement stmt = conn.createStatement();
//声明计数器,执行第一行
int count = stmt.executeUpdate(sql0);
//第2-100000行数据,插入时主键选择 0,让它自增
for (int i = 1; i < 10000; i++) {
String sql = "INSERT INTO task3 (id,emp_name,age)n" +
"VALUESn" +
"(0,SUBSTRINg(MD5(RAND()),1,20),FLOOR(RAND()*80));";
count += stmt.executeUpdate(sql);
}
System.out.println("本次共添加了 " + count + " 行数据");
//7.释放资源
stmt.close();
conn.close();
//结束时间
long endTime = System.currentTimeMillis();
System.out.println("程序运行时间为: " + (endTime - startTime));
}
}
//运行结果:
//本次共添加了 10000 行数据
//程序运行时间为: 43078
使用批处理的方法:
package com.xxm.advanced_camp.mission16_JDBC;
import com.mysql.cj.x.protobuf.MysqlxPrepare;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.Statement;
public class task3 {
public static void main(String[] args) throws Exception {
//开始时间
long startTime = System.currentTimeMillis();
//1. 注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取数据库连接对象
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/study", "root", "root");
//3.定义 sql 语句 ,并执行
//第一行数据,设置主键为1
String sql0 = "INSERT INTO task3 (id,emp_name,age)n" +
"VALUESn" +
"(1,SUBSTRINg(MD5(RAND()),1,20),FLOOR(RAND()*80));";
Statement stmt = conn.createStatement();
//声明计数器,执行第一行
int count = stmt.executeUpdate(sql0);
//第2-100000行数据,插入时主键选择 0,让它自增
for (int i = 1; i < 10000; i++) {
String sql = "INSERT INTO task3 (id,emp_name,age)n" +
"VALUESn" +
"(0,SUBSTRINg(MD5(RAND()),1,20),FLOOR(RAND()*80));";
count += stmt.executeUpdate(sql);
}
System.out.println("本次共添加了 " + count + " 行数据");
//7.释放资源
stmt.close();
conn.close();
//结束时间
long endTime = System.currentTimeMillis();
System.out.println("程序运行时间为: " + (endTime - startTime));
}
}
# 日报 11.11 JDBC
# 学习内容
## JDBC
JDBC 英文名为:Java Data base Connectivity(Java 数据库连接),官方解释它是独立于数据库的标准的 Java API。
JDBC 是一种规范,它提供一套完整的允许便捷式访问底层数据库的`接口`,简单来说它就是 Java 与数据库连接的桥梁或者插件,通过它,就能用 Java 代码操作数据库,实现数据库的增删改查、存储过程和事务处理等功能。
### JDBC 的核心 API
1. #### DriverManager 类
作用:
- 管理和注册驱动
- 创建数据库的连接
**类中方法**:
`Connection getConnection (String url, String user, String password)` :通过连接字符串,用户名,密码来得到数据。
库的连接对象
`Connection getConnection (String url, Properties info)` :通过连接字符串,属性对象来得到连接对象。
1. #### Connection 接口 :
一个连接对象,可用于创建 `Statement` 和 `PreparedStatement` 对象。
**类中方法**:
`Statement createStatement()` :创建一条 SQL 语句对象。
2. #### Statement接口:
一个 SQL 语句对象,用于将 SQL 语句发送给数据库服务器。
**类中方法**:
`int executeUpdate(String sql)` :
- 用于发送 DML 语句,增删改的操作,insert、update、delete
- 参数:SQL 语句
- 返回值:返回对数据库影响的行数
`ResultSet executeQuery(String sql)` :
- 用于发送 DQL 语句,执行查询的操作。select
- 参数:SQL 语句
- 返回值:查询的结果集
**释放资源**:
1. 需要释放的对象:ResultSet 结果集,Statement 语句,Connection 连接
2. 释放原则:先开的后关,后开的先关。ResultSet → Statement → Connection
3. 放在哪个代码块中:finally 块
3. #### PreparedStatemen 接口: 一个 SQL 语句对象,是 `Statement` 的子接口。
4. #### ResultSet 接口: 用于封装数据库查询的结果集,返回给客户端 。
`boolean next()`
- 游标向下移动 1 行
- 返回 boolean 类型,如果还有下一条记录,返回 true,否则返回 false
`数据类型 getXxx()`
- 通过字段名,参数是 String 类型。返回不同的类型
- 通过列号,参数是整数,从 1 开始。返回不同的类型
- 还有 boolean 型、Long 型,很多很多
### JDBC 的执行步骤
1. 注册驱动
2. 获取数据库对象
3. 定义 SQL 语句
4. 获取执行 SQL 的对象
5. 执行 SQL 语句
6. 处理结果
7. 释放资源
# 任务内容
1.)使用 JDBC 连接数据库并创建如下数据表:
| 编码 | 部门编码 | 姓名 | 性别 | 年龄 | 入职日期 |
| ---- | ---- | :--: | ---- | ---- | ---------- |
| 1 | 1 | 李雷 | 男 | 22 | 2021-01-09 |
| 2 | 1 | 韩梅梅 | | 21 | 2020-02-23 |
| 3 | 2 | 赵男 | 女 | 23 | 2018-05-17 |
| 4 | 3 | 周倩 | 女 | 20 | |
| 5 | 3 | 夏雨 | 男 | | 2017-09-29 |
| 编码 | 部门名称 |
| ---- | ---- |
| 1 | 研发部 |
| 2 | 产品部 |
| 3 | 运营部 |
| 4 | 财务部 |
答:创建表格
```java
package com.xxm.advanced_camp.mission16_JDBC;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class task1 {
public static void main(String[] args) throws Exception {
//1. 注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取数据库连接对象
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/study", "root", "root");
//3.定义 sql 语句
//创建员工表
String sql1 = "CREATE TABLE employers_table(n" +
"id INTEGER(8) NOT NULL AUTO_INCREMENT,n" +
"department_id INTEGER(8) NOT NULL,n" +
"emp_name CHAr(16) NOT NULL,n" +
"gender CHAr(8),n" +
"age INTEGER(8),n" +
"join_date CHAr(32),n" +
"PRIMARY KEY(id)n" +
");";
//创建部门表
String sql2 = "CREATE TABLE departments_table(n" +
"department_idtINTEGER(4) NOT NULL AUTO_INCREMENT,n" +
"department_nametCHAr(16) NOT NULL,n" +
"PRIMARY KEY(department_id)n" +
");";
//4.获取执行 sql 的对象
Statement stmt = conn.createStatement();
//5.执行 sql 语句
int count1 = stmt.executeUpdate(sql1);
int count2 = stmt.executeUpdate(sql2);
//6.处理结果
System.out.println(count1);
System.out.println(count2);
//7.释放资源
stmt.close();
conn.close();
}
}
任务2
使用 JDBC 完成如下任务:
- 将韩梅梅的性别更新为女,夏雨的年龄更新为 24 岁,并将周倩的入职日期更新为 2019-07-01;
- 查询所有在 2018 年之后入职且年龄大于 22 岁的员工;
- 分别使用内连接、左外连接、右外连接和全连接,实现员工表的部门表的关联查询;
- 利用 SQL 函数求出所有员工的平均年龄,找出年龄最大的员工和最小的员工;
- 将员工表按照年龄排序,将员工表按照入职日期排序;
- 将员工按照性别分组然后统计男女的人数;
- 开启事务,并通过不同的事务隔离级别完成数据更新;
- 给员工表插入十万条数据(员工姓名、年龄、日期都可以随机生成),然后再使用批处理完成同样的功能,比较两种操作的耗时。
答:1-7,由于在 SQL 中做过, 在 JDBC 中就不再做了。
但是要注意几个点:
- JDBC 的执行步骤
- 注册驱动
- 获取数据库对象
- 定义 SQL 语句
- 获取执行 SQL 的对象
- 执行 SQL 语句
- 处理结果
- 释放资源
答:
题中,各个要求不同的点,主要在 第三步,SQL 语句不同。
其中,第 1 个要求,在第 5-6 步的时候,要使用 executeUpdate , 接收结果时使用 int 类型(处理影响的行数);
后面几个要求,要使用 executeQuerey ,接收结果时使用 Result 类的对象,输出时类似这样。
第七步,释放资源时,要先关闭结果集 ResultSet,再关闭 Statement,再关闭 Connection 。
给员工表插入十万条数据(员工姓名、年龄、日期都可以随机生成),然后再使用批处理完成同样的功能,比较两种操作的耗时。
package com.xxm.advanced_camp.mission16_JDBC;
import com.mysql.cj.x.protobuf.MysqlxPrepare;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.Statement;
public class task3 {
public static void main(String[] args) throws Exception {
//开始时间
long startTime = System.currentTimeMillis();
//1. 注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取数据库连接对象
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/study", "root", "root");
//3.定义 sql 语句 ,并执行
//第一行数据,设置主键为1
String sql0 = "INSERT INTO task3 (id,emp_name,age)n" +
"VALUESn" +
"(1,SUBSTRINg(MD5(RAND()),1,20),FLOOR(RAND()*80));";
Statement stmt = conn.createStatement();
//声明计数器,执行第一行
int count = stmt.executeUpdate(sql0);
//第2-100000行数据,插入时主键选择 0,让它自增
for (int i = 1; i < 10000; i++) {
String sql = "INSERT INTO task3 (id,emp_name,age)n" +
"VALUESn" +
"(0,SUBSTRINg(MD5(RAND()),1,20),FLOOR(RAND()*80));";
count += stmt.executeUpdate(sql);
}
System.out.println("本次共添加了 " + count + " 行数据");
//7.释放资源
stmt.close();
conn.close();
//结束时间
long endTime = System.currentTimeMillis();
System.out.println("程序运行时间为: " + (endTime - startTime));
}
}
//运行结果:
//本次共添加了 10000 行数据
//程序运行时间为: 43078
使用批处理的方法:
package com.xxm.advanced_camp.mission16_JDBC;
import com.mysql.cj.x.protobuf.MysqlxPrepare;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.Statement;
public class task3 {
public static void main(String[] args) throws Exception {
//开始时间
long startTime = System.currentTimeMillis();
//1. 注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取数据库连接对象
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/study", "root", "root");
//3.定义 sql 语句 ,并执行
//第一行数据,设置主键为1
String sql0 = "INSERT INTO task3 (id,emp_name,age)n" +
"VALUESn" +
"(1,SUBSTRINg(MD5(RAND()),1,20),FLOOR(RAND()*80));";
Statement stmt = conn.createStatement();
//声明计数器,执行第一行
int count = stmt.executeUpdate(sql0);
//第2-100000行数据,插入时主键选择 0,让它自增
for (int i = 1; i < 10000; i++) {
String sql = "INSERT INTO task3 (id,emp_name,age)n" +
"VALUESn" +
"(0,SUBSTRINg(MD5(RAND()),1,20),FLOOR(RAND()*80));";
count += stmt.executeUpdate(sql);
}
System.out.println("本次共添加了 " + count + " 行数据");
//7.释放资源
stmt.close();
conn.close();
//结束时间
long endTime = System.currentTimeMillis();
System.out.println("程序运行时间为: " + (endTime - startTime));
}
}
//运行结果:
//本次共添加了 10000 行数据
//程序运行时间为: 54940
其实批处理应该是比普通循环快一些的…这里比普通循环要慢,原因无法解释。
//运行结果:
//本次共添加了 10000 行数据
//程序运行时间为: 54940
其实批处理应该是比普通循环快一些的..这里比普通循环要慢,原因无法解释。



