成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

mybatis利用插件實(shí)現(xiàn)分表

BDEEFE / 2166人閱讀

摘要:如標(biāo)題,這次的分表規(guī)則比較,部分用戶相關(guān)表按產(chǎn)品維度劃分,例如,是產(chǎn)品,新加一個產(chǎn)品就要新增一整套表研究了一波后面改成了不太合適,也有種殺雞牛刀的感覺。

如標(biāo)題,這次的分表規(guī)則比較??,部分用戶相關(guān)表按產(chǎn)品維度劃分,例如:user_1,user_2(1,2是產(chǎn)品id,新加一個產(chǎn)品就要新增一整套表...)研究了一波sharing-jdbc(后面改成了sharding-sphere)不太合適,也有種殺雞牛刀的感覺。
不想手寫SQL太麻煩,后面說不好表要改動,雖然有生成工具(不靈活),所以選擇了Mybatis-plus這個兄弟,借鑒他的分頁等各種插件決定自己實(shí)現(xiàn)一個分表插件,把需要分表的表在配置中維護(hù),利用jsqlparser解析sql重寫sql語句,廢話不多說上代碼

/**

分表插件

@author chonglou

@date 2019/2/2117:04

*/
@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})
public class ShardInterceptor implements Interceptor, ShardAgent {

private final ShardProperties shardProperties;

public ShardInterceptor(ShardProperties shardProperties) {
    this.shardProperties = shardProperties;
}

public static final CCJSqlParserManager parser = new CCJSqlParserManager();

@Override
public Object intercept(Invocation invocation) throws Throwable {
    StatementHandler statementHandler = (StatementHandler) realTarget(invocation.getTarget());
    MetaObject metaObject = SystemMetaObject.forObject(statementHandler);
    MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");
    if (!shardProperties.isException(mappedStatement.getId())) {
        if (SqlCommandType.INSERT.equals(mappedStatement.getSqlCommandType())
                || SqlCommandType.SELECT.equals(mappedStatement.getSqlCommandType())
                || SqlCommandType.UPDATE.equals(mappedStatement.getSqlCommandType())
                || SqlCommandType.DELETE.equals(mappedStatement.getSqlCommandType())) {

            String sql = statementHandler.getBoundSql().getSql();
            Statement statement = parser.parse(new StringReader(sql));
            if (statement instanceof Select) {
                Select select = (Select) statement;
                TableNameModifier modifier = new TableNameModifier(this);
                select.getSelectBody().accept(modifier);
            } else if (statement instanceof Update) {
                Update update = (Update) statement;
                List list = update.getTables();
                for (Table t : list) {
                    parserTable(t, true);
                }
            } else if (statement instanceof Delete) {
                Delete delete = (Delete) statement;
                parserTable(delete.getTable(), true);
                List
list = delete.getTables(); for (Table t : list) { parserTable(t, true); } } else if (statement instanceof Insert) { Insert insert = (Insert) statement; parserTable(insert.getTable(), false); } StatementDeParser deParser = new StatementDeParser(new StringBuilder()); statement.accept(deParser); sql = deParser.getBuffer().toString(); ReflectionUtils.setFieldValue(statementHandler.getBoundSql(), "sql", sql); } } return invocation.proceed(); } private Object realTarget(Object target) { if (Proxy.isProxyClass(target.getClass())) { MetaObject metaObject = SystemMetaObject.forObject(target); return realTarget(metaObject.getValue("h.target")); } else { return target; } } /** * 覆蓋表名設(shè)置別名 * * @param table * @return */ private Table parserTable(Table table, boolean alias) { if (null != table) { if (alias) { table.setAlias(new Alias(table.getName())); } table.setName(getTargetTableName(table.getName())); } return table; } @Override public Object plugin(Object target) { if (target instanceof StatementHandler) { return Plugin.wrap(target, this); } return target; } @Override public void setProperties(Properties properties) { } @Override public String getTargetTableName(String tableName) { if (shardProperties.isAgentTable(tableName)) { return ShardUtil.getTargetTableName(tableName); } return tableName; }

}

