A088_HRM_04_课程分类缓存_课程管理

1.内容介绍

1. 分布式缓存方案(掌握)
2. 缓存服务搭建(掌握)
3. 课程分类缓存(掌握)
4. 课程添加(掌握)

2.课程分类缓存

2.1.分布式缓存方案
2.1.1.什么是缓存

通常将数据从数据库中同步一份到内存中,客户端直接从内存中查询数据,减少了和数据库的交互次数,提高查询性能(内存读写很快),减轻数据库的压力
在这里插入图片描述

2.1.2.那些数据适合缓存

1)经常查询的热点数据
2)不经常变的数据(数据变化会导致缓存中的数据跟着变,如果比较频繁,性能开销比较大)

2.1.3.缓存的流程

1 第一次查询,先看缓存是否有数据,如果没有,去数据库查询数据,查询完成后,json化并保存到redis
2 如果有数据,则说明有缓存,直接走缓存
3 返回数据
1)注意:数据库数据被修改,缓存要清空,或者重置;(查询)当将需要缓存的数据保存到 缓存中时,不需要关注是否抛异常

2.1.4.为什么要缓存课程分类

门户首页需要展示课程分类,首页并发比较高,导致可能分类查询机率非常大,并且课程分类的数据不会经常变,没必要每次访问都重新去Mysql查询一次课程分类,我们可以考虑做缓存。

对于门户网站的首页,几乎全是静态html的展示形式。
理由:静态html是可以部署到 nginx服务器。
nginx服务有2大特点:1.只支持静态资源部署;2.支持的并发量非常高,大概是tomcat峰值并发量的100倍
2.1.5.传统缓存方案及流程

在这里插入图片描述

2.1.6.传统缓存方案的优缺点

1) 在集群环境中,每个应用都有一个本地缓存,当缓存发生修改会造成缓存不同步问题
2) 本地缓存本身要占用应用的内存空间
在这里插入图片描述

2.1.7.分布式缓存方案

在这里插入图片描述
使用Redis作为共享缓存 ,解决缓存不同步问题,Redis是独立的服务,缓存不用占用应用本身的内存空间。

2.2.课程集成Redis

SpringBoot提供了整合Redis的方案,我们使用spring-boot-starter-data-redis包就可以很方便的操作Redis了

2.2.1.导入依赖
<!-- 缓存redis -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2.2.2.配置redis
spring:
  redis:
  host: localhost
  port: 6379
  timeout: 5000 #连接超时 毫秒
  jedis:
    pool:
      maxActive: 30
      maxIdle: 30
      minIdle: 10
      maxWait: -1 #连接池最大等行时间 -1没有限制
  password: 123456
2.2.3.自定义redis的操作工具类
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;

@Component
public class RedisService {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    
//下面的4个重载的方法---保存所有value的数据类型。并都以json格式存储
    public void setStringKeyAndValue(String key, Object value) {
        stringRedisTemplate.opsForValue().set(key, JSONObject.toJSONString(value));
    }

    public void setStringKeyAndValue(String key, String value) {
        stringRedisTemplate.opsForValue().set(key, value);
    }

    public void setStringKeyAndValue(String key, Object value, long minute) {
        stringRedisTemplate.opsForValue().set(key, JSONObject.toJSONString(value), minute, TimeUnit.MINUTES);
    }

    public void setStringKeyAndValue(String key, String value, long minute) {
        stringRedisTemplate.opsForValue().set(key, value, minute, TimeUnit.MINUTES);
    }

    /**
     * 功能说明 取出对象并转换为对象类型
     * @param key
     * @param clazz
     * @return T
     * @author caiwen
     * @date 2020/8/22
     */
    public <T> T getKeyObjectValue(String key, Class<T> clazz) {
        T t = null;
        String s = stringRedisTemplate.opsForValue().get(key);
        if (StringUtils.equalsIgnoreCase(clazz.getName(), "java.util.lang.string")) {
            t = (T) s;
        } else if (StringUtils.isNotBlank(s)) {
            t = JSONObject.parseObject(s, clazz);
        }
        return t;
    }
}

2.3.课程分类实现缓存
2.3.1.课程分类缓存逻辑

先思考技术有什么特点?有什么用?能解决我什么问题
我要怎么使用?它提供了哪些功能?有哪些常用的API方法?
实战—解决实际的问题?

1.查询Redis中是否有课程分类
2. 如果有就取Redis数据,进行TreeData处理并返回
3.如果没有就从Mysql查询课程分类
4.把课程分类存储到Redis
5.把课程分类进行TreeData处理并返回

代码略
2.3.2.课程分类缓存清除

数据库中的课程分类被修改,删除,添加,Redis中的课程分类需要清空,或者重置,不然会造成缓存数据和数据库数据不一致问题。例如:

@Override
//删除缓存
public boolean insert(CourseType entity) {
    boolean insert = super.insert(entity);
    redisTemplate.delete(RedisConstants.KEY_COURSE_TYPE_TREE);
    return insert;
}
2.4.使用SpringCache实现缓存

对于缓存声明,Spring的缓存提供了一组java注解:
@Cacheable:触发缓存写入。
@CacheEvict:触发缓存清除。
@CachePut:更新缓存(不会影响到方法的运行)。
@Caching:重新组合要应用于方法的多个缓存操作。
@CacheConfig:设置类级别上共享的一些常见缓存设置。

