当前位置: 首页 > news >正文

12.jdbc第一步DriverManager

1.核心定位:JDBC 生态的 “驱动调度中枢”,用于管理数据库驱动实例。DriverManager 是 JDBC 核心工具类(java.sql.DriverManager)

2.是只能管理数据库的驱动实例吗?其他的驱动不能管吗?

  • 明确结论:DriverManager 只管理 “符合 JDBC 规范的数据库驱动实例”(即实现了 java.sql.Driver 接口的实例,如 MySQL 的 com.mysql.cj.jdbc.Driver 、 Oracle的oracle.jdbc.driver.OracleDriver),不管理其他任何 “非 JDBC 驱动实例”。
  • DriverManager 的设计目标是 “为 JDBC 数据库连接提供统一的驱动管理”,其管理范围有严格边界。

从底层源码来认识DriverManager

1.核心存储:驱动元信息集合(registeredDrivers)

// 存储驱动元信息的核心集合,线程安全的写时复制容器
private static final CopyOnWriteArrayList<DriverInfo> registeredDrivers = new CopyOnWriteArrayList<>();

存储元素:不是直接存储 Driver 实例,而是 DriverInfo(DriverManager 内部静态私有类),封装了 Driver 实例、类加载器、注销状态、权限等元信息; DriverInfo具体代码如下:

// DriverManager 内部静态私有类
private static class DriverInfo {// 核心:封装的 JDBC 驱动实例(实现了 java.sql.Driver 接口)final Driver driver;// 加载该驱动的类加载器(关键:用于类加载器适配和可见性判断)final ClassLoader classLoader;// 驱动的注销状态标记(默认 false:未注销;true:已注销)volatile boolean deregistered;// 驱动的权限对象(用于安全管理器的权限校验)private final SQLPermission permission;// 构造方法:创建 DriverInfo 时必须传入 Driver 实例和类加载器DriverInfo(Driver driver, ClassLoader classLoader) {this.driver = driver;this.classLoader = classLoader;this.deregistered = false;// 创建权限对象(用于后续 deregisterDriver 等操作的权限校验)this.permission = new SQLPermission("deregisterDriver");}
}

2.向 DriverManager 中注册驱动,即将 DriverInfo 加入集合

// 驱动注册方法:registerDriver 是外部触发入口(驱动静态代码块自动调用)
public static void registerDriver(Driver driver) throws SQLException {if (driver == null) {throw new NullPointerException("驱动实例不能为 null");}// 1. 获取当前线程的类加载器(用于封装到 DriverInfo)ClassLoader classLoader = Thread.currentThread().getContextClassLoader();// 2. 创建 DriverInfo 实例(封装驱动+类加载器等元信息)DriverInfo driverInfo = new DriverInfo(driver, classLoader);// 3. 核心操作:将 DriverInfo 加入 registeredDrivers 集合registeredDrivers.add(driverInfo);// 可选:打印调试日志(若开启日志)println("已注册驱动元信息:" + driverInfo.driver.getClass().getName());
}

3.获取连接核心源码 getConnection(String url, Properties info),遍历驱动器,找到能处理当前链接的驱动器,然后返回由由驱动创建的 Connection 对象,供上层使用。

private static Connection getConnection(String url, Properties info) throws SQLException {if (url == null || url.isEmpty()) {throw new SQLException("URL cannot be null or empty");}// 遍历所有已注册的驱动for (DriverInfo di : registeredDrivers) {if (di.deregistered) continue; // 跳过已注销的驱动try {// 筛选支持当前 URL 的驱动if (di.driver.acceptsURL(url)) {println("Trying to connect with driver: " + di.driver.getClass().getName());// 调用驱动的 connect 方法获取连接Connection conn = di.driver.connect(url, info);if (conn != null) {println("Connection successful");return conn;}}} catch (SQLException e) {println("Driver " + di.driver.getClass().getName() + " failed: " + e.getMessage());// 不中断,继续尝试下一个驱动}}// 所有驱动都失败,抛出异常throw new SQLException("No suitable driver found for " + url);
}

下一节重点讲解 Connection 对象

http://www.jsqmd.com/news/59897/

相关文章:

  • 移动云专业版root分辨率 安卓11
  • 最新发布!长租公寓哪家好?哪家更靠谱?TOP10权威推荐
  • 2025年7款免费AI论文写作工具推荐:毕业论文一键生成神器
  • 第7篇 Scrum 冲刺博客
  • 关于Java JSON库的选择
  • 解决Spring Cloud Gateway中使用CompletableFuture.supplyAsync()执行Feign调用报错
  • 补发读后感2
  • 解决mybatis批量更新慢问题
  • qy_蓝桥杯编程系列_编程18 进制转换
  • 详细介绍:kotlin - 显示HDR图(heic格式),使用GainMap算法,速度从5秒提升到0.6秒
  • anything
  • 递归函数,闭包,装饰器3
  • 从vw/vh到clamp(),前端响应式设计的痛点与进化 - 实践
  • 10413_基于Springboot的智慧养老院管理系统
  • 【Unity URP】Rendering Debugger和可视化MipMap方案
  • How to do a biology experiment for a Physician.
  • 2025–2030 年最紧缺的八大 IC 岗位
  • Firefox 禁用按下 Alt 显示菜单
  • LC 3479(2100) 线段树二分 水果成篮
  • 文件的常用操作
  • 聊聊Oracle数据库的向量能力 - 详解
  • ReAct+LangGraph:构建智能AI Agent的完整指南(建议收藏) - 详解
  • 第七天项目
  • Spring Boot框架中在Controller方法里获取Request和Response对象的2种方式
  • 2025煤炭氟氯测定仪TOP5权威推荐:精准检测选对品牌,奥
  • 2025年上海办公室装修公司口碑排名:迎湖办公室装修实力可靠
  • Scrum 冲刺博客_4
  • 第五天项目
  • [豪の算法奇妙冒险] 代码随想录算法训练营第十四天 | 翻转二叉树、对称二叉树、二叉树的最大深度、二叉树的最小深度
  • 团队作业4——7天敏捷冲刺