2019-04-09 SpringBoot+Druid+MyBatis+Atomikos 的多数据源配置
前面部分是网上找的,我按照网上写的把自己搭建的过程展示一次
1.引入依赖
目前项目本来使用到了Mybatis plus(在自己的Mapper接口中继承BaseMapper获得基本的CRUD,而不需要增加MapperXML配置) 所以已经引入了依赖,同时使用到Druid和Atomikos,因此依赖如下
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.9</version>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jta-atomikos</artifactId>
</dependency> <!-- mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.0.7.1</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.0.7.1</version>
</dependency>
2. 修改配置文件application.properties配置数据源属性配置,如果使用profiles,则去当前active中进行配置
spring.datasource.system.xa-properties.url=jdbc:mysql://localhost:3306/easyweb-shiro?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&rewriteBatchedStatements=true
spring.datasource.system.xa-properties.username=root
spring.datasource.system.xa-properties.password=x5
spring.datasource.system.xa-data-source-class-name=com.alibaba.druid.pool.xa.DruidXADataSource
spring.datasource.system.unique-resource-name=systemDataSource
其中spring.datasource.system是安全属性的前缀,可以自行命名
3.在SpringBoot入口类所能扫描到的路径下增加配置类(多个数据源就增加多套配置Bean)
package com.wf.ew.common.config.datasource; import javax.sql.DataSource; import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager; import com.atomikos.jdbc.AtomikosDataSourceBean; @Configuration
@MapperScan(basePackages = "com.wf.ew.system.dao", sqlSessionTemplateRef = "systemSqlSessionTemplate") // 指定Mapper接口类包使用的sqlSession
public class SystemConfig { @Bean(name="systemDataSource")
@Primary
@ConfigurationProperties(prefix = "spring.datasource.system") // 安全属性前缀
public DataSource dataSource() {
AtomikosDataSourceBean datasource = new AtomikosDataSourceBean();
System.out.println(datasource);
return datasource;
} @Bean(name="systemSqlSessionFactory")
@Primary
public SqlSessionFactory sqlSessionFactory(@Qualifier("systemDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/**/*Mapper.xml"));// 扫描指定目录的xml
return bean.getObject();
} @Bean(name="systemTransactionManager")
@Primary
public DataSourceTransactionManager transactionManager(@Qualifier("systemDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
} @Bean(name="systemSqlSessionTemplate")
@Primary
public SqlSessionTemplate sqlSessionTemplate(@Qualifier("systemSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
4. 配置分布式事务
package com.wf.ew.common.config.datasource; import javax.transaction.TransactionManager;
import javax.transaction.UserTransaction; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.jta.JtaTransactionManager; import com.atomikos.icatch.jta.UserTransactionImp;
import com.atomikos.icatch.jta.UserTransactionManager; @Configuration
public class TransactionManagerConfig { @Bean
public UserTransaction userTransaction() throws Throwable {
UserTransactionImp userTransactionImp = new UserTransactionImp();
userTransactionImp.setTransactionTimeout(10000);
return userTransactionImp;
} @Bean
public TransactionManager atomikosTransactionManager() throws Throwable {
UserTransactionManager userTransactionManager = new UserTransactionManager();
userTransactionManager.setForceShutdown(false);
return userTransactionManager;
} @Bean
@DependsOn({ "userTransaction", "atomikosTransactionManager" })
public PlatformTransactionManager transactionManager() throws Throwable {
JtaTransactionManager manager = new JtaTransactionManager(userTransaction(), atomikosTransactionManager());
return manager;
}
}
5.使用事务时,可以采用以下方式来选择使用不同的事务
@Transactional("transactionManager")
transactionManager为分布式事务,systemTransactionManager为数据源事务,名字参考Bean命名
以上为按照别人帖子进行的配置,但当我运行时候报错
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.wf.ew.system.dao.LoginRecordMapper.insert
at org.apache.ibatis.binding.MapperMethod$SqlCommand.<init>(MapperMethod.java:)
at org.apache.ibatis.binding.MapperMethod.<init>(MapperMethod.java:)
at org.apache.ibatis.binding.MapperProxy.cachedMapperMethod(MapperProxy.java:)
at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:)
at com.sun.proxy.$Proxy164.insert(Unknown Source)
at com.baomidou.mybatisplus.extension.service.impl.ServiceImpl.save(ServiceImpl.java:)
at com.baomidou.mybatisplus.extension.service.impl.ServiceImpl$$FastClassBySpringCGLIB$$.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:)
at com.alibaba.druid.support.spring.stat.DruidStatInterceptor.invoke(DruidStatInterceptor.java:)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:)
at com.wf.ew.system.service.impl.LoginRecordServiceImpl$$EnhancerBySpringCGLIB$$ad70ce8c.save(<generated>)
at com.baomidou.mybatisplus.extension.service.impl.ServiceImpl$$FastClassBySpringCGLIB$$.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:)
at com.alibaba.druid.support.spring.stat.DruidStatInterceptor.invoke(DruidStatInterceptor.java:)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:)
at com.wf.ew.system.service.impl.LoginRecordServiceImpl$$EnhancerBySpringCGLIB$$5843731c.save(<generated>)
at com.wf.ew.system.controller.MainController.addLoginRecord(MainController.java:)
at com.wf.ew.system.controller.MainController.doLogin(MainController.java:)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:)
at java.lang.reflect.Method.invoke(Method.java:)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:)
at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:)
at org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:)
at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:)
at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:)
at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:)
at org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:)
at org.apache.shiro.web.servlet.AbstractShiroFilter$.call(AbstractShiroFilter.java:)
at org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:)
at org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:)
at org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:)
at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:)
at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:)
at com.alibaba.druid.support.http.WebStatFilter.doFilter(WebStatFilter.java:)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:)
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:)
at java.lang.Thread.run(Thread.java:)
大致意思就是在MapperXML里找不到LoginRecordMapper.insert
因为insert是通过继承BaseMapper得到的,因此实际上LoginRecordMapper.XML里面是没有id=insert的配置的;解决的方法就是配置session工厂时采用MybatisSqlSessionFactoryBean,而不是SqlSessionFactoryBean
@Bean(name="systemSqlSessionFactory")
@Primary
public SqlSessionFactory sqlSessionFactory(@Qualifier("systemDataSource") DataSource dataSource) throws Exception {
//SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/**/*Mapper.xml"));// 扫描指定目录的xml
return bean.getObject();
}
红色部分为修改后的,注释为修改前的。
至此分布式数据源就弄好了,虽然还没来得及测试,但是配置上多数据源之后,能跟以前没配置的一样能登陆进行系统了。
总结:
当发现错误描述有点莫名其妙的时候(明明接口没有insert,所以xml也不需要写insert),看看是不是继承了什么类,去查看一下父类的代码;当看到父类是包含一堆方法的时候,我还想过怎么除了扫描自己的xml还怎么增加别的地方的xml,在查找BaseMapper说明的过程中,找到了更改session工厂的解决方法。
2019-04-09 SpringBoot+Druid+MyBatis+Atomikos 的多数据源配置的更多相关文章
- springboot+druid+mybatis plus的多数据源配置
思路 yml中配置多个数据源信息 通过AOP切换不同数据源 配合mybatis plus使用 POM依赖 <dependency> <groupId>org.springfra ...
- Spring Boot 入门系列(二十三)整合Mybatis,实现多数据源配置!
d之前介绍了Spring Boot 整合mybatis 使用注解方式配置的方式实现增删改查以及一些复杂自定义的sql 语句 .想必大家对spring boot 项目中,如何使用mybatis 有了一定 ...
- spring boot + druid + mybatis + atomikos 多数据源配置 并支持分布式事务
文章目录 一.综述 1.1 项目说明 1.2 项目结构 二.配置多数据源并支持分布式事务 2.1 导入基本依赖 2.2 在yml中配置多数据源信息 2.3 进行多数据源的配置 三.整合结果测试 3.1 ...
- springboot+druid+mybatis
pom.xml <dependency> <groupId>com.microsoft.sqlserver</groupId> <artifactId> ...
- springboot v2.0.3版本多数据源配置
本篇分享的是springboot多数据源配置,在从springboot v1.5版本升级到v2.0.3时,发现之前写的多数据源的方式不可用了,捕获错误信息如: 异常:jdbcUrl is requir ...
- Spring Boot + Mybatis多数据源和动态数据源配置
文章转自 https://blog.csdn.net/neosmith/article/details/61202084 网上的文章基本上都是只有多数据源或只有动态数据源,而最近的项目需要同时使用两种 ...
- springboot系列十、springboot整合redis、多redis数据源配置
一.简介 Redis 的数据库的整合在 java 里面提供的官方工具包:jedis,所以即便你现在使用的是 SpringBoot,那么也继续使用此开发包. 二.redidTemplate操作 在 Sp ...
- spring+mybatis最简多数据源配置
作者:纯洁的微笑出处:http://www.ityouknow.com/ 版权所有,欢迎保留原文链接进行转载:) 说起多数据源,一般都来解决那些问题呢,主从模式或者业务比较复杂需要连接不同的分库来支持 ...
- springboot+Druid+mybatis整合
一.添加Druid.MySQL连接池.mybatis依赖 <!--整合Druid--> <dependency> <groupId>com.alibaba</ ...
随机推荐
- Unity资源打包学习笔记(二)、如何实现高效的unity AssetBundle热更新
转载请标明出处:http://www.cnblogs.com/zblade/ 0x01 目的 在实际的游戏开发中,对于游戏都需要进行打补丁的操作,毕竟,测试是有限的,而bug是无法预估的.那么在手游中 ...
- Mybatis+mysql批量插入性能分析测试
前言 今天在网上看到一篇文章(后文中的文章指的就是它) https://www.jianshu.com/p/cce617be9f9e 发现了一种有关于mybatis批量插入的新方法,而且看了文章发现我 ...
- spring-boot-starter-actuator /info获取空信息
用了spring-boot-starter-actuator,在监控页面对应服务中显示空值,下面是正常情况下有的值 pom配置了 <build> <plugins> <p ...
- WebApiClient的SteeltoeOSS.Discovery扩展
1 背景 从园子里看到一些朋友在某些项目开发中,选择的架构是spring cloud搭建底层微服务框架,dotnet core来编写业务逻辑,SteeltoeOSS.Discovery是dotnet和 ...
- Visual Studio 2019 正式发布,重磅更新,支持live share
如约而至,微软已于今天推出 Visual Studio 2019 正式版,一同发布的还有 Visual Studio 2019 for Mac. Visual Studio 2019 下载地址:htt ...
- [SpringBoot guides系列翻译]通过JDBC和Spring访问关系数据库
原文 参考链接 hikaricp Spring Boot JDBC Starter Spring Boot Starter Parent h2 database introduction Autowi ...
- 一次node-sass安装记录
node-sass的版本是3.9.3 Please restart this script from an administrative PowerShell! 在当前powershell中执行下命令 ...
- linux-2.6.18源码分析笔记---中断
一.中断初始化 中断的一些硬件机制不做过多的描述,只介绍一些和linux实现比较贴近的机制,便于理解代码. 1.1 关于intel和linux几种门的简介 intel提供了4种门:系统门,中断门,陷阱 ...
- AFO && OI回忆录
技不如人,甘拜下风 今天是2019.4.6,联考第一天,菜鸡attack原题爆炸(其实是都不会)心灰意冷(其实并没有很难过)写下了这篇文章 T1 2h写个跟\(k\)无关的假算法写到最后发现是三个lo ...
- 生鲜配送管理系统_升鲜宝V2.0 小标签打印功能【代配送商品打印小标签功能】说明_15382353715
小标签打印说明 小标签打印可以打印本系统的订单商品数量,也可以把外部的订单商品导入本系统进行打印. 打印本系统中的订单商品操作说明[上篇文章已经讲解相关的操作说明] 打印本系统之外的订单商品明细清单 ...