Day210.首页显示课程名称数据整合、首页数据整合【Redis缓存】使用 -谷粒学院

谷粒学院

首页显示课程名师数据

一、后端部分

新建前端查询课程名师接口

  • 在service-edu模块创建controller

(1)查询最新前4条讲师数据

(2)查询最新前8条课程数据

@RestController
@CrossOrigin
@RequestMapping("/eduservice/indexFront")
public class IndexFrontController {
    
    

    @Autowired
    private EduCourseService eduCourseService;

    @Autowired
    private EduTeacherService eduTeacherService;

    //查询前8条热门课程,查询前4个名师
    @GetMapping("/index")
    public R index(){
    
    
        //查询前8条热门课程
        QueryWrapper<EduCourse> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("view_count");
        wrapper.last("limit 8");
        List<EduCourse> courseList = eduCourseService.list(wrapper);

        //查询前4张名师
        QueryWrapper<EduTeacher> wrapper1 = new QueryWrapper<>();
        wrapper1.orderByDesc("id");
        wrapper1.last("limit 4");
        List<EduTeacher> teacherList = eduTeacherService.list(wrapper1);


        return R.ok().data("courseList",courseList).data("teacherList",teacherList);
    }

}

二、前端部分

1、首页banner数据显示

  • 创建api文件夹,创建banner.js文件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QwAXi8ZF-1614873370481)(../../../../../AppData/Roaming/Typora/typora-user-images/image-20210304175724719.png)]

  • banner.js
import request from '@/utils/request'

export default{
    
    
    //查询前两条banner数据
    getListBanner(){
    
    
        return request({
    
    
            url: '/cmsservice/bannerFront/getAll/',
            method: 'get'
        })
    }
}

2、在首页面引入,调用实现

import banner from '@/api/banner';
export default {
    
    
  data() {
    
    
    return {
    
    
      swiperOption: {
    
    
		...
        bannerList:[],
    };
  },
  methods: {
    
    
    getBannerList(){
    
    
      banner.getListBanner().then(resp=>{
    
    
        this.bannerList = resp.data.data.list
      })
    }
  },
  created() {
    
    
    //获取两条banner数据
    this.getBannerList();
  },
};

3、在页面遍历显示banner

    <!-- 幻灯片 开始 -->
    <div v-swiper:mySwiper="swiperOption">
      <div class="swiper-wrapper">
        <div v-for='banner in bannerList' :key='banner.id' class="swiper-slide" style="background: #040b1b">
          <a target="_blank" :href="banner.linkUrl">
            <img
              :src="banner.imageUrl"
              :alt="banner.title"
            />
          </a>
        </div>
      </div>
      <div class="swiper-pagination swiper-pagination-white"></div>
      <div
        class="swiper-button-prev swiper-button-white"
        slot="button-prev"
      ></div>
      <div
        class="swiper-button-next swiper-button-white"
        slot="button-next"
      ></div>
    </div>
    <!-- 幻灯片 结束 -->

4、nginx访问配置

server {
    
    
    listen       9001;
    server_name  localhost;
    ......
    location ~ /cmsservice/ {
    
    
        proxy_pass http://localhost:8004;
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Rl2janph-1614873370485)(../../../../../AppData/Roaming/Typora/typora-user-images/image-20210304183537527.png)]

5、首页显示课程和名师数据

  • 创建api文件夹,创建index.js文件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RdfiwI9C-1614873370488)(../../../../../AppData/Roaming/Typora/typora-user-images/image-20210304211016498.png)]

  • index.js
import request from '@/utils/request'

export default{
    
    
    //查询热门课程和名师
    getIndexData(){
    
    
        return request({
    
    
            url: '/eduservice/indexFront/index/',
            method: 'get'
        })
    }
}

6、在首页面引入,调用实现

