zoukankan      html  css  js  c++  java
  • 项目集成seata和mybatisplus冲突问题解决方案:(分页插件失效, 自动填充失效, 自己注入的id生成器失效 找不到mapper文件解决方案)

    项目集成seata和mybatis-plus,seata与mybatis-plus冲突问题(所有插件失效,自动填充失效,找不到mapper文件解决方案)

    自动填充代码:

    package com.from.mybatis.handler;
    ​
    import cn.hutool.core.date.DateUtil;
    import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
    import org.apache.ibatis.reflection.MetaObject;
    import org.springframework.stereotype.Component;
    ​
    import java.util.Date;
    ​
    @Component
    public class MyBatisMetaObjectHandler implements MetaObjectHandler {
        /**
         * 自定义插入时填充规则
         */
        @Override
        public void insertFill(MetaObject metaObject) {
            // 注意是类属性字段名称,不是表字段名称
            this.setFieldValByName("createTime", new Date(), metaObject);
            this.setFieldValByName("delFlag", 0, metaObject);
        }
    ​
        /**
         * 自定义更新时填充规则
         */
        @Override
        public void updateFill(MetaObject metaObject) {
            String now = DateUtil.now();
            // 注意是类属性字段名称,不是表字段名称
            this.setFieldValByName("updateTime", new Date(), metaObject);
        }
    ​
    }
    ​

    id生成器代码:

    package com.from.mybatis.config;
    ​
    import java.util.Date;
    import java.util.UUID;
    ​
    /**
     * compressed id generator, result id not great than 53bits before 2318-06-04.
     */
    public class IdGenerator {
    ​
        private static IdGenerator instance = new IdGenerator(0);
    ​
        public static IdGenerator initDefaultInstance(int machineId) {
            instance = new IdGenerator(machineId);
            return instance;
        }
    ​
        public static IdGenerator getInstance() {
            return instance;
        }
    ​
        public static long generateId() {
            return instance.nextId();
        }
    ​
        // total bits=53(max 2^53-1:9007199254740992-1)
    // private final static long TIME_BIT = 40; // max: 2318-06-04
        private final static long MACHINE_BIT = 5; // max 31
        private final static long SEQUENCE_BIT = 8; // 256/10ms
    /**
         * mask/max value
         */
        private final static long MAX_MACHINE_NUM = -1L ^ (-1L << MACHINE_BIT);
        private final static long MAX_SEQUENCE = -1L ^ (-1L << SEQUENCE_BIT);
    ​
        private final static long MACHINE_LEFT = SEQUENCE_BIT;
        private final static long TIMESTMP_LEFT = MACHINE_BIT + SEQUENCE_BIT;
    ​
        private long machineId;
        private long sequence = 0L;
        private long lastStmp = -1L;
    ​
        private IdGenerator(long machineId) {
            if (machineId > MAX_MACHINE_NUM || machineId < 0) {
                throw new IllegalArgumentException(
                        "machineId can't be greater than " + MAX_MACHINE_NUM + " or less than 0");
            }
            this.machineId = machineId;
        }
    ​
        /**
         * generate new ID
         *
         * @return
         */
        public synchronized long nextId() {
            long currStmp = getTimestamp();
            if (currStmp < lastStmp) {
                throw new RuntimeException("Clock moved backwards.  Refusing to generate id");
            }
    ​
            if (currStmp == lastStmp) {
                sequence = (sequence + 1) & MAX_SEQUENCE;
                if (sequence == 0L) {
                    currStmp = getNextTimestamp();
                }
            } else {
                sequence = 0L;
            }
    ​
            lastStmp = currStmp;
    ​
            return currStmp << TIMESTMP_LEFT //
                    | machineId << MACHINE_LEFT //
                    | sequence;
        }
    ​
        private long getNextTimestamp() {
            long mill = getTimestamp();
            while (mill <= lastStmp) {
                mill = getTimestamp();
            }
            return mill;
        }
    ​
        private long getTimestamp() {
            // per 10ms
            return System.currentTimeMillis() / 10;// 10ms
        }
    ​
        public static Date parseIdTimestamp(long id) {
            return new Date((id >>> TIMESTMP_LEFT) * 10);
        }
    ​
        public static String uuid() {
            return UUID.randomUUID().toString().replaceAll("-", "");
        }
    }
    ​
    package com.from.mybatis.config;
    ​
    ​
    import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
    import org.springframework.stereotype.Component;
    ​
    @Component
    public class CustomerIdGenerator implements IdentifierGenerator {
        @Override
        public Long nextId(Object entity) {
            // 填充自己的Id生成器,
            return IdGenerator.generateId();
        }
    }

    具体代理配置:

    package com.from.seata.config;
    import com.alibaba.druid.pool.DruidDataSource;
    import com.baomidou.mybatisplus.annotation.DbType;
    import com.baomidou.mybatisplus.autoconfigure.MybatisPlusProperties;
    import com.baomidou.mybatisplus.core.MybatisConfiguration;
    import com.baomidou.mybatisplus.core.config.GlobalConfig;
    import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
    import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
    import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
    import com.from.mybatis.config.CustomerIdGenerator;
    import com.from.mybatis.handler.MyBatisMetaObjectHandler;
    import io.seata.rm.datasource.DataSourceProxy;
    import org.mybatis.spring.transaction.SpringManagedTransactionFactory;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.boot.context.properties.EnableConfigurationProperties;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Primary;
    import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
    import javax.sql.DataSource;
    import java.io.IOException;
    @Configuration
    @EnableConfigurationProperties({MybatisPlusProperties.class})
    public class DataSourcesProxyConfig {
        //自动填充注入
        @Bean
        public MyBatisMetaObjectHandler myBatisMetaObjectHandler() {
            return new MyBatisMetaObjectHandler();
        }
        //id生成器注入
        @Bean
        public CustomerIdGenerator customerIdGenerator() {
            return new CustomerIdGenerator();
        }
        //获取数据源
        @Bean
        @ConfigurationProperties(prefix = "spring.datasource")
        public DataSource druidDataSource() {
            return new DruidDataSource();
        }
    ​
        //配种数据源
        @Primary//@Primary标识必须配置在代码数据源上,否则本地事务失效
        @Bean
        public DataSourceProxy dataSourceProxy(DataSource druidDataSource) {
            return new DataSourceProxy(druidDataSource);
        }
    ​
        private MybatisPlusProperties properties;
    ​
        public DataSourcesProxyConfig(MybatisPlusProperties properties) {
            this.properties = properties;
        }
    ​
        //配置mybatisplus的数据源,所有插件会失效,所以注入进来,配置给代理数据源
        @Bean
        public MybatisSqlSessionFactoryBean sqlSessionFactory(DataSourceProxy dataSourceProxy) throws Exception {
            // 这里必须用 MybatisSqlSessionFactoryBean 代替了 SqlSessionFactoryBean,否则 MyBatisPlus 不会生效
            MybatisSqlSessionFactoryBean sqlBean = new MybatisSqlSessionFactoryBean();
            sqlBean.setDataSource(dataSourceProxy);
            sqlBean.setTransactionFactory(new SpringManagedTransactionFactory());
            try {
                //注意:!!!!这个如果写的有sql,须有该配置,try cach以下,打开不捕获异常的化,没sql会报错
                sqlBean.setMapperLocations(new PathMatchingResourcePatternResolver()
                        .getResources("classpath:/mapper/**/*.xml"));
            } catch (IOException ignored) {
            }
            MybatisConfiguration configuration = this.properties.getConfiguration();
            if (configuration == null) {
                configuration = new MybatisConfiguration();
            }
            MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
            //向代理数据源添加分页拦截器
            interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
            sqlBean.setPlugins(interceptor);
            //代理数据源添加id生成器,字段自动填充
            sqlBean.setGlobalConfig(new GlobalConfig()
                    .setMetaObjectHandler(myBatisMetaObjectHandler())
                    .setIdentifierGenerator(customerIdGenerator()));
            sqlBean.setConfiguration(configuration);
            return sqlBean;
        }
    }

    关于seata服务端和客户端集成配置,可以看另一篇文章!

  • 相关阅读:
    ammap demo
    sql批量新增和修改
    js右键菜单
    C# 索引器
    NUnit使用体会
    js拖动效果
    Js 原型对象与原型链(转)
    sql for xml子句
    ASP.NET应用程序生命周期
    HttpWebRequest和HttpWebResponse
  • 原文地址:https://www.cnblogs.com/859630097com/p/15694701.html
Copyright © 2011-2022 走看看