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服务端和客户端集成配置,可以看另一篇文章!

  • 相关阅读:
    ACM ICPC 2008–2009 NEERC MSC A, B, C, G, L
    POJ 1088 滑雪 DP
    UVA 11584 最短回文串划分 DP
    POJ 2531 Network Saboteur DFS+剪枝
    UVa 10739 String to Palindrome 字符串dp
    UVa 11151 Longest Palindrome 字符串dp
    UVa 10154 Weights and Measures dp 降维
    UVa 10271 Chopsticks dp
    UVa 10617 Again Palindrome 字符串dp
    UVa 10651 Pebble Solitaire 状态压缩 dp
  • 原文地址:https://www.cnblogs.com/859630097com/p/15694701.html
Copyright © 2011-2022 走看看