当前位置:网站首页>使用SSM框架,配置多个数据库连接
使用SSM框架,配置多个数据库连接
2022-06-28 05:55:00 【不会code的coder】
公司要求,需要使用两个数据库,一个mysql,一个oracle。所以需要配置两个数据库来进行操作。
1.首先,需要在jdbc.properties文件中将两个库的配置数据写入,不过一个写driver,另一个写driver2,区别两个库的变量名。
代码如下:
#oracle web
jdbc.driver=oracle.jdbc.driver.OracleDriver
jdbc.url=jdbc:oracle:thin:@192.168.3.4:1521:ORCL
jdbc.username=abc
jdbc.password=adasdsa
#mysql
jdbc.driver2=com.mysql.jdbc.Driver
jdbc.url2=jdbc:mysql://192.168.3.4:3306/logcount?useUnicode=true&characterEncoding=utf-8
jdbc.username2=root
jdbc.password2=1234565
2.在spring-mybatis.xml中的配置:
- 先开启注解模式
- 两个数据库分别配置不同id的DataSource
- 就是配置切换数据库的自定义类的路径,选中默认数据库。
- 配置aop拦截dao层的所有访问接口,在dao层注解更改数据库。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.1.xsd">
<!-- 开启注解模式 -->
<context:annotation-config />
<context:component-scan base-package="com.shiyanlou" />
<context:property-placeholder location="classpath:jdbc.properties" />
<!-- oracle数据库 -->
<bean id="dataSource_first"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<!-- sqlite数据库 -->
<bean id="dateSource_second"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driver2}" />
<property name="url" value="${jdbc.url2}" />
<property name="username" value="${jdbc.username2}" />
<property name="password" value="${jdbc.password2}" />
</bean>
<!-- 下面的是切换数据库的自定义类 -->
<bean id="dataSource" class="com.shiyanlou.util.MultipleDataSource">
<!-- 默认使用sqlite数据库 -->
<property name="defaultTargetDataSource" ref="dateSource_second"></property>
<property name="targetDataSources">
<map>
<entry key="dataSource_first" value-ref="dataSource_first"></entry>
<entry key="dateSource_second" value-ref="dateSource_second"></entry>
</map>
</property>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="mapperLocations" value="classpath:/mappers/*.xml"></property>
<property name="configLocation" value="classpath:mybatis-config.xml" />
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"
p:basePackage="com.shiyanlou.dao" p:sqlSessionFactoryBeanName="sqlSessionFactory">
</bean>
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<tx:annotation-driven transaction-manager="txManager" />
<!-- 切面 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<bean id="dataSourceAspect" class="com.shiyanlou.util.DataSourceAspect"></bean>
<aop:config>
<aop:aspect ref="dataSourceAspect">
<!-- 拦截所有service方法,在dao层添加注解 -->
<aop:pointcut expression="execution(* com.shiyanlou.dao..*.*(..))" id="dataSourcePointcut"/>
<aop:before method="intercept" pointcut-ref="dataSourcePointcut"/>
</aop:aspect>
</aop:config>
</beans>
3.工具类的配置:自定义注解
- 注解类DataSource.java
/**
* <p>Title: DataSource.java</p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2018</p>
* @author 林猛
* @date 2018年5月3日
* @version 1.0
*/
package com.shiyanlou.util;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author linmeng
*
*/
/* @Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)*/
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface DataSource{
String value();
}
- 注解类DataSourceAspect.java
/**
* <p>Title: DataSourceAspect.java</p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2018</p>
* @author 林猛
* @date 2018年5月3日
* @version 1.0
*/
package com.shiyanlou.util;
import java.lang.reflect.Method;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
/**
* @author linmeng
*
*/
public class DataSourceAspect{
// 拦截目标方法,获取由@DataSource指定的数据源标识,设置到线程存储中以便切换数据源
public void intercept(JoinPoint point) throws Exception{
Class<?> target = point.getTarget().getClass();
MethodSignature signature=(MethodSignature)point.getSignature();
// 默认使用目标类型的注解,如果没有则使用其实现接口的注解
for (Class<?> clazz : target.getInterfaces()) {
resolveDataSource(clazz, signature.getMethod());
}
resolveDataSource(target, signature.getMethod());
}
/**
* 提取目标对象方法注解和类型注解中的数据源标识
*/
public void resolveDataSource(Class<?>clazz,Method method) {
try {
Class<?>[]types=method.getParameterTypes();
// 默认使用类型注解
if (clazz.isAnnotationPresent(DataSource.class)) {
DataSource source = clazz.getAnnotation(DataSource.class);
DbContextHolder.setDataSource(source.value());
}
// 方法注解可以覆盖类型注解
Method m=clazz.getMethod(method.getName(), types);
if (m!=null && m.isAnnotationPresent(DataSource.class)) {
DataSource source = m.getAnnotation(DataSource.class);
DbContextHolder.setDataSource(source.value());
}
} catch (Exception e) {
System.out.println(clazz+":"+e.getMessage());
}
}
}
- 切换数据库的工具类DbContextHolder.java:
/**
* <p>Title: DbContextHolder.java</p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2018</p>
* @author 林猛
* @date 2018年5月2日
* @version 1.0
*/
package com.shiyanlou.util;
/**
* @author linmeng
* 切换数据源的工具类
*/
public class DbContextHolder {
private static final ThreadLocal<String>THREAD_DATA_SOURCE =new ThreadLocal<>();
/**
* 设置当前数据库
*/
public static void setDataSource(String dataSource) {
THREAD_DATA_SOURCE.set(dataSource);
}
/**
* 取得当前数据库
*/
public static String getDataSource() {
return THREAD_DATA_SOURCE.get();
}
/**
* 清除上下文数据
*/
public static void clearDataSource() {
THREAD_DATA_SOURCE.remove();
}
}
自定义数据库切换类:
/**
* <p>Title: MultipleDataSource.java</p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2018</p>
* @author 林猛
* @date 2018年5月2日
* @version 1.0
*/
package com.shiyanlou.util;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
/**
* @author linmeng
* 自定义数据库切换类
*/
public class MultipleDataSource extends AbstractRoutingDataSource{
@Override
protected Object determineCurrentLookupKey() {
// TODO Auto-generated method stub
return DbContextHolder.getDataSource();
}
}
到此为止,数据库配置就完全完成了,使用的时候非常方便,如果配置的是两个数据库的话,有一个默认数据库,不需要任何修改,而需要使用另一个数据库的时候,只需要在dao层添加一个注解:
/**
* <p>Title: CityDao.java</p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2018</p>
* @author 林猛
* @date 2018年5月4日
* @version 1.0
*/
package com.shiyanlou.dao;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.annotations.Param;
import com.shiyanlou.domain.CityInfo;
import com.shiyanlou.util.DataSource;
/**
* @author linmeng
*
*/
@DataSource(value="dataSource_first")
public interface CityDao {
public List<CityInfo>getAdInfo(@Param("city")String city);
public Integer getAdInfoCount(String city);
public List<CityInfo>getCityInfo(Map<String, Object>map);
public List<CityInfo>getPoiData(Map<String, Object>map);
public Integer getCityInfoCount(Map<String, Object>map);
public List<CityInfo>singleCityExport(@Param("city")String city);
}
这个注解是跟spring-mybatis.xml中配置的targetDataSources中的entry key value有关系。
这里面好多具体配置我也不是特别懂,但是这样配置是可以使用的。大家可以试一下。
边栏推荐
- 数据中台:AI中台的实施与总结
- 深度学习19种损失函数
- CSI以及本地盘的相关实现记录
- 数据仓库:分层设计详解
- Mysql-16-subquery
- 6. graduation design temperature and humidity monitoring system (esp8266 + DHT11 +oled real-time upload temperature and humidity data to the public network server and display the real-time temperature
- Linked list in JS (including leetcode examples) < continuous update ~>
- 原动力×云原生正发声 降本增效大讲堂
- Binder面试之:内存管理单元
- YYGH-6-微信登录
猜你喜欢
[CAD drawing Video] AutoCAD 2014 master's way
How popular are FB and WhatsApp mass messages in 2022?
Linked list in JS (including leetcode examples) < continuous update ~>
数据中台:六问数据中台
線條動畫
上海域格ASR CAT1 4g模块2路保活低功耗4G应用
Jenkins继续集成2
Filecoin黑客松开发者大赛
What is the e-commerce conversion rate so abstract?
Where is the era bonus for developers?
随机推荐
高质量国产立体声编解码器CJC8988,Pin to Pin替代WM8988
Syn retransmission caused by IPVS
JSP
Office is being updated and the application cannot start normally
Video tutorial on website operation to achieve SEO operation [21 lectures]
使用pytorch和tensorflow计算分类模型的混淆矩阵
Flink window mechanism (two waits and the last explanation)
What are the advantages of e-mail marketing? Why do sellers of shopline independent station attach so much importance to it?
Ethereum Classic的难度计算|猿创征文
How to add live chat in your Shopify store?
Taobao seo training video course [22 lectures]
Ape pink ape power - Developer activity attack!
一看就会 MotionLayout使用的几种方式
Solution of dam safety automatic monitoring system for medium and small reservoirs
How popular are FB and WhatsApp mass messages in 2022?
numpy. reshape, numpy. Understanding of transfer
[CAD drawing Video] AutoCAD 2014 master's way
猿粉猿动力-开发者活动袭!
numpy.reshape, numpy.transpose的理解
Qtcanpool knowledge 07:ribbon