具体使用方式见文档《Springboot整合Cache基于Redis实现缓存.docx》

2.4.1.开启SpringCache
//缓存服务
@SpringBootApplication
@EnableCaching
public class CacheApplication {

    public static void main(String[] args) {
        SpringApplication.run(CacheApplication.class) ;
    }
}
2.4.2.课程分类缓存
@Override
@Cacheable(cacheNames = RedisConstants.KEY_COURSE_TYPE_TREE,key = "'ALL'")
public List<CourseType> treeData() {
    log.debug("从数据

库查询课程分类..........................");
    return treeDataMethodThree();
}
2.4.3.缓存的删除
@Override
@CacheEvict(cacheNames = RedisConstants.KEY_COURSE_TYPE_TREE,key = "'ALL'")
public boolean insert(CourseType entity) {
    return super.insert(entity);
}
@Override
@CacheEvict(cacheNames = RedisConstants.KEY_COURSE_TYPE_TREE,key = "'ALL'")
public boolean deleteById(Serializable id) {
    return super.deleteById(id);
}
@Override
@CacheEvict(cacheNames = RedisConstants.KEY_COURSE_TYPE_TREE,key = "'ALL'")
public boolean updateById(CourseType entity) {
    return super.updateById(entity);
}

3.课程管理

3.1.课程设计
3.1.1.课程页面设计
  1. 课程列表
    课程新增,录入课程数据到数据库
    课程营销,配置课程的价格等营销信息
    上传资源,添加课程的相册信息
    课程发布,也叫课程上线,只有发布之后的课程才能在门户网站显示,基于ES实现
    课程下线,取消课程发布的课程,不能给门户显示
    在这里插入图片描述
  2. 课程新增
    录入课程基本信息
    录入课程营销
    录入课程详情
    在这里插入图片描述
    这里的数据需要保存到三张表 ,基本信息保存到t_course ,营销信息保存到t_course_marker ,课程详情保存到t_course_detail
3.1.2.课程表设计

按照不同的维度对课程垂直分表
T_course保存课程基本信息
T_course_resource保存课程资源,比如相册
T_course_market保存课程营销信息
T_course_detail保存课程详情
在这里插入图片描述

3.2.课程基本管理
3.2.1.基础代码生成
3.2.2.课程CRUD实现
3.3.课程添加

上面我们已经分析过添加弹窗的布局 , 我们需要把一个表单的数据,添加到三张表
t_course :课程表
t_course_detail : 课程详情表
t_course_market :课程营销表
t_course_resource :课程资源表,通过 “上传资源”按钮单独上传课程的资源(课程相册)

补充:CourseType的children字段增加一个
@JsonInclude(JsonInclude.Include.NON_EMPTY):转JSON的时候不处理空值字段

3.3.1.前段提交添加

参数格式

var param = {
                course:{
                    courseTypeId:this.addForm.courseTypeId,
                    name:this.addForm.name,
                    users:this.addForm.users,
                    grade:this.addForm.gradeId,
                    gradeName:gradeName,
                    pic:this.addForm.pic,
                    startTime:this.addForm.startTime,
                    endTime:this.addForm.endTime
   },
               courseDetail:{
                    description:this.addForm.description,
                    intro:this.addForm.intro
   },
               courseMarket:{
                    charge:this.addForm.chargeId,
                    qq:this.addForm.qq,
                    price:this.addForm.price,
                    priceOld:this.addForm.priceOld,
                    expires:this.addForm.expires
   }
};
3.3.2.参数DTO封装
//封装课程添加的参数
public class CourseSaveDto {
    private Course course;
    private CourseDetail courseDetail;
    private CourseMarket courseMarket;
3.3.3.课程添加controller
/**
* 保存和修改公用的
* @return Ajaxresult转换结果
*/
@RequestMapping(value="/saveOrUpdate",method= RequestMethod.POST)
public AjaxResult saveOrUpdate(@RequestBody CourseSaveDto courseDto){
    try {
        courseService.saveOrUpdate(courseDto);
        return AjaxResult.me();
    } catch (Exception e) {
        e.printStackTrace();
        return AjaxResult.me().setSuccess(false).setMessage("保存对象失败!"+e.getMessage());
    }
}
3.3.4.课程添加service
@Override
public void saveOrUpdate(CourseSaveDto courseDto) {
    Course course = courseDto.getCourse();
    CourseDetail courseDetail = courseDto.getCourseDetail();
    CourseMarket courseMarket = courseDto.getCourseMarket();
    //1.基本判断
    //2.保存course
    course.setStatus(Course.STATUS_OFFLINE);
    course.setUserId(42l);
    course.setUserName("yhptest1");
    course.setTenantId(26l);
    course.setTenantName("源码时代");
    baseMapper.insert(course);
    //3.保存详情
    courseDetail.setId(course.getId());

    courseDetailMapper.insert(courseDetail);

    //4.保存营销
    courseMarket.setId(course.getId());
    courseMarketMapper.insert(courseMarket);
}

注意:课程营销courseMarket和课程详情courseDetail的ID使用课程course的ID ,创建课程的用户和机构暂时写死,因为还没做登录。

4.课程总结

4.1.重点

1.Redis缓存
2.课程添加

4.2.面试题

1.缓存的查询流程

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值