<script>
import banner from "@/api/banner";
import index from "@/api/index";
export default {
    
    
  data() {
    
    
    return {
    
    
      swiperOption: {
    
    
        //配置分页
        pagination: {
    
    
          el: ".swiper-pagination", //分页的dom节点
        },
        //配置导航
        navigation: {
    
    
          nextEl: ".swiper-button-next", //下一页dom节点
          prevEl: ".swiper-button-prev", //前一页dom节点
        },
      },
      bannerList: [],
      teacherList: [],
      courseList: [],
    };
  },
  methods: {
    
    
    //查询幻灯片
    getBannerList() {
    
    
      banner.getListBanner().then((resp) => {
    
    
        this.bannerList = resp.data.data.list;
      });
    },
    //查询热门课程和讲师
    getHotCourseAndTeacher() {
    
    
      index.getIndexData().then((resp) => {
    
    
        this.courseList = resp.data.data.courseList;
        this.teacherList = resp.data.data.teacherList;
      });
    },
  },
  created() {
    
    
    //获取两条banner数据
    this.getBannerList();
    //获取热门课程和讲师
    this.getHotCourseAndTeacher();
  },
};
</script>

7、在页面遍历显示课程和名师、幻灯片遍历

<!-- 幻灯片 开始 -->
    <div v-swiper:mySwiper="swiperOption">
      <div class="swiper-wrapper">
        <div
          v-for="banner in bannerList"
          :key="banner.id"
          class="swiper-slide"
          style="background: #040b1b"
        >
          <a target="_blank" :href="banner.linkUrl">
            <img :src="banner.imageUrl" :alt="banner.title" />
          </a>
        </div>
      </div>
      <div class="swiper-pagination swiper-pagination-white"></div>
      <div
        class="swiper-button-prev swiper-button-white"
        slot="button-prev"
      ></div>
      <div
        class="swiper-button-next swiper-button-white"
        slot="button-next"
      ></div>
    </div>
    <!-- 幻灯片 结束 -->
    <!-- 幻灯片 结束 -->
    <div id="aCoursesList">
      <!-- 网校课程 开始 -->
      <div>
        <section class="container">
          <header class="comm-title">
            <h2 class="tac">
              <span class="c-333">热门课程</span>
            </h2>
          </header>
          <div>
            <article class="comm-course-list">
              <ul class="of" id="bna">
                <li v-for="course in courseList" :key="course.id">
                  <div class="cc-l-wrap">
                    <section class="course-img">
                      <img
                        :src="course.cover"
                        class="img-responsive"
                        :alt="course.title"
                      />
                      <div class="cc-mask">
                        <a href="#" title="开始学习" class="comm-btn c-btn-1"
                          >开始 学习</a
                        >
                      </div>
                    </section>
                    <h3 class="hLh30 txtOf mt10">
                      <a
                        href="#"
                        :title="course.title"
                        class="course-title fsize18 c- 333"
                        >{
   
   { course.title }}</a
                      >
                    </h3>
                    <section class="mt10 hLh20 of">
                      <span
                        class="fr jgTag bg-green"
                        v-if="Number(course.price) === 0"
                      >
                        <i class="c-fff fsize12 f-fA">免费</i>
                      </span>
                      <span class="fl jgAttr c-ccc f-fA">
                        <i class="c-999 f-fA">9634人学习</i>
                        |
                        <i class="c-999 f-fA">9634评论</i>
                      </span>
                    </section>
                  </div>
                </li>
              </ul>
              <div class="clear"></div>
            </article>
            <section class="tac pt20">
              <a href="#" title="全部课程" class="comm-btn c-btn-2">全部课程</a>
            </section>
          </div>
        </section>
      </div>
      <!-- /网校课程 结束 -->
      <!-- 网校名师 开始 -->
      <div>
        <section class="container">
          <header class="comm-title">
            <h2 class="tac">
              <span class="c-333">名师大咖</span>
            </h2>
          </header>
          <div>
            <article class="i-teacher-list">
              <ul class="of">
                <li v-for="teacher in teacherList" :key="teacher.id"> 
                  <section class="i-teach-wrap">
                    <div class="i-teach-pic">
                      <a href="/teacher/1" :title="teacher.name">
                        <img
                          :alt="teacher.name"
                          :src="teacher.avatar"
                        />
                      </a>
                    </div>
                    <div class="mt10 hLh30 txtOf tac">
                      <a href="/teacher/1" :title="teacher.name" class="fsize18 c-666"
                        >{
   
   {teacher.name}}</a
                      >
                    </div>
                    <div class="hLh30 txtOf tac">
                      <span class="fsize14 c-999"
                        >{
   
   {teacher.career}}</span
                      >
                    </div>
                    <div class="mt15 i-q-txt">
                      <p class="c-999 f-fA">
                        {
   
   {teacher.intro}}
                      </p>
                    </div>
                  </section>
                </li>
              </ul>
              <div class="clear"></div>
            </article>
            <section class="tac pt20">
              <a href="#" title="全部讲师" class="comm-btn c-btn-2">全部讲师</a>
            </section>
          </div>
        </section>
      </div>

