在线教育业务笔记03- 讲师banner(轮播图)管理模块
一、新建banner微服务
1、在service模块下创建子模块service-cms

2、使用代码生成器生成banner代码
2.1、sql文件阿里云地址
https://cor2022314.oss-cn-beijing.aliyuncs.com/guli_cms.sql
2.2、MyBatis-Plus代码生成器

package codedemo;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import org.junit.Test;
/**
* @author Tzc
*/
public class CodeGenerator {
@Test
public void run() {
// 1、创建代码生成器
AutoGenerator mpg = new AutoGenerator();
// 2、全局配置
GlobalConfig gc = new GlobalConfig();
String projectPath = System.getProperty("user.dir");
gc.setOutputDir("E:\\work\\guli_parent\\service\\service_cms" + "/src/main/java");
gc.setAuthor("Tzc");
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("root");
dsc.setDbType(DbType.MYSQL);
mpg.setDataSource(dsc);
// 4、包配置
PackageConfig pc = new PackageConfig();
pc.setModuleName("educms"); // 模块名
//包 com.atguigu.eduservice
pc.setParent("com.atguigu");
//包 com.atguigu.eduservice.controller
pc.setController("controller");
pc.setEntity("entity");
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();
}
}
2.3、生成代码
3、配置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/educms/mapper/xml/*.xml
spring.redis.host=192.168.108.3
spring.redis.port=6379
spring.redis.database= 0
spring.redis.timeout=1800000
# nacos服务地址
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
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
#mybatis日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
4、创建启动类

package com.atguigu.educms;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.bind.annotation.CrossOrigin;
/**
* @author Tzc
*/
@CrossOrigin
@SpringBootApplication
@ComponentScan({"com.atguigu"})
@MapperScan("com.atguigu.educms.mapper")
public class CmsApplication {
public static void main(String[] args) {
SpringApplication.run(CmsApplication.class, args);
}
}
二、集成Redis
1、在common公共模块添加依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>guli_parent</artifactId>
<groupId>com.atguigu</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>common</artifactId>
<packaging>pom</packaging>
<modules>
<module>service_base</module>
<module>common_utils</module>
</modules>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<scope>provided</scope>
</dependency>
<!--mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<scope>provided</scope>
</dependency>
<!--lombok用来简化实体类:需要安装lombok插件-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<!--swagger-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<scope>provided</scope>
</dependency>
<!-- redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
</dependencies>
</project>

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>common</artifactId>
<groupId>com.atguigu</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>common_utils</artifactId>
<dependencies>
<!--spring2.X集成redis所需common-pool2-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.6.0</version>
</dependency>
<!-- JWT-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
</dependency>
</dependencies>
</project>
2、在service-base模块添加redis配置类
引入common_utils模块依赖


package com.atguigu.servicebase;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.time.Duration;
/**
* @EnableCaching // 开启缓存
* @Configuration // 配置类
* @author Tzc
*/
@EnableCaching
@Configuration
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、 Spring Boot缓存注解介绍
1、 @Cacheable
根据方法对其返回结果进行缓存(redis),下次请求时,如果缓存存在,则直接读取缓存数据返回;如果缓存不存在,则执行方法,并把返回的结果存入缓存中。一般用在查询方法上。
属性值:
value :缓存名,必填,它指定了你的缓存存放在哪块命名空间
cacheNames: 与 value 差不多,二选一即可
key:可选属性,可以使用 SpEL 标签自定义缓存的key
2、 @CacheEvict
会清空指定的缓存 一般用在更新或者删除方法上
属性值:
value :缓存名,必填,它指定了你的缓存存放在哪块命名空间
cacheNames: 与 value 差不多,二选一即可
key:可选属性,可以使用 SpEL 标签自定义缓存的key
allEntries: 是否清空所有缓存,默认为 false。如果指定为 true,则方法调用后将立即清空所有的缓存
beforeInvocation : 是否在方法执行前就清空,默认为 false。如果指定为 true,则在方法执行前就会清空缓存
3、 @CachePut
使用该注解标志的方法,每次都会执行,并将结果存入指定的缓存中。其他方法可以直接从响应的缓存中读取缓存数据,而不需要再去查询数据库。一般用在新增方法上。
属性值:
value :缓存名,必填,它指定了你的缓存存放在哪块命名空间
cacheNames: 与 value 差不多,二选一即可
key:可选属性,可以使用 SpEL 标签自定义缓存的key
4、启动redis服务

三、banner Api接口
1、后台管理Controller