/**

@author chonglou

@date 2019/2/2218:24

*/
public interface ShardAgent {

String getTargetTableName(String name);

}

/**
*工具

@author chonglou

@date 2019/2/2514:11

*/
public class ShardUtil {

private final static String KEY_GENERATOR = "keyGenerator";

public static void setKeyGenerator(Object keyGenerator) {
    HttpServletRequest request = SpringContextHolder.getRequest();
    request.setAttribute(KEY_GENERATOR, keyGenerator);
}

public static String getTargetTableName(String tableName) {
    HttpServletRequest request = SpringContextHolder.getRequest();
    Object productId = request.getAttribute(KEY_GENERATOR);
    if (null == productId) {
        throw new RuntimeException("keyGenerator is null.");
    }
    return tableName.concat("_").concat(productId.toString());
}

}

/**

Spring的ApplicationContext的持有者,可以用靜態(tài)方法的方式獲取spring容器中的bean,

Request 以及 Session

*

@author chonglou

*/
@Component
public class SpringContextHolder implements ApplicationContextAware {

private static ApplicationContext applicationContext;

@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    SpringContextHolder.applicationContext = applicationContext;
}

public static ApplicationContext getApplicationContext() {
    assertApplicationContext();
    return applicationContext;
}

public static  T getBean(String beanName) {
    assertApplicationContext();
    return (T) applicationContext.getBean(beanName);
}

public static  T getBean(Class requiredType) {
    assertApplicationContext();
    return applicationContext.getBean(requiredType);
}

private static void assertApplicationContext() {
    if (null == SpringContextHolder.applicationContext) {
        throw new RuntimeException("applicationContext屬性為null,請檢查是否注入了SpringContextHolder!");
    }
}

/**
 * 獲取當(dāng)前請求的Request對象
 *
 * @return HttpServletRequest
 */
public static HttpServletRequest getRequest() {
    ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
    return requestAttributes.getRequest();
}

/**
 * 獲取當(dāng)前請求的session對象
 *
 * @return HttpSession
 */
public static HttpSession getSession() {
    return getRequest().getSession();
}

}

/**

查詢語句修改

@author chonglou

@date 2019/2/2211:31

*/
public class TableNameModifier extends SelectDeParser {

private ShardAgent shardAgent;

TableNameModifier(ShardAgent shardAgent) {
    super();
    this.shardAgent = shardAgent;
}

@Override
public void visit(Table tableName) {
    StringBuilder buffer = new StringBuilder();
    tableName.setName(shardAgent.getTargetTableName(tableName.getName()));
    buffer.append(tableName.getFullyQualifiedName());
    Alias alias = tableName.getAlias();
    if (alias == null) {
        alias = new Alias(tableName.getName());
    }
    buffer.append(alias);
    Pivot pivot = tableName.getPivot();
    if (pivot != null) {
        pivot.accept(this);
    }

    MySQLIndexHint indexHint = tableName.getIndexHint();
    if (indexHint != null) {
        buffer.append(indexHint);
    }

}

}
/**

@author chonglou

@date 2019/2/2215:34

*/
@ConfigurationProperties(prefix = "shard.config")
public class ShardProperties {

private List exceptionMapperId;

private List agentTables;

public boolean isException(String mapperId) {
    return null != exceptionMapperId && exceptionMapperId.contains(mapperId);
}

public boolean isAgentTable(String tableName) {
    return null != agentTables && agentTables.contains(tableName);
}

public List getExceptionMapperId() {
    return exceptionMapperId;
}

public void setExceptionMapperId(List exceptionMapperId) {
    this.exceptionMapperId = exceptionMapperId;
}

public List getAgentTables() {
    return agentTables;
}

public void setAgentTables(List agentTables) {
    this.agentTables = agentTables;
}

}

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/77460.html

