1. 程式人生 > 其它 >專案整合seata和mybatis-plus衝突問題解決方案:(分頁外掛失效, 自動填充失效, 自己注入的id生成器失效 找不到mapper檔案解決方案)

專案整合seata和mybatis-plus衝突問題解決方案:(分頁外掛失效, 自動填充失效, 自己注入的id生成器失效 找不到mapper檔案解決方案)

專案整合seata和mybatis-plus衝突問題解決方案: 分頁外掛失效, 自動填充失效, 自己注入的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服務端和客戶端整合配置,可以看另一篇文章!