## Connection - [Connection](#connection) - [一、基本信息](#一基本信息) - [二、基本描述](#二基本描述) - [三、主要功能](#三主要功能) - [四、接口源码](#四接口源码) - [六、最佳实践](#六最佳实践) ### 一、基本信息 ✒️ **作者** - Lex 📝 **博客** - [掘金](https://juejin.cn/user/4251135018533068/posts) 📚 **源码地址 ** - [github](https://github.com/xuchengsheng/spring-reading) ### 二、基本描述 `Connection` 接口是 Java JDBC API 中的一部分,代表着与数据库的连接。它提供了方法来管理数据库连接、执行 SQL 语句以及处理事务,是与数据库交互的重要接口之一。 ### 三、主要功能 1. **执行 SQL 语句** + 通过 `createStatement()` 方法创建 `Statement` 对象,或者通过 `prepareStatement(String sql)` 方法创建 `PreparedStatement` 对象,用于执行 SQL 查询、更新或删除等操作。 2. **事务管理** + 支持事务操作,可以通过 `commit()` 提交事务或者 `rollback()` 回滚事务。 3. **设置事务属性** + 可以设置事务的隔离级别、自动提交等属性。 ### 四、接口源码 `Connection` 接口,用于表示与特定数据库的连接。它提供了方法来执行 SQL 语句、管理事务、提交或回滚更改以及关闭连接。 ```java /** *
表示与特定数据库的连接(会话)。SQL 语句在连接的上下文中执行并返回结果。 *
* Connection
对象的数据库能够提供描述其表、支持的 SQL 语法、存储的过程、连接的功能等信息。这些信息是通过 getMetaData
方法获取的。
*
*
注意:在配置 Connection
时,JDBC 应用程序应使用适当的 Connection
方法,如 setAutoCommit
或 setTransactionIsolation
。应用程序不应直接调用 SQL 命令来更改连接的配置,而应使用 JDBC 方法。默认情况下,Connection
对象处于自动提交模式,这意味着它在执行每个语句后会自动提交更改。如果已禁用自动提交模式,则必须显式调用 commit
方法才能提交更改;否则,数据库更改将不会保存。
*
* 使用 JDBC 2.1 核心 API 创建的新的 Connection
对象具有一个最初为空的类型映射。用户可以为此类型映射中的用户定义类型(UDT)输入自定义映射。
* 当从数据源检索到 UDT 并使用 ResultSet.getObject
方法时,getObject
方法将检查连接的类型映射以查看是否存在该 UDT 的条目。如果存在,则 getObject
方法将把 UDT 映射到指定的类。如果不存在条目,则使用标准映射映射 UDT。
*
* 用户可以创建一个新的类型映射,它是一个 java.util.Map
对象,向其中添加一个条目,并将其传递给可以执行自定义映射的 java.sql
方法。在这种情况下,方法将使用给定的类型映射而不是与连接关联的类型映射。
*
* 例如,以下代码片段指定 SQL 类型 ATHLETES
将映射到 Java 编程语言中的类 Athletes
。该代码片段检索 Connection
对象 con
的类型映射,将条目插入其中,然后将带有新条目的类型映射设置为连接的类型映射。
*
* java.util.Map map = con.getTypeMap(); * map.put("mySchemaName.ATHLETES", Class.forName("Athletes")); * con.setTypeMap(map); ** * @see DriverManager#getConnection * @see Statement * @see ResultSet * @see DatabaseMetaData * @since 1.1 */ public interface Connection extends Wrapper, AutoCloseable { /** * 创建一个用于向数据库发送 SQL 语句的
Statement
对象。
* 通常使用 Statement
对象执行无参数的 SQL 语句。如果相同的 SQL 语句需要执行多次,使用 PreparedStatement
对象可能更有效率。
*
* 使用返回的 Statement
对象创建的结果集默认为 TYPE_FORWARD_ONLY
类型,并且并发级别为 CONCUR_READ_ONLY
。可以通过调用 {@link #getHoldability} 来确定创建的结果集的可保持性。
*
* @return 一个新的默认 Statement
对象
* @exception SQLException 如果发生数据库访问错误,或者在关闭的连接上调用此方法
*/
Statement createStatement() throws SQLException;
/**
* 创建一个用于向数据库发送参数化 SQL 语句的 PreparedStatement
对象。
*
* 可以预编译带有或不带有 IN 参数的 SQL 语句,并将其存储在 PreparedStatement
对象中。然后可以使用该对象多次有效地执行此语句。
*
注意:此方法针对处理受益于预编译的参数化 SQL 语句进行了优化。如果驱动程序支持预编译,则方法 prepareStatement
将向数据库发送语句进行预编译。某些驱动程序可能不支持预编译。在这种情况下,直到执行 PreparedStatement
对象时,语句才会被发送到数据库。这对用户没有直接影响;但是,它影响了哪些方法会抛出某些 SQLException
对象。
*
* 使用返回的 PreparedStatement
对象创建的结果集默认为 TYPE_FORWARD_ONLY
类型,并且并发级别为 CONCUR_READ_ONLY
。可以通过调用 {@link #getHoldability} 来确定创建的结果集的可保持性。
*
* @param sql 可能包含一个或多个 '?' IN 参数占位符的 SQL 语句
* @return 包含预编译的 SQL 语句的新的默认 PreparedStatement
对象
* @exception SQLException 如果发生数据库访问错误,或者在关闭的连接上调用此方法
*/
PreparedStatement prepareStatement(String sql) throws SQLException;
/**
* 使自上次提交/回滚以来所做的所有更改永久,并释放此 Connection
对象当前持有的任何数据库锁定。
* 只有在禁用自动提交模式时才应该使用此方法。
*
* @exception SQLException 如果发生数据库访问错误,如果在参与分布式事务时调用此方法,如果在关闭的连接上调用此方法或者此 Connection
对象处于自动提交模式下
* @see #setAutoCommit
*/
void commit() throws SQLException;
/**
* 撤消当前事务中所做的所有更改,并释放此 Connection
对象当前持有的任何数据库锁定。
* 只有在禁用自动提交模式时才应该使用此方法。
*
* @exception SQLException 如果发生数据库访问错误,如果在参与分布式事务时调用此方法,如果在关闭的连接上调用此方法或者此 Connection
对象处于自动提交模式下
* @see #setAutoCommit
*/
void rollback() throws SQLException;
/**
* 立即释放此 Connection
对象的数据库和 JDBC 资源,而不是等待它们自动释放。
*
* 对已关闭的 Connection
对象调用 close
方法是一个无操作。
*
* 强烈建议在调用 close
方法之前显式地提交或回滚活动事务。如果调用了 close
方法且存在活动事务,则结果是由实现定义的。
*
* @exception SQLException 如果发生数据库访问错误
*/
void close() throws SQLException;
// ....
}
```
### 六、最佳实践
使用 Java JDBC API 连接到数据库,并执行插入操作。它首先配置了一个 `DataSource` 对象,用于连接到 MySQL
数据库。然后,它使用这个数据源获取了一个数据库连接,并设置了不自动提交,开启了一个事务。接着,它准备了一个 SQL
插入语句,并创建了一个 `PreparedStatement`
对象来执行插入操作。在执行插入操作后,它提交了事务,并打印了影响的行数。如果在执行过程中发生了异常,它会回滚事务并打印异常信息。最后,它处理了关闭连接时可能发生的异常。
```java
public class ConnectionDemo {
public static void main(String[] args) {
// 使用 DataSource 体现了高内聚,有利于后面更改数据库
MysqlDataSource dataSource = new MysqlDataSource();
// 数据库连接 URL,格式为 jdbc:数据库驱动名称://主机地址:端口号/数据库名称
dataSource.setUrl("jdbc:mysql://localhost:3306/spring-reading");
// 数据库用户名
dataSource.setUser("root");
// 数据库密码
dataSource.setPassword("123456");
try (Connection connection = dataSource.getConnection()) {
// 设置不自动提交,开启事务
connection.setAutoCommit(false);
// SQL 插入语句
String sql = "insert into scores(score) values(?)";
// 创建 PreparedStatement 对象,用于执行 SQL 插入操作
try (PreparedStatement statement = connection.prepareStatement(sql)) {
// 设置参数
statement.setInt(1, new Random().nextInt(100));
// 执行插入操作
int row = statement.executeUpdate();
// 模拟异常,用于测试事务回滚
// int i = 1 / 0;
// 提交事务
connection.commit();
// 打印影响行数
System.out.println("row = " + row);
} catch (Exception e) {
// 发生异常时回滚事务
connection.rollback();
// 打印异常信息
e.printStackTrace();
}
} catch (SQLException e) {
// 处理关闭连接异常
e.printStackTrace();
}
}
}
```