尚硅谷在线教育十:首页数据显示

文章目录

1. 首页数据banner显示(后端)

1.1 在service创建子模块service_cms

1.2 创建配置文件

在application.properties中

# 服务端口
server.port=8004
# 服务名
spring.application.name=service-cms
# mysql数据库连接
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/guli?serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=root
#返回json的全局时间格式
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8
#配置mapper xml文件的路径
mybatis-plus.mapper-locations=classpath:com/atguigu/cmsservice/mapper/xml/*.xml
#mybatis日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

1.3 创建数据库表。使用表生成代码生成器

1.3.1数据库的SQL语句

CREATE TABLE `crm_banner` (
  `id` CHAR(19) NOT NULL DEFAULT '' COMMENT 'ID',
  `title` VARCHAR(20) DEFAULT '' COMMENT '标题',
  `image_url` VARCHAR(500) NOT NULL DEFAULT '' COMMENT '图片地址',
  `link_url` VARCHAR(500) DEFAULT '' COMMENT '链接地址',
  `sort` INT(10) UNSIGNED NOT NULL DEFAULT '0' COMMENT '排序',
  `is_deleted` TINYINT(1) UNSIGNED NOT NULL DEFAULT '0' COMMENT '逻辑删除 1(true)已删除, 0(false)未删除',
  `gmt_create` DATETIME NOT NULL COMMENT '创建时间',
  `gmt_modified` DATETIME NOT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_name` (`title`)
) ENGINE=INNODB DEFAULT CHARSET=utf8mb4 COMMENT='首页banner表';

#
# Data for table "crm_banner"
#

INSERT INTO `crm_banner` VALUES ('1194556896025845762','test1','https://online-teach-file.oss-cn-beijing.aliyuncs.com/cms/2019/11/14/297acd3b-b592-4cfb-a446-a28310369675.jpg','/course',1,0,'2019-11-13 18:05:32','2019-11-18 10:28:22'),
('1194607458461216769','test2','https://online-teach-file.oss-cn-beijing.aliyuncs.com/cms/2019/11/13/8f80790d-d736-4842-a6a4-4dcb0d684d4e.jpg','/teacher',2,0,'2019-11-13 21:26:27','2019-11-14 09:12:15');

1.3.2代码生成器

 @Test
    public void run() {

        // 1、创建代码生成器
        AutoGenerator mpg = new AutoGenerator();

        // 2、全局配置
        GlobalConfig gc = new GlobalConfig();
        String projectPath = System.getProperty("user.dir");
        gc.setOutputDir("D:\\尚硅谷在线教育项目\\在线教育--谷粒学院\\项目源码\\day10\\后端代码\\后端代码\\guli_parent\\service\\service_cms" + "/src/main/java");

        gc.setAuthor("smile");
        gc.setOpen(false); //生成后是否打开资源管理器
        gc.setFileOverride(false); //重新生成时文件是否覆盖

        //UserServie
        gc.setServiceName("%sService");	//去掉Service接口的首字母I

        gc.setIdType(IdType.ID_WORKER_STR); //主键策略
        gc.setDateType(DateType.ONLY_DATE);//定义生成的实体类中日期类型
        gc.setSwagger2(true);//开启Swagger2模式

        mpg.setGlobalConfig(gc);

        // 3、数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://localhost:3306/guli?serverTimezone=GMT%2B8");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("199866");
        dsc.setDbType(DbType.MYSQL);
        mpg.setDataSource(dsc);

        // 4、包配置
        PackageConfig pc = new PackageConfig();
        pc.setModuleName("educms"); //模块名
        //包  com.atguigu.eduservice
        pc.setParent("com.blb");
        //包  com.atguigu.eduservice.controller
        pc.setController("controller");
        pc.setEntity("domain");
        pc.setService("service");
        pc.setMapper("mapper");
        mpg.setPackageInfo(pc);

        // 5、策略配置
        StrategyConfig strategy = new StrategyConfig();

        strategy.setInclude("crm_banner");

        strategy.setNaming(NamingStrategy.underline_to_camel);//数据库表映射到实体的命名策略
        strategy.setTablePrefix(pc.getModuleName() + "_"); //生成实体时去掉表前缀

        strategy.setColumnNaming(NamingStrategy.underline_to_camel);//数据库表字段映射到实体的命名策略
        strategy.setEntityLombokModel(true); // lombok 模型 @Accessors(chain = true) setter链式操作

        strategy.setRestControllerStyle(true); //restful api风格控制器
        strategy.setControllerMappingHyphenStyle(true); //url中驼峰转连字符

        mpg.setStrategy(strategy);


        // 6、执行
        mpg.execute();
    }

1.4 banner接口的编写

1.4.1. 后台管理员接口的编写

controller层

@RestController
@CrossOrigin
@RequestMapping("/educms/banneradmin")
public class BannerAdminController {

    @Autowired
    private CrmBannerService crmBannerService;

    //1.分页查询banner
    @GetMapping("/pageBanner/{page}/{limit}")
    public R pageBanner(@PathVariable long page,@PathVariable long limit)
    {
        Page<CrmBanner> crmBannerPage = new Page<>(page,limit);
        crmBannerService.page(crmBannerPage,null);
        return R.ok().data("items",crmBannerPage.getRecords()).data("total",crmBannerPage.getTotal());
    }

    //添加banner
    @PostMapping("/addbanner")
    public R addBanner(@RequestBody CrmBanner crmBanner)
    {
        crmBannerService.save(crmBanner);
        return R.ok();
    }

    //根据id查询banner
    @GetMapping("/get/{id}")
    public R getBanner(@PathVariable String id)
    {
        CrmBanner crmBanner = crmBannerService.getById(id);
        return R.ok().data("item",crmBanner);

    }

    //修改banner
    @PutMapping("/update")
    public R updateBanner(@RequestBody CrmBanner banner)
    {
        crmBannerService.updateById(banner);
        return R.ok();
    }

    //根据id删除banner
    @DeleteMapping("/delete/{id}")
    public R deleteBanner(@PathVariable("id") String id)
    {
        crmBannerService.removeById(id);
        return R.ok();
    }


}
  1. 前台显示banner接口的编写
    controller层
@RestController
@RequestMapping("/educms/bannerfront")
@CrossOrigin
public class BannerFrontController {

    @Autowired
    private CrmBannerService bannerService;

    //查询所有banner
    @GetMapping("/getAllBanner")
    public R getAllBanner()
    {
        List<CrmBanner> list= bannerService.selectAllBanner();
        return R.ok().data("list",list);
    }

}

service层的编写

@Service
public class CrmBannerServiceImpl extends ServiceImpl<CrmBannerMapper, CrmBanner> implements CrmBannerService {

    @Override
    public List<CrmBanner> selectAllBanner() {
        List<CrmBanner> list = baseMapper.selectList(null);
        return list;
    }
}

1.4.2 热门课程和名师的编写

在service_edu的module下在controller层创建一个名为IndexFrontController的controller,实现热门课程和名师的查询
创建一个IndexFrontController类

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

    @Autowired
    private EduCourseService eduCourseService;

    @Autowired
    private EduTeacherService eduTeacherService;

    @GetMapping("/index")
    public R index()
    {
        //查询前八门热门课程
        List<EduCourse> courseList =eduCourseService.getFrontClass();
        //查询前四名讲师
        List<EduTeacher> teacherList= eduTeacherService.getFrontTeacher();
        return R.ok().data("courseList",courseList).data("teacherList",teacherList);
    }
}

service实现
EduCourseServiceImpl

//查询前八门热门课程
    @Override
    public List<EduCourse> getFrontClass() {
        QueryWrapper<EduCourse> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("id");
        wrapper.last("limit 8");
        List<EduCourse> list = baseMapper.selectList(wrapper);
        return list;
    }

EduTeacherServiceImpl

@Service
public class EduTeacherServiceImpl extends ServiceImpl<EduTeacherMapper, EduTeacher> implements EduTeacherService {

    @Override
    public List<EduTeacher> getFrontTeacher() {
        QueryWrapper<EduTeacher> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("id");
        wrapper.last("limit 4");
        List<EduTeacher> list = baseMapper.selectList(wrapper);
        return list;
    }
}

2.首页数据banner显示(前端)

2.1前端页面准备工作

  1. 使用命令下载axios依赖npm install axios
  2. 封装axios
    创建一个utils文件夹,文件夹下面创建request.sj
    尚硅谷在线教育十:首页数据显示
    request.js里面的代码
import axios from 'axios'

//创建axios实例
const service = axios.create({
    baseURL: 'http://localhost:9001',//api的base_url
    timeout:20000 //请求超时时间
})
export default service

2.2首页banner数据显示

  1. 创建aip文件夹,在api文件夹创建js文件,定义调用接口的路径
    尚硅谷在线教育十:首页数据显示
    banner.js
import request from '@/utils/request.js'

export default{
    //查询前两条banner数据
    getListBanner(){
        return request({
            url: '/educms/bannerfront/getAllBanner',
            method: 'GET'
        })
    }
}
  1. 在页面调用接口得到数据进行显示
    在pages/index.vue中进行调用
    创建bannerList数组
    尚硅谷在线教育十:首页数据显示
    banner数据的调用
created(){
          //调用查询banner的方法
          this.getBannerList()
  },
  methods:{
      //查询banner数据
     getBannerList()
     {
       banner.getListBanner()
       .then(response => {
         this.bannerList=response.data.data.list
       })
     }     
  }
  1. 轮播图数据的改变
    轮播图数据改成后台传过来的数据
    <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>
  1. nginx路由的配置
    加上后台接口的地址转发
    尚硅谷在线教育十:首页数据显示

2.3热门课程和名师的显示

  1. 添加路由
    在api文件夹下建一个名为index.js的文件
import request from '@/utils/request.js'

export default{
    //查询热门课程和名师
    getIndexData(){
        return request({
            url: '/eduservice/indexfront/index',
            method: 'GET'
        })
    }
    
}    
  1. 在页面调用接口得到数据进行显示
    在pages/index.vue中进行调用
    创建eduList数组和teacherList数组
    尚硅谷在线教育十:首页数据显示
    访问接口
 //获得热门课程和名师
     getHotCourseTeacher()
     {
       index.getIndexData()
       .then(response=>{
         this.eduList=response.data.data.courseList
         this.teacherList=response.data.data.teacherList
       })
     }  
  1. 热门课程和名师循环数组显示
//热门课程
 <ul class="of" id="bna">
                <li v-for="course in eduList" :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">{{course.buyCount}}人学习</i>
                        |
                        <i class="c-999 f-fA">{{course.viewCount}}评论</i>
                      </span>
                    </section>
                  </div>
                </li>
              </ul>
//名师
<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>

3.首页数据加redis

3.1redis特点

  1. 基于key-value进行存储
  2. 支持多种数据结构:string(字符串),list(列表),hash(哈希),set(集合),zset(有序集合)
  3. 支持持久化,通过内存进行存储,也可以存到硬盘里面
  4. 支持过期时间,支持事务
    一般来讲,把经常经常查询,不经常修改,不是特别重要是数据放到redis作为缓存

3.2 项目集成redis

  1. 在common的pom中引入依赖
 <!-- 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>
  1. 在service_base中加入redis的配置信息
    放在com.atguigu.servicebase包下面
    创建一个RedisConfig类
@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))
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
                .disableCachingNullValues();
        RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
                .cacheDefaults(config)
                .build();
        return cacheManager;
    }
}

3.3 在接口中添加redis缓存

由于首页中数据变化不是很频繁,而且首页访问量较大,所有我们有必要把首页接口的数据缓存到redis缓存中,减少数据库的压力和提高访问速度
改造service-cms莫快递首页banner接口

3.3.1 redis在Spring Boot缓存注解

  1. 缓存@Cacheable
    根据方法对其返回结果进行缓存,下次请求时,如果缓存存在,则直接读取缓存数据返回;如果缓存不存在,则执行方法,并把返回的结果存入缓存中。一般用在查询方法上。查看源码,属性值如下:
    尚硅谷在线教育十:首页数据显示

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

尚硅谷在线教育十:首页数据显示

(3)缓存@CacheEvict
使用该注解标志的方法,会清空指定的缓存。一般用在更新或者删除方法上
查看源码,属性值如下:
尚硅谷在线教育十:首页数据显示
在application.properties中添加redis配置

spring.redis.host=localhost
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.lettuce.pool.max-idle=5
spring.redis.lettuce.pool.min-idle=0

Redis添加
在CrmBannerServiceImpl接口中添加redis

@Service
public class CrmBannerServiceImpl extends ServiceImpl<CrmBannerMapper, CrmBanner> implements CrmBannerService {

    @Cacheable(value = "banner",key = "'selectIndexList'")
    @Override
    public List<CrmBanner> selectAllBanner() {
        //根据id降序排序查询前两条数据
        QueryWrapper<CrmBanner> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("id");
        //用last方法实现SQL语句的拼接
        queryWrapper.last("limit 2");
        List<CrmBanner> list = baseMapper.selectList(queryWrapper);
        return list;
    }
}
上一篇:Visual Studio 集成开发工具学习(2)Visual Studio 2008快捷键大全


下一篇:springboot入门