首页数据添加Redis缓存

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YVtmQLJ6-1614873370501)(../../../../../AppData/Roaming/Typora/typora-user-images/image-20210304220447902.png)]

二、项目集成Redis

1、在common模块添加依赖

由于redis缓存是公共应用,所以我们把依赖与配置添加到了common模块下面,在common模块pom.xml下添加以下依赖

<!-- redis -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

<!-- spring2.X集成redis所需common-pool2 -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
    <version>2.6.0</version>
</dependency>

2 、在service-base模块添加redis配置类

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0T2EKP1b-1614873370504)(../../../../../AppData/Roaming/Typora/typora-user-images/image-20210304220615019.png)]

@Configuration //配置类
@EnableCaching //开启缓存
public class RedisConfig extends CachingConfigurerSupport {
    
    
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
    
    
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        template.setConnectionFactory(factory);
        //key序列化方式
        template.setKeySerializer(redisSerializer);
        //value序列化
        template.setValueSerializer(jackson2JsonRedisSerializer);
        //value hashmap序列化
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        return template;
    }

    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
    
    
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new
                Jackson2JsonRedisSerializer(Object.class);
//解决查询缓存转换异常的问题
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
// 配置序列化(解决乱码的问题),过期时间600秒
        RedisCacheConfiguration config =
                RedisCacheConfiguration.defaultCacheConfig()
                        .entryTtl(Duration.ofSeconds(600)) //设置缓存存在的时间 600s
                        .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
                        .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
                        .disableCachingNullValues();
        RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
                .cacheDefaults(config)
                .build();
        return cacheManager;
    }


}

3、在接口中添加redis缓存

由于首页数据变化不是很频繁,而且首页访问量相对较大,所以我们有必要把首页接口数据缓存到redis缓存中,减少数据库压力和提高访问速度。

改造service-cms模块首页banner接口,首页课程与讲师接口类似

3.1 Spring Boot缓存注解

(1)缓存@Cacheable
根据方法对其返回结果进行缓存,下次请求时,如果缓存存在,则直接读取缓存数据返回;如果缓存不
存在,则执行方法,并把返回的结果存入缓存中。一般用在查询方法上。
查看源码,属性值如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WdWq4lQA-1614873370506)(../../../../../AppData/Roaming/Typora/typora-user-images/image-20210304230807810.png)]

(2)缓存@CachePut

使用该注解标志的方法,每次都会执行,并将结果存入指定的缓存中。其他方法可以直接从响应的缓存
中读取缓存数据,而不需要再去查询数据库。一般用在新增方法上。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QFANIdKJ-1614873370508)(../../../../../AppData/Roaming/Typora/typora-user-images/image-20210304230844858.png)]

(3)缓存@CacheEvict

使用该注解标志的方法,会清空指定的缓存。一般用在更新或者删除方法
查看源码,属性值如下:

在这里插入图片描述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5tbBkNIt-1614873370513)(../../../../../AppData/Roaming/Typora/typora-user-images/image-20210304231019746.png)]

3.2 启动redis服务

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ymeFOa1R-1614873370518)(../../../../../AppData/Roaming/Typora/typora-user-images/image-20210304232225622.png)]


3.3连接redis服务可能遇到的问题

在这里插入图片描述

如果报:NOAUTH Authentication required错误就是设置了密码

auth 你的密码

在这里插入图片描述

redis配置文件修改:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VFFY5WfX-1614873370522)(../../../../../AppData/Roaming/Typora/typora-user-images/image-20210304233110462.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oKpxZF1m-1614873370524)(../../../../../AppData/Roaming/Typora/typora-user-images/image-20210304233130182.png)]

