Springboot框架下tkMapper想实现批量插入,一般是需要自定义BaseMapper来继承InsertListMapper
tkmapper提供的有两个insertList方法,
一个支持主键自动生成?tk.mybatis.mapper.additional.insert
一个不支持主键生成 tk.mybatis.mapper.common.special
按需使用,这里我们采用支持主键生成的InsertListMapper
import tk.mybatis.mapper.additional.insert.InsertListMapper;
import tk.mybatis.mapper.common.Mapper;
public interface BaseMapper<T> extends Mapper<T>, InsertListMapper<T> {
}
用mybatis-generator自动生成mapper和实体之后,mapper方法直接调用insertList
//自动生成的Mapper文件
public interface TAccountAssetsDailyMapper extends BaseMapper<TAccountAssetsDaily> {
}
//以下是使用insertList
List<TAccountAssetsDaily> list = incomeMapper.getAccountAssetsList(final_date);
if (!list.isEmpty()) {
//根据日期先删后插
Example example = new Example(TAccountAssetsDaily.class);
example.createCriteria().andEqualTo("createDate", final_date);
tAccountAssetsDailyMapper.deleteByExample(example);
tAccountAssetsDailyMapper.insertList(list);
}
以上是tkMapper的普通版的批量插入
有些时候我们在插入数据库的时候数据量很大,会造成数据库慢查询、cpu飙高 !~
为了处理这种情况,决定使用分批插入的情况。网上查了有几种实现方式,都不太满意。这里决定自己写一个通用的批量插入,让代码优雅起来 ~
import com.test.base.BaseMapper;
import java.util.ArrayList;
import java.util.List;
public class BatchInsertUtil {
//静态分批插入方法
public static <T> int insertList(List<T> dataList, Class mapperCls) {
BaseMapper<T> baseMapper = (BaseMapper<T>) SpringContextUtils.getBean(mapperCls);
List<T> list;
//这里写死每次处理2000条,可以提出来做动态参数
int batchSize = 2000;
for (int i = 0; i < dataList.size(); i += batchSize) {
int end = Math.min(dataList.size(), i + batchSize);
list = dataList.subList(i, end);
baseMapper.insertList(list);
}
return dataList.size();
}
}
这里用到了SpringContextUtils 根据class获取到mapper的bean对象,在转换成BaseMapper来执行insertList分批插入
使用的时候就更简单了? 代码如下
List<TAccountAssetsDaily> list = incomeMapper.getAccountAssetsList(income_date);
if (!list.isEmpty()) {
Example example = new Example(TAccountAssetsDaily.class);
example.createCriteria().andEqualTo("createDate", income_date);
tAccountAssetsDailyMapper.deleteByExample(example);
//使用起来就这么简单
BatchInsertUtil.insertList(list, TAccountAssetsDailyMapper.class);
}
以上就是tkMapper批量插入相关的处理办法,目前感觉是最优解也是最好用的方法 ~
SpringContextUtils类和普通的实现可能有点区别这里提供下代码
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class SpringContextUtils implements BeanFactoryPostProcessor, ApplicationContextAware {
public static ApplicationContext applicationContext;
private static ConfigurableListableBeanFactory beanFactory;
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException
{
SpringContextUtils.beanFactory = beanFactory;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
SpringContextUtils.applicationContext = applicationContext;
}
public static Object getBean(String name) {
return applicationContext.getBean(name);
}
public static <T> T getBean(Class<T> requiredType) {
return applicationContext.getBean(requiredType);
}
public static boolean containsBean(String name) {
return applicationContext.containsBean(name);
}
public static boolean isSingleton(String name) {
return applicationContext.isSingleton(name);
}
public static Class<? extends Object> getType(String name) {
return applicationContext.getType(name);
}
/// 获取当前环境
public static String getActiveProfile() {
return applicationContext.getEnvironment().getActiveProfiles()[0];
}
}