手写insert方法,通过拼接的方式实现,批量插入
通过获取实体类上@注解,获取字段名称,
以及通过拼接的方式使用获取对象的属性值
import io.lettuce.core.dynamic.annotation.Value;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service;
import javax.persistence.*;
import javax.transaction.Transactional;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@Service
@Transactional
@Slf4j
public class BatchService {
@PersistenceContext
private EntityManager entityManager;
//配置文件中每次批量提交的数量
private long batchSize = 500;
public BatchService(){
}
public String getTableName(Class<?> entityClass) {
Table tableAnnotation = entityClass.getAnnotation(Table.class);
if (tableAnnotation != null) {
return tableAnnotation.name();
}
return null;
}
public String[] getColumnNames(Class<?> entityClass) {
List<String> columns = new ArrayList<>();
Field[] fields = entityClass.getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(Column.class) && !field.isAnnotationPresent(Id.class)) {
Column columnAnnotation = field.getAnnotation(Column.class);
String name = columnAnnotation.name();
columns.add(name);
}
}
return columns.toArray(new String[fields.length-1]);
}
public String[] getColumn(Class<?> entityClass) {
List<String> columns = new ArrayList<>();
Field[] fields = entityClass.getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(Column.class) && !field.isAnnotationPresent(Id.class)) {
String columnName = field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1);
columns.add(columnName);
}
}
return columns.toArray(new String[fields.length-1]);
}
public String[] getColumnLowwer(Class<?> entityClass) {
List<String> columns = new ArrayList<>();
Field[] fields = entityClass.getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(Column.class) && !field.isAnnotationPresent(Id.class)) {
String columnName = field.getName();
columns.add(columnName);
}
}
return columns.toArray(new String[fields.length-1]);
}
@Transactional
public <T> List<T> saveAll(Class<?> entityClass,List<T> list) {
String tableName = getTableName(entityClass);
String[] columns = getColumnNames(entityClass);
String[] column = getColumn(entityClass);
String[] columnLowwer = getColumnLowwer(entityClass);
StringBuilder sb = into(tableName, columns);
int i = 0;
for (T entity : list) {
i++;
if (i > 1) {
sb.append(",");
}
sb.append("(");
for (int j = 0; j < column.length; j++) {
try {
Class<?> type = entityClass.getDeclaredField(columnLowwer[j]).getType();
Object value = entity.getClass().getMethod("get" + column[j]).invoke(entity);
if (value == null){
sb.append(String.format("%s", null));
}else {
sb.append(String.format("'%s'", transferType(type,value)));
}
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
}
if (j < columns.length - 1) {
sb.append(",");
}
}
sb.append(")");
// 每一千条执行一次
if (i >= 1000) {
log.info(sb.toString());
entityManager.createNativeQuery(sb.toString() + ";").executeUpdate();
i = 0;
sb = into(tableName, columns);
}
}
if (i > 0) {
entityManager.createNativeQuery(sb.toString() + ";").executeUpdate();
}
return list;
}
// SQL前半段方法提取
private StringBuilder into(String tableName, String[] columns) {
StringBuilder sb = new StringBuilder();
sb.append("insert into ").append(tableName).append("(");
for (int i = 0; i < columns.length; i++) {
sb.append(columns[i]);
if (i < columns.length - 1) {
sb.append(",");
}
}
sb.append(") values");
return sb;
}
private Object transferType(Class<?> type,Object value){
if(type.getTypeName().equals("java.util.Date")){
Date date= (Date) value;
value = SysDateUtils.date2Str(date,"yyyy-MM-dd HH:mm:ss");
}
return value;
}
}