注意: ListUtil.partition(),这个方法从某种意义上说并没有达到真正分页的效果,因为当我们使用这个方法时,List结果早已执行出来了;我们要做的就是在结果没有出来之前就减少 DB 的压力。
当然,具体业务具体分析,少量的数据可以使用这个方法
直接使用 Hutool 工具类中的 ListUtil.partition(list,100)方法,参数一: 具体 list、参数二: 具体分多少条
public class MybatisParameterUtils {
public static <T, F> void cutInParameter(LambdaQueryWrapper<T> wrapper, SFunction<T, ?> column, List<F> coll) throws Exception {
List<List<F>> newList = splitList(coll, 900);
if (ObjectUtils.isEmpty(newList)) {
throw new Exception("参数错误");
} else if (newList.size() == 1) {
wrapper.in(column, newList.get(0));
return;
}
wrapper.and(i -> {
i.in(column, newList.get(0));
newList.remove(0);
for (List<F> objects : newList) {
i.or().in(column, objects);
}
});
}
public static <T, F> void cutNotInParameter(LambdaQueryWrapper<T> wrapper, SFunction<T, ?> column, List<F> coll) throws Exception {
List<List<F>> newList = splitList(coll, 900);
if (ObjectUtils.isEmpty(newList)) {
throw new Exception("参数错误");
} else if (newList.size() == 1) {
wrapper.notIn(column, newList.get(0));
return;
}
wrapper.and(i -> {
i.in(column, newList.get(0));
newList.remove(0);
for (List<F> objects : newList) {
i.or().notIn(column, objects);
}
});
}
public static <T, F> void cutInParameter(LambdaQueryChainWrapper<T> wrapper, SFunction<T, ?> column, List<F> coll) throws Exception {
List<List<F>> newList = splitList(coll, 900);
if (ObjectUtils.isEmpty(newList)) {
throw new Exception("参数错误");
} else if (newList.size() == 1) {
wrapper.in(column, newList.get(0));
return;
}
wrapper.and(i -> {
i.in(column, newList.get(0));
newList.remove(0);
for (List<F> objects : newList) {
i.or().in(column, objects);
}
});
}
public static <T, F> void cutNotInParameter(LambdaQueryChainWrapper<T> wrapper, SFunction<T, ?> column, List<F> coll) throws Exception {
List<List<F>> newList = splitList(coll, 900);
if (ObjectUtils.isEmpty(newList)) {
throw new Exception("参数错误");
} else if (newList.size() == 1) {
wrapper.notIn(column, newList.get(0));
return;
}
wrapper.and(i -> {
i.in(column, newList.get(0));
newList.remove(0);
for (List<F> objects : newList) {
i.or().notIn(column, objects);
}
});
}
public static <T, F> void cutInParameter(LambdaUpdateWrapper<T> wrapper, SFunction<T, ?> column, List<F> coll) throws Exception {
List<List<F>> newList = splitList(coll, 900);
if (ObjectUtils.isEmpty(newList)) {
throw new Exception("参数错误");
} else if (newList.size() == 1) {
wrapper.in(column, newList.get(0));
return;
}
wrapper.and(i -> {
i.in(column, newList.get(0));
newList.remove(0);
for (List<F> objects : newList) {
i.or().in(column, objects);
}
});
}
public static <T, F> void cutNotInParameter(LambdaUpdateWrapper<T> wrapper, SFunction<T, ?> column, List<F> coll) throws Exception {
List<List<F>> newList = splitList(coll, 900);
if (ObjectUtils.isEmpty(newList)) {
throw new Exception("参数错误");
} else if (newList.size() == 1) {
wrapper.notIn(column, newList.get(0));
return;
}
wrapper.and(i -> {
i.in(column, newList.get(0));
newList.remove(0);
for (List<F> objects : newList) {
i.or().notIn(column, objects);
}
});
}
public static <T, F> void cutInParameter(LambdaUpdateChainWrapper<T> wrapper, SFunction<T, ?> column, List<F> coll) throws Exception {
List<List<F>> newList = splitList(coll, 900);
if (ObjectUtils.isEmpty(newList)) {
throw new Exception("参数错误");
} else if (newList.size() == 1) {
wrapper.in(column, newList.get(0));
return;
}
wrapper.and(i -> {
i.in(column, newList.get(0));
newList.remove(0);
for (List<F> objects : newList) {
i.or().in(column, objects);
}
});
}
public static <T, F> void cutNotInParameter(LambdaUpdateChainWrapper<T> wrapper, SFunction<T, ?> column, List<F> coll) throws Exception {
List<List<F>> newList = splitList(coll, 900);
if (ObjectUtils.isEmpty(newList)) {
throw new Exception("参数错误");
} else if (newList.size() == 1) {
wrapper.notIn(column, newList.get(0));
return;
}
wrapper.and(i -> {
i.in(column, newList.get(0));
newList.remove(0);
for (List<F> objects : newList) {
i.or().notIn(column, objects);
}
});
}
public static <F> List<List<F>> splitList(List<F> list, int groupSize) {
int length = list.size();
// 计算可以分成多少组
int num = (length + groupSize - 1) / groupSize;
List<List<F>> newList = new ArrayList<>(num);
for (int i = 0; i < num; i++) {
// 开始位置
int fromIndex = i * groupSize;
// 结束位置
int toIndex = Math.min((i + 1) * groupSize, length);
newList.add(list.subList(fromIndex, toIndex));
}
return newList;
}
}
// 这是一个条件wrapper get方法的方法引用 一个参数list
MybatisParameterUtils.cutInParameter(deleteInfoWrapper, Vo::getId, list);
<if test="dto.idList != null and dto.idList.size() > 0">
and (t.id IN
<foreach collection="dto.idList" index="index" open="(" close=")" item="item" >
<if test="index !=0">
<choose>
<when test="index % 1000 == 999">) OR t.id IN (</when>
<otherwise>,</otherwise>
</choose>
</if>
#{item}
</foreach>
)
</if>
import java.util.List;
public class MassiveDataProcessor {
private DataService dataService; // 假设有一个用于操作数据的Service
// 分页处理海量数据
public void processMassiveData() {
int pageSize = 1000; // 每页数据量
long totalCount = dataService.getTotalCount(); // 获取总数据量
long totalPages = (totalCount + pageSize - 1) / pageSize; // 计算总页数
for (int currentPage = 1; currentPage <= totalPages; currentPage++) {
List<Data> dataList = dataService.getDataByPage(currentPage, pageSize); // 获取当前页的数据
batchUpdateData(dataList); // 批量更新当前页的数据
}
}
// 批量更新数据
private void batchUpdateData(List<Data> dataList) {
int batchSize = 100; // 每批次处理的数据量
for (int i = 0; i < dataList.size(); i += batchSize) {
List<Data> batchList = dataList.subList(i, Math.min(i + batchSize, dataList.size()));
dataService.batchUpdate(batchList); // 调用Service进行批量更新操作
}
}
}
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
public interface YourEntityRepository extends JpaRepository<YourEntity, Long> {
Page<YourEntity> findAll(Pageable pageable);
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class YourService {
@Autowired
private YourEntityRepository yourEntityRepository;
public void batchUpdate(List<YourEntity> entities) {
int pageSize = 1000; // 每批次处理的数量
int currentPage = 0;
PageRequest pageRequest = PageRequest.of(currentPage, pageSize);
do {
Page<YourEntity> page = yourEntityRepository.findAll(pageRequest);
List<YourEntity> pageEntities = page.getContent();
// 对当前批次的数据进行处理,例如修改或插入
for (YourEntity entity : pageEntities) {
// 修改逻辑
// entity.setSomeField(newValue);
// yourEntityRepository.save(entity);
// 或者插入逻辑
// yourEntityRepository.save(newEntity);
}
// 准备下一个批次
currentPage++;
pageRequest = PageRequest.of(currentPage, pageSize);
} while (page.hasNext()); // 如果还有更多页面,继续循环
}
}