批量保存
/**
* 批量保存,参数为对象集合<br>
* 条件:对象属性与数据库字段完全对应,允许使用大骆驼拼写法
* <br> 2018年4月28日下午5:30:53
* @throws Exception
*/
private String insert00000(List<Serializable> list, String tableName){
StringBuilder sb = new StringBuilder();
sb.append("INSERT INTO " + tableName);
sb.append("(company_name,telephone,address,types,update_time) ");
sb.append("VALUES ");
MessageFormat mf = new MessageFormat(
"("
+ "#'{'list[{0}].companyName},"
+ "#'{'list[{0}].telephone},"
+ "#'{'list[{0}].address},"
+ "#'{'list[{0}].types},"
+ "#'{'list[{0}].updateTime}"
+ ")");
int listSize = list.size();
for (int i = 0; i < listSize; i++) {
sb.append(mf.format(new Object[]{i}));
if (i < listSize - 1) {
sb.append(",");
}
}
return sb.toString();
}
========================================================================
package com.lyb.serviceimpl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.lyb.dao.BatchExecuteDAO;
/**
*
* @author lyb
* 2019年11月7日 下午3:20:19
*/
@Service
public class BatchExecuteServiceImpl {
@Autowired
private BatchExecuteDAO batchExecuteDAO;
/**
* 批量保存
* @param list 对象集合
* @param tableName 数据库表名
* @return
*/
public <T> Integer batchSaveList( List<T> list, String tableName){
//每次保存的数据量;listInsert的容量。最大 999
int size = 400;
//将原集合的数据分出一部分到该集合中进行保存
List<T> listInsert = null;
int result = 0; //统计插入记录总数
//循环保存size数量的数据
int listSize = list.size();
while(listSize > size ){
listInsert = list.subList(0, size);
//调用保存数据的 DAO
int result1 = batchExecuteDAO.insert(listInsert, tableName);
result += result1;
//原集合数据更新为未保存的数据
list = list.subList(size, list.size());
listSize = list.size();
}
//保存最后剩下的,数量不足size的。并累计保存结果
int result2 = batchExecuteDAO.insert(list, tableName);
result += result2;
return result;
}
}
package com.lyb.dao;
import java.util.List;
import org.apache.ibatis.annotations.InsertProvider;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import com.lyb.provider.BatchExecuteProvider;
/**
* 批量操数据库的工具
* @author lyb
* 2019年11月7日 下午3:19:01
*/
@Mapper
public interface BatchExecuteDAO {
/**
* 批量保存数据
* @param list 数据集合
* @param tableName 数据库表名
* @return 保存记录数
*/
@InsertProvider(type = BatchExecuteProvider.class, method = "insert")
<T> Integer insert(@Param("list")List<T> list, @Param("tableName")String tableName);
}
package com.lyb.provider;
import java.text.MessageFormat;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.ibatis.annotations.Param;
import org.springframework.core.env.Environment;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.serializer.SerializerFeature;
/**
* 批量保存数据<br>
* 一次最多保存999条<br>
* 条件:对象属性与数据库字段完全对应,允许使用大骆驼拼写法
* @author lyb
* 2019年10月29日 下午3:32:43
*/
public class BatchExecuteProvider {
/** 获取properties 配置文件 */
private static Environment env;
/**
* 通过该构造器为env 赋值
*/
public BatchExecuteProvider(Environment environment) {
BatchExecuteProvider.env = environment;
}
/**
* DAO 中使用该构造器创建对象
*/
public BatchExecuteProvider() {}
/**
* 批量保存,参数为对象集合<br>
* 一次最多保存999条数据
* 条件:对象属性与数据库字段完全对应,允许使用大骆驼拼写法
* <br> 2018年4月28日下午5:30:53
* @throws Exception
*/
@SuppressWarnings("rawtypes")
public <T> String insert(@Param("list") List<T> list, @Param("tableName")String tableName) throws Exception{
if(list == null || list.size() == 0 ){
return null;
}
if(tableName == null || tableName.trim().length() == 0){
throw new Exception("tableName 不能为空");
}
//判定是否使用了帕斯卡命名法
boolean camelCase = false; //默认没有使用帕斯卡
String named = env.getProperty("mybatis.configuration.map-underscore-to-camel-case");
if(named != null) {
named = named.trim();
if("true".equalsIgnoreCase(named)){
camelCase = true;
}
}
//将对象集转为Map集
String strJsonArray = JSONArray.toJSONString(list, SerializerFeature.WriteMapNullValue);
List<Map> listMap = JSONArray.parseArray(strJsonArray, Map.class);
if(listMap == null || listMap.size() == 0){
throw new Exception("数据为空");
}
//拼接sql
Map m0 = null;
for (int i = 0; i < listMap.size(); i++) {
m0 = listMap.get(i);
if(m0 != null && !m0.isEmpty()){
break;
}
}
if(m0 == null ){
throw new Exception("数据为空");
}
StringBuilder sql = new StringBuilder(); //SQL语句
StringBuilder propertyName = new StringBuilder(); //对象的属性名称
sql.append("INSERT INTO "+tableName+" (");
Set set0 = m0.keySet();
Object[] keyArray = set0.toArray();
//组合数据库字段名 、 占位符
for (int i = 0; i < keyArray.length; i++) {
String key = (String) keyArray[i];
if(camelCase && key.matches(".*[A-Z]+.*")){ //使用帕斯卡并且包含大写字母
String newKey = CamelCaseToUnderline(key); //帕斯卡转下划线
sql.append(newKey+",");
}else{ //没有用帕斯卡,也包含大写?:字段名不区分大小写
sql.append(key+",");
}
propertyName.append("#'{'list[{0}]."+key+"},");
}
//去掉最后一个逗号
sql.deleteCharAt(sql.length()-1);
propertyName.deleteCharAt(propertyName.length()-1);
sql.append(") VALUES ");
String values = "(" + propertyName.toString() + ")";
MessageFormat mf = new MessageFormat(values);
int listSize = list.size();
for (int i = 0; i < listSize; i++) {
sql.append(mf.format(new Object[]{i}));
if (i < listSize - 1) {
sql.append(",");
}
}
return sql.toString();
}
/**
* 大骆驼拼写法转为 下划线写法
* <br> 2018年4月28日下午3:00:29
*/
private String CamelCaseToUnderline(String str){
StringBuilder sb = new StringBuilder();
char[] ca = str.toCharArray();
for (int j = 0; j < ca.length; j++) {
char c = ca[j];
if( Character.isUpperCase(c)){
char nc = Character.toLowerCase(c);//转为小写
sb.append("_"+nc);
}else{
sb.append(c);
}
}
return sb.toString();
}
}