- 浏览: 394939 次
- 性别:
- 来自: 杭州
文章分类
- 全部博客 (760)
- 股票日志 (26)
- Selenium (0)
- selenium 2 环境的搭建 (1)
- 并发 (7)
- 框架开发 (1)
- 动态代理 (2)
- Struts2 (2)
- POI (2)
- jdk (3)
- maven (31)
- spring (35)
- mysql (31)
- 工作机会 (3)
- xtream (1)
- oracle dbms_metadata GET_DDL (0)
- SSI (1)
- DB (61)
- powermock (4)
- java 基础 (25)
- 多线程 (11)
- 高手 (2)
- java 底层 (2)
- 专业网站 (1)
- 开发联想 (1)
- 开发联想 (1)
- bat文件 (2)
- 清queue 语句 (1)
- 清queue 语句 (1)
- jquery (7)
- html5 (1)
- Jenkins (10)
- Linux (17)
- 工作issue (2)
- tomcat log (3)
- jvm (23)
- 项目细节 (0)
- oracle (41)
- 泛型 (3)
- 新知识点 (1)
- 数据库ddl 语句 (0)
- AQ (2)
- jms (0)
- 网络资源 (6)
- github (6)
- Easymock (1)
- Dom 解析XML (1)
- windows命令 (2)
- java (7)
- 正则表达式 (5)
- sequence (1)
- oracle 表meta信息 (1)
- 小工具技巧 (1)
- 辅助工具 (1)
- Junit (1)
- 泛型 generic (2)
- Java程序设计 (1)
- cglib (2)
- 架构师之路 (1)
- 数据库连接池 (5)
- c3p0 (1)
- eclipse使用 (1)
- oracle sql plus (1)
- 码农人生 (3)
- SVN (15)
- sqlplus (2)
- jsoup (1)
- 网络爬虫 (2)
- 新技能 (1)
- zookeeper (4)
- hadoop (1)
- SVNKIT (1)
- 从工具到知识点的整理 (1)
- log4j (13)
- 读文件 (0)
- 转义字符 (1)
- command (1)
- web service (3)
- 锁 (1)
- shell 脚本 (1)
- 遇到的错误 (2)
- tomcat (14)
- 房产 (5)
- bootstrap jquery ui (1)
- easyui (2)
- 个人征信 (1)
- 读写分离 (1)
- 备份 (1)
- rmi (6)
- webservice (1)
- JMX (4)
- 内存管理 (3)
- java设计 (1)
- timer (1)
- lock (2)
- concurrent (2)
- collection (1)
- tns (1)
- java基础 (15)
- File (1)
- 本机资源 (1)
- bat (1)
- windows (4)
- 数据结构 (3)
- 代码安全 (1)
- 作用域 (1)
- 图 (2)
- jvm内存结构 (1)
- 计算机思想 (1)
- quartz (6)
- Mongo DB (2)
- Nosql (4)
- sql (5)
- 第三方Java 工具 jar 项目 (2)
- drools (1)
- java swing (2)
- 调用console (1)
- runtime (1)
- process (1)
- swing (2)
- grouplayout (1)
- dubbo (0)
- bootstrap (0)
- nodejs (2)
- SVN hooks (1)
- jdbc (3)
- jdbc error (1)
- precedure (1)
- partition_key (1)
- active mq (1)
- blob (2)
- Eclipse (6)
- web server (1)
- bootstrapt (2)
- struts (1)
- ajax (1)
- js call back (1)
- 思想境界拓展 (1)
- JIRA (1)
- log (1)
- jaxb (3)
- xml java互相转换 (1)
- 装修 (2)
- 互联网 (2)
- threadlocal (3)
- mybatis (22)
- xstream (1)
- 排序 (1)
- 股票资源 (1)
- RPC (2)
- NIO (3)
- http client (6)
- 他人博客 (1)
- 代理服务器 (1)
- 网络 (2)
- web (1)
- 股票 (5)
- deadlock (1)
- JConsole (2)
- activemq (3)
- oralce (1)
- 游标 (1)
- 12月13日道富内部培训 (0)
- grant (1)
- 速查 (2)
- classloader (4)
- netty (4)
- 设计模式 (2)
- 缓存 (2)
- ehcache (2)
- framework (1)
- 内存分析 (2)
- dump (1)
- memory (2)
- 多高线程,并发 (1)
- hbase (2)
- 分布式系统 (1)
- socket (3)
- socket (1)
- 面试问题 (1)
- jetty (2)
- http (2)
- 源码 (1)
- 日志 (2)
- jni (1)
- 编码约定 (1)
- memorycache (1)
- redis (13)
- 杂谈 (1)
- drool (1)
- blockingqueue (1)
- ScheduledExecutorService (1)
- 网页爬虫 (1)
- httpclient (4)
- httpparser (1)
- map (1)
- 单例 (1)
- synchronized (2)
- thread (1)
- job (1)
- hashcode (1)
- copyonwriteArrayList (2)
- 录制声音 (1)
- java 标准 (2)
- SSL/TLS (1)
- itext (1)
- pdf (1)
- 钻石 (2)
- sonar (1)
- unicode (1)
- 编码 (4)
- html (1)
- SecurityManager (1)
- 坑 (1)
- Restful (2)
- svn hook (1)
- concurrentHashMap (1)
- 垃圾回收 (1)
- vbs (8)
- visual svn (2)
- power shell (1)
- wmi (3)
- mof (2)
- c# (1)
- concurrency (1)
- 劳动法 (1)
- 三国志游戏 (2)
- 三国 (1)
- 洪榕 (2)
- 金融投资知识 (1)
- motan (1)
- tkmybatis mapper (1)
- 工商注册信息查询 (1)
- consul (1)
- 支付业务知识 (2)
- 数据库备份 (1)
- 字段设计 (1)
- 字段 (1)
- dba (1)
- 插件 (2)
- PropEdit插件 (1)
- web工程 (1)
- 银行业知识 (2)
- 国内托管银行 (1)
- 数据库 (1)
- 事务 (2)
- git (18)
- component-scan (1)
- 私人 (0)
- db2 (14)
- alias (1)
- 住房 (1)
- 户口 (1)
- fastjson (1)
- test (6)
- RSA (2)
- 密钥 (1)
- putty (1)
- sftp (1)
- 加密 (1)
- 公钥私钥 (3)
- markdown (1)
- sweet (1)
- sourcetree (1)
- 好工具 (1)
- cmd (1)
- scp (1)
- notepad++ (1)
- ssh免密登录 (1)
- https (1)
- ssl (2)
- js (2)
- h2 (1)
- 内存 (2)
- 浏览器 (1)
- js特效 (1)
- io (1)
- 乱码 (1)
- 小工具 (1)
- 每周技术任务 (1)
- mongodb (7)
- 内存泄漏 (1)
- 码云 (2)
- 如何搭建java 视频服务器 tomcat (1)
- 资源 (1)
- 书 (1)
- 四色建模法 (1)
- 建模 (1)
- 配置 (1)
- 职位 (1)
- nginx (1)
- excel (1)
- log4j2 (2)
- 做菜 (1)
- jmap (1)
- jspwiki (1)
- activiti (1)
- 工作流引擎 (1)
- 安卓 (1)
- acitviti 例子 (1)
- 二维码 (1)
- 工作流 (1)
- powerdesign (2)
- 软件设计 (1)
- 乐观锁 (1)
- 王者荣耀 (1)
- session (2)
- token (5)
- cookie (4)
- springboot (24)
- jwt (2)
- 项目路径 (1)
- magicbook (1)
- requestType (1)
- json (2)
- swagger (1)
- eolinker (1)
- springdata (1)
- springmvc (1)
- controlleradvice (1)
- profile (1)
- 银行四要素 (1)
- 支付人员资源 (1)
- 支付渠道 (1)
- yaml (1)
- 中文编码 (1)
- mongo (2)
- serializable (1)
- 序列化 (1)
- zyd (1)
- unittest (1)
- 工具 (1)
- Something (1)
- 通达信 (1)
- protobuf (1)
- 算法 (1)
- springcloud (2)
- hikari (1)
- rocketmq (7)
- cachecloud (1)
- serfj (1)
- axure (1)
- lombok (1)
- 分布式锁 (1)
- 线程 (2)
- 同步代码块 (1)
- cobar (1)
- mq (1)
- rabbitmq (1)
- 定时执行 (1)
- 支付系统 (3)
- 唱歌 (1)
- elasticjob (1)
- 定时任务 (1)
- 界面 (1)
- flink (2)
- 大数据 (1)
- 接私活 (0)
- 内部培训 (2)
最新评论
-
dannyhz:
做股票从短线 试水,然后 慢慢发现 波段和 中期的故事可挖, ...
搭台唱戏 -
dannyhz:
http://developer.51cto.com/art/ ...
如何自己开发框架 它的注意点是什么
https://www.cnblogs.com/liujiduo/p/5004691.html
不仅讲了 多数据源 , 甚至讲了自定义注解,并在spring里用pointcut aop来拦截。
可以看到AbstractRoutingDataSource获取数据源之前会先调用determineCurrentLookupKey方法查找当前的lookupKey,这个lookupKey就是数据源标识。
因此通过重写这个查找数据源标识的方法就可以让spring切换到指定的数据源了。
第一步:创建一个DynamicDataSource的类,继承AbstractRoutingDataSource并重写determineCurrentLookupKey方法,代码如下:
复制代码
1 public class DynamicDataSource extends AbstractRoutingDataSource {
2
3 @Override
4 protected Object determineCurrentLookupKey() {
5 // 从自定义的位置获取数据源标识
6 return DynamicDataSourceHolder.getDataSource();
7 }
8
9 }
复制代码
第二步:创建DynamicDataSourceHolder用于持有当前线程中使用的数据源标识,代码如下:
复制代码
1 public class DynamicDataSourceHolder {
2 /**
3 * 注意:数据源标识保存在线程变量中,避免多线程操作数据源时互相干扰
4 */
5 private static final ThreadLocal<String> THREAD_DATA_SOURCE = new ThreadLocal<String>();
6
7 public static String getDataSource() {
8 return THREAD_DATA_SOURCE.get();
9 }
10
11 public static void setDataSource(String dataSource) {
12 THREAD_DATA_SOURCE.set(dataSource);
13 }
14
15 public static void clearDataSource() {
16 THREAD_DATA_SOURCE.remove();
17 }
18
19 }
复制代码
第三步:配置多个数据源和第一步里创建的DynamicDataSource的bean,简化的配置如下:
复制代码
1 <!--创建数据源1,连接数据库db1 -->
2 <bean id="dataSource1" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
3 <property name="driverClassName" value="${db1.driver}" />
4 <property name="url" value="${db1.url}" />
5 <property name="username" value="${db1.username}" />
6 <property name="password" value="${db1.password}" />
7 </bean>
8 <!--创建数据源2,连接数据库db2 -->
9 <bean id="dataSource2" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
10 <property name="driverClassName" value="${db2.driver}" />
11 <property name="url" value="${db2.url}" />
12 <property name="username" value="${db2.username}" />
13 <property name="password" value="${db2.password}" />
14 </bean>
15 <!--创建数据源3,连接数据库db3 -->
16 <bean id="dataSource3" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
17 <property name="driverClassName" value="${db3.driver}" />
18 <property name="url" value="${db3.url}" />
19 <property name="username" value="${db3.username}" />
20 <property name="password" value="${db3.password}" />
21 </bean>
22
23 <bean id="dynamicDataSource" class="com.test.context.datasource.DynamicDataSource">
24 <property name="targetDataSources">
25 <map key-type="java.lang.String">
26 <!-- 指定lookupKey和与之对应的数据源 -->
27 <entry key="dataSource1" value-ref="dataSource1"></entry>
28 <entry key="dataSource2" value-ref="dataSource2"></entry>
29 <entry key="dataSource3 " value-ref="dataSource3"></entry>
30 </map>
31 </property>
32 <!-- 这里可以指定默认的数据源 -->
33 <property name="defaultTargetDataSource" ref="dataSource1" />
34 </bean>
复制代码
到这里已经可以使用多数据源了,在操作数据库之前只要DynamicDataSourceHolder.setDataSource("dataSource2")即可切换到数据源2并对数据库db2进行操作了。
示例代码如下:
复制代码
1 @Service
2 public class DataServiceImpl implements DataService {
3 @Autowired
4 private DataMapper dataMapper;
5
6 @Override
7 public List<Map<String, Object>> getList1() {
8 // 没有指定,则默认使用数据源1
9 return dataMapper.getList1();
10 }
11
12 @Override
13 public List<Map<String, Object>> getList2() {
14 // 指定切换到数据源2
15 DynamicDataSourceHolder.setDataSource("dataSource2");
16 return dataMapper.getList2();
17 }
18
19 @Override
20 public List<Map<String, Object>> getList3() {
21 // 指定切换到数据源3
22 DynamicDataSourceHolder.setDataSource("dataSource3");
23 return dataMapper.getList3();
24 }
25 }
复制代码
--------------------------------------------------------------------------------------华丽的分割线--------------------------------------------------------------------------------------------------
但是问题来了,如果每次切换数据源时都调用DynamicDataSourceHolder.setDataSource("xxx")就显得十分繁琐了,而且代码量大了很容易会遗漏,后期维护起来也比较麻烦。能不能直接通过注解的方式指定需要访问的数据源呢,比如在dao层使用@DataSource("xxx")就指定访问数据源xxx?当然可以!前提是,再加一点额外的配置^_^。
首先,我们得定义一个名为DataSource的注解,代码如下:
1 @Target({ TYPE, METHOD })
2 @Retention(RUNTIME)
3 public @interface DataSource {
4 String value();
5 }
然后,定义AOP切面以便拦截所有带有注解@DataSource的方法,取出注解的值作为数据源标识放到DynamicDataSourceHolder的线程变量中:
复制代码
1 public class DataSourceAspect {
2
3 /**
4 * 拦截目标方法,获取由@DataSource指定的数据源标识,设置到线程存储中以便切换数据源
5 *
6 * @param point
7 * @throws Exception
8 */
9 public void intercept(JoinPoint point) throws Exception {
10 Class<?> target = point.getTarget().getClass();
11 MethodSignature signature = (MethodSignature) point.getSignature();
12 // 默认使用目标类型的注解,如果没有则使用其实现接口的注解
13 for (Class<?> clazz : target.getInterfaces()) {
14 resolveDataSource(clazz, signature.getMethod());
15 }
16 resolveDataSource(target, signature.getMethod());
17 }
18
19 /**
20 * 提取目标对象方法注解和类型注解中的数据源标识
21 *
22 * @param clazz
23 * @param method
24 */
25 private void resolveDataSource(Class<?> clazz, Method method) {
26 try {
27 Class<?>[] types = method.getParameterTypes();
28 // 默认使用类型注解
29 if (clazz.isAnnotationPresent(DataSource.class)) {
30 DataSource source = clazz.getAnnotation(DataSource.class);
31 DynamicDataSourceHolder.setDataSource(source.value());
32 }
33 // 方法注解可以覆盖类型注解
34 Method m = clazz.getMethod(method.getName(), types);
35 if (m != null && m.isAnnotationPresent(DataSource.class)) {
36 DataSource source = m.getAnnotation(DataSource.class);
37 DynamicDataSourceHolder.setDataSource(source.value());
38 }
39 } catch (Exception e) {
40 System.out.println(clazz + ":" + e.getMessage());
41 }
42 }
43
44 }
复制代码
最后在spring配置文件中配置拦截规则就可以了,比如拦截service层或者dao层的所有方法:
复制代码
1 <bean id="dataSourceAspect" class="com.test.context.datasource.DataSourceAspect" />
2 <aop:config>
3 <aop:aspect ref="dataSourceAspect">
4 <!-- 拦截所有service方法 -->
5 <aop:pointcut id="dataSourcePointcut" expression="execution(* com.test.*.dao.*.*(..))"/>
6 <aop:before pointcut-ref="dataSourcePointcut" method="intercept" />
7 </aop:aspect>
8 </aop:config>
9 </bean>
复制代码
OK,这样就可以直接在类或者方法上使用注解@DataSource来指定数据源,不需要每次都手动设置了。
示例代码如下:
复制代码
1 @Service
2 // 默认DataServiceImpl下的所有方法均访问数据源1
3 @DataSource("dataSource1")
4 public class DataServiceImpl implements DataService {
5 @Autowired
6 private DataMapper dataMapper;
7
8 @Override
9 public List<Map<String, Object>> getList1() {
10 // 不指定,则默认使用数据源1
11 return dataMapper.getList1();
12 }
13
14 @Override
15 // 覆盖类上指定的,使用数据源2
16 @DataSource("dataSource2")
17 public List<Map<String, Object>> getList2() {
18 return dataMapper.getList2();
19 }
20
21 @Override
22 // 覆盖类上指定的,使用数据源3
23 @DataSource("dataSource3")
24 public List<Map<String, Object>> getList3() {
25 return dataMapper.getList3();
26 }
27 }
复制代码
提示:注解@DataSource既可以加在方法上,也可以加在接口或者接口的实现类上,优先级别:方法>实现类>接口。也就是说如果接口、接口实现类以及方法上分别加了@DataSource注解来指定数据源,则优先以方法上指定的为准。
不仅讲了 多数据源 , 甚至讲了自定义注解,并在spring里用pointcut aop来拦截。
引用
可以看到AbstractRoutingDataSource获取数据源之前会先调用determineCurrentLookupKey方法查找当前的lookupKey,这个lookupKey就是数据源标识。
因此通过重写这个查找数据源标识的方法就可以让spring切换到指定的数据源了。
第一步:创建一个DynamicDataSource的类,继承AbstractRoutingDataSource并重写determineCurrentLookupKey方法,代码如下:
复制代码
1 public class DynamicDataSource extends AbstractRoutingDataSource {
2
3 @Override
4 protected Object determineCurrentLookupKey() {
5 // 从自定义的位置获取数据源标识
6 return DynamicDataSourceHolder.getDataSource();
7 }
8
9 }
复制代码
第二步:创建DynamicDataSourceHolder用于持有当前线程中使用的数据源标识,代码如下:
复制代码
1 public class DynamicDataSourceHolder {
2 /**
3 * 注意:数据源标识保存在线程变量中,避免多线程操作数据源时互相干扰
4 */
5 private static final ThreadLocal<String> THREAD_DATA_SOURCE = new ThreadLocal<String>();
6
7 public static String getDataSource() {
8 return THREAD_DATA_SOURCE.get();
9 }
10
11 public static void setDataSource(String dataSource) {
12 THREAD_DATA_SOURCE.set(dataSource);
13 }
14
15 public static void clearDataSource() {
16 THREAD_DATA_SOURCE.remove();
17 }
18
19 }
复制代码
第三步:配置多个数据源和第一步里创建的DynamicDataSource的bean,简化的配置如下:
复制代码
1 <!--创建数据源1,连接数据库db1 -->
2 <bean id="dataSource1" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
3 <property name="driverClassName" value="${db1.driver}" />
4 <property name="url" value="${db1.url}" />
5 <property name="username" value="${db1.username}" />
6 <property name="password" value="${db1.password}" />
7 </bean>
8 <!--创建数据源2,连接数据库db2 -->
9 <bean id="dataSource2" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
10 <property name="driverClassName" value="${db2.driver}" />
11 <property name="url" value="${db2.url}" />
12 <property name="username" value="${db2.username}" />
13 <property name="password" value="${db2.password}" />
14 </bean>
15 <!--创建数据源3,连接数据库db3 -->
16 <bean id="dataSource3" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
17 <property name="driverClassName" value="${db3.driver}" />
18 <property name="url" value="${db3.url}" />
19 <property name="username" value="${db3.username}" />
20 <property name="password" value="${db3.password}" />
21 </bean>
22
23 <bean id="dynamicDataSource" class="com.test.context.datasource.DynamicDataSource">
24 <property name="targetDataSources">
25 <map key-type="java.lang.String">
26 <!-- 指定lookupKey和与之对应的数据源 -->
27 <entry key="dataSource1" value-ref="dataSource1"></entry>
28 <entry key="dataSource2" value-ref="dataSource2"></entry>
29 <entry key="dataSource3 " value-ref="dataSource3"></entry>
30 </map>
31 </property>
32 <!-- 这里可以指定默认的数据源 -->
33 <property name="defaultTargetDataSource" ref="dataSource1" />
34 </bean>
复制代码
到这里已经可以使用多数据源了,在操作数据库之前只要DynamicDataSourceHolder.setDataSource("dataSource2")即可切换到数据源2并对数据库db2进行操作了。
示例代码如下:
复制代码
1 @Service
2 public class DataServiceImpl implements DataService {
3 @Autowired
4 private DataMapper dataMapper;
5
6 @Override
7 public List<Map<String, Object>> getList1() {
8 // 没有指定,则默认使用数据源1
9 return dataMapper.getList1();
10 }
11
12 @Override
13 public List<Map<String, Object>> getList2() {
14 // 指定切换到数据源2
15 DynamicDataSourceHolder.setDataSource("dataSource2");
16 return dataMapper.getList2();
17 }
18
19 @Override
20 public List<Map<String, Object>> getList3() {
21 // 指定切换到数据源3
22 DynamicDataSourceHolder.setDataSource("dataSource3");
23 return dataMapper.getList3();
24 }
25 }
复制代码
--------------------------------------------------------------------------------------华丽的分割线--------------------------------------------------------------------------------------------------
但是问题来了,如果每次切换数据源时都调用DynamicDataSourceHolder.setDataSource("xxx")就显得十分繁琐了,而且代码量大了很容易会遗漏,后期维护起来也比较麻烦。能不能直接通过注解的方式指定需要访问的数据源呢,比如在dao层使用@DataSource("xxx")就指定访问数据源xxx?当然可以!前提是,再加一点额外的配置^_^。
首先,我们得定义一个名为DataSource的注解,代码如下:
1 @Target({ TYPE, METHOD })
2 @Retention(RUNTIME)
3 public @interface DataSource {
4 String value();
5 }
然后,定义AOP切面以便拦截所有带有注解@DataSource的方法,取出注解的值作为数据源标识放到DynamicDataSourceHolder的线程变量中:
复制代码
1 public class DataSourceAspect {
2
3 /**
4 * 拦截目标方法,获取由@DataSource指定的数据源标识,设置到线程存储中以便切换数据源
5 *
6 * @param point
7 * @throws Exception
8 */
9 public void intercept(JoinPoint point) throws Exception {
10 Class<?> target = point.getTarget().getClass();
11 MethodSignature signature = (MethodSignature) point.getSignature();
12 // 默认使用目标类型的注解,如果没有则使用其实现接口的注解
13 for (Class<?> clazz : target.getInterfaces()) {
14 resolveDataSource(clazz, signature.getMethod());
15 }
16 resolveDataSource(target, signature.getMethod());
17 }
18
19 /**
20 * 提取目标对象方法注解和类型注解中的数据源标识
21 *
22 * @param clazz
23 * @param method
24 */
25 private void resolveDataSource(Class<?> clazz, Method method) {
26 try {
27 Class<?>[] types = method.getParameterTypes();
28 // 默认使用类型注解
29 if (clazz.isAnnotationPresent(DataSource.class)) {
30 DataSource source = clazz.getAnnotation(DataSource.class);
31 DynamicDataSourceHolder.setDataSource(source.value());
32 }
33 // 方法注解可以覆盖类型注解
34 Method m = clazz.getMethod(method.getName(), types);
35 if (m != null && m.isAnnotationPresent(DataSource.class)) {
36 DataSource source = m.getAnnotation(DataSource.class);
37 DynamicDataSourceHolder.setDataSource(source.value());
38 }
39 } catch (Exception e) {
40 System.out.println(clazz + ":" + e.getMessage());
41 }
42 }
43
44 }
复制代码
最后在spring配置文件中配置拦截规则就可以了,比如拦截service层或者dao层的所有方法:
复制代码
1 <bean id="dataSourceAspect" class="com.test.context.datasource.DataSourceAspect" />
2 <aop:config>
3 <aop:aspect ref="dataSourceAspect">
4 <!-- 拦截所有service方法 -->
5 <aop:pointcut id="dataSourcePointcut" expression="execution(* com.test.*.dao.*.*(..))"/>
6 <aop:before pointcut-ref="dataSourcePointcut" method="intercept" />
7 </aop:aspect>
8 </aop:config>
9 </bean>
复制代码
OK,这样就可以直接在类或者方法上使用注解@DataSource来指定数据源,不需要每次都手动设置了。
示例代码如下:
复制代码
1 @Service
2 // 默认DataServiceImpl下的所有方法均访问数据源1
3 @DataSource("dataSource1")
4 public class DataServiceImpl implements DataService {
5 @Autowired
6 private DataMapper dataMapper;
7
8 @Override
9 public List<Map<String, Object>> getList1() {
10 // 不指定,则默认使用数据源1
11 return dataMapper.getList1();
12 }
13
14 @Override
15 // 覆盖类上指定的,使用数据源2
16 @DataSource("dataSource2")
17 public List<Map<String, Object>> getList2() {
18 return dataMapper.getList2();
19 }
20
21 @Override
22 // 覆盖类上指定的,使用数据源3
23 @DataSource("dataSource3")
24 public List<Map<String, Object>> getList3() {
25 return dataMapper.getList3();
26 }
27 }
复制代码
提示:注解@DataSource既可以加在方法上,也可以加在接口或者接口的实现类上,优先级别:方法>实现类>接口。也就是说如果接口、接口实现类以及方法上分别加了@DataSource注解来指定数据源,则优先以方法上指定的为准。
发表评论
-
spring mvc的工作原理 有图很清晰
2018-09-29 11:01 380引用 https://www.cnblogs.com/xiao ... -
spring property loader的 placeholder的详细分析
2018-09-29 10:59 400引用 https://blog.csdn.net/liuxin ... -
对于spring controller的详细分析和使用指导
2018-09-29 10:58 402引用 https://www.cnblogs.com/lcs- ... -
简单servlet spring 已经mvc controller
2018-09-28 20:42 324引用 https://blog.csdn.net/liuxin ... -
mybatis 中 selectkey的作用
2018-09-21 19:07 592引用 https://blog.csdn.net/czd335 ... -
@value 的详解
2018-08-23 19:07 435引用 http://www.cnblogs.com/kings ... -
关于 多个值不同的处理 比如channelid 为空和非空的处理
2018-07-21 16:00 1967引用 <update id="update& ... -
mybatis调用查询日期
2018-07-19 22:42 573引用 dao: List<Date> getLa ... -
mybatis 对string类型判断比较 group case when then 综合
2018-07-19 20:57 1053引用 特别注意两点 一个是where 的用法 group的用 ... -
spring mvc ,spring boot里面的关于 global exception handle , controller advice的解释
2018-07-18 12:43 587引用 https://blog.csdn.net/kingin ... -
mybatis plus的文档
2018-07-11 19:31 529引用 http://mp.baomidou.com/#/qui ... -
springboot mybatis详解
2018-07-11 19:30 363引用 https://blog.csdn.net/mickjo ... -
关于spring 的json的传递 yixiaoping
2018-06-29 22:01 248https://blog.csdn.net/**/articl ... -
github 下载具体版本的 spring
2018-06-06 22:02 389引用https://blog.csdn.net/bbc2005 ... -
tomcat 到 servlet 到 spring servlet dispatcher的一串
2018-05-30 21:57 611引用 五月 30, 2018 9:31:35 下午 org. ... -
mybatis对乐观锁的 支持例子
2018-05-28 20:45 669引用 https://blog.csdn.net/zhouz ... -
mybatis timeout = 60 加上一个时间 可以让sql时间更长
2018-04-13 19:46 1172引用 <select id="fi ... -
mybatis 的分段插入大量数据的完整方法
2018-04-10 18:33 717https://blog.csdn.net/java_mr_z ... -
前三句可以打印 mybatis log
2018-03-25 21:46 456引用 @Test public void test( ... -
mybatis 转义字符
2018-03-22 20:13 487引用 <= <= ...
相关推荐
本篇文章将深入探讨如何基于注解和Spring实现多数据源配置和使用。 首先,我们需要理解"注解"在Java中的作用。注解是一种元数据,它提供了一种安全的方法来关联信息和代码(类、方法、变量等)。Spring框架广泛使用...
Spring框架支持多种数据源的配置方式,包括但不限于基于XML的配置、基于注解的配置以及基于Java配置的方式。本文主要关注基于XML的配置方法。 #### 三、XML配置详解 ##### 1. 数据源配置 数据源的配置通常涉及到...
在Spring Boot应用中,多数据源配置是一项关键的技术,它允许我们同时管理多个数据库,比如主库和从库,或者不同类型的数据库。本教程将详细阐述如何在Spring Boot项目中实现这一功能,从数据源配置、实体管理到...
在多数据源配置中,Spring能够帮助管理不同的数据源,通过配置bean来切换和控制数据源的使用。 **SpringMVC** 是Spring框架的一部分,专为Web开发设计。它简化了模型-视图-控制器(Model-View-Controller,MVC)的...
SpringBoot实现多数据源主要依靠Spring的`@Configuration`和`@DataSourceConfiguration`注解,以及Spring JDBC的`DataSource`接口。下面是一个基本的配置示例: ```java @Configuration public class ...
本教程将详细介绍如何使用注解来配置Spring的多数据源,结合spring、restlet和mysql环境进行实战演示。在开始之前,请确保已经执行了提供的`mysql_dml.sql`文件,以初始化必要的测试数据。 首先,我们需要理解...
在Spring Boot应用中,多数据源配置是一项重要的技术实践,特别是在大型系统中,可能需要连接到多个数据库以实现数据隔离、读写分离或是分布式事务管理。Spring Boot以其强大的自动化配置能力,使得设置多数据源变得...
Spring Boot结合JPA(Java Persistence API)和JdbcTemplate,为开发者提供了灵活且强大的多数据源配置能力。本示例将详细介绍如何在Spring Boot项目中实现这样的配置,以支持不同类型的数据库。 首先,我们要理解...
5. **编程或声明式数据源切换**:在业务代码中,可以使用Spring的`@Resource`注解注入DataSource,然后根据需求手动切换,或者通过AOP和Spring的代理机制自动处理数据源的切换。 6. **测试与优化**:最后,对整个...
通过上述步骤,我们可以实现在Spring环境中配置多个数据源、SessionFactory和TransactionManager的目标。这对于构建复杂的企业级应用、优化数据库性能以及提高系统的可伸缩性具有重要意义。然而,需要注意的是,多...
如果使用Spring Data JPA或Hibernate,数据源配置更为简单,因为它们会自动创建并管理数据源。Spring Data JPA通过`spring-boot-starter-data-jpa`依赖自动配置了JPA和HikariCP数据源。 总的来说,Spring提供了...
通过以上步骤,我们成功地在Spring Boot中实现了基于AOP注解的多数据源动态切换。这使得在运行时可以根据业务需求选择合适的数据源,提高了代码的灵活性和可维护性。在实际项目中,你可能还需要考虑事务管理、数据源...
在Spring Boot应用中,使用`spring-data-jpa`来配置MySQL多数据源是一项常见的需求,尤其是在构建大型分布式系统时,为了实现数据隔离、负载均衡或读写分离等目的。本教程将详细介绍如何在Spring Boot项目中配置多个...
- 数据源相关的Java配置类,用于配置Spring的DataSource和MybatisPlus。 - Mapper接口和对应的XML文件,定义数据库操作。 - 业务逻辑层的Java类,其中的方法使用了自定义注解来切换数据源。 通过这样的设计,项目...
在本教程中,我们将深入探讨如何在Spring Boot项目中配置和使用多数据源以及JdbcTemplate。 首先,让我们了解什么是`JdbcTemplate`。它是Spring提供的一种模板类,用于执行SQL语句,通过回调机制将结果转换为Java...
本教程将深入探讨如何在Spring中配置和管理多个数据源,并以MySQL为例进行实战演示。 首先,我们需要理解Spring Boot对数据源的默认支持。Spring Boot通过`spring.datasource.*`的配置属性简化了数据库连接的设置,...
通过以上步骤,你可以在Spring应用中成功配置和使用多个数据源。这使得你的系统更具扩展性和灵活性,能够适应复杂的企业级需求。记住,正确管理和配置数据源对于系统的稳定性和性能至关重要,因此在实际操作时一定要...
使用注解配置实现Spring动态数据源切换,实现原理 1、自定义动态数据源类DynamicDataSource: 实现spring类AbstractRoutingDataSource的方法determineCurrentLookupKey 2、自定义Spring AOP类DataSourceAspect 3、...
这些代码可以直接集成到你的项目中,只需要调整为匹配你的数据库配置,就可以实现Spring Boot 2下的多数据源支持,同时利用Hibernate和MyBatis的优势。 总之,多数据源的实现是Spring Boot 2应用中的高级特性,它...