基於注解實現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的方式實現數據庫配置

配置類圖如下:

其中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());
    }

}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM