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ù)庫實現(xiàn)

        共 9368字,需瀏覽 19分鐘

         ·

        2021-08-11 03:05

        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ù)器配置,默認端口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é)點映射配置

        <?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é)點名稱列表-->
                <table name="mycat_test_student" dataNode="dn1,dn2"/>
            </schema>
            <!--Mycat節(jié)點名稱、節(jié)點地址、mysql數(shù)據(jù)庫名-->
            <dataNode name="dn1" dataHost="localhost1" database="db01" />
            <dataNode name="dn2" dataHost="localhost1" database="db02" />

            <!--Mycat節(jié)點地址-->
            <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é)點標識
                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;
            }

            // 返回當前攔截的對象(StatementHandler)的動態(tài)代理
            // 當攔截對象的方法被執(zhí)行時, 動態(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)鍵實現(xiàn),主要過程如下:

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

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

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

        • 配置 Mybatis 的攔截器插件

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

        注意

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


        喜歡,在看



        瀏覽 91
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        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>
            小怮女一级A片 | 男女无遮挡120秒 | 午夜福利视频中文字幕 | 精品综合 | 免费男人下部进女人下部视频 | 夜夜操夜夜操 | 国产精品片18区乱婬人成人 | 欧美操逼系列 | 日本在线xxxx | 人人看人人搂人人摸 |