SpringBoot 多数据源配置
前言:
才接触公司项目的时候看到公司springboot项目中使用了多个数据源的操作,当时除了会直接用,对多数据源就没任何其他的了解了,而且公司使用的是自己开发的一个脚手架,我感觉是把springboot和mybatis结合在了一起,框架中导入的和数据源连接相关的依赖都是公司开发然后打包之后的依赖包。所以当时我想通过公司写的代码去了解熟悉这个多数据源,结果发现是真的看不懂,和数据源相关的都是技术大佬自己去建方法,继承mybatis中的类,反正感觉很复杂,完全搞不懂。
然后中秋节就想着自己在网上学学吧,搜了很多关于springboot多数据源的配置,还是感觉看不懂,什么SqlSessionFactory、configuration… 再加上一些Springboot的注解。唉,我发现了,springboot自动配置和mybatis的相关配置完全忘完了。自己以前还看过好多遍,视频也看过,笔记也做过,没用… 之后就是从想搞懂多数据源到重新熟悉mybatis中sqlSession的创建。废话不多说,睡觉,12点半了。
对于mybatis常用对象的详细介绍推荐看这篇文章:https://blog.csdn.net/u013412772/article/details/73648537/
2. Mybatis中sqlSession的创建
2.1 SqlSession
sqlSession类似于JDBC中的Connection,它是应用程序与持久层之间执行交互操作的一个单线程对象,SqlSession对象包含了以数据库为背景的所有执行SQL操作的方法,底层封装了JDBC连接,可以用SqlSession实实例直接执行被映射的SQL语句,SqlSession的实例不能被共享,同时它是线程不安全的,不能将其实例的引用放在一个类的静态字段、实力字段中。
2.2 相关对象
**SqlSessionFactoryBuilder(构造器):**根据mybatis配置文件生成SqlSessionFactory;
**SqlSessionFactory(工厂接口):**生成SqlSession,使用的是工厂模式;
**SqlSession(会话):**既可以发送SQL执行返回结果,也可以获取Mapper的接口;
**SQL Mapper(映射器):**由一个java接口和XML文件构成,需要给出对应的SQL和映射规则;负责发送SQL去执行,并返回结果;
SqlSessionFactory 可以被认为是一个数据库连接池,它的作用是创建SqlSession接口对象,SqlSession就相当于一个数据库连接(Connection对象); SqlSessionFactory是在dataSource的基础上建立的。
2.3 mybatis.xml配置文件
对于mybatis配置文件,主要由以下属性配置组成,里面配置了数据库的连接环境信息(数据源,事务,加载映射文件和属性文件)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 加载类路径下的属性文件 -->
<properties resource="db.properties"/>
<!-- 设置类型别名 -->
<typeAliases>
<typeAlias type="cn.itcast.javaee.mybatis.app04.Student" alias="student"/>
</typeAliases>
<!-- 设置一个默认的连接环境信息 -->
<environments default="mysql_developer">
<!-- 连接环境信息,取一个任意唯一的名字 -->
<environment id="mysql_developer">
<!-- mybatis使用jdbc事务管理方式 -->
<transactionManager type="jdbc"/>
<!-- mybatis使用连接池方式来获取连接 -->
<dataSource type="pooled">
<!-- 配置与数据库交互的4个必要属性 -->
<property name="driver" value="${mysql.driver}"/>
<property name="url" value="${mysql.url}"/>
<property name="username" value="${mysql.username}"/>
<property name="password" value="${mysql.password}"/>
</dataSource>
</environment>
<!-- 连接环境信息,取一个任意唯一的名字 -->
<environment id="oracle_developer">
<!-- mybatis使用jdbc事务管理方式 -->
<transactionManager type="jdbc"/>
<!-- mybatis使用连接池方式来获取连接 -->
<dataSource type="pooled">
<!-- 配置与数据库交互的4个必要属性 -->
<property name="driver" value="${oracle.driver}"/>
<property name="url" value="${oracle.url}"/>
<property name="username" value="${oracle.username}"/>
<property name="password" value="${oracle.password}"/>
</dataSource>
</environment>
</environments>
<!-- 加载映射文件-->
<mappers>
<mapper resource="cn/itcast/javaee/mybatis/app14/StudentMapper.xml"/>
</mappers>
</configuration>
2.4 使用SqlSession执行SQL
//读取mybatis-config.xml文件
InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml");
//初始化mybatis,创建SqlSessionFactory类的实例
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
//创建session实例
SqlSession session = sqlSessionFactory.openSession();
/*
* 接下来在这里做很多事情,到目前为止,目的已经达到得到了SqlSession对象.通过调用SqlSession里面的方法,
* 可以测试MyBatis和Dao层接口方法之间的正确性,当然也可以做别的很多事情,在这里就不列举了
*/
//插入数据
User user = new User();
user.setPassword("123");
user.setUsername("123");
//第一个参数为方法的完全限定名:位置信息+映射文件当中的id
session.insert("com.cn.dao.UserMapping.insertUserInformation", user);
//提交事务
session.commit();
//关闭session
session.close();
3. SpringBoot自动配置数据源
首先,SpringBoot2.x版本默认使用的HikariCP数据源;常见数据源有(C3P0、DBCP、Druid、HikariCP)
3.1 自动装配DataSource原理
参考连接:https://blog.csdn.net/const_/article/details/96977428
Springboot实现了自动加载DataSource的相关配置,只需要引入相关依赖,在配置文件中配置相关属性即可;
自动配置类:org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
@Configuration
// 自动配置条件,当给定的类名在类路径上存在,则实例化当前Bean
@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })
// 开启属性配置类生效,这里生效的是:DataSourceProperties 配置类
@EnableConfigurationProperties(DataSourceProperties.class)
// 引入两个配置类
@Import({ DataSourcePoolMetadataProvidersConfiguration.class,
DataSourceInitializationConfiguration.class })
public class DataSourceAutoConfiguration {
......
@Configuration
// 按照条件注册Bean,需实现Condition接口,matches方法返回true
@Conditional(PooledDataSourceCondition.class)
// 当BeanFactory中不存在 DataSource、XADataSource 类型的 bean
@ConditionalOnMissingBean({ DataSource.class, XADataSource.class })
// 导入数据源配置类
@Import({ DataSourceConfiguration.Hikari.class, DataSourceConfiguration.Tomcat.class,
DataSourceConfiguration.Dbcp2.class, DataSourceConfiguration.Generic.class,
DataSourceJmxConfiguration.class })
protected static class PooledDataSourceConfiguration {
}
在PooledDataSourceConfiguration内部类上有 Tomcat.class 、Hikari.class 、Dbcp2.class 、Generic.class 四个内部类。每个内部类上都包含有 @ConditionalOnClass(XXX.class) 条件注解,即只有某些特定条件才会创建一个特定的 bean。
abstract class DataSourceConfiguration {
......
// 判断当前 classpath 下是否存在指定类
@ConditionalOnClass(HikariDataSource.class)
// beanFactory中不存在 DataSource 类型的 bean
@ConditionalOnMissingBean(DataSource.class)
// spring.datasource.type 属性值默认为 com.zaxxer.hikari.HikariDataSource
@ConditionalOnProperty(name = "spring.datasource.type", havingValue = "com.zaxxer.hikari.HikariDataSource", matchIfMissing = true)
static class Hikari {
@Bean
@ConfigurationProperties(prefix = "spring.datasource.hikari")
public HikariDataSource dataSource(DataSourceProperties properties) {
HikariDataSource dataSource = createDataSource(properties,
HikariDataSource.class);
if (StringUtils.hasText(properties.getName())) {
dataSource.setPoolName(properties.getName());
}
return dataSource;
}
}
属性绑定:
通过上面的@EnableConfigurationProperties(DataSourceProperties.class)注解来生效的。
@ConfigurationProperties(prefix = “spring.datasource”) 表示通过绑定配置文件中以 spring.datasource 开头的属性到配置类中。
@ConfigurationProperties(prefix = "spring.datasource")
public class DataSourceProperties implements BeanClassLoaderAware, InitializingBean {
......
}
最终 DataSourceAutoConfiguration 数据源自动配置将 DataSource 对象注册到 IOC 容器中,默认的数据源类型 com.zaxxer.hikari.HikariDataSource
;
4. SpringBoot-DataSource项目
基于springboot自定义多数据源及动态切换的代码在gitee上,可以借鉴;
https://gitee.com/leejiezh/springboot-datasource
下一篇:Java8新特性;因为在工作中遇到好多代码都是使用的新特性去写的,所以觉得还是有必要简单的学习一下