课程类型的优化
无限极树的优化
方案一:发送一条SQL 将所以数据都查询出来 然后在通过循环将子级节点放入到父级节点中
代码实现:
//循环方案-一条sql自己组织关系
private List<CourseType> treeDataLoop(long pid) {
//1查询所有的节点
List<CourseType> allNodes = courseTypeMapper.selectList(null);
//为了查询父亲方便,我建立所有节点的一个key(Id)-vue(Node)集合 n
Map<Long,CourseType> allNodeDto = new HashMap<>();
for (CourseType courseType : allNodes) {
allNodeDto.put(courseType.getId(),courseType);
}
//2组织关系
List<CourseType> result = new ArrayList<>();
for (CourseType courseType : allNodes) {
//n
//2.1 如果是一级节点之间放入result
if (courseType.getPid().intValue()==0) {
result.add(courseType);
}else{
//2.2 不是一级节点要建立父子关系-把自己作为父亲一个儿子添加进去
//2.2.1 获取父亲
Long pidTmp = courseType.getPid(); //不能发sql
//方案1:遍历获取父亲,效率低下 两层for n*N
/*
for (CourseType courseType1 : allNodes) {
if (courseType1.getId() == pidTmp) {
//获取到了父亲了。。。。
}
}*/
//方案2:提前建立id和node直接关系,直接获取 //2n
CourseType parent = allNodeDto.get(pidTmp);
//2.2.2 给父亲添加儿子(自己)
parent.getChildren().add(courseType);
}
}
return result;
}
启动后会报一个错 空指针异常 因为在我们的实体类中 如果第一次没有创建一个空的集合 在parent.getChildren()获取的时候就获取不到 所以我们需要在domain里面 初始化儿子的时候就新建一个没有数据的集合
这个时候还有一个问题:
虽然就算我们只发送了一条sql 但是如果有几万个人同时访问 这样对数据库的压力也是巨大的 所以需要进一步的优化 ---- 缓存
缓存:用内存查询替换数据库磁盘查询.
经常查询,很少修改
但是这种技术也只适合于后台的前端 不适合前台的前端 因为即使做了缓存 如果有几万个人同时访问页面 那么缓存也是抵不住压力的 这里就涉及到了一个新的技术 ----- 页面静态化
课程类型的缓存
常见的缓存实现方案:
二级缓存 :jpa,Mybatis 默认情况下,不支持集群环境使用
在没有集群的时候就可以使用它
中央缓存:redis/memcached 集群环境
缓存的工作原理图
数据存储-json(转换)
queryCourseTypes{
List<CourseType> xxx = cache.queryCourseTypes(); // string--->Object
if(xxx ==null){
List<CourseType> yyy = maper.queryCourseTypes();
cache.setCourseTypes(yyy); //string object->string
return yyy;
}
return xxx;
}
说明: 当我们去查询一个数据时 我们首先去缓存中查询cache.queryCourseTypes() , 如果缓存中的数据不为空 则直接返回 如果数据xxx为空 就去数据库查询该数据 然后先将数据存入到缓存中 然后返回数据
但是缓存是不支持直接存放对象的 所以我们需要将对象转换为json字符串进行存储
而要获取数据 就要 把json字符串转换为java对象进行返回
java对象和json字符串之间相互转换?
需要使用到json的框架 json-lib,jackson,gson,fastjson
Fastjson
Fastjson是一个Java语言编写的高性能的JSON处理器,由阿里巴巴公司开发。无依赖,不需要例外额外的jar,能够直接跑在JDK上。FastJson在复杂类型的Bean转换Json上会出现一些问题,可能会出现引用的类型,导致Json转换出错,需要制定引用。
FastJson采用独创的算法,将parse的速度提升到极致,超过所有json库
缓存和项目集成
除了课程模块要用缓存,其他模块也要用缓存,所有抽取缓存服务供其他模块使用,并且把像缓存这样的简单服务全部封装在一个公共服务模块里面
与Redis的集成
参考文章
NoSQL-Redis基本介绍
Redis客户端的基本使用和在java中使用
与Redis的交互部分
为了简化我们的代码 我的是将他放在之前的hrm-common-service-2090中
首先还是先导入依赖 在原有的基础上再加上jedis
<!-- redis客户端-jedis -->
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
编写配置类
redis.properties
redis.host=127.0.0.1
redis.port=6379
redis.password=admin
redis.timeout=1000
导入Redis工具类
RedisUtils.java
/**
* 获取连接池对象
*/
public enum RedisUtils {
INSTANCE;
static JedisPool jedisPool = null;
static {
//1 创建连接池配置对象
JedisPoolConfig config = new