国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > Java > 正文

Spring Boot + Mybatis多數據源和動態數據源配置方法

2024-07-13 10:16:52
字體:
來源:轉載
供稿:網友

網上的文章基本上都是只有多數據源或只有動態數據源,而最近的項目需要同時使用兩種方式,記錄一下配置方法供大家參考。

應用場景

項目需要同時連接兩個不同的數據庫A, B,并且它們都為主從架構,一臺寫庫,多臺讀庫。

多數據源

首先要將spring boot自帶的DataSourceAutoConfiguration禁掉,因為它會讀取application.properties文件的spring.datasource.*屬性并自動配置單數據源。在@SpringBootApplication注解中添加exclude屬性即可:

@SpringBootApplication(exclude = {  DataSourceAutoConfiguration.class})public class TitanWebApplication { public static void main(String[] args) {  SpringApplication.run(TitanWebApplication.class, args); }}

然后在application.properties中配置多數據源連接信息:

# titan庫spring.datasource.titan-master.url=jdbc:mysql://X.X.X.X:port/titan?characterEncoding=UTF-8spring.datasource.titan-master.username=spring.datasource.titan-master.password=spring.datasource.titan-master.driver-class-name=com.mysql.jdbc.Driver# 連接池配置# 省略# 其它庫spring.datasource.db2.url=jdbc:mysql://X.X.X.X:port/titan2?characterEncoding=UTF-8spring.datasource.db2.username=spring.datasource.db2.password=spring.datasource.db2.driver-class-name=com.mysql.jdbc.Driver

由于我們禁掉了自動數據源配置,因些下一步就需要手動將這些數據源創建出來:

@Configurationpublic class DataSourceConfig { @Bean(name = "titanMasterDS") @ConfigurationProperties(prefix = "spring.datasource.titan-master") // application.properteis中對應屬性的前綴 public DataSource dataSource1() {  return DataSourceBuilder.create().build(); } @Bean(name = "ds2") @ConfigurationProperties(prefix = "spring.datasource.db2") // application.properteis中對應屬性的前綴 public DataSource dataSource2() {  return DataSourceBuilder.create().build(); }}

接下來需要配置兩個mybatis的SqlSessionFactory分別使用不同的數據源:

@Configuration@MapperScan(basePackages = {"titan.mapper"}, sqlSessionFactoryRef = "sqlSessionFactory1")public class MybatisDbAConfig { @Autowired @Qualifier("titanMasterDS") private DataSource ds1; @Bean public SqlSessionFactory sqlSessionFactory1() throws Exception {  SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();  factoryBean.setDataSource(ds1); // 使用titan數據源, 連接titan庫  return factoryBean.getObject(); } @Bean public SqlSessionTemplate sqlSessionTemplate1() throws Exception {  SqlSessionTemplate template = new SqlSessionTemplate(sqlSessionFactory1()); // 使用上面配置的Factory  return template; }}

經過上面的配置后,titan.mapper下的Mapper接口,都會使用titan數據源。同理可配第二個SqlSessionFactory:

@Configuration@MapperScan(basePackages = {"other.mapper"}, sqlSessionFactoryRef = "sqlSessionFactory2")public class MybatisDbBConfig { @Autowired @Qualifier("ds2") private DataSource ds2; @Bean public SqlSessionFactory sqlSessionFactory2() throws Exception {  SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();  factoryBean.setDataSource(ds2);  return factoryBean.getObject(); } @Bean public SqlSessionTemplate sqlSessionTemplate2() throws Exception {  SqlSessionTemplate template = new SqlSessionTemplate(sqlSessionFactory2());  return template; }}

完成這些配置后,假設有2個Mapper titan.mapper.UserMapper和other.mapper.RoleMapper,使用前者時會自動連接titan庫,后者連接ds2庫。

動態數據源

使用動態數據源的初衷,是能在應用層做到讀寫分離,即在程序代碼中控制不同的查詢方法去連接不同的庫。除了這種方法以外,數據庫中間件也是個不錯的選擇,它的優點是數據庫集群對應用來說只暴露為單庫,不需要切換數據源的代碼邏輯。

我們通過自定義注解 + AOP的方式實現數據源動態切換。

首先定義一個ContextHolder, 用于保存當前線程使用的數據源名:

public class DataSourceContextHolder { public static final Logger log = LoggerFactory.getLogger(DataSourceContextHolder.class); /**  * 默認數據源  */ public static final String DEFAULT_DS = "titan-master"; private static final ThreadLocal<String> contextHolder = new ThreadLocal<>(); // 設置數據源名 public static void setDB(String dbType) {  log.debug("切換到{}數據源", dbType);  contextHolder.set(dbType); } // 獲取數據源名 public static String getDB() {  return (contextHolder.get()); } // 清除數據源名 public static void clearDB() {  contextHolder.remove(); }}

然后自定義一個javax.sql.DataSource接口的實現,這里只需要繼承Spring為我們預先實現好的父類AbstractRoutingDataSource即可:

public class DynamicDataSource extends AbstractRoutingDataSource { private static final Logger log = LoggerFactory.getLogger(DynamicDataSource.class); @Override protected Object determineCurrentLookupKey() {  log.debug("數據源為{}", DataSourceContextHolder.getDB());  return DataSourceContextHolder.getDB(); }}

創建動態數據源:

/**  * 動態數據源: 通過AOP在不同數據源之間動態切換  * @return  */ @Bean(name = "dynamicDS1") public DataSource dataSource() {  DynamicDataSource dynamicDataSource = new DynamicDataSource();  // 默認數據源  dynamicDataSource.setDefaultTargetDataSource(dataSource1());  // 配置多數據源  Map<Object, Object> dsMap = new HashMap(5);  dsMap.put("titan-master", dataSource1());  dsMap.put("ds2", dataSource2());  dynamicDataSource.setTargetDataSources(dsMap);  return dynamicDataSource; }

自定義注釋@DS用于在編碼時指定方法使用哪個數據源:

@Retention(RetentionPolicy.RUNTIME)@Target({  ElementType.METHOD})public @interface DS { String value() default "titan-master";}

編寫AOP切面,實現切換邏輯:

@Aspect@Componentpublic class DynamicDataSourceAspect { @Before("@annotation(DS)") public void beforeSwitchDS(JoinPoint point){  //獲得當前訪問的class  Class<?> className = point.getTarget().getClass();  //獲得訪問的方法名  String methodName = point.getSignature().getName();  //得到方法的參數的類型  Class[] argClass = ((MethodSignature)point.getSignature()).getParameterTypes();  String dataSource = DataSourceContextHolder.DEFAULT_DS;  try {   // 得到訪問的方法對象   Method method = className.getMethod(methodName, argClass);   // 判斷是否存在@DS注解   if (method.isAnnotationPresent(DS.class)) {    DS annotation = method.getAnnotation(DS.class);    // 取出注解中的數據源名    dataSource = annotation.value();   }  } catch (Exception e) {   e.printStackTrace();  }  // 切換數據源  DataSourceContextHolder.setDB(dataSource); } @After("@annotation(DS)") public void afterSwitchDS(JoinPoint point){  DataSourceContextHolder.clearDB(); }}

完成上述配置后,在先前SqlSessionFactory配置中指定使用DynamicDataSource就可以在Service中愉快的切換數據源了:

@Autowired private UserAModelMapper userAMapper; @DS("titan-master") public String ds1() {  return userAMapper.selectByPrimaryKey(1).getName(); } @DS("ds2") public String ds2() {  return userAMapper.selectByPrimaryKey(1).getName(); }

總結

以上所述是小編給大家介紹的Spring Boot + Mybatis多數據源和動態數據源配置方法,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對VeVb武林網網站的支持!


注:相關教程知識閱讀請移步到JAVA教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 雷山县| 阜阳市| 思茅市| 靖宇县| 淄博市| 友谊县| 利津县| 甘谷县| 鄂伦春自治旗| 翁源县| 浦江县| 教育| 正蓝旗| 东阿县| 若尔盖县| 莱阳市| 嘉兴市| 彰武县| 武乡县| 仙桃市| 芜湖市| 广灵县| 台前县| 平乡县| 深圳市| 五寨县| 丹东市| 太谷县| 商都县| 唐河县| 吉水县| 四会市| 左云县| 玉溪市| 阳山县| 临颍县| 沈丘县| 渝北区| 双江| 虎林市| 丰县|