博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
2019-04-09 SpringBoot+Druid+MyBatis+Atomikos 的多数据源配置
阅读量:7056 次
发布时间:2019-06-28

本文共 15224 字,大约阅读时间需要 50 分钟。

前面部分是网上找的,我按照网上写的把自己搭建的过程展示一次

1.引入依赖

目前项目本来使用到了Mybatis plus(在自己的Mapper接口中继承BaseMapper获得基本的CRUD,而不需要增加MapperXML配置) 所以已经引入了依赖,同时使用到Druid和Atomikos,因此依赖如下

    
com.alibaba
druid-spring-boot-starter
1.1.9
org.springframework.boot
spring-boot-starter-jta-atomikos
com.baomidou
mybatis-plus-boot-starter
3.0.7.1
com.baomidou
mybatis-plus-generator
3.0.7.1

2. 修改配置文件application.properties配置数据源属性配置,如果使用profiles,则去当前active中进行配置

spring.datasource.system.xa-properties.url=jdbc:mysql://localhost:3306/easyweb-shiro?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&rewriteBatchedStatements=truespring.datasource.system.xa-properties.username=rootspring.datasource.system.xa-properties.password=x5spring.datasource.system.xa-data-source-class-name=com.alibaba.druid.pool.xa.DruidXADataSourcespring.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接口类包使用的sqlSessionpublic 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;@Configurationpublic 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.
(MapperMethod.java:227) at org.apache.ibatis.binding.MapperMethod.
(MapperMethod.java:49) at org.apache.ibatis.binding.MapperProxy.cachedMapperMethod(MapperProxy.java:65) at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:58) at com.sun.proxy.$Proxy164.insert(Unknown Source) at com.baomidou.mybatisplus.extension.service.impl.ServiceImpl.save(ServiceImpl.java:105) at com.baomidou.mybatisplus.extension.service.impl.ServiceImpl$$FastClassBySpringCGLIB$$76535273.invoke(
) at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:747) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) at com.alibaba.druid.support.spring.stat.DruidStatInterceptor.invoke(DruidStatInterceptor.java:72) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:689) at com.wf.ew.system.service.impl.LoginRecordServiceImpl$$EnhancerBySpringCGLIB$$ad70ce8c.save(
) at com.baomidou.mybatisplus.extension.service.impl.ServiceImpl$$FastClassBySpringCGLIB$$76535273.invoke(
) at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:747) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) at com.alibaba.druid.support.spring.stat.DruidStatInterceptor.invoke(DruidStatInterceptor.java:72) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:689) at com.wf.ew.system.service.impl.LoginRecordServiceImpl$$EnhancerBySpringCGLIB$$5843731c.save(
) at com.wf.ew.system.controller.MainController.addLoginRecord(MainController.java:167) at com.wf.ew.system.controller.MainController.doLogin(MainController.java:74) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:209) at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:877) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:783) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974) at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:877) at javax.servlet.http.HttpServlet.service(HttpServlet.java:661) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851) at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:61) at org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108) at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137) at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125) at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66) at org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:449) at org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365) at org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90) at org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83) at org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:383) at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362) at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at com.alibaba.druid.support.http.WebStatFilter.doFilter(WebStatFilter.java:123) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:496) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:748)

大致意思就是在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工厂的解决方法。

转载于:https://www.cnblogs.com/WongHugh/p/10674593.html

你可能感兴趣的文章
完整安装配置awstats的方法
查看>>
powerDesigner调节字体
查看>>
P1063 能量项链(区间dp)
查看>>
vim 学习总结
查看>>
centos6 内核优化
查看>>
Linux安装gitlab
查看>>
十四条令PHP初学者头疼问题大总结(1)
查看>>
MySQL的备份与还原
查看>>
加密U盘专业加密芯片方案
查看>>
js比较字符数组元素是否重复
查看>>
码客Online:HTC Zoe是什么功能?
查看>>
windows server 2012 r2 搭建企业文件共享存储
查看>>
从零学习游戏服务器开发(三) CSBattleMgr服务源码研究
查看>>
我的友情链接
查看>>
jQuery ajax - serialize() 方法
查看>>
Linux中设置服务自启动的三种方式(转)
查看>>
将Shapefile(SHP)转换为Surfer中的网格(GRD)的方法-适用Surfe14以上版本
查看>>
Linux下实现Apache站点安全
查看>>
el表达式
查看>>
看看JDK 8能给开发者们带来什么
查看>>