✒️ 作者 - Lex 📝 博客 - 掘金 📚 **源码地址 ** - github
Connection
接口是 Java JDBC API 中的一部分,代表着与数据库的连接。它提供了方法来管理数据库连接、执行 SQL
语句以及处理事务,是与数据库交互的重要接口之一。
-
执行 SQL 语句
- 通过
createStatement()
方法创建Statement
对象,或者通过prepareStatement(String sql)
方法创建PreparedStatement
对象,用于执行 SQL 查询、更新或删除等操作。
- 通过
-
事务管理
- 支持事务操作,可以通过
commit()
提交事务或者rollback()
回滚事务。
- 支持事务操作,可以通过
-
设置事务属性
- 可以设置事务的隔离级别、自动提交等属性。
Connection
接口,用于表示与特定数据库的连接。它提供了方法来执行 SQL 语句、管理事务、提交或回滚更改以及关闭连接。
/**
* <P>表示与特定数据库的连接(会话)。SQL 语句在连接的上下文中执行并返回结果。
* <P>
* <code>Connection</code> 对象的数据库能够提供描述其表、支持的 SQL 语法、存储的过程、连接的功能等信息。这些信息是通过 <code>getMetaData</code> 方法获取的。
*
* <P><B>注意:</B>在配置 <code>Connection</code> 时,JDBC 应用程序应使用适当的 <code>Connection</code> 方法,如 <code>setAutoCommit</code> 或 <code>setTransactionIsolation</code>。应用程序不应直接调用 SQL 命令来更改连接的配置,而应使用 JDBC 方法。默认情况下,<code>Connection</code> 对象处于自动提交模式,这意味着它在执行每个语句后会自动提交更改。如果已禁用自动提交模式,则必须显式调用 <code>commit</code> 方法才能提交更改;否则,数据库更改将不会保存。
* <P>
* 使用 JDBC 2.1 核心 API 创建的新的 <code>Connection</code> 对象具有一个最初为空的类型映射。用户可以为此类型映射中的用户定义类型(UDT)输入自定义映射。
* 当从数据源检索到 UDT 并使用 <code>ResultSet.getObject</code> 方法时,<code>getObject</code> 方法将检查连接的类型映射以查看是否存在该 UDT 的条目。如果存在,则 <code>getObject</code> 方法将把 UDT 映射到指定的类。如果不存在条目,则使用标准映射映射 UDT。
* <p>
* 用户可以创建一个新的类型映射,它是一个 <code>java.util.Map</code> 对象,向其中添加一个条目,并将其传递给可以执行自定义映射的 <code>java.sql</code> 方法。在这种情况下,方法将使用给定的类型映射而不是与连接关联的类型映射。
* <p>
* 例如,以下代码片段指定 SQL 类型 <code>ATHLETES</code> 将映射到 Java 编程语言中的类 <code>Athletes</code>。该代码片段检索 <code>Connection</code> 对象 <code>con</code> 的类型映射,将条目插入其中,然后将带有新条目的类型映射设置为连接的类型映射。
* <pre>
* java.util.Map map = con.getTypeMap();
* map.put("mySchemaName.ATHLETES", Class.forName("Athletes"));
* con.setTypeMap(map);
* </pre>
*
* @see DriverManager#getConnection
* @see Statement
* @see ResultSet
* @see DatabaseMetaData
* @since 1.1
*/
public interface Connection extends Wrapper, AutoCloseable {
/**
* 创建一个用于向数据库发送 SQL 语句的 <code>Statement</code> 对象。
* 通常使用 <code>Statement</code> 对象执行无参数的 SQL 语句。如果相同的 SQL 语句需要执行多次,使用 <code>PreparedStatement</code> 对象可能更有效率。
* <P>
* 使用返回的 <code>Statement</code> 对象创建的结果集默认为 <code>TYPE_FORWARD_ONLY</code> 类型,并且并发级别为 <code>CONCUR_READ_ONLY</code>。可以通过调用 {@link #getHoldability} 来确定创建的结果集的可保持性。
*
* @return 一个新的默认 <code>Statement</code> 对象
* @exception SQLException 如果发生数据库访问错误,或者在关闭的连接上调用此方法
*/
Statement createStatement() throws SQLException;
/**
* 创建一个用于向数据库发送参数化 SQL 语句的 <code>PreparedStatement</code> 对象。
* <P>
* 可以预编译带有或不带有 IN 参数的 SQL 语句,并将其存储在 <code>PreparedStatement</code> 对象中。然后可以使用该对象多次有效地执行此语句。
* <P><B>注意:</B>此方法针对处理受益于预编译的参数化 SQL 语句进行了优化。如果驱动程序支持预编译,则方法 <code>prepareStatement</code> 将向数据库发送语句进行预编译。某些驱动程序可能不支持预编译。在这种情况下,直到执行 <code>PreparedStatement</code> 对象时,语句才会被发送到数据库。这对用户没有直接影响;但是,它影响了哪些方法会抛出某些 <code>SQLException</code> 对象。
* <P>
* 使用返回的 <code>PreparedStatement</code> 对象创建的结果集默认为 <code>TYPE_FORWARD_ONLY</code> 类型,并且并发级别为 <code>CONCUR_READ_ONLY</code>。可以通过调用 {@link #getHoldability} 来确定创建的结果集的可保持性。
*
* @param sql 可能包含一个或多个 '?' IN 参数占位符的 SQL 语句
* @return 包含预编译的 SQL 语句的新的默认 <code>PreparedStatement</code> 对象
* @exception SQLException 如果发生数据库访问错误,或者在关闭的连接上调用此方法
*/
PreparedStatement prepareStatement(String sql) throws SQLException;
/**
* 使自上次提交/回滚以来所做的所有更改永久,并释放此 <code>Connection</code> 对象当前持有的任何数据库锁定。
* 只有在禁用自动提交模式时才应该使用此方法。
*
* @exception SQLException 如果发生数据库访问错误,如果在参与分布式事务时调用此方法,如果在关闭的连接上调用此方法或者此 <code>Connection</code> 对象处于自动提交模式下
* @see #setAutoCommit
*/
void commit() throws SQLException;
/**
* 撤消当前事务中所做的所有更改,并释放此 <code>Connection</code> 对象当前持有的任何数据库锁定。
* 只有在禁用自动提交模式时才应该使用此方法。
*
* @exception SQLException 如果发生数据库访问错误,如果在参与分布式事务时调用此方法,如果在关闭的连接上调用此方法或者此 <code>Connection</code> 对象处于自动提交模式下
* @see #setAutoCommit
*/
void rollback() throws SQLException;
/**
* 立即释放此 <code>Connection</code> 对象的数据库和 JDBC 资源,而不是等待它们自动释放。
* <P>
* 对已关闭的 <code>Connection</code> 对象调用 <code>close</code> 方法是一个无操作。
* <P>
* 强烈建议在调用 <code>close</code> 方法之前显式地提交或回滚活动事务。如果调用了 <code>close</code> 方法且存在活动事务,则结果是由实现定义的。
*
* @exception SQLException 如果发生数据库访问错误
*/
void close() throws SQLException;
// ....
}
使用 Java JDBC API 连接到数据库,并执行插入操作。它首先配置了一个 DataSource
对象,用于连接到 MySQL
数据库。然后,它使用这个数据源获取了一个数据库连接,并设置了不自动提交,开启了一个事务。接着,它准备了一个 SQL
插入语句,并创建了一个 PreparedStatement
对象来执行插入操作。在执行插入操作后,它提交了事务,并打印了影响的行数。如果在执行过程中发生了异常,它会回滚事务并打印异常信息。最后,它处理了关闭连接时可能发生的异常。
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();
}
}
}