jdbc开发
JDBC介绍
JDBC(Java Data Base Connectivity,java数据库连接)是Java访问数据库的标准规范,是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。
驱动则是数据库厂商对jdbc接口的具体实现,开发人员只需要学会jdbc接口的调用,导入相应驱动实现就可以实现对不同数据库的操作
JDBC的作用:JDBC是用于执行SQL语句的Java API(Java语言通过JDBC可以操作数据库)。
由来
直接写代码操作数据库会产生以下问题:
- 不同数据库的操作方式和解析方式不同,每个数据库都要写一套代码
- 不同数据库相互切换麻烦。
JDBC规范定义接口,具体的实现由各大数据库厂商来实现
JDBC是Java访问数据库的标准规范。真正怎么操作数据库还需要具体的实现类,也就是数据库驱动。每个数据库厂商根据自家数据库的通信格式编写好自己数据库的驱动。所以我们只需要会调用JDBC接口中的方法即可。数据库驱动由数据库厂商提供。
JDBC的包
java.sql
:JDBC访问数据库的基础包,在JavaSE中的包。如:java.sql.Connection
javax.sql
: JDBC访问数据库的扩展包- 数据库的驱动,各大数据库厂商来实现。如:MySQL的驱动:
com.mysql.jdbc.Driver
JDBC四个核心对象
这几个类都是在java.sql包中
- DriverManager: 用于注册驱动,获取连接
- Connection: 表示与数据库创建的连接
- Statement: 用于执行静态 SQL 语句并返回它所生成结果的对象
- ResultSet: 结果集或一张虚拟表(客户端表数据的对象)
DriverManager
java.sql.DriverManager
提供驱动的基础服务,对驱动实现细节进行屏蔽
注册加载驱动,用于获取连接
registerDriver():注册驱动
源代码
1
2
3
4
5
6
7
8
9
10public class Driver extends NonRegisteringDriver implements java.sql.Driver {
// Register ourselves with the DriverManager
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
}
加载驱动的方式
- 推荐使用类加载,只注册一次
创建Driver对象,注册了二次驱动
1
2
3
4
5
6
7
8
9
10
11Driver driver = new com.mysql.jdbc.Driver();
//注册驱动
DriverManager.registerDriver(driver);
Enumeration<Driver> drivers = DriverManager.getDrivers();
while(drivers.hasMoreElements()) {
nums ++;
//打印出驱动
System.out.println(drivers.nextElement());
}
//打印出驱动个数
System.out.println("驱动个数:" + nums);1
2
3
4
5
6//注释掉:DriverManager.registerDriver(driver);可以看到驱动个数为1个
//说明了DriverManager.registerDriver(driver);这行代码可以去掉,如果加上,就会出现了两个驱动,
// 因为在创建Driver这个对象的时候,其内的static语句块会自动执行了。
Driver driver = new com.mysql.jdbc.Driver();
//注册驱动
// DriverManager.registerDriver(driver);类加载,使用静态代码块
1
2
3//创建Class对象时,会执行类的静态代码块
//在com.mysql.jdbc.Driver类的静态代码块中,注册驱动
Class.forName("com.mysql.jdbc.Driver");// 静态代码块
Connection
代表客户端程序与数据库的连接
与数据的交互都需要依赖于此连接
方法:
Statement createStatement()
: 创建一个 Statement 对象来将 SQL 语句发送到数据库- prepareStatement(sql);
- setAutoCommit(false);
- commit();
- rollback();
- getMetaData();获取连接的元数据信息,和连接相关的数据(元数据:解释数据的数据)
- getDatabaseProductName():数据库产品的名字
- getDriverName():获取驱动的信息
- getURL(): 获取连接的URL;
示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22// jdbc:公共协议+子协议+ip地址+数据库名字
// ? 参数
// useSSL=true SSL(Secure Sockets Layer 安全套接层),
// 及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种安全协议
Connection connection = null;
connection = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/bd1807?useSSL=true",
"root",
"123456"
);
DatabaseMetaData metaData = connection.getMetaData();
metaData.getDatabaseProductName();//数据库产品的名字
System.out.println(metaData.getDriverName());//获取驱动的
metaData.getURL();
// 能得到connection,说明数据库已经连接
System.out.println(connection);
DatabaseMetaData metaData = connection.getMetaData();
metaData.getDatabaseProductName();//数据库产品的名字
System.out.println(metaData.getDriverName());//获取驱动的信息
metaData.getURL();
statement
boolean execute(String sql)
:此方法可以执行任意sql语句。- 返回boolean值,表示是否返回ResultSet结果集。
- 仅当执行select语句,且有返回结果时返回true,
- 其它语句都返回false;
ResultSet executeQuery(String sql)
- 根据查询语句返回结果集,只能执行SELECT语句
int executeUpdate(String sql)
;- 根据执行的DML(INSERT、UPDATE、DELETE)语句
- 返回受影响的行数;用于增删改
- executeBatch(); //批处理,返回int[]
ResultSet
- 代表返回结果的结果集
- ResultSet内部有一个指针,刚开始记录开始位置
- 调用next方法, ResultSet内部指针会移动到下一行数据(遍历一行)
- 我们可以通过ResultSet得到一行数据 getXxx得到某列数据
- getMetaData(): 获取结果集的元数据
- getColumnCount():获取结果的列
- getColumnName(int column):获取对应列的名字
- getInt(“字段名”);
- getString(“字段名”)
- 遍历的时候,得到字段的名字,通过反射,获得属性Field,赋值封装到对象
jdbc开发
创建项目
- 新建java工程
- 新建lib文件夹,用来放library文件;
- 导入jdbc的实现类(数据库的jar)
- 右键jar—> buildPath —-> add to build path
连接数据库
注册驱动,Drivermanager管理具体的驱动程序,实现对底层屏蔽,对开发人员提供统一的访问
建立连接
url : jdbc:公共协议+子协议+ip地址+数据库名字
- URL地址格式:
协议名:子协议://服务器名或IP地址:端口号/数据库名?参数=参数值
,localhost:3306可以省略 - 如果出现乱码需要加上参数:
?characterEncoding=utf8
,表示让数据库以UTF-8编码来处理数据。
- URL地址格式:
user: 用户名
password: 密码
发送sql
Statement对象:实现sql发送
Statement statement = connection.createStatement();
- statement.executeQuery(sql);//查询语句,返回一个结果集
- statement.executeUpdate(sql); //增删改,DDL,返回影响的行数##
- statement.executeBatch();//批处理,返回int[]
处理响应结果
ResultSet底层维护了一个指向结果集的游标
程序中每次读取一行,一个一个读(游标指向行的(字段)信息)
- next():游标向下,返回boolean类型,true有数据
- getInt(String str):通过字段名称获取
1 | ResultSet result = statement.executeQuery(sql);// 查询语句,返回一个结果集 |
释放资源
1 | finally { |
示例
代码如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43import java.sql.*;
public class JdbcDemo01 {
public static void main(String[] args) throws ClassNotFoundException {
Class.forName("com.mysql.jdbc.Driver");
Connection conn = null;
Statement statement = null;
ResultSet resultSet = null;
String url = "jdbc:mysql://localhost:3306/test";
String username = "root";
String password = "123456";
try {
conn = DriverManager.getConnection(url, username, password);
statement = conn.createStatement();
String sql = "select * from user";
resultSet = statement.executeQuery(sql);
if (resultSet.next()) {
String name1 = resultSet.getString("name");
String username1 = resultSet.getString("username");
String password1 = resultSet.getString("password");
System.out.println("姓名:" + name1 + ",用户名:" + username1 + ",密码:" + password1);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
JDBC事务
事务的基本概念:事务指逻辑上的一组操作,组成这组操作的各个单元,要不全部成功,要不全部不成功。
事务的特点
特点 | 描述 |
---|---|
原子性 | 一个事务是不可分割的最小单位 |
一致性 | 一个事务在执行之前和之后都必须处于一致性状态 |
隔离性 | 多个并发事务之间的操作不会互相干扰 |
持久性 | 提交的事务会使得修改的书是永久的 |
API介绍
1 | Connection接口中与事务有关的方法 |
使用步骤
注册驱动
Class.forName("com.mysql.jdbc.Driver");
获取连接
DriverManager.getConnection(url, username, password);
获取到Statement
Connection.createStatement();
开启事务
Connection.setAutoCommit(false);//设置不自动提交事务
使用Statement执行SQL
Statement.executeUpdate(sql);
提交或回滚事务
Connection.commit();//提交事务
关闭资源
Statement.close();
Connection.close();
1 | import java.sql.*; |
jdbc工具类
通过上面案例需求我们会发现每次去执行SQL语句都需要注册驱动,获取连接,得到Statement,以及释放资源。发现很多重复的劳动,我们可以将重复的代码定义到某个类的方法中。直接调用方法,可以简化代码。那么我们接下来定义一个JDBCUtil类。把注册驱动,获取连接,得到Statement,以及释放资源的代码放到这个类的方法中。以后直接调用方法即可。
我们可以将重复的代码定义到某个类的方法中。直接调用方法,可以简化代码。定义一个JDBCUtil类。把注册驱动,获取连接,得到Statement,以及释放资源的代码放到这个类的方法中,以后直接调用方法即可。
1 | 编写JDBC工具类步骤 |