• 医院项目-预约挂号-第三部分


    数据字典:

    何为数据字典?数据字典就是管理系统常用的分类数据或者一些固定数据,例如:省市区三级联动数据、民族数据、行业数据、学历数据等,由于该系统大量使用这种数据,所以我们要做一个数据管理方便管理系统数据,一般系统基本都会做数据管理。

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    数据字典的表:

    
    CREATE TABLE `dict` (
      `id` bigint(20) NOT NULL DEFAULT '0' COMMENT 'id',
      `parent_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '上级id',
      `name` varchar(100) NOT NULL DEFAULT '' COMMENT '名称',
      `value` bigint(20) DEFAULT NULL COMMENT '值',
      `dict_code` varchar(20) DEFAULT NULL COMMENT '编码',
      `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
      `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
      `is_deleted` tinyint(3) NOT NULL DEFAULT '1' COMMENT '删除标记(0:不可用 1:可用)',
      PRIMARY KEY (`id`),
      KEY `idx_dict_code` (`dict_code`),
      KEY `idx_parent_id` (`parent_id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='组织架构表';
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    表中的数据:

    太多了,自己资料中复制
    
    • 1

    在这里插入图片描述

    数据字典列表接口:

    1,搭建service-cmn模块

    创建新模块;

    在这里插入图片描述

    在这里插入图片描述

    依赖:不修改

    在这里插入图片描述

    添加配置文件application.properties,复制一个hosp的修改端口和spring.application.name

    # 服务端口
    server.port=8202
    # 服务名
    spring.application.name=service-cmn
    
    # 环境设置:dev、test、prod
    spring.profiles.active=dev
    
    # mysql数据库连接
    spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
    spring.datasource.url=jdbc:mysql://127.0.0.1:3306/yygh_cmn?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false&serverTimezone=UTC
    spring.datasource.username=root
    spring.datasource.password=root
    
    
    # springboot2.6.9等高版本继承swagger需要增加这个配置
    #spring.mvc.pathmatch.matching-strategy=ant_path_matcher
    
    #返回json的全局时间格式
    spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
    spring.jackson.time-zone=GMT+8
    
    #spring.data.mongodb.uri=mongodb://192.168.44.165:27017/yygh_hosp
    
    # nacos服务地址
    #spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
    
    #rabbitmq地址
    #spring.rabbitmq.host=192.168.44.165
    #spring.rabbitmq.port=5672
    #spring.rabbitmq.username=guest
    #spring.rabbitmq.password=guest
    
    #配置mapper xml文件的路径
    #mybatis-plus.mapper-locations=classpath:com/atguigu/yygh/mapper/xml/*.xml
    #mybatis-plus.mapper-locations=classpath:com/atguigu/yygh/mapper/xml/*.xml
    # nacos服务地址
    #spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
    
    #开启sentinel
    #feign.sentinel.enabled=true
    #设置sentinel地址
    #spring.cloud.sentinel.transport.dashboard=http://127.0.0.1:8858
    
    #mongodb地址
    #spring.data.mongodb.host=192.168.44.163
    #spring.data.mongodb.port=27017
    #spring.data.mongodb.database=yygh_hosp
    
    #rabbitmq地址
    #spring.rabbitmq.host=127.0.0.1
    #spring.rabbitmq.port=5672
    #spring.rabbitmq.username=guest
    #spring.rabbitmq.password=guest
    
    #logging.level.root=DEBUG
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    创建包:

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    启动类:

    package com.fan.yygh.cmn;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.context.annotation.ComponentScan;
    
    @SpringBootApplication
    @ComponentScan(basePackages = "com.fan")
    public class ServiceCmnApplication {
        public static void main(String[] args) {
            SpringApplication.run(ServiceCmnApplication.class,args);
        }
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    构建项目包:

    在这里插入图片描述

    配置类:

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    service接口:

    DictService中有一个泛型别忘记修改

    在这里插入图片描述

    在这里插入图片描述

    添加数据字典controller:

    在这里插入图片描述

    在这里插入图片描述

    为了配合这个ui层级关系;

    在这里插入图片描述

    在这里插入图片描述

    controller:

    package com.fan.yygh.cmn.controller;
    
    import com.fan.yygh.cmn.service.DictService;
    import com.fan.yygh.common.result.Result;
    import com.fan.yygh.model.cmn.Dict;
    import io.swagger.annotations.Api;
    import io.swagger.annotations.ApiOperation;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.*;
    
    import javax.annotation.Resource;
    import java.util.List;
    
    @RestController
    @Api(value = "数据字典接口")
    @CrossOrigin
    @RequestMapping("/admin/cmn/dict")
    public class DictController {
    
        @Resource
        private DictService dictService;
        //
        @ApiOperation("根据数据id查询子数据列表")
        @GetMapping("findChildData/{id}")
        public Result findChildData(@PathVariable long id){
            List list = dictService.findChildData(id);
            return Result.ok(list);
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    package com.fan.yygh.cmn.service.impl;
    
    import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
    import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
    import com.fan.yygh.cmn.mapper.DictMapper;
    import com.fan.yygh.cmn.service.DictService;
    import com.fan.yygh.model.cmn.Dict;
    import org.springframework.stereotype.Service;
    
    import java.util.List;
    @Service
    public class DictServiceImpl extends ServiceImpl implements DictService {
        @Override
        public List findChildData(long id) {
            QueryWrapper wrapper = new QueryWrapper<>();
            //即条件是parent_id==id,即字典的父级id等于参数id时,返回那些数据
            wrapper.eq("parent_id",id);
            List dictList = baseMapper.selectList(wrapper);
            //向list集合每个dict对象中设置hasChildren字段值
            for (Dict dict : dictList) {
                Long dictId = dict.getId();//查出每个二级字典自己的主id
                boolean isChild = this.isChildren(dictId);
                dict.setHasChildren(isChild);
            }
            return dictList;
        }
    
        //判断id下面是否有子节点
        private boolean isChildren(Long id){
            QueryWrapper queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("parent_id",id);
            Integer count = baseMapper.selectCount(queryWrapper);
            return count>0;
        }
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    在这里插入图片描述

    数据字典列表前端:

    漏由设置:

    在这里插入图片描述

      /* 数据字典的漏由 */
      {
        path: '/cmn',
        component: Layout,
        redirect: '/cmn/list',
        name: '数据字典管理',
        alwaysShow:true, //总是显示
        meta: { title: '数据字典管理', icon: 'example' },
        children: [
          {
            path: 'list',
            name: '数据字典列表',
            component: () => import('@/views/dict/list'),
            meta: { title: '数据字典列表', icon: 'table' }
          }
        
        ]
      },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    views创建:

    在这里插入图片描述

    接口定义:dict.js

    import request from  '@/utils/request'
    
    //定义接口路径的
    
    export default {
      //数据字典列表
      dictList(id) {
       return request ({
         url: `/admin/cmn/dict/findChildData/${id}`,
         method: 'get'
       })
     }
    
     
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    在这里插入图片描述

    页面调用:

    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67

    在这里插入图片描述

    在这里插入图片描述

    将这的接口临时改成8202:
    在这里插入图片描述

    修改完端口号后,重启前端,查看:

    由于前一个cmd终端没关掉,直接开启新的,9528端口被占用了:
    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    换成高版本进行数据字典的下拉显示:

    在这里插入图片描述

    然后 npm install 从新下载依赖,并npm run dev ,测试:

    在这里插入图片描述

    lazy属性是我们点下拉按钮的时候才进行查询后台

    在这里插入图片描述

    3、EasyExcel介绍

    Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,但POI还是有一些缺陷,比如07版Excel解压缩以及解压后存储都是在内存中完成的,内存消耗依然很大。easyexcel重写了poi对07版Excel的解析,能够原本一个3M的excel用POI sax依然需要100M左右内存降低到几M,并且再大的excel不会出现内存溢出,03版依赖POI的sax模式。在上层做了模型转换的封装,让使用者更加简单方便。
    EasyExcel是一个基于Java的简单、省内存的读写Excel的开源项目。在尽可能节约内存的情况下支持读写百M的Excel。

    文档地址:https://alibaba-easyexcel.github.io/index.html
    github地址:https://github.com/alibaba/easyexcel

    1,添加依赖,将依赖放到cmn模块中:

    
        
        
            com.alibaba
            easyexcel
            2.1.1
        
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2.创建包和实体类:

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    测试:

    在这里插入图片描述

    package com.fan.easyexcel;
    
    import com.alibaba.excel.EasyExcel;
    
    import java.util.ArrayList;
    
    public class TestWriter {
        public static void main(String[] args) {
            ArrayList list = new ArrayList<>();
            for (int i = 0; i < 10; i++) {
                UserDate userDate = new UserDate();
                userDate.setUid(i);
                userDate.setUsername("tom"+i);
                list.add(userDate);
            }
            //设置excel文件路径和文件名称
            String fileName = "F:\\excel\\01.xlsx";
            //调用方法实现写操作
            EasyExcel.write(fileName,UserDate.class).sheet("用户信息")
                    .doWrite(list);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    启动项目测试:运行main方法进行测试:

    在这里插入图片描述

    注意了:刚才写入操作中高版本jdk可能会报错导致数据加载不到xlsx中 换成低版本的就可以了

    读操作:

    在这里插入图片描述

    创建监听器:

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    package com.fan.easyexcel;
    
    import com.alibaba.excel.context.AnalysisContext;
    import com.alibaba.excel.event.AnalysisEventListener;
    import com.alibaba.excel.metadata.CellData;
    import com.alibaba.excel.util.ConverterUtils;
    
    import java.util.Map;
    
    public class ExcelListener extends AnalysisEventListener {
        @Override
        public void invoke(UserDate userDate, AnalysisContext analysisContext) {
            System.out.println(userDate);
        }
    
        @Override
        public void invokeHeadMap(Map headMap, AnalysisContext context) {
            System.out.println("表头信息:"+headMap);
        }
    
    
        @Override
        public void doAfterAllAnalysed(AnalysisContext analysisContext) {
    
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    测试类:

    package com.fan.easyexcel;
    
    import com.alibaba.excel.EasyExcel;
    
    public class TestRead {
        public static void main(String[] args) {
            String fileName = "F:\\excel\\01.xlsx";
            EasyExcel.read(fileName,UserDate.class,new ExcelListener())
            .sheet().doRead();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在这里插入图片描述

    在这里插入图片描述

    和项目的集成实操:

    在model模块添加导出实体:
    在model模块查看实体:com.atguigu.yygh.vo.cmn.DictEeVo

    然后:

    controller:

    //导出数据字典接口
        @GetMapping("exportData")
        public Result exportDict(HttpServletResponse response){
            dictService.exportDictData(response);
            return Result.ok();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述

    在这里插入图片描述

    实现类DictServiceImpl:

        @Override //导出字典的接口
        public void exportDictData(HttpServletResponse response) {
            //设置下载信息
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
    
            // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
            String fileName = null;
            try {
                fileName = URLEncoder.encode("dict", "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            response.setHeader("Content-disposition", "attachment;filename="+ fileName + ".xlsx");
    
            List dictList = baseMapper.selectList(null);
            //Dict-->DictEevo
            ArrayList dictVoList = new ArrayList<>();
            for (Dict dict : dictList) {
                DictEeVo dictEeVo = new DictEeVo();
                BeanUtils.copyProperties(dict,dictEeVo);
                dictVoList.add(dictEeVo);
            }
            //调用方法进行写操作
            try {
                EasyExcel.write(response.getOutputStream(),DictEeVo.class)
                        .sheet("dict")
                        .doWrite(dictVoList);
            } catch (IOException e) {
                e.printStackTrace();
            }
    
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    前端:

    列表页面添加导出按钮
    src/views/cmn/dict/list.vue

    在这里插入图片描述

    导出按钮标签:

           
            
    导出
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    js添加导出方法:

    exportData() {
    	window.location.href = 'http://localhost:8202/admin/cmn/dict/exportData'
    }
    
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    测试:谷歌自动连接到迅雷下载了:

    在这里插入图片描述

    查看下载的内容:
    在这里插入图片描述

    点击之后直接下载没有弹窗提示下载路径的,和浏览器设置有关,默认下载到浏览器下载地址

    改造下载页面:

    在这里插入图片描述

    直接下载是和浏览器有关, 在设置里面有个:下载前询问每个文件的保存位置,选上就会有弹框了

    导入数据字典的controller:

    //导入数据字典的controller
        @PostMapping("importData")
        public Result importDict(MultipartFile file){
            dictService.importDictData(file);
            return Result.ok();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述

    在这里插入图片描述

    监听器:

    在这里插入图片描述

    在这里插入图片描述

    spring构造器注入、还可以setting注入

    在这里插入图片描述

    实现类DictServiceImpl中:

      @Override//导入数据字典的controller
        public void importDictData(MultipartFile file) {
            try {
                EasyExcel.read(file.getInputStream(),DictEeVo.class,new DictListener(baseMapper))
                        .sheet().doRead();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述

    前端:

    列表页面添加导入按钮,说明:按钮位置与导出并列

    src/views/cmn/dict/list.vue
     导入
    
    • 1
    • 2

    在这里插入图片描述

    在这里插入图片描述
    添加导入弹出层:

                    
                    
                        
    
                        
                        
                        点击上传
                        
    只能上传xls文件,且不超过500kb
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    dialog:
    在这里插入图片描述

    添加弹出可见模型:

    // 定义数据
    data() {
    return {
    	list: [],
    	listLoading: true,
    	dialogImportVisible: false  //设置弹框是否弹出
    }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    测试:

    id 上级id 名称 值 编码
    100 1 电脑 100 cc
    1001 100 华为电脑 1001 huawei

    在这里插入图片描述

    在这里插入图片描述

    页面测试:重启后台:

    看数据库:已经上传上去;将逻辑删除改成0看页面显示不:

    在这里插入图片描述

    在这里插入图片描述

    Spring Cache + Redis 缓存数据:

    缓存:

    Spring Cache 是一个非常优秀的缓存组件。自Spring 3.1起,提供了类似于@Transactional注解事务的注解Cache支持,且提供了Cache抽象,方便切换各种底层Cache(如:redis)

    使用Spring Cache的好处:
    1,提供基本的Cache抽象,方便切换各种底层Cache;
    2,通过注解Cache可以实现类似于事务一样,缓存逻辑透明的应用到我们的业务代码上,且只需要更少的代码就可以完成;
    3,提供事务回滚时也自动回滚缓存;
    4,支持比较复杂的缓存逻辑;

    项目集成Spring Cache + Redis

    因为缓存也是公共使用,所有的service模块都有可能使用缓存,所以我们把依赖与部分配置加在service-util模块,这样其他service模块都可以使用了

    1.1service-util添加依赖
    在service-util模块的pom.xml添加依赖

    
    
    org.springframework.boot
    spring-boot-starter-data-redis
    
    
    
    
    org.apache.commons
    commons-pool2
    2.6.0
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    1.2 service-util添加配置类

    在这里插入图片描述

    创建com.atguigu.yygh.common.config.RedisConfig

    package com.fan.yygh.common.config;
    
    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.EnableCaching;
    import org.springframework.cache.interceptor.KeyGenerator;
    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.lang.reflect.Method;
    import java.time.Duration;
    
    @Configuration
    @EnableCaching //开启缓存
    public class RedisConfig {
        /**
         * 自定义key规则
         * @return
         */
        @Bean
        public KeyGenerator keyGenerator() {
            return new KeyGenerator() {
                @Override
                public Object generate(Object target, Method method, Object... params) {
                    StringBuilder sb = new StringBuilder();
                    sb.append(target.getClass().getName());
                    sb.append(method.getName());
                    for (Object obj : params) {
                        sb.append(obj.toString());
                    }
                    return sb.toString();
                }
            };
        }
    
        /**
         * 设置RedisTemplate规则
         * @param redisConnectionFactory
         * @return
         */
        @Bean
        public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
            RedisTemplate redisTemplate = new RedisTemplate<>();
            redisTemplate.setConnectionFactory(redisConnectionFactory);
            Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
    
    //解决查询缓存转换异常的问题
            ObjectMapper om = new ObjectMapper();
    // 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public
            om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
    // 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会跑出异常
            om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
            jackson2JsonRedisSerializer.setObjectMapper(om);
    
    //序列号key value
            redisTemplate.setKeySerializer(new StringRedisSerializer());
            redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
            redisTemplate.setHashKeySerializer(new StringRedisSerializer());
            redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
    
            redisTemplate.afterPropertiesSet();
            return redisTemplate;
        }
    
        /**
         * 设置CacheManager缓存规则
         * @param factory
         * @return
         */
        @Bean
        public CacheManager cacheManager(RedisConnectionFactory factory) {
            RedisSerializer 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;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104

    说明:
    @EnableCaching:标记注解 @EnableCaching,开启缓存,并配置Redis缓存管理器。@EnableCaching 注释触发后置处理器, 检查每一个Spring bean 的 public 方法是否存在缓存注解。如果找到这样的一个注释, 自动创建一个代理拦截方法调用和处理相应的缓存行为

    1.3service-cmn添加redis配置

    spring.redis.host=192.168.44.165
    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    常用缓存标签

    2.1.2 缓存@Cacheable

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

    属性/方法名解释
    value缓存名,必填,它指定了你的缓存存放在哪块命名空间
    cacheNames与 value 差不多,二选一即可
    key可选属性,可以使用 SpEL 标签自定义缓存的key

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

    属性/方法名解释
    value缓存名,必填,它指定了你的缓存存放在哪块命名空间
    cacheNames与 value 差不多,二选一即可
    key可选属性,可以使用 SpEL 标签自定义缓存的key

    2.1.3 缓存@CacheEvict

    evict 逐出,赶出,收回,清空

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

    属性/方法名解释
    value缓存名,必填,它指定了你的缓存存放在哪块命名空间
    cacheNames与 value 差不多,二选一即可
    key可选属性,可以使用 SpEL 标签自定义缓存的key
    allEntries是否清空所有缓存,默认为 false。如果指定为 true,则方法调用后将立即清空所有的缓存
    beforeInvocation是否在方法执行前就清空,默认为 false。如果指定为 true,则在方法执行前就会清空缓存

    修改impl:

    查询需要的注解:
    @Cacheable(value = “dict”,keyGenerator = “keyGenerator”)
    导入需要的注解:
    @CacheEvict(value = “dict”, allEntries=true)

    在这里插入图片描述

    value: 缓存管理器中配置的缓存的名称,这里可以理解为一个组的概念,缓存管理器中可以有多套缓存配置,每套都有一个名称,类似于组名,这个可以配置这个值,选择使用哪个缓存的名称,配置后就会应用那个缓存名称对应的配置。

    下面介绍一下 @Cacheable 这个注解常用的几个属性:

    cacheNames/value :用来指定缓存组件的名字

    key :缓存数据时使用的 key,可以用它来指定。默认是使用方法参数的值。(这个 key 你可以使用 spEL 表达式来编写)

    keyGenerator :key 的生成器。 key 和 keyGenerator 二选一使用

    cacheManager :可以用来指定缓存管理器。从哪个缓存管理器里面获取缓存。

    condition :可以用来指定符合条件的情况下才缓存

    unless :否定缓存。当 unless 指定的条件为 true ,方法的返回值就不会被缓存。当然你也可以获取到结果进行判断。(通过 #result 获取方法结果)

    sync :是否使用异步模式。

    ① cacheNames

    用来指定缓存组件的名字,将方法的返回结果放在哪个缓存中,可以是数组的方式,支持指定多个缓存。

    在这里插入图片描述

    新增:

    在这里插入图片描述

    启动后端和redis:测试:

    在这里插入图片描述

    前端页面查询后:

    在这里插入图片描述

    在这里插入图片描述

    获取此key 对应的value:

    在这里插入图片描述

    nginx配置不同的访问端口:

    在这里插入图片描述

    为了简单化,使用windows的nginx:

    下载到本地解压:

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    启动:nginx

    注意:启动报错的话,把nginx文件夹单独放出来到根目录。重新启动;

    在这里插入图片描述
    ‘’
    修改:
    在这里插入图片描述

    测试:

    在这里插入图片描述

  • 相关阅读:
    【Linux】自动化构建工具:make/Makefile
    JAVA--AI编程助手【代码智能补全工具】盘点,让AI提高你的编程效率
    46LVS+Keepalived群集
    26.ELK.针对‘ES中索引创建迟缓’问题优化
    【升职加薪秘籍】我在服务监控方面的实践(5)-应用监控
    艾美捷藻红蛋白RPE背景及参数说明书
    性能优化之分页查询 | StartDT Tech Lab 12
    使用nginx搭建creates.io镜像
    企业电子招标采购系统源码Spring Boot + Mybatis + Redis + Layui + 前后端分离 构建企业电子招采平台之立项流程图
    特征解耦,torch.cumprod(),np.random.seed(),plt.scatter
  • 原文地址:https://blog.csdn.net/weixin_38568503/article/details/126085610