自動填充程式碼:
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; } }