相關(guān)文章

  • 帶你深入淺出MyBatis技術(shù)原理與實(shí)戰(zhàn)(PDF實(shí)戰(zhàn)實(shí)踐)

    摘要:目錄其中每個章節(jié)知識點(diǎn)都是相關(guān)連由淺入深的一步步全面分析了技術(shù)原理以及實(shí)戰(zhàn)由于文案較長想深入學(xué)習(xí)以及對于該文檔感興趣的朋友們可以加群免費(fèi)獲取。這些場景在大量的編碼中使用,具備較強(qiáng)的實(shí)用價值,這些內(nèi)容都是通過實(shí)戰(zhàn)得來的,供讀者們參考。 前言系統(tǒng)掌握MyBatis編程技巧已經(jīng)成了用Java構(gòu)建移動互聯(lián)網(wǎng)網(wǎng)站的必要條件 本文主要講解了Mybatis的應(yīng)用,解析了其原理,從而形成一個完整的知識...

    MoAir 評論0 收藏0
  • Sharding-Jdbc實(shí)現(xiàn)mysql分庫分表

    摘要:實(shí)現(xiàn)數(shù)據(jù)庫分庫分表可以自己實(shí)現(xiàn),也可以使用和實(shí)現(xiàn)。分布式數(shù)據(jù)庫的自增不是自增的。分布式數(shù)據(jù)庫分頁查詢需要使用插入時間實(shí)現(xiàn)。包含分庫分片和讀寫分離功能。 Sharding-Jdbc實(shí)現(xiàn)mysql分庫分表 簡單介紹 數(shù)據(jù)庫分庫分表和讀寫分離區(qū)別,分庫分表是在多個庫建相同的表和同一個庫建不同的表,根據(jù)隨機(jī)或者哈希等方式查找實(shí)現(xiàn)。讀寫分離是為了解決數(shù)據(jù)庫的讀寫性能不足,使用主庫master進(jìn)行...

    go4it 評論0 收藏0
  • Mybatis Interceptor 攔截器

    摘要:攔截器的使用場景主要是更新數(shù)據(jù)庫的通用字段,分庫分表,加解密等的處理。攔截器均需要實(shí)現(xiàn)該接口。攔截器攔截器的使用需要查看每一個所提供的方法參數(shù)。對應(yīng)構(gòu)造器,為,為,為??蓞⒖紨r截器原理探究。 攔截器(Interceptor)在 Mybatis 中被當(dāng)做插件(plugin)對待,官方文檔提供了 Executor(攔截執(zhí)行器的方法),ParameterHandler(攔截參數(shù)的處理),Re...

    nemo 評論0 收藏0
  • springboot實(shí)踐筆記之一:springboot+sharding-jdbc+mybatis

    摘要:現(xiàn)在的分片策略是上海深圳分別建庫,每個庫都存各自交易所的兩支股票的,且按照月分表。五配置分片策略數(shù)據(jù)庫分片策略在這個實(shí)例中,數(shù)據(jù)庫的分庫就是根據(jù)上海和深圳來分的,在中是單鍵分片。 由于當(dāng)當(dāng)發(fā)布了最新的Sharding-Sphere,所以本文已經(jīng)過時,不日將推出新的版本 項(xiàng)目中遇到了分庫分表的問題,找到了shrding-jdbc,于是就搞了一個springboot+sharding-jd...

    Snailclimb 評論0 收藏0
  • Spring Boot中整合Sharding-JDBC讀寫分離示例

    摘要:今天就給大家介紹下方式的使用,主要講解讀寫分離的配置,其余的后面再介紹。主要還是用提供的,配置如下配置內(nèi)容如下主數(shù)據(jù)源從數(shù)據(jù)源讀寫分離配置查詢時的負(fù)載均衡算法,目前有種算法,輪詢和隨機(jī),算法接口是。 在我《Spring Cloud微服務(wù)-全棧技術(shù)與案例解析》書中,第18章節(jié)分庫分表解決方案里有對Sharding-JDBC的使用進(jìn)行詳細(xì)的講解。 之前是通過XML方式來配置數(shù)據(jù)源,讀寫分離...

    kbyyd24 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看

    <