Mybatis插件动态数据库链接

场景:
springboot+mybatis-plus+mysql+clickhouse
同时整合了mysql和clickhouse 并且clickhouse设置了集群
要求对clickhouse数据库链接做负载均衡
算法采用当前线程Id的hash算法

解决方案:

  1. 自定义 mybatis Interceptor 拦截Executor
package io.renren.modules.ck.config;import com.alibaba.druid.pool.DruidPooledConnection;
import com.baomidou.mybatisplus.core.executor.MybatisSimpleExecutor;
import io.renren.common.utils.CkMybatisUtil;
import io.renren.modules.ck.dao.CkMybatisDao;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.transaction.Transaction;import java.lang.reflect.Field;
import java.util.Properties;@Intercepts({@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})})
public class CkDataSourceInterceptor implements Interceptor {@Overridepublic Object intercept(Invocation invocation) throws Throwable {Object[] args = invocation.getArgs();if (args[0] instanceof MappedStatement) {MappedStatement ms = (MappedStatement) args[0];String id = ms.getId();if (id.contains(CkMybatisDao.class.getName())) {Object target = invocation.getTarget();MybatisSimpleExecutor executor=(MybatisSimpleExecutor) target;Transaction transaction = executor.getTransaction();DruidPooledConnection connection = CkMybatisUtil.getDataSource().getConnection();Class<? extends Transaction> transactionClass = transaction.getClass();Field connectionField = transactionClass.getDeclaredField("connection");connectionField.setAccessible(true);connectionField.set(transaction,connection);}}return invocation.proceed();}@Overridepublic Object plugin(Object target) {return Plugin.wrap(target, this);}@Overridepublic void setProperties(Properties properties) {}
}

2.注册CkDataSourceInterceptor

package io.renren.modules.ck.config;import com.baomidou.mybatisplus.autoconfigure.ConfigurationCustomizer;
import org.springframework.context.annotation.Bean;@org.springframework.context.annotation.Configuration
public class MybatisInterceptorConfig {//将插件加入到mybatis插件拦截链中@Beanpublic ConfigurationCustomizer configurationCustomizer() {return configuration -> {//插件拦截链采用了责任链模式,执行顺序和加入连接链的顺序有关CkDataSourceInterceptor interceptor = new CkDataSourceInterceptor();configuration.addInterceptor(interceptor);};}}

3.CkMybatisUtil 获取数据源方法 在这里可以写负载均衡算法处理数据源

package io.renren.common.utils;import com.alibaba.druid.pool.DruidDataSource;public class CkMybatisUtil {public static DruidDataSource getDataSource(){DruidDataSource druidDataSource = new DruidDataSource();druidDataSource.setUrl("jdbc:clickhouse://localhost:8123/clickhouse");druidDataSource.setUsername("default");druidDataSource.setDriverClassName("ru.yandex.clickhouse.ClickHouseDriver");return druidDataSource;}}

4.clickhouse mapper映射的Dao接口

package io.renren.modules.ck.dao;import io.renren.modules.ck.entity.CkTableColumnEntity;
import io.renren.modules.ck.entity.CkTableInfoEntity;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;import java.util.List;@Mapper
public interface CkMybatisDao {void createCkTable(@Param("table") CkTableInfoEntity table, @Param("columns") List<CkTableColumnEntity> columns);void insert(@Param("tableName") String tableName, @Param("columnDataList") List<List<Object>> columnDataList,@Param("columns") List<CkTableColumnEntity> columns);
}

4.sql的xml文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="io.renren.modules.ck.dao.CkMybatisDao"><select id="createCkTable">create table clickhouse.${table.tableName}(<foreach collection="columns" item="column" separator=",">${column.columnName} ${column.dataType}</foreach>)Engine = ReplacingMergeTree primary key ${table.pkColumn}order by${table.pkColumn}</select><select id="insert">insert into clickhouse.${tableName}<foreach collection="columns" item="column" separator="," open="(" close=")">${column.columnName}</foreach>values<foreach collection="columnDataList" item="columnData" separator="," ><foreach collection="columnData" item="value" separator="," open="(" close=")">${value}</foreach></foreach></select>
</mapper>

所有准备工作完成 直接在Service中注入CkMybatisDao 就可操作clickhouse了 并且 其他Dao依然是操作mysql

Mybatis插件动态数据库链接相关推荐

  1. c++map的使用_mybatis源码 | mybatis插件及动态代理的使用

    学习背景 最近公司在做一些数据库安全方面的事情,如数据库中不能存手机号明文,不能存身份证号明文, 但是项目已经进行了好几个月了, 这时候在应用层面去改显然不太现实, 所以就有了Mybatis的自定义插 ...

  2. mybatis查询mysql数据库很慢_mybatis查询大量数据库

