[toc]
JDBC 是什么 (Java DataBase Connectivity)
jdbc 是一种 Java 编程语言和各种数据库之间数据库无关连接的行业标准, JDBC API 为基于 SQL 的数据库访问提供了调用级 API
数据库无关
在没有 JDBC 之前, 我们需要编写不同的程序对接不同厂商的数据库系统, 像下图所示, 需要针对不同的数据库 API 编程, 可想而知, 当我们需要更换数据库系统而产生的大量重复工作, 增加不必要的开发成本
而 JDBC 的出现, 统一了 Java 程序访问不同数据库系统的 API, 应用程序通过调用 JDBC 来操作数据库时, 实际上是右数据库系统厂商提供的 JDBC 驱动程序来完成的. 这样一来, 即使要更换数据库系统, 也仅仅是更换相应的驱动程序就可以了.(本文使用 MySQL 的驱动程序)
JDBC API 主要完成以下三个工作:
建立与数据库的连接或访问任何表格数据源
发送 SQL 语句到数据库
处理数据返回的结果
这三个工作中都有其对应的 jdbc API 来完成各自的任务. 应用程序可以使用这些 API 来操作数据库系统了
- JDBC API
- DriverManager
管理 JDBC 驱动的服务类, 主要功能是获取 Connection 对象 (示例程序中的第 2 步)
getConnection 方法
Connection getConnection(url,username,password)
url 写法: jdbc:MySQL://localhost:3306/mydb 本地数据库简写: jdbc:MySQL:///mydb
jdbc: 协议
MySQL: 子协议
localhost: 主机名
3306: 端口号
mydb: 数据库名称
Connection
数据库连接对象, 每个 Connection 对象表示一个连接会话.
Connection 的常用方法
1. 返回 Statement 对象
- Statement createStatement()
- PreparedStatement PreparedStatement(String sql)
:Statement 的子类, 将 SQL 语句提交到数据库进行预编译
CallableStatement prepareCall(String sql)
:Statement 的子类, 处理存储过程
2. 处理事务的常用方法
void setAutoCommit(boolean autoCommit)
: 设置是否自动提交, 默认 true
void commit: 提交事务
void rollback: 事务回滚
Savepoint setSavepoint
: 创建一个保存点
Savepoint setSavepoint(Stirng name)
: 指定名称来创建一个保存点
void rollback(Savepoint savepoint)
: 将事务回滚到指定的保存点
void setTransactionIsolation(int level)
: 设置事务隔离级别
Statement
执行具体的 SQL 语句, 以及执行 DDL,DCL,DML 语句.
Statement 子类 PreparedStatement
预编译的 Statement 对象
SQL 语句一次编译多次执行
允许数据库预编译 SQL 语句 (常带有参数或者叫占位符), 这样一来, 以后每次只需要改变 SQL 命令的参数, 而不需要每次都编译 SQL 语句, 性能得到了提升
PreparedStatement 主要方法
void setXXX(int parmIndex,XXX value)
: 设置预编译语句的参数
Statement 常用方法
ResultSet executeQuery(String sql)
: 只能执行查询语句, 返回 ResultSet
int executeUpdate(String sql)
: 主要用于执行 DML 语句的, 返回受影响行数.
boolean execute(String sql)
: 执行任何 SQL 语句
addBatch(String sql)
: 添加到批处理
executeBatch(): 执行批处理
clearBatch(): 清空批处理
ResultSet
结果集: 查询结果的封装
ResultSet 主要方法
移动指针的方法
next(): 移动指针到 ResultSet 记录的下一行, 如果存在该条记录返回 true
.......
获取当前行, 指定列的值
getInt(),getString()
针对不同数据类型的方法,
通用的两个泛型方法
<T> T getObject(int columnIndex,Class<T> type),<T> T getObject(String columnLabel,Class<T> type)
JDBC 实际操作
建库建表的 SQL 语句
-- 建库
CREATE DATABASE `mydb` CHARACTER SET utf8 COLLATE utf8_general_ci;
-- 建表
- CREATE TABLE IF NOT EXISTS `user`(
- `id` INT UNSIGNED AUTO_INCREMENT,
- `username` VARCHAR(100) NOT NULL,
- `password` VARCHAR(40) NOT NULL,
- `name` VARCHAR(40) NOT NULL,
- PRIMARY KEY ( `id` )
- )ENGINE=InnoDB DEFAULT CHARSET=utf8;
示例程序框架
我们会在业务逻辑代码 start 的地方开始具体的执行操作
- public void excute() throws SQLException {
- Connection conn = null;
- PreparedStatement smt = null;
- ResultSet resultset = null;
- try {
- //1, 加载驱动
- Class.forName("com.mysql.jdbc.Driver");
- //2, 获取 Connection 对象
- conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb?characterEncoding=utf-8", "root", "******");
- if (conn != null) {
- System.out.println("连接成功");
- }
- conn.setAutoCommit(false);
- // 业务逻辑代码 start
- // 插入数据操作
- String insertSql = "insert into user(username,password,name) values(?,?,?)";
- smt = conn.prepareStatement(insertSql);
- smt.setString(1, "xiaoming");
- smt.setString(2, "123");
- smt.setString(3, "小明");
- int result = smt.executeUpdate();
- if (result> 0) {
- System.out.println("添加成功");
- }
- smt.clearParameters();
- // 修改数据操作
- String updateSql = "update user set name=? where id=?";
- smt = conn.prepareStatement(updateSql);
- smt.setString(1, "小牛");
- smt.setInt(2, 2);
- int updateResult = smt.executeUpdate();
- if (updateResult> 0) {
- System.out.println("修改成功");
- }
- smt.clearParameters();
- // 查询数据操作
- String sql = "select *from user where id =?";
- smt= conn.prepareStatement(sql);
- smt.setInt(1,3);
- resultset = smt.executeQuery();
- while (resultset.next()) {
- int uid = resultset.getInt("id");
- System.out.println(String.format("id:%s,username:%s,password:%s,name:%s", uid,
- resultset.getString("username"),
- resultset.getString("password"),
- resultset.getString("name")));
- }
- // 业务逻辑代码 end
- conn.commit();
- } catch (Exception e) {
- System.out.println(e);
- conn.rollback();
- }
- //4, 释放资源 写到 finally 里面, 防止报错不能执行资源回收
- finally {
- if (conn != null) {
- try {
- conn.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- if (smt != null) {
- try {
- smt.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- if (resultset != null) {
- try {
- resultset.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- }
- }
执行结果
连接成功
添加成功
修改成功
id:3,username:xiaoming,password:123,name: 小明
业务逻辑代码中如果有错误, 连接对象将执行回滚操作, 保证数据的一致性.
来源: https://juejin.im/post/5c245c756fb9a04a0821bba2