ps -ef|grep redis

kill 杀掉redis进程

重启redis服务
./redis-server

./redis-cli 你的配置文件配置

3.4 banner接口改造

(1)在service-cms模块配置文件添加redis配置

spring.redis.host=192.168.44.132 
spring.redis.port=6379
spring.redis.database= 0
spring.redis.timeout=1800000
spring.redis.lettuce.pool.max-active=20
spring.redis.lettuce.pool.max-wait=-1
spring.redis.password=你设置的redis密码,没有可以不写
#最大阻塞等待时间(负数表示没限制)
spring.redis.lettuce.pool.max-idle=5
spring.redis.lettuce.pool.min-idle=0

(2)修改CrmBannerServiceImpl,添加redis缓存注解

@Service
public class CrmBannerServiceImpl extends ServiceImpl<CrmBannerMapper, CrmBanner> implements CrmBannerService {
    
    
    
    //@Cacheable用于查询
    @Cacheable(value = "banner", key = "'selectIndexList'")
    @Override
    public List<CrmBanner> selectIndexList() {
    
    
        List<CrmBanner> list = baseMapper.selectList(new
        QueryWrapper<CrmBanner>().orderByDesc("sort"));
        return list;
    }
    
    @Override
    public void pageBanner(Page<CrmBanner> pageParam, Object o) {
    
    
        baseMapper.selectPage(pageParam,null);
    }
    
    @Override
    public CrmBanner getBannerById(String id) {
    
    
    	return baseMapper.selectById(id);
    }
    
    @CacheEvict(value = "banner", allEntries=true)
    @Override
    public void saveBanner(CrmBanner banner) {
    
    
   		 baseMapper.insert(banner);
    }
    
    //CacheEvict用于更新或删除,allEntries属性清楚缓存
    @CacheEvict(value = "banner", allEntries=true)
    @Override
    public void updateBannerById(CrmBanner banner) {
    
    
   		 baseMapper.updateById(banner);
    }
    
    //CacheEvict用于更新或删除,allEntries属性清楚缓存
    @CacheEvict(value = "banner", allEntries=true)
    @Override
    public void removeBannerById(String id) {
    
    
   		 baseMapper.deleteById(id);
    }

  • 整合到8001项目中

com.achang.eduservice.controller.front.IndexFrontController

@RestController
@CrossOrigin
@RequestMapping("/eduservice/indexFront")
public class IndexFrontController {
    
    

    @Autowired
    private EduCourseService eduCourseService;

    @Autowired
    private EduTeacherService eduTeacherService;

    //查询前8条热门课程,查询前4个名师
    @GetMapping("/index")
    public R index(){
    
    

        //调用查询前8热门课程的方法
        List<EduCourse> courseList = eduCourseService.selectHotCourse();
        //查询前4张热门讲师
        List<EduTeacher> teacherList = eduTeacherService.selectHotTeacher();
        
        return R.ok().data("courseList",courseList).data("teacherList",teacherList);
    }

}
  • com.achang.eduservice.service.impl.EduCourseServiceImpl
    //查询8个热门课程
    @Override
    @Cacheable(key = "'selectHotCourse'",value = "course")
    public List<EduCourse> selectHotCourse() {
    
    

        //查询前8条热门课程
        QueryWrapper<EduCourse> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("view_count");
        wrapper.last("limit 8");

        return baseMapper.selectList(wrapper);

    }
  • com.achang.eduservice.service.impl.EduTeacherServiceImpl
    //查询前4个热门讲师
    @Override
    @Cacheable(key = "'selectHotTeacher'",value = "teacher")
    public List<EduTeacher> selectHotTeacher() {
    
    
        QueryWrapper<EduTeacher> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("id");
        wrapper.last("limit 4");

        return baseMapper.selectList(wrapper);
    }
  • 启动项目测试,测试

redis多了如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wayLRtnH-1614873370525)(../../../../../AppData/Roaming/Typora/typora-user-images/image-20210304235241621.png)]


猜你喜欢

转载自blog.csdn.net/qq_43284469/article/details/114380942