素材巴巴 > 程序开发 >

快速Mybatis动态数据源(基于java类)

程序开发 2023-09-17 10:25:45

上级文章:

快速Mybatis配置动态多数据源(基于XML):https://blog.csdn.net/qq_28033719/article/details/103565736


相对于xml配置来说,就干掉了一些文件

变动了这些

如果修改为只需要类配置的话,就能够更加的具有动态性,我只需要填写,jdbc.properties,一个文件就能够实现动态数据源的新增数据源,如果是springboot+mybatisplus的话更加容易


1、DataSourceAspect

package org.angular.test.aspect;import org.angular.test.annotation.DBSource;
 import org.angular.test.conf.DbContextHolder;
 import org.aspectj.lang.JoinPoint;
 import org.aspectj.lang.ProceedingJoinPoint;
 import org.aspectj.lang.annotation.*;
 import org.aspectj.lang.reflect.MethodSignature;
 import org.springframework.core.annotation.Order;
 import org.springframework.stereotype.Component;import java.lang.reflect.Method;/*** Created by Tanjw on 2019/12/11.*/
 @Component
 @Aspect
 @Order(-100) //这是为了保证AOP在事务注解之前生效,Order的值越小,优先级越高
 public class DataSourceAspect {private static final org.slf4j.Logger LOGGER = org.slf4j.LoggerFactory.getLogger(DataSourceAspect.class);/*** Around拦截,并需要返回结果集合* @param point* @return*/@Around(value = "@annotation(org.angular.test.annotation.DBSource)")public Object SensorsSourceAround(ProceedingJoinPoint point) {// classClass className = point.getTarget().getClass();// methodString methodName = point.getSignature().getName();// paramsClass[] argClass = ((MethodSignature)point.getSignature()).getParameterTypes();String dataSource = "";try {// get objectMethod method = className.getMethod(methodName, argClass);// @DBSource exist?if (method.isAnnotationPresent(DBSource.class)) {// DataSourceNamedataSource = method.getAnnotation(DBSource.class).value();}// proceedLOGGER.info("change to >>>> " + dataSource + " <<<< Source...");DbContextHolder.setDbType(dataSource);return point.proceed();} catch (Throwable throwable) {throwable.printStackTrace();}return null;}@After("@annotation(org.angular.test.annotation.DBSource)")public void afterSwitchDS(JoinPoint point){DbContextHolder.clearDbType();}}
 

2、DSConfigProperties

/*** Copyright © 2018 organization baomidou* 
* Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at**     http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.* 
*/
 package org.angular.test.bean;/*** Created by Tanjw on 2019/12/18.*/
 public class DSConfigProperties {/*** 连接池类型,如果不设置自动查找 Druid > HikariCp*/private String type;/*** JDBC driver*/private String driverClassName;/*** JDBC url 地址*/private String jdbcUrl;/*** JDBC 用户名*/private String username;/*** JDBC 密码*/private String password;public String getType() {return type;}public void setType(String type) {this.type = type;}public String getDriverClassName() {return driverClassName;}public void setDriverClassName(String driverClassName) {this.driverClassName = driverClassName;}public String getJdbcUrl() {return jdbcUrl;}public void setJdbcUrl(String jdbcUrl) {this.jdbcUrl = jdbcUrl;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}
 }
 

3、DSConfig

package org.angular.test.conf;import org.angular.test.bean.DSConfigProperties;
 import org.springframework.context.annotation.Configuration;import java.util.Map;/***  Created by Tanjw on 2019/12/18.*/
 @Configuration
 public class DSConfig {private Map datasource;public Map getDatasource() {return datasource;}public void setDatasource(Map datasource) {this.datasource = datasource;}
 }
 

4、MybatisDataSourceConf

package org.angular.test.conf;import com.alibaba.druid.pool.DruidDataSource;
 import org.angular.test.bean.DSConfigProperties;
 import org.angular.test.util.PropertiesUtil;
 import org.apache.ibatis.session.SqlSessionFactory;
 import org.mybatis.spring.SqlSessionFactoryBean;
 import org.mybatis.spring.annotation.MapperScan;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Lazy;import javax.sql.DataSource;
 import java.util.*;/*** Created by Tanjw on 2019/12/11.*/
 @Configuration
 @MapperScan(basePackages = {"com.gffunds.marketing.job.executor.core.mapper"})
 public class MybatisDataSourceConf {private DSConfig dSConfig;/*** SourceList, 弃用2019-12-18*//*@Primary@Bean(name = "nttestdb")@ConfigurationProperties(prefix = "db.datasource.nttestdb")public DataSource getDateSource1() {return DataSourceBuilder.create().build();}*//*** DynamicSourceBean*/@Bean(name = "dynamicDataSource")public DynamicDataSource DataSource() {Map targetDataSource = buildDataSource();DynamicDataSource dataSource = new DynamicDataSource();dataSource.setTargetDataSources(targetDataSource);return dataSource;}@Lazy@Bean(name = "sqlSessionFactory")public SqlSessionFactory test1SqlSessionFactory(@Qualifier("dynamicDataSource") DataSource dynamicDataSource)throws Exception {SqlSessionFactoryBean bean = new SqlSessionFactoryBean();bean.setDataSource(dynamicDataSource);return bean.getObject();}/*** 动态创建数据源*/private Map buildDataSource() {Map targetDataSource = new HashMap<>();initDBConfig("jdbc.datasource.");Map dbMap = dSConfig.getDatasource();// 配置datasource相关配置for(Map.Entry en : dbMap.entrySet()) {DSConfigProperties entity = en.getValue();DruidDataSource ds = new DruidDataSource();ds.setUrl(entity.getJdbcUrl());ds.setUsername(entity.getUsername());ds.setPassword(entity.getPassword());ds.setDriverClassName(entity.getDriverClassName());targetDataSource.put(en.getKey(), ds);}return targetDataSource;}private void initDBConfig(String cfgPrefix) {dSConfig = new DSConfig();Map datasource = new HashMap();Properties properties = PropertiesUtil.getProperty("jdbc.properties");Enumeration keys = properties.keys();while(keys.hasMoreElements()) {String key = String.valueOf(keys.nextElement());if (key.startsWith(cfgPrefix)) {String dbName = key.split(cfgPrefix)[1].split("\.")[0];String dbAttr = key.split(cfgPrefix)[1].split("\.")[1].split("=")[0];if(datasource.get(dbName) == null)datasource.put(dbName, new DSConfigProperties());DSConfigProperties config = datasource.get(dbName);switch (dbAttr) {case "driver":config.setDriverClassName(String.valueOf(properties.getProperty(key)));break;case "url":config.setJdbcUrl(String.valueOf(properties.getProperty(key)));break;case "username":config.setUsername(String.valueOf(properties.getProperty(key)));break;case "password":config.setPassword(String.valueOf(properties.getProperty(key)));break;}}}dSConfig.setDatasource(datasource);}
 }

5、PropertiesUitl

package org.angular.test.util;import javafx.beans.property.Property;import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.Enumeration;
 import java.util.List;
 import java.util.Properties;/*** 获取配置文件信息* Created by Tanjw on 2019/12/16.*/
 public class PropertiesUtil {/*** 获取相应的配置列表名* @param classpath* @param prefix* @return*/public static List getMap(String classpath, String prefix) {Properties properties = getProperty(classpath);List dbList = new ArrayList<>();Enumeration en = properties.keys();A:while(en.hasMoreElements()) {String str = String.valueOf(en.nextElement());str = str.split(prefix)[1].split("\.")[0];for(String dbStr : dbList) {if(dbStr.equals(str)) {continue A;}}dbList.add(str);}return dbList;}/*** 获取配置文件* @param classpath* @return*/public static Properties getProperty(String classpath) {Properties properties = new Properties();InputStream inputStream = PropertiesUtil.class.getClassLoader().getResourceAsStream(classpath);try {properties.load(inputStream);} catch (IOException e) {e.printStackTrace();}return properties;}
 }
 

 

6、jdbc.properties,我设置成默认截取 jdbc.datasource.前缀的方法,如果是springboot来个ConfigurationProperties直接就模板注入,爽的飞起

#templateDS
 jdbc.template.driver=oracle.jdbc.driver.OracleDriver
 jdbc.template.url=jdbc:oracle:thin:@localhost:1521/orcl
 jdbc.template.username=scott
 jdbc.template.password=tjw#oracle
 jdbc.datasource.orcl.driver=oracle.jdbc.driver.OracleDriver
 jdbc.datasource.orcl.url=jdbc:oracle:thin:@localhost:1521/orcl
 jdbc.datasource.orcl.username=scott
 jdbc.datasource.orcl.password=tjw#mysql
 jdbc.datasource.springboottest.driver=com.mysql.jdbc.Driver
 jdbc.datasource.springboottest.url=jdbc:mysql://localhost:3306/springboot_test
 jdbc.datasource.springboottest.username=root
 jdbc.datasource.springboottest.password=root

然后这样配置,mybatis会扫不到mapper,我就用比较粗暴的方法直接 new Directory 建立文件夹,和我存放Dao的目录名一致

因为这样子编译之后,包体会把xml和你的mapper接口放到一起,才不会说找不到mapper方法的问题


然后访问:

http://localhost:8088/angularTest/phone/getMysqlList  Mysql库

http://localhost:8088/angularTest/phone/getOrclList Orcl库

都能显示对应的数据就完成了,那个注解可以继续使用


下级文章:

快速Mybatis拦截器 - Inteceptor:https://blog.csdn.net/qq_28033719/article/details/107939959

快速cglib替代AOP解决内部调用:https://blog.csdn.net/qq_28033719/article/details/108339751


标签:

素材巴巴 Copyright © 2013-2021 http://www.sucaibaba.com/. Some Rights Reserved. 备案号:备案中。