JDBC 使用

📚前言

前面我有篇文章介绍了 Java 连接 MySQL 数据库 ,后来在韩顺平老师视频里面学习到更加多的知识,也了解到 JDBC 规范对厂商的数据库操作统一了接口使用。

这篇文章有部分内容和之前内容一样,但是其内容比之前的更加完善。

📚JDBC

一套用于执行 SQL 语句的 Java API 接口,不同数据库厂商通过 JDBC 接口来为其数据库实现相应操作,例如数据库连接、执行 SQL 语句、获取结果集等等。

DriverManager
Connection
Statement
PreparedStatement
CallableStatement
Result
继承
继承
继承
继承
Wrapper
Statement
AutoCloseable
PreparedStatement
CallableStatement

📕Statement 区别表

SQL 注入占位符INOUT
Statement✔️
PreparedStatement✔️✔️
CallableStatement✔️✔️✔️
  • IN、OUT 指存储过程时定义的参数
    • IN:存储过程内部修改参数值,不会反馈到数据表数据里面,类似于局部变量
    • OUT:存储过程内部修改参数值,会反馈到数据表数据里面,类似于全局变量

📕JDBC 接口使用

加载JDBC驱动程序
获取数据库连接
执行SQL语句
处理结果集
释放资源

📕加载JDBC驱动

Class.forName("com.mysql.jdbc.Driver");

在 Java6 即 JDBC4.0 之后可以自动去加载并注册驱动,通过数据库厂商提供的驱动文件。

com.mysql.jdbc.Driver
com.mysql.fabric.jdbc.FabricMySQLDriver

例如 MySQL 的驱动文件(JAR包)里面,在 META-INF -> services -> java.sql.Driver 文件包含 java.sql.Driver 的 JDBC 驱动程序实现的名称,即实现驱动的类为 com.mysql.jdbc.Driver

像 Redis 数据库就没有遵守 JDBC 规范,它拥有自己的连接方式,也没有在 META-INF 目录下提供驱动服务,因此当使用 Redis 数据库时,Java 官方的 sql 没法来操作 Redis 数据库。
在这里插入图片描述

提供驱动服务并遵守 JDBC 规范的数据库

市面上大部分数据库厂商都会遵守 JDBC 规范,这样不仅可以减轻开发人员的工作量,也有利用于代码移植。

📕获取数据库连接

String url = "JDBC:mysql://localhost:3306";
String user = "root";	// 用户
String pwd = "root";	// 密码
Connection connection = DriverManager.getConnection(url, user, pwd);

在 url 里面可以添加不同的参数,来决定连接的数据库、ssl 安全验证、连接超时值等等操作。

Java 连接 MySQL 数据库 就有提到通过关闭 SSL 安全验证来解决连接时警告问题。

JDBC:mysql://localhost:3306 为根目录,后面可以跟数据库名,例如有一个 java 数据库,那么就可以通过 url 直接去连接 java 数据库,即 JDBC:mysql://localhost:3306/java。

URL 参数设置
参数值类型含义
useSSLboolean连接是否使用 SSL 验证
connectTimeoutint连接数据库系统的超时值
autoReconnectboolean是否自动重新连接
userString连接数据库系统的用户
passwordString连接数据库系统的用户的密码
rewriteBatchedStatementsboolean批处理

📕执行 SQL 语句

在执行 SQL 语句之前,需要创建 Statement 对象来操作数据库。

String sql = "select ? from mysql.user";
PreparedStatement preparedStatement = connection.prepareStatement(sql);

在前面文章里面有介绍如何创建 Statement 对象来执行 SQL 语句,这里使用预处理类 PreparedStatement 来处理 SQL 语句。

preparedStatement.setString(1, "user");

它的好处就是支持使用 ? 在 SQL 语句里面进行占位,再通过相应方法来写入参数,例如上面代码中通过 setString() 函数向第一个 ? 占位符填入参数 user,来查询数据库 mysql.user 表里面的用户。

设置存储过程

在前面 Statement 区别表里面有介绍 PreparedStatement 支持处理存储过程 IN 参数占位设置。

-- 修改语句结束符
mysql> delimiter $$
-- 查询数据库用户表的字段结构
mysql> desc mysql.user$$
+------------------------+-----------------------------------+------+-----+-----------------------+-------+
| Field                  | Type                              | Null | Key | Default               | Extra |
+------------------------+-----------------------------------+------+-----+-----------------------+-------+
| Host                   | char(60)                          | NO   | PRI |                       |       |
| User                   | char(32)                          | NO   | PRI |                       |       |
-- 创建存储过程  查询数据库的用户名和主机号
mysql> create procedure mysql.queryUser(IN h char(60), u char(32))
    -> begin
    -> select * from user where (host, user) = (h, u);
    -> end$$
Query OK, 0 rows affected (0.00 sec)
-- 修改语句结束符
mysql> delimiter ;

在上面通过 IN 设置了两个参数 h 和 u,用来通过 host 和 user 来查看指定用户的权限信息。

String sql = "{call mysql.queryUser(?, ?)}";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
// 指定 h 参数值为 localhost
preparedStatement.setString(1, "localhost");
// 指定 u 参数值为 root
preparedStatement.setString(2, "root");
// 执行查询
ResultSet resultSet = preparedStatement.executeQuery();

📕处理结果集

Java 连接 MySQL 数据库 里面介绍了在知道字段的情况下,通过相应函数去获取数据的方法。

那么在不知道字段名的情况下,就像上面存储过程 mysql.queryUser 查看指定用户的权限信息,我又该如何去获取数据呢?

while(resultSet.next()){	// 游标下移
    ResultSetMetaData data = resultSet.getMetaData();
    for (int i = 1;i<data.getColumnCount();i++){
        String field = data.getColumnLabel(i);
        System.out.println(String.format("%s:\t%s", field, resultSet.getString(field)));
    }
}

游标下移是为了获取下一行的数据,当位于最后一行之后使用该方法会返回 false,使其停止获取数据。

在这里通过 resultSet.getMetaData() 方法获取当前行所有数据对应字段的元信息,再通过 data.getColumnLabel(i) 方法依次获取字段,最后通过 resultSet.getString(field) 方法获取对应字段的数据。

如果你需要获取相同类型的数据,其实可以通过 data.getColumnTypeName(i) 方法来处理。

📕事务相关命令

  • connection.setAutoCommit(false):将自动提交设置为 false
  • connection.commit():手动提交操作
  • connection.setSavepoint(“a”):设置保存点
  • connection.rollback(savepoint_a):回滚到保存点
  • connection.rollback():回滚到关闭自动提交
  • connection.setTransactionIsolation(connection.TRANSACTION_READ_UNCOMMITTED):设置事务隔离级别

📕批量处理命令

需要开启批处理支持

  • statement.addBatch(sql):添加 SQL 命令到批处理列表里面
  • statement.executeBatch():执行批处理列表里面的 SQL 命令
  • statement.clearBatch():清除批处理列表里面的 SQL 命令



如果你是无意刷到这篇文章并看到这里,希望你给我的文章来一个赞赞👍👍。如果你不同意其中的内容或有什么问题都可以在下方评论区留下你的想法或疑惑,谢谢你的支持!!😀😀

参考文献

  1. JDBC Tutorial
  2. JAR File Specification
  3. 深入理解JDBC设计模式: DriverManager 解析
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hjhcos

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值