    初识 MyBatis MyBatis 是第一个支持自定义 SQL.存储过程和高级映射的类持久框架.MyBatis 消除了大部分 JDBC 的样板代码.手动设置参数以及检索结果.MyBatis 能够支持 ...

  3. MyBatis(四)MyBatis插件原理

    MyBatis插件原理 MyBatis对开发者非常友好,它通过提供插件机制,让我们可以根据自己的需要去增强MyBatis的功能.其底层是使用了代理模式+责任链模式 MyBatis官方https://m ...

  4. 后端技术:mybatis插件原理详解

    关注"Java后端技术全栈" 回复"面试"获取全套面试资料 上次发文说到了如何集成分页插件MyBatis插件原理分析,看完感觉自己better了,今天我们接着来 ...

  5. SpringCloud或SpringBoot+Mybatis-Plus利用mybatis插件实现数据操作记录及更新对比

    引文 本文主要介绍如何使用mybatis插件实现拦截数据库操作并根据不同需求进行数据对比分析,主要适用于系统中需要对数据操作进行记录.在更新数据时准确记录更新字段 核心:mybatis插件(拦截器). ...

  6. MyBatis 03 动态SQL

    MyBatis 03 动态SQL 文章目录 MyBatis 03 动态SQL 一.学习目标 二.动态SQL if 标签2-1 if 标签2-2 where标签2-1 where 标签2-2 choos ...

  7. 学习MyBatis必知必会(6)~MyBatis基础拓展(别名、属性、resultMap、Mapper接口、多参数处理、myBatis插件)

    Mapper基础的拓展包括:别名.属性[动态引入].resultMap[解决列名和属性名不匹配].Mapper接口[好比DAO层].参数处理[注解@Param处理多个参数].myBatis插件[ecl ...

  8. Discuz!NT 中的数据库链接类(重构到抽象类工厂模式)

       在7月份中我曾经写过一篇随笔叫,叫" .NET2.0 框架中的 AbstractFactory 模式 " . 里面主要说了在2.0框架下的数据库链接工厂中新增的几个类,而这几 ...

  9. MyBatis中动态sql实现时间范围比较的查询

    场景 前端传递两个时间参数,开始时间和结束时间,然后从数据库中筛选出某个时间属性在此范围的数据. Mybatis的动态sql的写法. 注: 博客: https://blog.csdn.net/bada ...

  10. MyBatis(三)——动态SQL

    文章目录 1. 简介 2. 搭建环境 2.1 在MySQL中创建blog表 2.2 编写实体类 2.3 编写实体类对应Mapper接口 2.4 编写Mapper接口对应的Mapper.xml文件 2. ...

最新文章

  1. 新网站是如何吸引蜘蛛进行爬取的?
  2. android 之Fragment的详解
  3. 手机web——自适应网页设计(html/css控制) - 51CTO.COM
  4. 自定义的Sort对象
  5. vue上传文件到php,vue+axios+php如何实现上传文件功能?,formdata上传文件附加参数...
  6. 厉害了!国人开发的编程语言 Go+ 1.0 即将发布!
  7. linux echo 变量 字符串,echo命令 – 输出字符串或提取Shell变量的值 – 运维那些事...
  8. php密码重复,AngularJs验证重复密码的方法(两种)
  9. spring整合atomikos实现分布式事务的方法示例_分布式-分布式事务处理
  10. 关闭虚拟机linux的防火墙,Linux虚拟机SSH服务、防火墙开启关闭
  11. 视频:网站建设-如何利用网络赚大钱2
  12. java 打印gc_java – 以编程方式打印启用GC日志记录时通常在JVM出口上打印的堆使用情况...
  13. 键盘各键对应的ASCII码值(包括鼠标和键盘所有的键)
  14. QT之Tcp数据发送测试工具
  15. JAVA一元线性回归法_一元线性回归的java实现
  16. 基于hilbert变换的数字信号_基于Hilbert变换处理绝对重力仪测量数据
  17. 基于偏微分方程的图像分割(二)Snake模型 Matlab实现
  18. tpadmin合成推广二维码
  19. 如何查看虚拟机服务器ftp,如何通过FTP工具查看虚拟空间使用了多少?
  20. 图中连通块的个数:并查集

热门文章

  1. Javaweb面试题及答案
  2. Power BI 与企业数据安全
  3. win10安装c语言gmp库的使用,Window下使用GMP库
  4. 信号处理中的预加重、去加重和均衡
  5. shell脚本for循环的基础格式以及取值列表的多种取值方式
  6. pythonopencv直方图均衡化_OpenCV-Python教程(10、直方图均衡化)
  7. 公差基本偏差代号_基本偏差代号公差等级代号.ppt
  8. Hilo - 阿里巴巴出品的免费开源 H5 游戏引擎,轻巧无依赖,适合用来开发营销互动小游戏
  9. ArcGIS软件操作问题及解决方法总结
  10. 绩效考核|绩效管理|绩效面谈|绩效述职|绩效汇报PPT模板