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

基于注解实现SpringBoot多数据源配置

1.功能介绍

在实际的开发中,同一个项目中使用多个数据源是很常见的场景。最近在学习的过程中使用注解的方式实现了一个Springboot项目多数据源的功能。具体实现方式如下。

2.在application.properties中添加多数据源配置

添加多个数据源和mapper文件路径配置,此配置用于基于java的配置数据源中使用。

#数据库配置
spring.datasource.demo.user.url=jdbc:mysql://xxx.xx.xx.xx:3306/demo-user
spring.datasource.demo.user.username=xxxx
spring.datasource.demo.user.password=xxxx
spring.datasource.demo.user.driver-class-name=com.mysql.jdbc.Driver

spring.datasource.demo.server.url=jdbc:mysql://xxx.xx.xx.xx:3306/springbootdemo
spring.datasource.demo.server.username=xxxx
spring.datasource.demo.server.password=xxxx
spring.datasource.demo.server.driver-class-name=com.mysql.jdbc.Driver

#mapper文件的路径
mybatis.demo.server.mapper-location=classpath*:mapper/demo-server/*.xml
mybatis.demo.user.mapper-location=classpath*:mapper/demo-user/*.xml

3.基于java的方式实现数据库配置

配置类图如下:
929184-20180624171236014-1309149716.png

其中DemoUserDbConfig类源代码如下:
其中Configuration注解表识此类为Spring的配置类。
MapperScan注解中的basePackages、annotationClass、sqlSessionTemplateRef用于配置此数据库链接扫描com.example包中所有注解为DemoUserMapper的接口。

@Configuration
@MapperScan(basePackages = {"com.example"},annotationClass = DemoUserMapper.class,
       sqlSessionTemplateRef = "demoUserTemplate")
public class DemoUserDbConfig extends AbstractDbConfig {

    @Value("${spring.datasource.demo.user.url}")
    private String url;

    @Value("${spring.datasource.demo.user.username}")
    private String userName;

    @Value("${spring.datasource.demo.user.password}")
    private String password;

    @Value("${spring.datasource.demo.user.driver-class-name}")
    private String driveClassName;

    @Value(value = "${mybatis.demo.user.mapper-location}")
    private String mapperLocation;


    @Bean(name = "demoUser")
    public DataSource secondaryDataSource() {
        return dataSourceFactory(driveClassName, url, userName, password);
    }

    @Bean(name = "demoUserTemplate")
    public SqlSessionTemplate demoUserSqlTemplate() throws Exception {
        return new SqlSessionTemplate((sqlSessionFactory(secondaryDataSource(), mapperLocation)));
    }

    @Bean
    @Qualifier("demoUserTransaction")
    public PlatformTransactionManager demoUserTransaction() {
        return new DataSourceTransactionManager(secondaryDataSource());
    }
}

其中AbstractDatasource设置了通用的方法,源代码如下:

public abstract class AbstractDbConfig {

    protected SqlSessionFactory sqlSessionFactory(DataSource dataSource, String mapperLocation) throws Exception {
        SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
        factoryBean.setDataSource(dataSource);
        ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
        Resource[] resource= resourceResolver.getResources(mapperLocation);
        factoryBean.setMapperLocations(resource);
        return factoryBean.getObject();
    }

    protected DataSource dataSourceFactory(String driveClassName, String url, String userName, String password){
        DruidDataSource datasource = new DruidDataSource();
        datasource.setDriverClassName(driveClassName);
        datasource.setUrl(url);
        datasource.setUsername(userName);
        datasource.setPassword(password);
        datasource.setMaxActive(20);
        datasource.setInitialSize(20);
        return datasource;
    }
}

使用相同的方法定义其他数据源。

4.定义接口和mapper文件

分别定义连接demo-user数据库和springbootdemo数据库的mapper文件。连接demo-user数据库的接口如下,使用DemoUserMapper注解表识。

@DemoUserMapper
public interface UserDao {

    /**
     * 返回所有的dictionary列表
     *
     * @return 所有的dictionary列表
     */
    List<String> list();

}

mapper文件如下:

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.example.multidatasource.business.user.UserDao">

    <select id="list" resultType="string">
        SELECT `name` FROM `user`
    </select>
</mapper>

定义读取springbootdemo数据库的接口,代码如下。使用DemoServerMapper注解表识

@DemoServerMapper
public interface DictionaryDao {

    /**
     * 返回所有的dictionary列表
     *
     * @return 所有的dictionary列表
     */
    List<Dictionary> list();

    /**
     * 查询此key下的所有子节点
     *
     * @param key 数据字典key
     * @return 返回key所有的子节点列表
     */
    List<Dictionary> listChildrenByKey(String key);

    /**
     * 插入数据到数据库
     *
     * @param dictionary
     */
    void insert(Dictionary dictionary);

}

