spring+mybatis读写分离

操作类型枚举

package com.dlq.blog.db;

/**
 * 读、写类型枚举
 * @author donglq
 * @date 2017/10/5 1:50
 */
public enum DBWRType {
    WRITE(1, "WRITE", "写"), READ(2, "READ", "读");

    DBWRType(int code, String name, String desc) {
        this.code = code;
        this.name = name;
        this.desc = desc;
    }

    public int code;

    public String name;

    public String desc;

}

自定义注解

package com.dlq.blog.db.annotation;

import com.dlq.blog.db.DBWRType;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 读、写注解
 * @author donglq
 * @date 2017/10/5 1:54
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface DBWR {

    DBWRType value() default DBWRType.WRITE;

}

上下文工具

package com.dlq.blog.db;

/**
 * 工具类,存放当前线程数据源key和表名后缀
 * 使用treadLocal的方式来保证线程安全
 * @author donglq
 * @date 2017/10/3 22:56
 */
public class DBContext {

    /**数据库逻辑名**/
    private static final ThreadLocal dbKeyHolder = new ThreadLocal();

    /**表明后缀**/
    private static final ThreadLocal tableSuffixHolder = new ThreadLocal();

    public static void setDbKey(String dbKey) {
        dbKeyHolder.set(dbKey);
    }

    public static String getDbKey() {
        return dbKeyHolder.get();
    }

    public static void clearDbKey() {
        dbKeyHolder.remove();
    }

    public static void setTableSuffix(String tableIndex){
        tableSuffixHolder.set(tableIndex);
    }

    public static String getTableSuffix(){
        return tableSuffixHolder.get();
    }
    public static void clearTableSuffix(){
        tableSuffixHolder.remove();
    }

}

AOP拦截

package com.dlq.blog.db;

import com.dlq.blog.db.annotation.DBWR;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Service;

import java.lang.reflect.Method;

/**
 * 读写分离路由
 * @author donglq
 * @date 2017/10/5 1:57
 */
@Aspect
@Service
public class DBWRRoute {

    @Pointcut("@annotation(com.dlq.blog.db.annotation.DBWR)")
    public void aopPoint() {
    }

    @Before("aopPoint()")
    public Object doRoute(JoinPoint jp) throws Throwable {
        //根据JoinPoint jp 获取方法名称和参数
        Method method = getMethod(jp);
        //获取注解
        DBWR dbwr = method.getAnnotation(DBWR.class);
        DBContext.setDbKey(dbwr.value().name);
        return null;
    }

    private Method getMethod(JoinPoint jp) throws NoSuchMethodException {
        Signature sig = jp.getSignature();
        MethodSignature msig = (MethodSignature) sig;
        return jp.getTarget().getClass().getMethod(msig.getName(), msig.getParameterTypes());
    }

}

动态数据源

package com.dlq.blog.db;

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import org.springframework.lang.Nullable;

/**
 * 动态获取当前数据源
 * @author donglq
 * @date 2017/10/3 22:59
 */
public class DynamicDataSource extends AbstractRoutingDataSource {

    /**
     * 获取当前数据源
     * @return
     */
    @Nullable
    @Override
    protected Object determineCurrentLookupKey() {
        String dbKey = DBContext.getDbKey();
        System.out.println("dbKey: " + dbKey);
        return dbKey;
    }
}

测试

配置



    
    
        
    

    
    
        
        
        
        
    

    
        
        
        
        
    

    
    
        
            
            
                
                
            
        
    

    
    
        
    

    
        
        
    

    
    
        
        
        
    

    
    
        
        
    


测试方法
DAO
package com.dlq.blog.dao;

import org.apache.ibatis.annotations.Param;

/**
 * @author donglq
 * @date 2017/10/4 10:13
 */
public interface UserDao {

    Object insert(@Param("user") User user);

    User select(@Param("user") User user);

}

package com.dlq.blog.dao;

/**
 * @author donglq
 * @date 2017/10/4 10:15
 */
public class User {

    private int id;

    private String firstname;

    private String lastname;

    private int gender;

    private String idcard;

    private String address;

    private String tableIndex;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getFirstname() {
        return firstname;
    }

    public void setFirstname(String firstname) {
        this.firstname = firstname;
    }

    public String getLastname() {
        return lastname;
    }

    public void setLastname(String lastname) {
        this.lastname = lastname;
    }

    public int getGender() {
        return gender;
    }

    public void setGender(int gender) {
        this.gender = gender;
    }

    public String getIdcard() {
        return idcard;
    }

    public void setIdcard(String idcard) {
        this.idcard = idcard;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getTableIndex() {
        return tableIndex;
    }

    public void setTableIndex(String tableIndex) {
        this.tableIndex = tableIndex;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", firstname='" + firstname + '\'' +
                ", lastname='" + lastname + '\'' +
                ", gender=" + gender +
                ", idcard='" + idcard + '\'' +
                ", address='" + address + '\'' +
                ", tableIndex='" + tableIndex + '\'' +
                '}';
    }
}

调用
@Resource
UserDao userDao;

@DBWR(DBWRType.WRITE)
public Object write(User user) {
    return userDao.insert(user);
}

@DBWR(DBWRType.READ)
public User read(User user) {
    return userDao.select(user);
}

你可能感兴趣的:(spring+mybatis读写分离)