1.JDBC是什么?
Java DataBase Connectivity(Java语言数据库连接)
2.JDBC本质是什么?
JDBC 本质上是一套由 SUN 公司(现为 Oracle)制定的接口规范。(interface)
3.为什么定义一套接口?
主要是为了实现多态。因为我们无法确定各个数据库厂商会以什么方式实现他们的数据库操作。所以,JDBC 定义了一套标准即契约,确保无论你使用的是 Oracle 还是 MySQL,程序都可以通过相同的方式与数据库交互。这样,程序员不必为了不同的数据库而写不同的代码,从而大大减少了开发的复杂性。
4.如何理解面向接口编程?有什么好处?
面向接口编程的核心思想是解耦合。通过使用接口,程序的各个部分之间可以降低相互依赖,从而提高程序的可扩展性。换句话说,接口使得代码更加模块化和灵活,便于后期的扩展和维护。
不建议面向具体编程
建议例如 Animal a=new Cat();
Animal b=new Dog();
不建议
Cat c=new Cat();
Dog d=new Dog();
面向对象三大特性:封装,继承,多态
关于多态好处
// 定义一个父类 Animal,包含 eat 方法
class Animal {
public void eat() {
System.out.println("This animal is eating.");
}
}// 定义具体的子类 Cat 和 Dog,继承自 Animal,并重写 eat 方法
class Cat extends Animal {
@Override
public void eat() {
System.out.println("The cat is eating.");
}
}class Dog extends Animal {
@Override
public void eat() {
System.out.println("The dog is eating.");
}
}// 测试多态的使用
public class Main {
public static void main(String[] args) {
Animal myCat = new Cat();
Animal myDog = new Dog();myCat.eat(); // 输出: The cat is eating.
myDog.eat(); // 输出: The dog is eating.
}
}
父类引用指向子类对象,能点出来什么看引用的类型,点出来的是什么看对象
其实JDBC就是一种典型桥接模式(这里流个映像,加个例子)
体现:
1.抽象部分(接口):
JDBC提供了一套统一的接口(例如:Connection,Statement,ResultSet等),这些接口定义了操作数据库的标准方法.无论你使用的是Oracle,Mysql,高斯,达梦等,接口(标准,契约)始终是固定的.
2.实现部分(具体的数据库厂商(或者说驱动))
各个数据库厂商会提供自己的JDBC驱动程序,简单说就是我已经按你标准实现好了,你无需关注底层逻辑,只要照着标准,比如说我现在要个连接,那么你就去getConnection就可以了.不需要管这个连接如何来的.各个厂商都有专业的人在负责维护他们的驱动,没有人比他们更加了解.这样做,对于程序员而言我们只需熟悉JDBC接口和里面的方法即可.大大降低了学习成本.
3.桥接作用
JDBC通过在程序和具体数据库实现之间架起一座桥梁,使得程序可以通过相同的JDBC接口与不同的数据库进行交互.这种设计极大地增强了程序的可移植性和可扩展性,因为如果你想要切换数据库,只需要更换驱动程序,而不需要修改应用代码
如果没有JDBC会怎么样:
那么你用的是Mysql,那么你得学习Mysql是如何去实现的
你用Oracle得,那么你去学习Oracle是如何实现的
光想获得一个连接,你都可能要学习很多不同数据库厂商定义的方法
那么JDBC到底定义了哪些接口
主要在两个包里面 分别 java.sql包 和javax.sql包
那么其实对应的也是JavaSE(Java标准库)和JavaEE(Java企业版)
java.sql:该包内提供了与关系型数据库进行基本操作的API,这些接口主要用于数据库连接,执行sql查询,更新,查理结果集,局部(单个数据源的事务处理)
关键的类和接口
Connection:表示与数据库的连接,用于发送 SQL 语句并接收结果
Statement:用于执行 SQL 查询和更新操作的对象
PreparedStaement:预编译的 SQL 语句执行对象,支持参数化查询,能够提高执行效率和安全性。
ResultSet:表示 SQL 查询的结果集,用于访问查询返回的数据。
DriverManager:用于管理 JDBC 驱动程序,并建立与数据库的连接
SQLException:处理数据库操作中发生的异常
javax.sql包扩展了java.sql包提供的功能,增加了更多高级的 API。这个包主要关注于企业级应用中常用的数据库连接池管理、分布式事务处理,以及对数据源(DataSource
)的支持。
关键类和接口
DataSource:表示数据库的数据源,内部管理着数据库连接。与 DriverManager
相比,DataSource
提供了一种更加灵活的数据库连接方式,通常与连接池结合使用。
ConnectionPoolDataSource:用于实现连接池的工厂接口,支持生成 PooledConnection
对象。
PooledConnection:表示可以在连接池中复用的数据库连接。连接池通过复用 PooledConnection
来提高数据库连接的性能和效率。
XADataSource
:这是一个用于分布式事务的接口,提供了一种方式来管理跨多个资源的全局事务。XADataSource
支持两阶段提交(2PC),这是分布式事务处理中常用的协议。
RowSet:扩展了 ResultSet
的功能,支持可序列化和断开连接的结果集处理。RowSet
使得结果集可以在不同的环境中传输或离线操作。
ConnectionEventListener:用于监听连接池中连接的生命周期事件,例如连接的关闭或错误事件。这对于管理连接池中的连接状态非常重要。
XAConnection
:表示一个能够参与分布式事务的数据库连接,通过这个接口,可以让一个数据库连接参与全局事务的管理。
Xid
:代表一个全局事务的标识符,用于在分布式事务中唯一标识一个事务。Xid
是分布式事务管理中的关键部分,用于协调多个资源的事务一致性。
理解两阶段提交:
两阶段提交是一种用于分布式系统中保证事务一致性的协议.它的目的是确保再分布式环境中,所有参与事务的数据库要么都成功提交事务,要么都回滚,以保证系统的一致性.
以下是一个模拟两阶段提交的简单demo
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class TwoPhaseCommitDemo {
public static void main(String[] args) {
Connection connA = null;
Connection connB = null;
try {
// 模拟获取两个数据库的连接
connA = DriverManager.getConnection("jdbc:mysql://localhost:3306/dbA", "user", "password");
connB = DriverManager.getConnection("jdbc:mysql://localhost:3306/dbB", "user", "password");
// 关闭自动提交模式,进入手动事务管理
connA.setAutoCommit(false);
connB.setAutoCommit(false);
// 第一阶段:准备阶段
try {
// 在数据库A中执行操作
executeOperationOnDB(connA);
// 在数据库B中执行操作
executeOperationOnDB(connB);
// 如果两个操作都成功,准备提交
System.out.println("两个数据库都已准备好提交。");
} catch (Exception e) {
// 如果有任何一个操作失败,回滚所有操作
System.out.println("准备阶段发生错误,正在回滚。");
connA.rollback();
connB.rollback();
return;
}
// 第二阶段:提交阶段
try {
connA.commit();
connB.commit();
System.out.println("两个数据库的事务提交成功。");
} catch (Exception e) {
// 如果提交过程中失败,则尝试回滚
System.out.println("提交阶段发生错误,正在回滚。");
connA.rollback();
connB.rollback();
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 关闭连接
try {
if (connA != null) connA.close();
if (connB != null) connB.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
// 模拟在数据库上执行操作的方法
private static void executeOperationOnDB(Connection conn) throws SQLException {
// 在此处执行具体的数据库操作,例如插入或更新数据
// 例如:conn.createStatement().executeUpdate("INSERT INTO table_name (column1) VALUES (value1)");
System.out.println("在 " + conn.getMetaData().getURL() + " 上执行操作。");
}
}