菜单树的优化:循环
1先一次性将所有的数据取出来,存入map中
2在判断是否是一级菜单,如果是就直接装进要返回的list集合中
3如果不是就将他的父级菜单,从map中拿出来,再通过父级菜单将当前这个菜单装入他的Children集合中去
private List<CourseType> getCourseTypesLoop(Long pid) { //0
List<CourseType> result = new ArrayList<>();
//1 查询所有类型
List<CourseType> allTypes = courseTypeMapper.selectList(null);
//建立id和CourseType的关联关系
Map<Long,CourseType> allTypesDto = new HashMap<>();
for (CourseType allType : allTypes) {
allTypesDto.put(allType.getId(),allType);
}
//2 遍历判断是否是第一级 pid为传入id,
for (CourseType type : allTypes) {
Long pidTmp = type.getPid();
//2.1是直接加入返回列表
if (pidTmp.longValue()== pid.longValue()){
result.add(type);
}else{
//2.2不是要把自己作为父亲儿子
//通过pid获取父亲
CourseType parent = allTypesDto.get(pidTmp);
//获取父亲儿子集合,把自己加进去
parent.getChildren().add(type);
}
}
return result;
}
redis的项目实战
因为在service模块中的controller中使用了 "/redis"这个路径了,所以不能直接放在service这个模块中,我们又建立了一个client模块
pom
<dependency>
<groupId>org.yyf</groupId>
<artifactId>hrm-common-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 给调用的模块来转换json-->
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson 调用者需要转换-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.58</version>
</dependency>
<!--客户端feign支持-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
redisclient.java
@FeignClient(value = "HRM-COMMON", fallbackFactory = RedisClientFallbackFactory.class )//服务提供
@RequestMapping("/redis")
public interface RedisClient {
@PostMapping
AjaxResult add(@RequestParam(value = "key", required = true) String key, @RequestParam(value = "value", required = true) String value);
@DeleteMapping
AjaxResult del(@RequestParam(value = "key", required = true) String key);
@GetMapping
String get(@RequestParam(value = "key", required = true) String key);
}
RedisClientFallbackFactory.java
@Component
public class RedisClientFallbackFactory implements FallbackFactory<RedisClient> {
@Override
public RedisClient create(Throwable throwable) {
return new RedisClient() {
@Override
public AjaxResult add(String key, String value) {
return AjaxResult.me().setSuccess(false).setMessage("redis调用失败");
}
@Override
public AjaxResult del(String key) {
return AjaxResult.me().setSuccess(false).setMessage("redis调用失败");
}
@Override
public String get(String key) {
return "redis调用失败";
}
};
}
}
RedisController .java
@RequestMapping("/redis")
public class RedisController {
@PostMapping
public AjaxResult add(
@RequestParam(value = "key",required = true) String key,
@RequestParam(value = "value",required = true) String value)
{
try
{
RedisUtils.INSTANCE.set(key,value);
return AjaxResult.me();
}catch (Exception e){
e.printStackTrace();
return AjaxResult.me().setSuccess(false).setMessage("添加失败");
}
}
@DeleteMapping
public AjaxResult del(@RequestParam(value = "key",required = true) String key)
{
try
{
RedisUtils.INSTANCE.del(key);
return AjaxResult.me();
}catch (Exception e){
e.printStackTrace();
return AjaxResult.me().setSuccess(false).setMessage("删除失败");
}
}
@GetMapping
public String get(@RequestParam(value = "key",required = true) String key)
{
try
{
return RedisUtils.INSTANCE.get(key);
}catch (Exception e){
e.printStackTrace();
}
return null;
}
}
redis.properties
redis.host=127.0.0.1
redis.port=6379
redis.password=123456 #我设置了密码,没有设置的请忽略
redis.timeout=1000
在你要调用redis服务的地方加上扫描
然后在相应的添加或修改或删除中加上方法,先建立缓存的方法
ICourseTypeCache.java
public interface ICourseTypeCache {
/**
* 获取courseType的缓存
* @return
*/
List<CourseType> getTreeData();
/**
* 设置courseType到缓存中
* @param courseTypesOfDb
*/
void setTreeData(List<CourseType> courseTypesOfDb);
}
ICourseTypeCache .java
@Component
public class CourseTypeCacheImpl implements ICourseTypeCache {
//获取和设置都要使用
private final static String COURSETYPE_KEY_IN_CACHE
= "courseType_Key_in_cache";
@Autowired
private RedisClient redisClient;
@Override
public List<CourseType> getTreeData() {
//获取的是字符串
String treeDataOfCache = redisClient.get(COURSETYPE_KEY_IN_CACHE);
//转换为java对象
return JSONArray.parseArray(treeDataOfCache,CourseType.class);
}
@Override
public void setTreeData(List<CourseType> courseTypesOfDb) {
if (courseTypesOfDb == null || courseTypesOfDb.size()<1){
//缓存穿透
redisClient.add(COURSETYPE_KEY_IN_CACHE,"[]");
}else{
//转换为json字符串
String jsonArrStr = JSONArray.toJSONString(courseTypesOfDb);
//设置获取
//缓存数据永远不过期 缓存击穿 缓存雪崩
redisClient.add(COURSETYPE_KEY_IN_CACHE,jsonArrStr);
}
}
}
然后将方法添加到对应的操作中
@Override
public boolean insert(CourseType entity) {
courseTypeMapper.insert(entity);
courseTypeCache.setTreeData(getCourseTypesLoop(0L));
return true;
}
@Override
public boolean deleteById(Serializable id) {
courseTypeMapper.deleteById(id);
courseTypeCache.setTreeData(getCourseTypesLoop(0L));
return true;
}
@Override
public boolean updateById(CourseType entity) {
courseTypeMapper.updateById(entity);
courseTypeCache.setTreeData(getCourseTypesLoop(0L));
return true;
}