package com.atguigu.educms.controller;
import com.atguigu.commonutils.R;
import com.atguigu.educms.entity.CrmBanner;
import com.atguigu.educms.service.CrmBannerService;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.*;
/**
* 后台banner管理接口
* @author Tzc
*/
@RestController
@RequestMapping("/educms/banneradmin")
@CrossOrigin
public class BannerAdminController {
@Autowired
private CrmBannerService bannerService;
/**
* 分页查询banner
* @param page 当前页码
* @param limit 每页记录数
* @return items
*/
@ApiOperation(value = "获取Banner分页列表")
@GetMapping("pageBanner/{page}/{limit}")
public R pageBanner(@ApiParam(name = "page", value = "当前页码", required = true)
@PathVariable Long page,
@ApiParam(name = "limit", value = "每页记录数", required = true)
@PathVariable Long limit) {
Page<CrmBanner> pageBanner = new Page<>(page, limit);
bannerService.page(pageBanner, null);
return R.ok().data("items", pageBanner.getRecords()).data("total", pageBanner.getTotal());
}
/**
* 添加banner
* @param crmBanner
* @return
*/
@ApiOperation(value = "修改Banner")
@PostMapping("addBanner")
public R addBanner(@RequestBody CrmBanner crmBanner) {
bannerService.save(crmBanner);
return R.ok();
}
/**
* 根据id获取Banner
* @param id
* @return
*/
@ApiOperation(value = "根据id获取Banner")
@GetMapping("get/{id}")
public R get(@PathVariable String id) {
CrmBanner banner = bannerService.getById(id);
return R.ok().data("item", banner);
}
/**
* 修改Banner
* @param banner
* @return
*/
@ApiOperation(value = "修改Banner")
@PutMapping("update")
public R updateById(@RequestBody CrmBanner banner) {
bannerService.updateById(banner);
return R.ok();
}
/**
* 删除Banner
* @param id
* @return
*/
@ApiOperation(value = "删除Banner")
@DeleteMapping("remove/{id}")
public R remove(@PathVariable String id) {
bannerService.removeById(id);
return R.ok();
}
}
2、前台页面显示接口
2.1、Controller

package com.atguigu.educms.controller;
import com.atguigu.commonutils.R;
import com.atguigu.educms.entity.CrmBanner;
import com.atguigu.educms.service.CrmBannerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* 前台bannber显示
* @author Tzc
*/
@RestController
@RequestMapping("/educms/bannerfront")
@CrossOrigin
public class BannerFrontController {
@Autowired
private CrmBannerService bannerService;
/**
* 查询所有banner
* @return
*/
@GetMapping("getAllBanner")
public R getAllBanner() {
List<CrmBanner> list = bannerService.selectAllBanner();
return R.ok().data("list", list);
}
}
2.2、Service

2.2.1、接口
package com.atguigu.educms.service;
import com.atguigu.educms.entity.CrmBanner;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* 首页banner表 服务类
*
* @author Tzc
*/
public interface CrmBannerService extends IService<CrmBanner> {
/**
* 查询所有banner
* @return
*/
List<CrmBanner> selectAllBanner();
/**
* 根据ID查询 banner
* @param id
* @return
*/
public CrmBanner getBannerById(String id);
/**
* 添加banner
* @param banner
*/
public void saveBanner(CrmBanner banner);
/**
* 修改banner
* @param banner
*/
public void updateBannerById(CrmBanner banner);
/**
* 根据 ID 删除banner
* @param id
*/
public void removeBannerById(String id);
}
2.2.1、实现类
package com.atguigu.educms.service.impl;
import com.atguigu.educms.entity.CrmBanner;
import com.atguigu.educms.mapper.CrmBannerMapper;
import com.atguigu.educms.service.CrmBannerService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 首页banner表 服务实现类
* @author Tzc
*/
@Service
public class CrmBannerServiceImpl extends ServiceImpl<CrmBannerMapper, CrmBanner> implements CrmBannerService {
/**
* @Cacheable(value = "banner",key = "'selectIndexList'")
* value 缓存名 必填,它指定了你的缓存存放在哪块命名空间
* key 可选属性 可以使用 SpEL 标签自定义缓存的key
* cacheNames 与 value 差不多,二选一即可
* 查询所有banner
* @return list
*/
@Cacheable(value = "banner",key = "'selectIndexList'")
@Override
public List<CrmBanner> selectAllBanner() {
// 根据id进行降序排列,显示排列之后前两条记录
QueryWrapper<CrmBanner> wrapper = new QueryWrapper<>();
// 根据id降序排列
wrapper.orderByDesc("id");
// last方法,拼接sql语句
wrapper.last("limit 2");
List<CrmBanner> list = baseMapper.selectList(null);
return list;
}
@Override
public CrmBanner getBannerById(String id) {
return baseMapper.selectById(id);
}
@CachePut(value = "banner")
@Override
public void saveBanner(CrmBanner banner) {
baseMapper.insert(banner);
}
@CacheEvict(value = "banner", allEntries=true)
@Override
public void updateBannerById(CrmBanner banner) {
baseMapper.updateById(banner);
}
@CacheEvict(value = "banner", allEntries=true)
@Override
public void removeBannerById(String id) {
baseMapper.deleteById(id);
}
}
四、前端页面显示
1、创建banner.js文件调用后端方法

import request from '@/utils/request'
export default {
// 查询前两条banner数据
getListBanner() {
return request({
url: '/educms/bannerfront/getAllBanner',
method: 'get'
})
}
}
2、在首页面引入banner.js文件,得到数据
<script>
import banner from '@/api/banner'
export default {
data () {
return {
swiperOption: {
// 配置分页
pagination: {
el: '.swiper-pagination'//分页的dom节点
},
// 配置导航
navigation: {
nextEl: '.swiper-button-next',//下一页dom节点
prevEl: '.swiper-button-prev'//前一页dom节点
}
},
// banner数组 用于存储数据
bannerList:[]
}
},
created() {
// 调用查询banner的方法
this.getBannerList()
},
methods:{
// 查询banner数据
getBannerList() {
banner.getListBanner()
.then(response => {
this.bannerList = response.data.data.list
})
}
}
}
</script
3、页面遍历 bannerList:[] 显示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>
本文记录了在线教育业务中讲师banner管理模块的开发过程,包括新建banner微服务,集成Redis以实现缓存功能,详细介绍了Spring Boot的@Cacheable、@CacheEvict和@CachePut注解的使用,并阐述了前端如何调用API接口显示轮播图。

3547

被折叠的 条评论
为什么被折叠?



