Java程序员干货学习笔记—Spring结合MyBatis实现数据库读写分离

发布时间:2019-11-19 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了Java程序员干货学习笔记—Spring结合MyBatis实现数据库读写分离脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

随着系统用户访问量不断增加,数据库的频繁访问将成为我们系统的一大瓶颈之一。由于项目前期用户量不大,我们实现单一的数据库就能完成。但是后期单一的数据库根本无法支撑庞大的项目去访问数据库,那么如何解决这个问题呢?

实际的应用中,数据库都是读多写少(读取数据的频率高,更新数据的频率相对较少),而读取数据通常耗时比较长,占用数据库服务器的CPU较多,从而影响用户体验。我们通常的做法就是把查询从主库中抽取出来,采用多个从库,使用负载均衡,减轻每个从库的查询压力

采用读写分离技的目标:有效减轻Master库的压力,又可以把用户查询数据的请求分发到不同的Slave库,从而保证系统的健壮性。我们看下采用读写分离的背景。

我们在项目开发初期的时候就设计了一个简单的读写分离,现在我把demo分享给大家。

**采用技术SPRing + mybatis
首先定义一个annotation**

import java.lang.annotation.ElementTyPE; import java.lang.annotation.Target; import java.lang.annotation.Retention; import java.lang.annotation.Retentionpolicy; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface DataSource {  public String value(); } 

再定义一个HandleDataSource

public class HandleDataSource {  public static final ThreadLocal holder = new ThreadLocal();  public static void putDataSource(String datasource) {  holder.set(datasource);  }  public static String getDataSource() {  return holder.get();  } } 

定义一个切面

import java.lang.reflect.Method; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.reflect.MethodSignature; public class DataSourceAspect {  public void pointCut() {  };  public void before(JoinPoint point) {  Object target = point.getTarget();// 拦截的实体类  String method = point.getSignature().getName();// 拦截的方法名  Class[] classz = target.getClass().getInterfaces();  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);  HandleDataSource.putDataSource(data.value());  }  } catch (Exception e) {  e.printStackTrace();  }  } } 

获取数据

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; public class ChooseDataSource extends AbstractRoutingDataSource {    protected Object determinecurrentLookupKey() {  return HandleDataSource.getDataSource();  }   } 

配置XMl

classpath*:MySQL.propertiescom.mySQL.jdbc.Driver${jdbc.url}${jdbc.user}${jdbc.password}SELECT 1 From DUAL32510010000true60com.mysql.jdbc.Driver${jdbc.url.read}${jdbc.user.read}${jdbc.password.read}SELECT 1 From DUAL32510010000true60 

注解到service接口上面

源码地址:http://ccblog.oss-cn-hangzhou...
数据库表就一张 根据mybatisxML大家自己建一下

另外这里还有一个瑕疵就是,当你使用注解事务的时候系统只能读取默认的数据源,这个问题主要是因为spring的事务和自定义的aop存在一个先后顺序的问题

Spring中的事务是通过aop来实现的,当我们自己写aop拦截的时候,会遇到跟spring的事务aop执行的先后顺序问题,比如说动态切换数据源的问题,如果事务在前,数据源切换在后,会导致数据源切换失效,所以就用到了Order(排序)这个关键字.

我们可以通过在@AspectJ的方法中实现org.springframework.core.Ordered 这个接口来定义order的顺序,order 的值越小,说明越先被执行。

脚本宝典总结

以上是脚本宝典为你收集整理的Java程序员干货学习笔记—Spring结合MyBatis实现数据库读写分离全部内容,希望文章能够帮你解决Java程序员干货学习笔记—Spring结合MyBatis实现数据库读写分离所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。