组懒加载
This commit is contained in:
@@ -42,6 +42,8 @@ public interface SchClassRepository extends JpaRepository<SchClass, Integer>, Jp
|
|||||||
@Param("keyword") String keyword,
|
@Param("keyword") String keyword,
|
||||||
Pageable pageable);
|
Pageable pageable);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
boolean existsBySchIdAndGroupIdAndName(Integer schId, Integer groupId, String name);
|
boolean existsBySchIdAndGroupIdAndName(Integer schId, Integer groupId, String name);
|
||||||
|
|
||||||
boolean existsBySchIdAndGroupIdAndNameAndIdNot(Integer schId, Integer groupId, String name, Integer id);
|
boolean existsBySchIdAndGroupIdAndNameAndIdNot(Integer schId, Integer groupId, String name, Integer id);
|
||||||
@@ -56,6 +58,15 @@ public interface SchClassRepository extends JpaRepository<SchClass, Integer>, Jp
|
|||||||
|
|
||||||
List<SchClass> findBySchIdAndEnrollYear(Integer schId, Integer enrollYear);
|
List<SchClass> findBySchIdAndEnrollYear(Integer schId, Integer enrollYear);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据学校ID和班级组ID列表查询班级
|
||||||
|
* @param schId 学校ID
|
||||||
|
* @param classIds 班级组ID列表(group_class_id,即 SchClass.classId)
|
||||||
|
* @return 匹配的班级列表(与入参顺序无关,按库内顺序返回)
|
||||||
|
*/
|
||||||
|
@Query("SELECT c FROM SchClass c WHERE c.schId = :schId AND c.classId IN :classIds")
|
||||||
|
List<SchClass> findBySchIdAndClassIds(@Param("schId") Integer schId, @Param("classIds") List<Integer> classIds);
|
||||||
|
|
||||||
boolean existsBySchIdAndClassId(Integer schId, Integer classId);
|
boolean existsBySchIdAndClassId(Integer schId, Integer classId);
|
||||||
|
|
||||||
@Query("SELECT COUNT(c) FROM SchClass c WHERE (c.firstTeacherId IN (:ids) OR c.secondTeacherId IN (:ids)) AND c.schId = :schId AND c.graduate = 0")
|
@Query("SELECT COUNT(c) FROM SchClass c WHERE (c.firstTeacherId IN (:ids) OR c.secondTeacherId IN (:ids)) AND c.schId = :schId AND c.graduate = 0")
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import org.springframework.context.annotation.Lazy;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@@ -77,7 +78,7 @@ public class ComSchTreeService implements IComSchTreeService {
|
|||||||
synchronized (lock) {
|
synchronized (lock) {
|
||||||
baseSchsystemMap = null;
|
baseSchsystemMap = null;
|
||||||
}
|
}
|
||||||
idToNameCache = null;
|
idToNameCacheBySchId.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -316,38 +317,25 @@ public class ComSchTreeService implements IComSchTreeService {
|
|||||||
|
|
||||||
|
|
||||||
public String getTeaGroupName(Integer schId, Integer id) {
|
public String getTeaGroupName(Integer schId, Integer id) {
|
||||||
BoaGroup tree = getTeaTree(schId,true);
|
if (id == null) return null;
|
||||||
if (tree == null) return null;
|
return getTeaNameCache(schId).get(id);
|
||||||
// 懒加载缓存(若树结构不变)
|
|
||||||
if (idToNameCache == null) {
|
|
||||||
idToNameCache = new HashMap<>();
|
|
||||||
buildCache(tree);
|
|
||||||
}
|
|
||||||
return idToNameCache.get(id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public List<SelectIntVO> getTeaGroupNameList(Integer schId, List<Integer> ids) {
|
public List<SelectIntVO> getTeaGroupNameList(Integer schId, List<Integer> ids) {
|
||||||
// 1. 构建缓存(如果尚未构建)
|
// 1. 获取当前学校的组名缓存(按 schId 懒加载,不跨学校串用)
|
||||||
if (idToNameCache == null) {
|
Map<Integer, String> cache = getTeaNameCache(schId);
|
||||||
BoaGroup tree = getTeaTree(schId,true);
|
|
||||||
if (tree == null) {
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
idToNameCache = new HashMap<>();
|
|
||||||
buildCache(tree);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. 如果缓存为空,直接返回空
|
// 2. 如果缓存为空,直接返回空
|
||||||
if (idToNameCache.isEmpty()) {
|
if (cache.isEmpty()) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 处理 ids 参数
|
// 3. 处理 ids 参数
|
||||||
List<Integer> targetIds;
|
List<Integer> targetIds;
|
||||||
if (ids == null) {
|
if (ids == null) {
|
||||||
// 如果 ids 为 null,返回全部(从缓存中取出所有 key)
|
// 如果 ids 为 null,返回全部(从当前学校缓存中取出所有 key)
|
||||||
targetIds = new ArrayList<>(idToNameCache.keySet());
|
targetIds = new ArrayList<>(cache.keySet());
|
||||||
} else {
|
} else {
|
||||||
// 过滤掉 null 的 ID,并去重(可选)
|
// 过滤掉 null 的 ID,并去重(可选)
|
||||||
targetIds = ids.stream()
|
targetIds = ids.stream()
|
||||||
@@ -362,7 +350,7 @@ public class ComSchTreeService implements IComSchTreeService {
|
|||||||
// 4. 根据 targetIds 构建结果列表
|
// 4. 根据 targetIds 构建结果列表
|
||||||
List<SelectIntVO> result = new ArrayList<>();
|
List<SelectIntVO> result = new ArrayList<>();
|
||||||
for (Integer id : targetIds) {
|
for (Integer id : targetIds) {
|
||||||
String name = idToNameCache.get(id);
|
String name = cache.get(id);
|
||||||
if (name != null) {
|
if (name != null) {
|
||||||
SelectIntVO vo = new SelectIntVO();
|
SelectIntVO vo = new SelectIntVO();
|
||||||
vo.setId(id);
|
vo.setId(id);
|
||||||
@@ -933,14 +921,34 @@ public class ComSchTreeService implements IComSchTreeService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<Integer, String> idToNameCache;
|
/**
|
||||||
|
* 教师组树 id->name 缓存,按学校分桶,避免跨学校串数据
|
||||||
|
* 组树变更后需调用 clearCache() 清空(同一学校内部结构变化也会失效)
|
||||||
|
*/
|
||||||
|
private final Map<Integer, Map<Integer, String>> idToNameCacheBySchId = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private void buildCache(BoaGroup node) {
|
/**
|
||||||
|
* 获取指定学校的组名缓存(懒加载:首次按 schId 构建;树为 null 时不落缓存,下次重试)
|
||||||
|
*/
|
||||||
|
private Map<Integer, String> getTeaNameCache(Integer schId) {
|
||||||
|
Map<Integer, String> cache = idToNameCacheBySchId.get(schId);
|
||||||
|
if (cache == null) {
|
||||||
|
BoaGroup tree = getTeaTree(schId, true);
|
||||||
|
cache = new HashMap<>();
|
||||||
|
if (tree != null) {
|
||||||
|
buildCache(tree, cache);
|
||||||
|
idToNameCacheBySchId.put(schId, cache);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buildCache(BoaGroup node, Map<Integer, String> cache) {
|
||||||
if (node == null) return;
|
if (node == null) return;
|
||||||
idToNameCache.put(node.getId(), node.getName());
|
cache.put(node.getId(), node.getName());
|
||||||
if (node.getChildren() != null) {
|
if (node.getChildren() != null) {
|
||||||
for (BoaGroup child : node.getChildren()) {
|
for (BoaGroup child : node.getChildren()) {
|
||||||
buildCache(child);
|
buildCache(child, cache);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -250,7 +250,7 @@ public class SchStudentLogService {
|
|||||||
try {
|
try {
|
||||||
LocalDateTime now = LocalDateTime.now();
|
LocalDateTime now = LocalDateTime.now();
|
||||||
// 1. 批量查询班级名称
|
// 1. 批量查询班级名称
|
||||||
List<SchClass> classList = schClassRepository.findAllById(affectedClassIds);
|
List<SchClass> classList = schClassRepository.findBySchIdAndClassIds(user.getSchId(),affectedClassIds.stream().collect(Collectors.toList()));
|
||||||
Map<Integer, SchClass> classMap = classList.stream()
|
Map<Integer, SchClass> classMap = classList.stream()
|
||||||
.collect(Collectors.toMap(SchClass::getClassId, Function.identity()));
|
.collect(Collectors.toMap(SchClass::getClassId, Function.identity()));
|
||||||
Map<Integer, String> gradeNameMap = baseSchsystemGradeService.getGradeNameMap(user.getSchId(), null, null);
|
Map<Integer, String> gradeNameMap = baseSchsystemGradeService.getGradeNameMap(user.getSchId(), null, null);
|
||||||
@@ -330,7 +330,7 @@ public class SchStudentLogService {
|
|||||||
// 查询原班级名称(可能跨校)
|
// 查询原班级名称(可能跨校)
|
||||||
String originalClassName = "未知班级";
|
String originalClassName = "未知班级";
|
||||||
if (originalSchId != null && originalClassId != null) {
|
if (originalSchId != null && originalClassId != null) {
|
||||||
SchClass originalClass = schClassRepository.findByIdAndSchId(originalClassId, originalSchId).orElse(null);
|
SchClass originalClass = schClassRepository.findByClassIdAndSchId(originalClassId, originalSchId).orElse(null);
|
||||||
if (originalClass != null) {
|
if (originalClass != null) {
|
||||||
originalClassName = gradeMap.get(originalClass.getGradeId()) + originalClass.getName();
|
originalClassName = gradeMap.get(originalClass.getGradeId()) + originalClass.getName();
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -139,7 +139,7 @@ public class SchStudentTransferService {
|
|||||||
throw new DException("以下学生不存在或不属于该校: " + missing);
|
throw new DException("以下学生不存在或不属于该校: " + missing);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Integer> syncStuIds=students.stream().map(s->s.getStuId()).collect(Collectors.toList());
|
// List<Integer> syncStuIds=students.stream().map(s->s.getStuId()).collect(Collectors.toList());
|
||||||
|
|
||||||
// 收集受影响的班级ID
|
// 收集受影响的班级ID
|
||||||
Set<Integer> classIds = students.stream()
|
Set<Integer> classIds = students.stream()
|
||||||
|
|||||||
Reference in New Issue
Block a user