1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        SpringBoot Mybatis Mycat 多租戶數(shù)據(jù)庫實(shí)現(xiàn)

        共 9585字,需瀏覽 20分鐘

         ·

        2021-08-13 23:23

        點(diǎn)擊上方“程序員大白”,選擇“星標(biāo)”公眾號

        重磅干貨,第一時(shí)間送達(dá)

        0x01:Mycat

        下載

        wget http://dl.mycat.io/1.6.7.3/20190927161129/Mycat-server-1.6.7.3-release-20190927161129-linux.tar.gz

        配置

        server.xml,Mycat服務(wù)器配置,默認(rèn)端口8066

        <?xml version="1.0" encoding="UTF-8"?>
        <!DOCTYPE mycat:server SYSTEM "server.dtd">
        <mycat:server xmlns:mycat="http://io.mycat/">
            <system>
                <property name="useSqlStat">0</property>
                <property name="useGlobleTableCheck">0</property>
                <property name="sequnceHandlerType">2</property>
                <property name="handleDistributedTransactions">0</property>
                <property name="useOffHeapForMerge">1</property>
                <property name="memoryPageSize">1m</property>
                <property name="spillsFileBufferSize">1k</property>
                <property name="useStreamOutput">0</property>
                <property name="systemReserveMemorySize">384m</property>
                <property name="useZKSwitch">true</property>
            </system>

            <!--Mycat用戶名-->
            <user name="root">
                <!--Mycat密碼-->
                <property name="password">root</property>
                <!--Mycat數(shù)據(jù)庫名-->
                <property name="schemas">mycat_test</property>
            </user>

        </mycat:server>

        schema.xml,Mycat和Mysql節(jié)點(diǎn)映射配置

        <?xml version="1.0"?>
        <!DOCTYPE mycat:schema SYSTEM "schema.dtd">
        <mycat:schema xmlns:mycat="http://io.mycat/">
            <!--Mycat數(shù)據(jù)庫名-->
            <schema name="mycat_test" checkSQLschema="true" sqlMaxLimit="100">
                <!--Mycat表名,節(jié)點(diǎn)名稱列表-->
                <table name="mycat_test_student" dataNode="dn1,dn2"/>
            </schema>
            <!--Mycat節(jié)點(diǎn)名稱、節(jié)點(diǎn)地址、mysql數(shù)據(jù)庫名-->
            <dataNode name="dn1" dataHost="localhost1" database="db01" />
            <dataNode name="dn2" dataHost="localhost1" database="db02" />

            <!--Mycat節(jié)點(diǎn)地址-->
            <dataHost name="localhost1" maxCon="1000" minCon="10" balance="0"
                      writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">

                <heartbeat>select user()</heartbeat>
                <!-- mysql數(shù)據(jù)庫服務(wù)器、賬戶、密碼 -->
                <writeHost host="hostM1" url="192.168.1.71:3306" user="test"
                           password="test@1234">

                </writeHost>
            </dataHost>
        </mycat:schema>

        0x02:Spring Boot

        數(shù)據(jù)源配置

        #mycat連接信息
        spring.datasource.url=jdbc:mysql://localhost:8066/mycat_test?serverTimezone=GMT
        spring.datasource.username=root
        spring.datasource.password=root
        spring.datasource.driver-class-name=com.mysql.jdbc.Driver

        #mybatis攔截器配置
        mybatis.config-location=classpath:mybatis.xml

        Mybatis

        mybatis.xml插件配置

        <?xml version="1.0" encoding="UTF-8"?>
        <!DOCTYPE configuration
                PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
                "http://mybatis.org/dtd/mybatis-3-config.dtd">


        <configuration>
            <settings>
                <!-- 打印查詢語句 -->
                <setting name="logImpl" value="STDOUT_LOGGING" />
            </settings>

            <typeAliases>
                <typeAlias alias="TestPojo" type="xx.xx.TestPojo"/>
            </typeAliases>

                <!-- 攔截器插件,改寫sql -->
            <plugins>
                <plugin interceptor="xx.interceptor.MyInterceptor">
                </plugin>
            </plugins>

        </configuration>

        攔截器

        //攔截StatementHandler的prepare方法
        @Intercepts(value = {
                @Signature(type = StatementHandler.class,
                        method = "prepare",
                        args = {Connection.class,Integer.class})})
        public class MyInterceptor implements Interceptor {
            // 修改sql,添加前后綴
            private static final String preState="/*!mycat:datanode=";
            private static final String afterState="*/";

            @Override
            public Object intercept(Invocation invocation) throws Throwable {
                StatementHandler statementHandler=(StatementHandler)invocation.getTarget();
                MetaObject metaStatementHandler=SystemMetaObject.forObject(statementHandler);
                Object object=null;
                //分離代理對象鏈
                while(metaStatementHandler.hasGetter("h")){
                    object=metaStatementHandler.getValue("h");
                    metaStatementHandler=SystemMetaObject.forObject(object);
                }

                //獲取sql
                String sql=(String)metaStatementHandler.getValue("delegate.boundSql.sql");

                //根據(jù)會話上下文,獲取節(jié)點(diǎn)標(biāo)識
                String node=(String) SessionUtil.getSession().getAttribute("appId");
                if(node!=null) {
                    //重寫sql,適配mycat
                    sql = preState + node + afterState + sql;
                }

                System.out.println("sql is "+sql);
                metaStatementHandler.setValue("delegate.boundSql.sql",sql);
                Object result = invocation.proceed();
                System.out.println("Invocation.proceed()");
                return result;
            }

            // 返回當(dāng)前攔截的對象(StatementHandler)的動態(tài)代理
            // 當(dāng)攔截對象的方法被執(zhí)行時(shí), 動態(tài)代理中執(zhí)行攔截器intercept方法.
            @Override
            public Object plugin(Object target) {
                return Plugin.wrap(target, this);
            }

            @Override
            public void setProperties(Properties properties) {
                String prop1 = properties.getProperty("prop1");
                String prop2 = properties.getProperty("prop2");
                System.out.println(prop1 + "------" + prop2);
            }
        }

        總結(jié)

        以上為關(guān)鍵實(shí)現(xiàn),主要過程如下:

        • 搭建 Mycat 服務(wù),設(shè)置提供的數(shù)據(jù)庫信息

        • 配置Mycat動態(tài)映射的兩個(gè)節(jié)點(diǎn),Mycat根據(jù)sql語句中的/*!mycat:datanode=dn1*/進(jìn)行動態(tài)切換數(shù)據(jù)源后執(zhí)行sql

        • 配置 SpringBoot 的 Mycat 數(shù)據(jù)源連接

        • 配置 Mybatis 的攔截器插件

        • 配置 Mybatis 攔截器實(shí)現(xiàn),根據(jù)上下文節(jié)點(diǎn),改寫 sql

        注意

        • 生產(chǎn)可采用Mycat集群,集群用ZK管理,以動態(tài)實(shí)例化數(shù)據(jù)源



        “拍一拍” 能撤回了 ?。?!

        5款Chrome插件,第1款絕對良心!

        為開發(fā)色情游戲,這家公司赴日尋找AV女優(yōu)拍攝,期望暴力賺錢結(jié)果...

        拼多多終于釀成慘劇

        華為阿里下班時(shí)間曝光:所有的光鮮,都有加班的味道


        關(guān)


        ,學(xué),西學(xué)學(xué)運(yùn)護(hù),質(zhì),結(jié),關(guān)[],學(xué)習(xí)進(jìn)!



        瀏覽 67
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評論
        圖片
        表情
        推薦
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            亚洲超碰在线 | 三级日本网站 | 日本韩国无码操逼视频 | 免费高清无码视频 | 日本wwwwxxxx泡妞下课 | 操逼逼大全 | 国产成人精品无码区免费福利 | 插逼网战 | sese在线 | 日韩免费性爱视频 |