简介:SQL Server JDBC驱动程序是Java与SQL Server数据库通信的关键组件,通过JDBC API,Java开发者可以编写代码访问和操作SQL Server数据。了解SQL Server JDBC驱动程序的分类、配置、连接和使用方法对于Java数据库开发至关重要。本文将详细介绍如何在Java项目中配置和使用SQL Server JDBC驱动,包括驱动类型、添加驱动到类路径、连接数据库的基本步骤以及驱动中的关键概念和高级特性。
1. SQL Server JDBC驱动程序概述
SQL Server JDBC驱动程序简介
Java数据库连接(JDBC)是一种标准化的Java API,用于连接和执行查询数据库。它允许Java应用程序执行SQL语句来访问数据库。SQL Server JDBC驱动程序是微软提供的,用于连接SQL Server数据库的JDBC实现,它允许Java开发者能够从Java平台访问SQL Server数据库。
驱动程序的作用与重要性
在企业级应用开发中,数据库操作是核心部分之一。SQL Server JDBC驱动程序的重要性体现在它为Java应用提供了一个可靠的桥梁,连接到SQL Server数据库,执行数据的CRUD(创建、读取、更新和删除)操作。此外,驱动程序还负责处理与数据库的通信协议,如认证和加密。
应用场景与基本要求
SQL Server JDBC驱动程序广泛应用于需要与SQL Server数据库交互的Java应用程序中。它适用于各种平台和环境,例如Java EE和Spring框架。在配置和使用该驱动程序时,开发者需满足驱动所依赖的Java版本和第三方库的兼容性要求,确保整个应用程序的稳定运行。
2. JDBC驱动程序的分类与特性
在本章中,我们将深入探讨JDBC驱动程序的不同类型,以及每种类型的特定优势和应用场景。理解不同类型的JDBC驱动程序对于在Java项目中高效地使用数据库至关重要。我们将详细比较Type 4与Type 2驱动程序,以及探讨它们在性能和兼容性方面的考量。
2.1 JDBC驱动程序的类型
2.1.1 Type 4驱动的定义与适用场景
Type 4驱动,也称为纯Java驱动,是一种完全用Java编写的驱动程序。它直接与数据库进行通信,无需额外的本地代码或驱动。Type 4驱动的最大优势在于它具有平台独立性,可以在任何支持Java的平台上运行,无需进行任何修改。
适用场景:
- 跨平台项目: 因为Type 4驱动是纯Java编写,所以非常适合需要跨平台部署的项目。
- 云服务: 在云计算环境中,部署和维护本地库可能会很复杂。Type 4驱动因此成为云服务的理想选择。
- 微服务架构: 在微服务架构中,服务可能需要频繁更改和迁移,使用Type 4驱动可以简化部署和维护过程。
2.1.2 Type 2驱动的特点及使用限制
Type 2驱动是一种中间件驱动,它由Java和本地代码(如C或C++)组合而成。这意味着Type 2驱动需要在客户端安装特定平台的本地库。Type 2驱动的一个主要优点是它通常会比Type 4驱动拥有更好的性能,因为可以利用本地库直接与操作系统进行通信。
使用限制:
- 平台依赖性: Type 2驱动需要在每个客户端的操作系统上安装特定平台的本地库,这限制了其在不同平台间的移植性。
- 安装要求: 用户可能需要在客户端安装额外的软件,这增加了配置的复杂性。
- 版本兼容性: 不同平台的本地库可能需要不同的版本支持,这可能会影响应用程序的维护和更新。
2.2 驱动程序的核心优势分析
2.2.1 性能对比:Type 4 vs Type 2
在性能方面,Type 2驱动由于使用了本地代码,通常能够提供比Type 4驱动更好的性能。然而,随着Java技术的不断进步,特别是JVM的性能优化,Type 4驱动在性能上与Type 2驱动之间的差距已经大幅缩小。
性能考量:
- CPU使用率: Type 2驱动可能会比Type 4驱动消耗更多的CPU资源,因为需要在Java和本地代码之间进行调用。
- 内存管理: 在某些情况下,Type 4驱动可能在内存管理方面表现更佳,因为它是完全用Java编写的,可以更好地利用JVM的垃圾回收机制。
2.2.2 兼容性考量:不同数据库版本的适配
在考虑使用Type 4或Type 2驱动时,数据库版本的兼容性也是一个重要的考量因素。Type 4驱动的优势在于其平台无关性,因此在支持多版本数据库的应用场景中表现得尤为出色。
兼容性考量:
- 数据库版本更新: Type 4驱动的更新通常不需要改变客户端环境,适用于经常更新数据库版本的场景。
- 遗留系统: 对于一些遗留系统,可能需要使用Type 2驱动,因为它能够提供更稳定的性能和兼容性。
在本章节中,我们对JDBC驱动程序的不同类型进行了详细的讨论,并对它们的性能和兼容性进行了比较。这些知识对于决定在Java项目中使用哪种类型的驱动程序至关重要。随着Java技术的不断发展,开发者需要不断更新自己的知识,以便在性能和兼容性之间找到最佳的平衡点。
3. 驱动程序在Java项目中的配置与应用
3.1 驱动程序的环境搭建
3.1.1 环境依赖与下载
在开始配置JDBC驱动程序之前,确保Java开发环境已经正确安装并配置好。对于SQL Server JDBC驱动程序,你可能需要下载Microsoft提供的官方驱动。以下是下载和安装驱动的步骤:
- 访问Microsoft官方网站或其他可信的资源获取Microsoft JDBC Driver for SQL Server。
- 根据你的系统架构(32位或64位),选择正确的驱动版本下载。
- 解压下载的文件,通常你会得到一个
.jar文件或包含多个文件的文件夹。
请确保下载的驱动版本与你的Java版本兼容,并检查系统需求以避免版本冲突。
3.1.2 Java项目中的具体配置步骤
对于Maven项目,你可以在 pom.xml 文件中添加相应的依赖项来配置驱动:
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>sqlserver-jdbc</artifactId>
<version>版本号</version>
</dependency>
对于传统的非Maven项目,需要手动将下载的JAR文件添加到项目的类路径中。这通常在项目的构建路径设置中完成。
3.2 驱动程序的加载与测试
3.2.1 Class.forName()方法的使用
一旦JDBC驱动程序已经被添加到项目中,你需要加载该驱动程序以使用它。这可以通过调用 Class.forName() 方法实现,该方法尝试加载指定的类。
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
上述代码中的字符串 com.microsoft.sqlserver.jdbc.SQLServerDriver 是SQL Server JDBC驱动程序的全限定名,它必须和你添加到项目中的JAR文件中的驱动程序类名相匹配。
3.2.2 使用单元测试验证配置有效性
为了验证驱动程序已正确配置,可以编写一个单元测试来尝试建立一个数据库连接:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class JDBCDriverTest {
public static void main(String[] args) {
Connection connection = null;
try {
connection = DriverManager.getConnection("jdbc:sqlserver://localhost:1433;databaseName=YourDB", "username", "password");
System.out.println("Connection Successful");
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
如果 main 方法成功执行并打印出"Connection Successful",则说明JDBC驱动程序已经配置成功,并且能够正确地与数据库进行通信。
以上就是驱动程序在Java项目中的配置与应用。确保遵循规范的配置流程,避免在开发过程中遇到不必要的错误。一旦驱动程序配置成功,便可以进行开发高效、安全的数据库应用了。
4. 连接SQL Server数据库的详细流程
4.1 数据库连接的基础知识
4.1.1 JDBC URL的格式与解析
Java数据库连接(JDBC)URL是连接数据库的标准化字符串,它为应用程序提供了定位并连接到数据库的方法。一个典型的JDBC URL遵循如下格式:
jdbc:mysql://[host][:port]/[database][?property1=value1&property2=value2]
其中, jdbc:mysql 指定使用MySQL数据库的JDBC驱动程序, host 和 port 分别指数据库服务器的地址和端口, database 是要连接的数据库名称。URL中的查询字符串 ?property1=value1&property2=value2 可以用来传递额外的连接属性,如时区、网络协议版本等。
举例来说,一个连接到本地主机上名为 mydb 的MySQL数据库的JDBC URL如下所示:
String url = "jdbc:mysql://localhost:3306/mydb";
解析这个URL,我们可以得到如下信息:
- 使用的JDBC驱动程序:MySQL
- 数据库服务器地址:
localhost - 数据库服务器端口:
3306 - 数据库名称:
mydb
4.1.2 用户认证与安全连接的建立
在建立了JDBC URL之后,下一步是进行用户认证,这涉及到数据库的用户名和密码。为了建立安全连接,我们还需要启用SSL/TLS加密,以确保数据在客户端和数据库服务器之间传输时的安全。
String user = "dbuser";
String password = "dbpassword";
Connection conn = DriverManager.getConnection(url, user, password);
为了安全起见,还可以在连接字符串中添加SSL加密相关的参数:
String url = "jdbc:mysql://localhost:3306/mydb?useSSL=true&serverTimezone=UTC";
在这里, useSSL=true 告诉JDBC驱动启用SSL连接,而 serverTimezone=UTC 则确保了时间相关操作时的时区一致性。
4.2 连接池的应用与管理
4.2.1 连接池的概念及其优势
连接池是一种管理数据库连接的技术,它允许预先建立多个数据库连接并存储在池中。当应用程序需要连接数据库时,它会从池中借用一个连接,而不是每次都创建一个新的连接。使用完后,连接将返回到池中,而不是被销毁,这样可以重复使用,减少资源消耗。
连接池的优势主要包括:
- 提高性能 :复用现有连接比创建新连接要快得多。
- 减少资源消耗 :避免了重复建立和销毁连接的资源开销。
- 控制连接数 :可以限制应用程序使用的最大连接数,从而避免过多的资源争用和潜在的死锁。
4.2.2 常用连接池技术的选择与配置
在Java项目中,有多种连接池可供选择,包括Apache DBCP、C3P0、HikariCP等。HikariCP因其出色的性能和简单的配置而受到广泛推荐。
要使用HikariCP,首先需要添加依赖到项目的 pom.xml 文件中:
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>4.0.3</version>
</dependency>
然后,在代码中配置连接池:
HikariDataSource dataSource = new HikariDataSource();
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/mydb");
dataSource.setUsername("dbuser");
dataSource.setPassword("dbpassword");
dataSource.setMaximumPoolSize(10);
这里的 maximumPoolSize 参数控制了连接池中允许的最大连接数。配置完成后,我们就可以通过 dataSource.getConnection() 来获取数据库连接了。
Connection connection = dataSource.getConnection();
通过以上配置,我们已经建立了一个简单的连接池,其后可以进一步进行性能调优,根据应用需求配置其他参数如连接存活时间、空闲超时时间等。
5. 核心JDBC对象的深入理解与应用
5.1 Connection对象的操作
5.1.1 连接的建立与关闭
在Java中,使用JDBC与SQL Server数据库建立连接是数据库编程中的基础。为了建立一个连接,我们首先需要创建一个 DriverManager 对象,它负责管理数据库驱动程序的加载和数据库连接的建立。
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DatabaseConnector {
public static void main(String[] args) {
Connection conn = null;
try {
// 加载并注册JDBC驱动
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
// 定义连接URL
String connectionUrl = "jdbc:sqlserver://localhost:1433;databaseName=MyDatabase;user=UserName;password=password";
// 建立连接
conn = DriverManager.getConnection(connectionUrl);
System.out.println("连接成功!");
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
} finally {
// 关闭连接
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
在这段代码中, Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver") 负责加载JDBC驱动程序类。紧接着, DriverManager.getConnection(connectionUrl) 通过给定的URL、用户名和密码建立与数据库的连接。连接建立之后,通常在数据库操作完成后,我们应当调用 conn.close() 来关闭连接,释放资源。
5.1.2 事务的开启与提交
事务管理允许我们定义一系列操作为一个单一的工作单元。在JDBC中,可以通过 Connection 对象来管理事务。默认情况下,每个连接都是自动提交模式,这意味着每个执行的SQL语句都会立即被提交。
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
public class TransactionManager {
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
try {
conn = DatabaseConnector.getConnection();
// 关闭自动提交模式
conn.setAutoCommit(false);
stmt = conn.createStatement();
// 执行一组SQL操作
stmt.executeUpdate("INSERT INTO table_name...");
stmt.executeUpdate("UPDATE table_name...");
// 手动提交事务
conn.commit();
System.out.println("事务提交成功");
} catch (SQLException e) {
// 出现异常时回滚事务
try {
if (conn != null) {
conn.rollback();
}
} catch (SQLException ex) {
ex.printStackTrace();
}
e.printStackTrace();
} finally {
// 清理资源
try {
if (stmt != null) {
stmt.close();
}
if (conn != null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
在上述代码中,我们首先获取了一个数据库连接,并通过 conn.setAutoCommit(false) 关闭了自动提交。接下来,执行了一系列SQL语句。如果所有的操作都成功执行,那么通过 conn.commit() 来提交事务,使其永久生效。如果在执行过程中遇到异常,通过 conn.rollback() 回滚事务,撤销所有未提交的操作。
5.2 Statement和PreparedStatement的对比与使用
5.2.1 Statement的执行与风险分析
Statement 是JDBC中用于执行静态SQL语句并返回其生成结果的对象。使用 Statement 对象可以执行三种类型的SQL语句:查询、更新、和调用存储过程。
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class StatementUsage {
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
conn = DatabaseConnector.getConnection();
stmt = conn.createStatement();
// 执行查询
rs = stmt.executeQuery("SELECT * FROM table_name");
// 处理结果集
while (rs.next()) {
// 获取数据
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 关闭资源
try {
if (rs != null) rs.close();
if (stmt != null) stmt.close();
if (conn != null) conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
尽管使用 Statement 可以完成任务,但直接使用字符串拼接的方式构建SQL语句容易引发SQL注入攻击。例如,通过恶意构造输入数据,攻击者可以改变SQL语句的原本意义,从而访问或修改数据库中的数据。
5.2.2 PreparedStatement的优势与场景
为了克服 Statement 带来的安全问题, PreparedStatement 应运而生。它继承自 Statement ,提供了一种预编译的SQL语句,可以有效地防止SQL注入攻击。
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class PreparedStatementUsage {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement pstmt = null;
try {
conn = DatabaseConnector.getConnection();
String sql = "INSERT INTO table_name (column1, column2) VALUES (?, ?)";
pstmt = conn.prepareStatement(sql);
// 设置参数
pstmt.setString(1, "value1");
pstmt.setInt(2, 123);
// 执行更新
int affectedRows = pstmt.executeUpdate();
System.out.println("受影响的行数:" + affectedRows);
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 关闭资源
try {
if (pstmt != null) pstmt.close();
if (conn != null) conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
PreparedStatement 的好处不仅限于安全。它还可以提高性能,因为数据库可以预编译SQL语句,并且仅需要参数化数据,无需重新编译整个语句。这在执行大量相似查询时尤其有益,例如批处理插入数据。
5.3 ResultSet的处理技巧
5.3.1 结果集的遍历与操作
ResultSet 对象表示数据库结果集的数据表。使用 ResultSet 遍历数据,我们可以逐行读取数据。它维护了一个指向当前行的游标,初始时在第一行之前。
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class ResultSetTraversal {
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
conn = DatabaseConnector.getConnection();
stmt = conn.createStatement();
rs = stmt.executeQuery("SELECT * FROM table_name");
// 结果集遍历
while (rs.next()) {
// 获取字段值
int id = rs.getInt("id");
String name = rs.getString("name");
// 处理数据
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 关闭资源
try {
if (rs != null) rs.close();
if (stmt != null) stmt.close();
if (conn != null) conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
5.3.2 处理大数据量时的性能优化
处理大量数据时, ResultSet 的默认游标类型是 TYPE_FORWARD_ONLY ,这意味着我们只能向前遍历结果集。如果需要多次遍历结果集,或者向前和向后遍历,可以改变游标类型为 TYPE_SCROLL_INSENSITIVE 或 TYPE_SCROLL_SENSITIVE ,但要注意,后者会带来性能开销。
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class ResultSetScrolling {
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
conn = DatabaseConnector.getConnection();
// 创建可滚动的结果集
stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
rs = stmt.executeQuery("SELECT * FROM table_name ORDER BY column_name");
// 向前遍历
while (rs.next()) {
// 处理数据
}
// 向后遍历
while (rs.previous()) {
// 处理数据
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 关闭资源
try {
if (rs != null) rs.close();
if (stmt != null) stmt.close();
if (conn != null) conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
在处理大量数据时,还应注意选择合适的返回行数。在 Statement 和 PreparedStatement 中,我们可以使用 setMaxRows(int max) 方法来限制返回的最大行数,以减少内存消耗。此外,如果结果集特别大,可以使用分页查询,每次只处理一定数量的记录,然后进行下一次查询。这不仅可以优化内存使用,还可以提高程序的响应速度。
以上是对核心JDBC对象操作的深入理解与应用,从基础的连接管理到进阶的事务处理,再到结果集的遍历与优化,每一部分都是数据操作中不可或缺的一部分。在实际应用中,我们需要根据具体情况来选择最合适的工具和技巧,以实现高效且安全的数据库操作。
6. SQL Server JDBC驱动的高级特性及最佳实践
随着数据库应用的不断深入,开发人员需要掌握SQL Server JDBC驱动的高级特性,以便编写出更加高效、安全和可维护的代码。本章将探讨事务管理的高级用法、批处理操作与性能调优、游标的种类与选择,以及最佳实践,如代码复用、安全性考虑和调试技巧。
6.1 高级特性解析
6.1.1 事务管理的高级用法
在JDBC中,事务管理涉及到多个操作的原子性保证。SQL Server JDBC驱动提供了丰富的API来控制事务的行为,使得开发者能够精细地管理事务的生命周期。
Connection connection = dataSource.getConnection();
connection.setAutoCommit(false); // 关闭自动提交
try {
// 执行一系列的数据库操作
connection.commit(); // 手动提交事务
} catch (Exception e) {
connection.rollback(); // 出现异常时回滚事务
}
事务还可以设置隔离级别,防止脏读、不可重复读和幻读等并发问题:
connection.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
6.1.2 批处理操作与性能调优
批处理是提高数据库操作效率的重要手段。SQL Server JDBC驱动支持批插入、更新和删除操作。
try (PreparedStatement pstmt = connection.prepareStatement("INSERT INTO Table VALUES (?, ?)")) {
for (int i = 0; i < data.length; i++) {
pstmt.setString(1, data[i][0]);
pstmt.setInt(2, data[i][1]);
pstmt.addBatch();
}
pstmt.executeBatch(); // 执行批处理
}
批处理的性能调优,如调整批大小、使用合适的事务大小等,可以显著影响性能。合理配置这些参数可以减少网络往返次数、降低数据库压力,并提高数据吞吐量。
6.1.3 游标的种类与选择
在处理大量数据时,选择合适的游标类型至关重要。SQL Server JDBC驱动提供了多种游标,包括TYPE_FORWARD_ONLY、TYPE_SCROLL_INSENSITIVE和TYPE_SCROLL_SENSITIVE等。
ResultSet rsScrollInsen = stmt.executeQuery("SELECT * FROM Table", ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
不同的游标类型在性能和功能上存在差异。开发者应根据实际需求进行选择,例如,只读操作通常可以使用TYPE_SCROLL_INSENSITIVE来提高性能,因为它可以缓存数据。
6.2 开发最佳实践
6.2.1 代码复用与模块化的驱动配置
在大型项目中,代码复用和模块化是保证开发效率和代码质量的关键。通过配置数据源、连接池和其他JDBC驱动相关的参数,可以将这些配置模块化,从而在不同的模块或服务中复用。
@Bean
public BasicDataSource dataSource() {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
dataSource.setUrl("jdbc:sqlserver://localhost:1433;databaseName=YourDB");
dataSource.setUsername("yourUsername");
dataSource.setPassword("yourPassword");
// 其他连接池配置...
return dataSource;
}
6.2.2 安全性考虑:防止SQL注入与参数化查询
安全性是任何数据库操作中都不可忽视的问题。SQL Server JDBC驱动支持参数化查询,这是防止SQL注入的最有效手段之一。
try (PreparedStatement pstmt = connection.prepareStatement("SELECT * FROM Users WHERE username = ? AND password = ?")) {
pstmt.setString(1, "user");
pstmt.setString(2, "pass");
ResultSet rs = pstmt.executeQuery();
}
6.2.3 调试技巧与性能监控
在复杂的数据库操作中,调试和性能监控是非常重要的。SQL Server JDBC驱动的日志功能可以帮助开发者理解驱动的行为,性能监控工具如SQL Server Profiler能够帮助跟踪长时间运行的查询和事务。
开发者可以利用以下代码设置日志记录:
Properties info = new Properties();
info.put("user", "username");
info.put("password", "password");
DriverManager.getConnection("jdbc:sqlserver://localhost:1433;databaseName=yourdb;log=1;", info);
性能监控工具SQL Server Profiler能够提供详细的数据库活动跟踪,有助于识别性能瓶颈和潜在问题。
通过综合应用本章所讨论的高级特性和最佳实践,开发者可以显著提升SQL Server JDBC驱动程序在应用程序中的表现和安全性。随着对这些高级特性的深入理解和实践,开发者将能够更加高效和安全地管理数据库连接和操作。
简介:SQL Server JDBC驱动程序是Java与SQL Server数据库通信的关键组件,通过JDBC API,Java开发者可以编写代码访问和操作SQL Server数据。了解SQL Server JDBC驱动程序的分类、配置、连接和使用方法对于Java数据库开发至关重要。本文将详细介绍如何在Java项目中配置和使用SQL Server JDBC驱动,包括驱动类型、添加驱动到类路径、连接数据库的基本步骤以及驱动中的关键概念和高级特性。

1256

被折叠的 条评论
为什么被折叠?