mapper文件代码如下:

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.example.multidatasource.business.dictionary.dao.DictionaryDao">

    <resultMap id="DictionaryResultMap" type="com.example.multidatasource.business.dictionary.Dictionary">
        <result property="id" column="id"></result>
        <result property="dictKey" column="dict_key"></result>
        <result property="dictValue" column="dict_value"></result>
        <result property="parentId" column="parent_id"></result>
        <result property="description" column="description"></result>
    </resultMap>

    <select id="list" resultMap="DictionaryResultMap">
        SELECT * FROM `dictionary`
    </select>

    <select id="listChildrenByKey" resultMap="DictionaryResultMap">
        SELECT * FROM dictionary where parent_id= (select id from dictionary where dict_key= #{key})
    </select>

    <delete id="delete" parameterType="int">
        delete from dictionary where id = #{id}
    </delete>

    <insert id="insert" parameterType="com.example.multidatasource.business.dictionary.Dictionary">
        INSERT INTO `dictionary`(`dict_key`,`dict_value`,`parent_id`,`description`)
        VALUES(#{dictKey}, #{dictValue}, #{parentId}, #{description})
    </insert>
</mapper>

5.定义注解

定义DemoUserMapper和DemoServerMapper注解,分别作为使用demo-user和springbootdemo数据库的表识。
定义代码如下:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Component
@Mapper
public @interface DemoServerMapper {

    /**
     * The value may indicate a suggestion for a logical component name,
     * to be turned into a Spring bean in case of an autodetected component.
     * @return the suggested component name, if any (or empty String otherwise)
     */
    String value() default "";
}

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Component
@Mapper
public @interface DemoUserMapper {

    /**
     * The value may indicate a suggestion for a logical component name,
     * to be turned into a Spring bean in case of an autodetected component.
     * @return the suggested component name, if any (or empty String otherwise)
     */
    String value() default "";
}

6.使用单元测试验证配置

编写单元测试代码如下:

@RunWith(SpringRunner.class)
@SpringBootTest
public class MultiDatasourceApplicationTests {

    @Autowired
    private DictionaryDao dictionaryDao;

    @Autowired
    private UserDao userDao;

    @Test
    public void contextLoads() {
        System.out.println(dictionaryDao.list());
        System.out.println("===================");
        System.out.println(userDao.list());
    }

}

转载于:https://www.cnblogs.com/vitasyuan/p/9221058.html

相关文章:

  • shell if 参数
  • 换个角度看问题
  • Lr(3)-脚本调试之“参数化、检查点”
  • 添加删除mysql用户
  • dp学习笔记1
  • AT&T以11亿美元的价格将数据中心出售给Brookfield
  • mysql开启常规日志
  • js里的数据转换
  • sql删除重复数据只保留一条
  • 构建可观测的分布式系统
  • centos 普通用户获得sudo超级权限
  • 比特币独角兽圈在5月份新机构客户中录得30%的
  • sql server数据库导入导出bcp方法
  • 弱监督学习下的商品识别:CVPR 2018细粒度识别挑战赛获胜方案简介
  • Linux系统中通过mdadm程序实现软件RAID功能
  • 网络传输文件的问题
  • python3.6+scrapy+mysql 爬虫实战
  • (ckeditor+ckfinder用法)Jquery,js获取ckeditor值
  • [笔记] php常见简单功能及函数
  • [译]CSS 居中(Center)方法大合集
  • Android路由框架AnnoRouter:使用Java接口来定义路由跳转
  • Debian下无root权限使用Python访问Oracle
  • ES6 学习笔记(一)let,const和解构赋值
  • extract-text-webpack-plugin用法
  • gops —— Go 程序诊断分析工具
  • interface和setter,getter
  • Java知识点总结(JDBC-连接步骤及CRUD)
  • JS题目及答案整理
  • Making An Indicator With Pure CSS
  • passportjs 源码分析
  • python学习笔记 - ThreadLocal
  • SQL 难点解决:记录的引用
  • text-decoration与color属性
  • 搭建gitbook 和 访问权限认证
  • 分享一份非常强势的Android面试题
  • - 概述 - 《设计模式(极简c++版)》
  • 记一次用 NodeJs 实现模拟登录的思路
  • 力扣(LeetCode)21
  • 码农张的Bug人生 - 见面之礼
  • 爬虫进阶 -- 神级程序员:让你的爬虫就像人类的用户行为!
  • 前端js -- this指向总结。
  • 如何合理的规划jvm性能调优
  • 深入体验bash on windows,在windows上搭建原生的linux开发环境,酷!
  • Semaphore
  • #QT项目实战(天气预报)
  • (003)SlickEdit Unity的补全
  • (07)Hive——窗口函数详解
  • (4)事件处理——(2)在页面加载的时候执行任务(Performing tasks on page load)...
  • (env: Windows,mp,1.06.2308310; lib: 3.2.4) uniapp微信小程序
  • (附源码)ssm高校实验室 毕业设计 800008
  • (论文阅读32/100)Flowing convnets for human pose estimation in videos
  • (转)PlayerPrefs在Windows下存到哪里去了?
  • (转载)Linux 多线程条件变量同步
  • (总结)Linux下的暴力密码在线破解工具Hydra详解
  • *p++,*(p++),*++p,(*p)++区别?