先来看一下数据源配置方法,如下:
1 2 3 4 5 6 <dataSource type ="UNPOOLED|POOLED" > <property name ="driver" value ="com.mysql.cj.jdbc.Driver" /> <property name ="url" value ="jdbc:mysql..." /> <property name ="username" value ="root" /> <property name ="password" value ="1234" /> </dataSource >
数据源的配置是内嵌在environment节点中的,MyBatis在解析environment节点时,会一并解析数据源的配置。MyBatis会根据具体的配置信息,为不同的数据源创建相应工厂类,通过工厂类即可创建数据源实例。
数据源工厂类的实现逻辑
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 public class UnpooledDataSourceFactory implements DataSourceFactory { private static final String DRIVER_PROPERTY_PREFIX = "driver."; private static final int DRIVER_PROPERTY_PREFIX_LENGTH = DRIVER_PROPERTY_PREFIX.length(); protected DataSource dataSource; public UnpooledDataSourceFactory() { // 创建 UnpooledDataSource 对象 this.dataSource = new UnpooledDataSource(); } @Override public void setProperties(Properties properties) { Properties driverProperties = new Properties(); // 为 dataSource 创建元信息对象 MetaObject metaDataSource = SystemMetaObject.forObject(dataSource); // 遍历 properties 键列表,properties 由配置文件解析器传入 for (Object key : properties.keySet()) { String propertyName = (String) key; // 检测 propertyName 是否以 "driver." 开头 if (propertyName.startsWith(DRIVER_PROPERTY_PREFIX)) { String value = properties.getProperty(propertyName); // 存储配置信息到 driverProperties 中 driverProperties.setProperty(propertyName .substring(DRIVER_PROPERTY_PREFIX_LENGTH), value); } else if (metaDataSource.hasSetter(propertyName)) { String value = (String) properties.get(propertyName); // 按需转换 value 类型 Object convertedValue = convertValue( metaDataSource, propertyName, value); // 设置转换后的值到 UnpooledDataSourceFactory 指定属性中 metaDataSource.setValue(propertyName, convertedValue); } else { throw new DataSourceException("……"); } } if (driverProperties.size() > 0) { // 设置 driverProperties 到 UnpooledDataSourceFactory 的 // driverProperties 属性中 metaDataSource.setValue("driverProperties", driverProperties); } } private Object convertValue( MetaObject metaDataSource, String propertyName, String value) { Object convertedValue = value; // 获取属性对应的 setter 方法的参数类型 Class<?> targetType = metaDataSource.getSetterType(propertyName); // 按照 setter 方法的参数类型进行类型转换 if (targetType == Integer.class || targetType == int.class) { convertedValue = Integer.valueOf(value); } else if (targetType == Long.class || targetType == long.class) { convertedValue = Long.valueOf(value); } else if(targetType == Boolean.class||targetType == boolean.class){ convertedValue = Boolean.valueOf(value); } return convertedValue; } @Override public DataSource getDataSource() { return dataSource; } }
除了 setProperties 方法稍复杂一点,其他的都比较简单。
PooledDataSourceFactory
1 2 3 4 5 6 public class PooledDataSourceFactory extends UnpooledDataSourceFactory { public PooledDataSourceFactory() { // 创建 PooledDataSource this.dataSource = new PooledDataSource(); } }
PooledDataSourceFactory继承自UnpooledDataSourceFactory,复用了父类的逻辑,因此它的实现很简单。