首页
瞬间
关于
Search
1
使用easypoi导入导出excel,SSM和SpringBoot通用代码
1,349 阅读
2
王昆鹏|河南云软|拖欠工资
1,193 阅读
3
SpringBoot开启Druid监控,并去除内置广告
1,102 阅读
4
记一次redis暴露端口到外网所发生的事故《watchdogs挖矿木马综合分析报告》
1,039 阅读
5
重温记忆:Dubbo和Zk的安装
917 阅读
Docker
微服务
AI
RAG
技术
前端技术
后端技术
其他教程
资源分享区
JQuery
SEO
Java基础
Linux专题
SpringCloud
SpringMVC
Mybatis
SpringBoot
SSM
数据库
其他技术
手机赚钱
游戏试玩
曝光台
面试宝典
软件分享
学习资源
登录
Search
标签搜索
Linux专题
SpringBoot
SSM
tomcat
JavaWeb
springMVC
JVM'
JavaSE
Dubbo
其他教程
Docker
Myeclispe/Eclipse
Spring
学习资源
Mysql
建站经历
微服务
Nginx
手机赚钱
前端
Typecho
累计撰写
114
篇文章
累计收到
16
条评论
首页
栏目
Docker
微服务
AI
RAG
技术
前端技术
后端技术
其他教程
资源分享区
JQuery
SEO
Java基础
Linux专题
SpringCloud
SpringMVC
Mybatis
SpringBoot
SSM
数据库
其他技术
手机赚钱
游戏试玩
曝光台
面试宝典
软件分享
学习资源
页面
瞬间
关于
搜索到
12
篇与
的结果
2019-02-23
Mybatis之配置多个数据源
有时候我们会配置多个数据源来减轻数据库的压力,以便服务能正常运行。在此就不介绍数据库读写分离的具体实现只是在代码方面实现数据库的动态切换,如有感兴趣的小伙伴可以看看数据库中间件mycat来实现数据库的读写分离首先我们需要新建这几个类,用来实现数据库的动态切换,我们需要创建四个类,如下:分别用来处理不同的业务需求。DataSource.javaimport java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.Ret <!--more--> 有时候我们会配置多个数据源来减轻数据库的压力,以便服务能正常运行。在此就不介绍数据库读写分离的具体实现 只是在代码方面实现数据库的动态切换,如有感兴趣的小伙伴可以看看数据库中间件mycat来实现数据库的读写分离 上次参考别的文章进行写的,出现了很对问题,大致就是在有事务的方法上就会出现数据源切换错误,我们的从库,只允许读操作,因此,就会导致操作不成功,写操作也会自己切换到读库上,最后发现是用完数据源没有清空引起的。 首先我们需要新建这几个类,用来实现数据库的动态切换,我们需要创建四个类,如下: 分别用来处理不同的业务需求。 `DataSource.java`import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;/**RUNTIME编译器将把注释记录在类文件中,在运行时 VM 将保留注释,因此可以反射性地读取。*/@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface DataSource{ String value();} `DataSourceAspect.java`import java.lang.reflect.Method;import org.apache.log4j.Logger;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.reflect.MethodSignature;import com.gainet.controller.admin.IndexController;public class DataSourceAspect{/** * 在dao层方法获取datasource对象之前,在切面中指定当前线程数据源 */ private static final Logger logger = Logger .getLogger(DataSourceAspect.class); public void before(JoinPoint point) { Object target = point.getTarget(); String method = point.getSignature().getName(); Class[] classz = target.getClass().getInterfaces(); // 获取目标类的接口, 所以@DataSource需要写在接口上 Class[] parameterTypes = ((MethodSignature) point.getSignature()) .getMethod().getParameterTypes(); try { Method m = classz[0].getMethod(method, parameterTypes); if (m != null && m.isAnnotationPresent(DataSource.class)) { DataSource data = m.getAnnotation(DataSource.class); logger.info("数据库库类型:" + data.value()); HandleDataSource.putDataSource(data.value()); // 数据源放到当前线程中 if(null==data.value() || "".equals(data.value())){ HandleDataSource.putDataSource("master"); // 数据源放到当前线程中 } }else{ HandleDataSource.putDataSource("master"); // 数据源放到当前线程中 logger.info("数据库库类型:master" ); } } catch (Exception e) { e.printStackTrace(); } } //执行完切面后,将线程共享中的数据源名称清空 public void after(JoinPoint joinPoint){ logger.info("执行完切面,将线程共享中的数据源名称清空"); HandleDataSource.removeDataSource(); } }`DynamicDataSource.java`import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;public class DynamicDataSource extends AbstractRoutingDataSource{/** * 获取与数据源相关的key 此key是Map resolvedDataSources 中与数据源绑定的key值 * 在通过determineTargetDataSource获取目标数据源时使用 */ @Override protected Object determineCurrentLookupKey() { return HandleDataSource.getDataSource(); } }`HandleDataSource.java` public class HandleDataSource{public static final ThreadLocal holder = new ThreadLocal(); /** * 绑定当前线程数据源 * * @param key */ public static void putDataSource(String datasource) { holder.set(datasource); } /** * 获取当前线程的数据源 * * @return */ public static String getDataSource() { return holder.get(); } /** * 移除数据源 */ public static void removeDataSource() { holder.remove(); }}`db.properties`main database 主库jdbc.driverClassName=com.mysql.jdbc.Driverjdbc.url=jdbc\:mysql\://192.168.103.23\:3306/hotel-proof?useUnicode\=true&characterEncoding\=utf-8&useSSL\=false jdbc.username=rootjdbc.password=123456jdbc.initialSize=1jdbc.minIdle=1jdbc.maxActive=20jdbc.maxWait=60000jdbc.removeAbandoned=truejdbc.removeAbandonedTimeout=180jdbc.timeBetweenEvictionRunsMillis=60000jdbc.minEvictableIdleTimeMillis=300000jdbc.validationQuery=SELECT 1jdbc.testWhileIdle=truejdbc.testOnBorrow=falsejdbc.testOnReturn=falseslave database 从库slave.jdbc.driverClassName=com.mysql.jdbc.Driverslave.jdbc.url=jdbc\:mysql\://ip\:端口/数据库?useUnicode\=true&characterEncoding\=utf-8&useSSL\=falseslave.jdbc.username=rootslave.jdbc.password=123456slave.jdbc.initialSize=1slave.jdbc.minIdle=1slave.jdbc.maxActive=20slave.jdbc.maxWait=60000slave.jdbc.removeAbandoned=trueslave.jdbc.removeAbandonedTimeout=180slave.jdbc.timeBetweenEvictionRunsMillis=60000slave.jdbc.minEvictableIdleTimeMillis=300000slave.jdbc.validationQuery=SELECT 1slave.jdbc.testWhileIdle=trueslave.jdbc.testOnBorrow=falseslave.jdbc.testOnReturn=false`applicationContext-dao.xml` classpath:mybatis/db.properties classpath:alipayinfo.properties classpath:wxpayinfo.properties 怎样使用呢? 我们只需要把注解 @DataSource("slave") 打在接口上即可,一定要在接口上,不然不起作用。
2019年02月23日
486 阅读
0 评论
0 点赞
2019-02-23
如何在Controller层实现事务管理?
有时候我i们需要让一个controller中的操作数据库的方法一下走完,如果发生错误就要回滚之前的插入的所有的数据,这个时候就需要controller事务了。在spring aop 事务管理中发现,我们是在service层实现的事务管理。 现在有如下场景,大家讨论下看如何实现? ControllerA、ControllerB、ControllerC….共同依赖ServiceA、ServiceB,上述Controller的save操作需要把数据同步ServiceA和ServiceB。 由于每个Controller保存ServiceB的extraData字段是通过Json组装的,所以每
2019年02月23日
360 阅读
0 评论
0 点赞
2019-02-23
SpringMVC参数校验
使用SpringMVC时配合hibernate-validate进行参数的合法性校验,能节省一定的代码量。1.搭建Web工程并引入hibernate-validate依赖
2019年02月23日
416 阅读
0 评论
0 点赞
2019-02-22
老的JAVA WEB 项目(文件夹有WebRoot等)报错java.lang.NoClassDefFoundError问题
老的JAVA WEB 项目(文件夹有WebRoot等)报错java.lang.NoClassDefFoundError问题
2019年02月22日
210 阅读
0 评论
0 点赞
2019-02-15
Shiro之记住我功能的实现
Shiro之记住我功能的实现
2019年02月15日
261 阅读
0 评论
0 点赞
1
2
3