源码中的设计没那么复杂,不信来看看MyBatis的DataSource的实现

本文详细探讨了MyBatis中DataSource的设计,包括DataSourceFactory、UnpooledDataSource和PooledDataSource。UnpooledDataSource不支持连接池,而PooledDataSource利用Java动态代理管理连接池,通过PoolState组件维护连接状态,实现高效的数据库连接管理。文章通过流程图帮助理解连接的获取与释放过程。
摘要由CSDN通过智能技术生成

本文我们来给大家介绍了MyBatis中的DataSource的设计实现。其实蛮容易的哦。

DataSource

  首先大家要清楚DataSource属于MyBatis三层架构设计的基础层

然后我们来看看具体的实现。

  在数据持久层中,数据源是一个非常重要的组件,其性能直接关系到整个数据持久层的性能,在实际开发中我们常用的数据源有 Apache Common DBCP,C3P0,Druid 等,MyBatis不仅可以集成第三方数据源,还提供的有自己实现的数据源。

   在MyBatis中提供了两个 javax.sql.DataSource 接口的实现,分别是 PooledDataSource 和 UnpooledDataSource .

 

1 DataSourceFactory

   DataSourceFactory是用来创建DataSource对象的,接口中声明了两个方法,作用如下

public interface DataSourceFactory {
  // 设置 DataSource 的相关属性,一般紧跟在初始化完成之后
  void setProperties(Properties props);

  // 获取 DataSource 对象
  DataSource getDataSource();

}

DataSourceFactory接口的两个具体实现是 UnpooledDataSourceFactory 和 PooledDataSourceFactory 这两个工厂对象的作用通过名称我们也能发现是用来创建不带连接池的数据源对象和创建带连接池的数据源对象,先来看下 UnpooledDataSourceFactory 中的方法

  /**
   * 完成对 UnpooledDataSource 的配置
   * @param properties 封装的有 DataSource 所需要的相关属性信息
   */
  @Override
  public void setProperties(Properties properties) {
    Properties driverProperties = new Properties();
    // 创建 DataSource 对应的 MetaObject 对象
    MetaObject metaDataSource = SystemMetaObject.forObject(dataSource);
    // 遍历 Properties 集合,该集合中配置了数据源需要的信息
    for (Object key : properties.keySet()) {
      String propertyName = (String) key; // 获取属性名称
      if (propertyName.startsWith(DRIVER_PROPERTY_PREFIX)) {
        // 以 "driver." 开头的配置项是对 DataSource 的配置
        String value = properties.getProperty(propertyName);
        driverProperties.setProperty(propertyName.substring(DRIVER_PROPERTY_PREFIX_LENGTH), value);
      } else if (metaDataSource.hasSetter(propertyName)) {
        // 有该属性的 setter 方法
        String value = (String) properties.get(propertyName);
        Object convertedValue = convertValue(metaDataSource, propertyName, value);
        // 设置 DataSource 的相关属性值
        metaDataSource.setValue(propertyName, convertedValue);
      } else {
        throw new DataSourceException("Unknown DataSource property: " + propertyName);
      }
    }
    if (driverProperties.size() > 0) {
      // 设置 DataSource.driverProperties 的属性值
      metaDataSource.setValue("driverProperties", driverProperties);
    }
  }

UnpooledDataSourceFactory的getDataSource方法实现比较简单,直接返回DataSource属性记录的 UnpooledDataSource 对象

2 UnpooledDataSource

  UnpooledDataSource 是 DataSource接口的其中一个实现,但是 UnpooledDataSource 并没有提供数据库连接池的支持,我们来看下他的具体实现吧

  声明的相关属性信息

  private ClassLoader driverClassLoader; // 加载Driver的类加载器
  private Properties driverProperties; // 数据库连接驱动的相关信息
  // 缓存所有已注册的数据库连接驱动
  private static Map<String, Driver> registeredDrivers = new ConcurrentHashMap<>();

  private String driver; // 驱动
  private String url; // 数据库 url
  private String username; // 账号
  private String password; // 密码

  private Boolean autoCommit; // 是否自动提交
  private Integer defaultTransactionIsolationLevel; // 事务隔离级别
  private Integer defaultNetworkTimeout;

然后在静态代码块中完成了 Driver的复制

  static {
    // 从 DriverManager 中获取 Drivers
    Enumeration<Driver> drivers = DriverManager.getDrivers();
    while (drivers.hasMoreElements()) {
      Driver driver = drivers.nextElement();
      // 将获取的 Driver 记录到 Map 集合中
      registeredDrivers.put(driver.getClass().getName(), driver);
    }
  }

UnpooledDataSource 中获取Connection的方法最终都会调用 doGetConnection() 方法。

<
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

倾听铃的声

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值