根据本文在service层基础接口、基础实现类中构建批量插入、更新方法后,对于任何一张数据库表,在自动生成mybatis相关文件后,只需要定义表对应的Service层并且正确完成基类继承,就可以直接使用。
1、在接口基类BaseService中定义批量插入、更新方法
/**
* 批量插入数据
* @author 北北
* @date 2017年10月31日下午3:03:36
* @param list 数据对象列表
* @param eachCommitCount 每次提交数量,默认3000
* @return -99 异常
*/
public String insert(List<M> list, Integer eachCommitCount);
/**
* 批量更新
* @author 北北
* @date 2017年10月31日下午3:11:35
* @param list 数据对象列表
* @param eachCommitCount 每次提交数量,默认3000
* @return -99 异常
*/
public String update(List<M> list, Integer eachCommitCount);
2、在实现基类BaseServiceImpl写实现逻辑
@Autowired
private SqlSessionTemplate sqlSessionTemplate;
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public String insert(List<M> list, Integer eachCommitCount){
//非空判断
if(list==null || list.isEmpty()){
return "没有新增数据。";
}
if(eachCommitCount == null){
//每次默认提交数量
eachCommitCount = 3000;
}
SqlSession session = null;
try{
//提取当前service对象泛型实例化类对应的Mapper类
Class mapperClass = genericMapperClass();
if(mapperClass == null){
return "新增数据时候无法取得mapperClass。";
}
// 新获取一个模式为BATCH,自动提交为false的session
// 如果自动提交设置为true,将无法控制提交的条数,改为最后统一提交,可能导致内存溢出
session = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);
//通过新的session获取mapper
BaseMapper<M, E> mapper = (BaseMapper)session.getMapper(mapperClass);
//批量插入数据处理
for(int i=0; i<list.size(); i++){
mapper.insertSelective(list.get(i));
if(i % eachCommitCount == 0 || i == list.size() - 1) {
//手动每 eachCommitCount 个一提交,提交后无法回滚
session.commit();
//清理缓存,防止溢出
session.clearCache();
}
}
} catch (Exception e) {
//没有提交的数据可以回滚
session.rollback();
logger.error("批量插入数据异常", e);
return "批量插入数据异常。";
} finally{
session.close();
}
return "000";
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public String update(List<M> list, Integer eachCommitCount){
//非空判断
if(list==null || list.isEmpty()){
return "没有更新的数据。";
}
if(eachCommitCount==null){
//每次默认提交数量
eachCommitCount = 3000;
}
SqlSession session = null;
try{
//提取当前service对象泛型实体类对应的Mapper类
Class mapperClass = genericMapperClass();
if(mapperClass == null){
return "更新数据时候无法取得mapperClass。";
}
// 新获取一个模式为BATCH,自动提交为false的session
// 如果自动提交设置为true,将无法控制提交的条数,改为最后统一提交,可能导致内存溢出
session = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);
//通过新的session获取mapper
BaseMapper<M, E> mapper = (BaseMapper)session.getMapper(mapperClass);
//批量更新数据处理
for(int i=0; i<list.size(); i++){
mapper.updateByPrimaryKeySelective(list.get(i));
if(i % eachCommitCount == 0 || i == list.size() - 1) {
//手动每 eachCommitCount 个一提交,提交后无法回滚
session.commit();
//清理缓存,防止溢出
session.clearCache();
}
}
} catch (Exception e) {
//没有提交的数据可以回滚
session.rollback();
logger.error("批量更新数据异常", e);
return "批量更新数据异常。";
} finally{
session.close();
}
return "000";
}
/**
* 获取当前Service对象泛型实体类的对应Mapper类
* @author 北北
* @date 2018年1月18日下午4:15:05
* @return
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
private Class genericMapperClass() {
try {
//提取当前service对象泛型实例化类对应的Mapper类
Class<M> modelClass = (Class<M>) ReflectUtil.getGenericClass(this.getClass(), 0);
String modelClassName = modelClass.getName();
String mapperClassName = modelClassName.replace("model", "dao") + "Mapper";
Class mapperClass;
mapperClass = Class.forName(mapperClassName);
return mapperClass;
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
3、以user表为例,正确生成User类、UserExample类、UserMapper类后,创建UserService接口及其实现类UserServiceImpl,然后分别继承基础接口及基础实现类,就可以使用了。
注:
1、BaseService、BaseServiceImpl类的定义请参考:Spring Boot一步步整合Mybatis框架
2、ReflectUtil类的定义请参考:如何获取泛型类的子类中声明的泛型类型
3、sqlSessionTemplate对象注入请参考:Mybatis联表分页查询 的方式二部分内容。 (至于非spring boot项目,请自行百度解决办法,大概是配置ApplicationContext.xml文件)
网友评论