SpringBoot--中间件技术-2:整合redis,redis实战小案例,springboot cache,cache简化redis的实现,含代码

SpringBoot整合Redis

实现步骤

  1. 导pom文件坐标

    xml 复制代码
    <!--redis依赖-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
  2. yaml主配置文件,配置redis端口号

    yaml 复制代码
    spring:
      redis:
        host: localhost
        port: 6379
  3. 测试类

    字符串专用类:StringRedisTemplate stringRedisTemplate

    java 复制代码
    @Autowired
    public RedisTemplate redisTemplate;
    @Test
    public void stringTest(){
        // 各种类型支持
        stringRedisTemplate.opsForValue();
        stringRedisTemplate.opsForList();
        stringRedisTemplate.opsForSet();
        stringRedisTemplate.opsForHash();
        stringRedisTemplate.opsForZSet();
    
        // 字符串
        stringRedisTemplate.opsForValue().set("teacher","刘老板");
        String teacher = stringRedisTemplate.opsForValue().get("teacher");
        System.out.println("stringRedisTemplate输出结果"+teacher);
    
        // 操作list列表
        stringRedisTemplate.opsForList().leftPush("tang","李白");
        stringRedisTemplate.opsForList().leftPush("tang","杜甫");
    
        stringRedisTemplate.opsForList().leftPushAll("songAll","欧阳修","苏轼","苏辙");
        List<String> songAll = stringRedisTemplate.opsForList().range("songAll", 0, 2);
        songAll.forEach(System.out::println);
    
    }

    对象专用类:RedisTemplate redisTemplate

    java 复制代码
    @Autowired(required = false)
    public RedisTemplate redisTemplate;
    @Test
    public void redisTemplate(){
        // 各种类型支持
        redisTemplate.opsForValue();
        redisTemplate.opsForList();
        redisTemplate.opsForSet();
        redisTemplate.opsForHash();
        redisTemplate.opsForZSet();
    
        ValueOperations valueOperations = redisTemplate.opsForValue();
        valueOperations.set("panda","花花");
        String panda = (String) valueOperations.get("panda");
        System.out.println(panda);
    
        Student student = new Student(1,"惠晨怡","女");
        redisTemplate.opsForValue().set("stu",student);
        Student student1 = (Student) redisTemplate.opsForValue().get("stu");
        System.out.println(student1);
    
        redisTemplate.opsForList().leftPushAll("animal","狗","猫","龙","鼠");
        List animal = redisTemplate.opsForList().range("animal", 0, 3);
        animal.forEach(System.out::println);
    
    }

    在可视化页面中查看对象存入的键和值,看不明白,没有可读性,可以使用自定义类

    自定义类实现步骤:

    pom文件导入fastJson

    xml 复制代码
    <!--fastjson工具包 -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.3</version>
    </dependency>
    
    <dependency>
        <groupId>com.colobu</groupId>
        <artifactId>fastjson-jaxrs-json-provider</artifactId>
        <version>0.3.1</version>
    </dependency>

    添加配置类RedisConfig

    java 复制代码
    @Configuration
    public class RedisConfig {
    
        @Bean
        public RedisTemplate<Object,Object> jsonRedisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
            // 创建自定义模板
            RedisTemplate<Object, Object> template = new RedisTemplate<>();
            //配置json类型的序列化工具
            template.setKeySerializer(new StringRedisSerializer());
            template.setDefaultSerializer(new Jackson2JsonRedisSerializer<Object>(Object.class));
    template.setConnectionFactory(redisConnectionFactory);
            return template;
        }
    }

    测试:装配的redis模板类需要和自定义的同名

    java 复制代码
    @Autowired
    public RedisTemplate jsonRedisTemplate;
    @Test
    public void test03(){
        jsonRedisTemplate.opsForValue();
        jsonRedisTemplate.opsForList();
        jsonRedisTemplate.opsForSet();
        jsonRedisTemplate.opsForHash();
        jsonRedisTemplate.opsForZSet();
    
        Student student1 = new Student(2,"惠晨怡","男");
        Student student2 = new Student(3,"尚恒通","男");
        Student student3 = new Student(4,"李竟坡","男");
    
        ArrayList<Student> students = new ArrayList<>(Arrays.asList(student1,student2,student3));
    
        jsonRedisTemplate.opsForValue().set("stus",students);
        Object stus = jsonRedisTemplate.opsForValue().get("stus");
        String s = JSON.toJSONString(stus);
        List<Student> list = JSONObject.parseArray(s, Student.class);
        list.forEach(System.out::println);
    }

SpringBoot整合Redis实战案例

redis在项目中起到缓存作用,案例演示redis在项目中的实现

  1. 导入pom.xml文件

    springboot版本2.7.14

    xml 复制代码
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    
    <!--mysql-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.29</version>
    </dependency>
    
    <!--mybatis-->
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>2.0.1</version>
    </dependency>
    
    <!--redis-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
  2. yaml配置文件配置数据源和redis

    yaml 复制代码
    # 配置数据源
    spring:
      datasource:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/spring?serverTimezone=GMT
        username: root
        password: 123456
    
      # 配置redis
      redis:
        host: localhost
        port: 6379
    
    mybatis:
      configuration:
        map-underscore-to-camel-case: true

    用到了mybatis,所以配置了一个自动驼峰映射

  3. Redis自定义模板配置类

    java 复制代码
    @Component
    public class RedisConfig {
    
        @Bean
        public RedisTemplate<Object,Object> jsonRedisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
            RedisTemplate<Object, Object> template = new RedisTemplate<>();
            template.setKeySerializer(new StringRedisSerializer());
            template.setDefaultSerializer(new Jackson2JsonRedisSerializer<Object>(Object.class));
            template.setConnectionFactory(redisConnectionFactory);
            return template;
        }
    }
  4. 导入redisUtil工具类,工具栏中封装了大量redis操作代码,一般真实开发环境中都可以看到一个公司自己封装的RedisUtil

    java 复制代码
    @Component
    public  class RedisUtil {
    
        @Autowired(required = false)
        private RedisTemplate jsonRedisTemplate;
    
        // =========================================================
        /**
         * 指定缓存失效时间
         * @param key  键
         * @param time 时间(秒)
         */
        public boolean expire(String key, long time) {
            try {
                if (time > 0) {
                    jsonRedisTemplate.expire(key, time, TimeUnit.SECONDS);
                }
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
    
        /**
         * 根据key 获取过期时间
         * @param key 键 不能为null
         * @return 时间(秒) 返回0代表为永久有效
         */
        public long getExpire(String key) {
            return jsonRedisTemplate.getExpire(key, TimeUnit.SECONDS);
        }
    
    
        /**
         * 判断key是否存在
         * @param key 键
         * @return true 存在 false不存在
         */
        public boolean hasKey(String key) {
            try {
                return jsonRedisTemplate.hasKey(key);
            } catch (Exception e) {
                return false;
            }
        }
    
    
        /**
         * 删除缓存
         * @param key 可以传一个值 或多个
         */
        @SuppressWarnings("unchecked")
        public void del(String... key) {
            if (key != null && key.length > 0) {
                if (key.length == 1) {
                    jsonRedisTemplate.delete(key[0]);
                } else {
                    jsonRedisTemplate.delete(CollectionUtils.arrayToList(key));
                }
            }
        }
    
    
        // ============================String=============================
    
        /**
         * 普通缓存获取
         * @param key 键
         * @return 值
         */
        public Object get(String key) {
            return key == null ? null : jsonRedisTemplate.opsForValue().get(key);
        }
    
        /**
         * 普通缓存放入
         * @param key   键
         * @param value 值
         * @return true成功 false失败
         */
    
        public boolean set(String key, Object value) {
            try {
                jsonRedisTemplate.opsForValue().set(key, value);
                return true;
            } catch (Exception e) {
                return false;
            }
        }
    
    
        /**
         * 普通缓存放入并设置时间
         * @param key   键
         * @param value 值
         * @param time  时间(秒) time要大于0 如果time小于等于0 将设置无限期
         * @return true成功 false 失败
         */
    
        public boolean set(String key, Object value, long time) {
            try {
                if (time > 0) {
                    jsonRedisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
                } else {
                    set(key, value);
                }
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
    
    
        /**
         * 递增
         * @param key   键
         * @param delta 要增加几(大于0)
         */
        public long incr(String key, long delta) {
            if (delta < 0) {
                throw new RuntimeException("递增因子必须大于0");
            }
            return jsonRedisTemplate.opsForValue().increment(key, delta);
        }
    
    
        /**
         * 递减
         * @param key   键
         * @param delta 要减少几(小于0)
         */
        public long decr(String key, long delta) {
            if (delta < 0) {
                throw new RuntimeException("递减因子必须大于0");
            }
            return jsonRedisTemplate.opsForValue().increment(key, -delta);
        }
    
    
        // ================================Map=================================
    
        /**
         * HashGet
         * @param key  键 不能为null
         * @param item 项 不能为null
         */
        public Object hget(String key, String item) {
            return jsonRedisTemplate.opsForHash().get(key, item);
        }
    
        /**
         * 获取hashKey对应的所有键值
         * @param key 键
         * @return 对应的多个键值
         */
        public Map<Object, Object> hmget(String key) {
            return jsonRedisTemplate.opsForHash().entries(key);
        }
    
        /**
         * HashSet
         * @param key 键
         * @param map 对应多个键值
         */
        public boolean hmset(String key, Map<String, Object> map) {
            try {
                jsonRedisTemplate.opsForHash().putAll(key, map);
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
    
    
        /**
         * HashSet 并设置时间
         * @param key  键
         * @param map  对应多个键值
         * @param time 时间(秒)
         * @return true成功 false失败
         */
        public boolean hmset(String key, Map<String, Object> map, long time) {
            try {
                jsonRedisTemplate.opsForHash().putAll(key, map);
                if (time > 0) {
                    expire(key, time);
                }
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
    
    
        /**
         * 向一张hash表中放入数据,如果不存在将创建
         *
         * @param key   键
         * @param item  项
         * @param value 值
         * @return true 成功 false失败
         */
        public boolean hset(String key, String item, Object value) {
            try {
                jsonRedisTemplate.opsForHash().put(key, item, value);
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
    
        /**
         * 向一张hash表中放入数据,如果不存在将创建
         *
         * @param key   键
         * @param item  项
         * @param value 值
         * @param time  时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
         * @return true 成功 false失败
         */
        public boolean hset(String key, String item, Object value, long time) {
            try {
                jsonRedisTemplate.opsForHash().put(key, item, value);
                if (time > 0) {
                    expire(key, time);
                }
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
    
    
        /**
         * 删除hash表中的值
         *
         * @param key  键 不能为null
         * @param item 项 可以使多个 不能为null
         */
        public void hdel(String key, Object... item) {
            jsonRedisTemplate.opsForHash().delete(key, item);
        }
    
    
        /**
         * 判断hash表中是否有该项的值
         *
         * @param key  键 不能为null
         * @param item 项 不能为null
         * @return true 存在 false不存在
         */
        public boolean hHasKey(String key, String item) {
            return jsonRedisTemplate.opsForHash().hasKey(key, item);
        }
    
    
        /**
         * hash递增 如果不存在,就会创建一个 并把新增后的值返回
         *
         * @param key  键
         * @param item 项
         * @param by   要增加几(大于0)
         */
        public double hincr(String key, String item, double by) {
            return jsonRedisTemplate.opsForHash().increment(key, item, by);
        }
    
    
        /**
         * hash递减
         *
         * @param key  键
         * @param item 项
         * @param by   要减少记(小于0)
         */
        public double hdecr(String key, String item, double by) {
            return jsonRedisTemplate.opsForHash().increment(key, item, -by);
        }
    
    
        // ============================set=============================
    
        /**
         * 根据key获取Set中的所有值
         * @param key 键
         */
        public Set<Object> sGet(String key) {
            try {
                return jsonRedisTemplate.opsForSet().members(key);
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
    
    
        /**
         * 根据value从一个set中查询,是否存在
         *
         * @param key   键
         * @param value 值
         * @return true 存在 false不存在
         */
        public boolean sHasKey(String key, Object value) {
            try {
                return jsonRedisTemplate.opsForSet().isMember(key, value);
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
    
    
        /**
         * 将数据放入set缓存
         *
         * @param key    键
         * @param values 值 可以是多个
         * @return 成功个数
         */
        public long sSet(String key, Object... values) {
            try {
                return jsonRedisTemplate.opsForSet().add(key, values);
            } catch (Exception e) {
                e.printStackTrace();
                return 0;
            }
        }
    
    
        /**
         * 将set数据放入缓存
         *
         * @param key    键
         * @param time   时间(秒)
         * @param values 值 可以是多个
         * @return 成功个数
         */
        public long sSetAndTime(String key, long time, Object... values) {
            try {
                Long count = jsonRedisTemplate.opsForSet().add(key, values);
                if (time > 0)
                    expire(key, time);
                return count;
            } catch (Exception e) {
                e.printStackTrace();
                return 0;
            }
        }
    
    
        /**
         * 获取set缓存的长度
         *
         * @param key 键
         */
        public long sGetSetSize(String key) {
            try {
                return jsonRedisTemplate.opsForSet().size(key);
            } catch (Exception e) {
                e.printStackTrace();
                return 0;
            }
        }
    
    
        /**
         * 移除值为value的
         *
         * @param key    键
         * @param values 值 可以是多个
         * @return 移除的个数
         */
    
        public long setRemove(String key, Object... values) {
            try {
                Long count = jsonRedisTemplate.opsForSet().remove(key, values);
                return count;
            } catch (Exception e) {
                e.printStackTrace();
                return 0;
            }
        }
    
        // ===============================list=================================
    
        /**
         * 获取list缓存的内容
         *
         * @param key   键
         * @param start 开始
         * @param end   结束 0 到 -1代表所有值
         */
        public List<Object> lGet(String key, long start, long end) {
            try {
                return jsonRedisTemplate.opsForList().range(key, start, end);
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
    
    
        /**
         * 获取list缓存的长度
         *
         * @param key 键
         */
        public long lGetListSize(String key) {
            try {
                return jsonRedisTemplate.opsForList().size(key);
            } catch (Exception e) {
                e.printStackTrace();
                return 0;
            }
        }
    
    
        /**
         * 通过索引 获取list中的值
         *
         * @param key   键
         * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
         */
        public Object lGetIndex(String key, long index) {
            try {
                return jsonRedisTemplate.opsForList().index(key, index);
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
    
    
        /**
         * 将list放入缓存
         *
         * @param key   键
         * @param value 值
         */
        public boolean lSet(String key, Object value) {
            try {
                jsonRedisTemplate.opsForList().rightPush(key, value);
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
    
    
        /**
         * 将list放入缓存
         * @param key   键
         * @param value 值
         * @param time  时间(秒)
         */
        public boolean lSet(String key, Object value, long time) {
            try {
                jsonRedisTemplate.opsForList().rightPush(key, value);
                if (time > 0)
                    expire(key, time);
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
    
        }
    
    
        /**
         * 将list放入缓存
         *
         * @param key   键
         * @param value 值
         * @return
         */
        public boolean lSet(String key, List<Object> value) {
            try {
                jsonRedisTemplate.opsForList().rightPushAll(key, value);
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
    
        }
    
    
        /**
         * 将list放入缓存
         *
         * @param key   键
         * @param value 值
         * @param time  时间(秒)
         * @return
         */
        public boolean lSet(String key, List<Object> value, long time) {
            try {
                jsonRedisTemplate.opsForList().rightPushAll(key, value);
                if (time > 0)
                    expire(key, time);
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
    
        /**
         * 根据索引修改list中的某条数据
         *
         * @param key   键
         * @param index 索引
         * @param value 值
         * @return
         */
    
        public boolean lUpdateIndex(String key, long index, Object value) {
            try {
                jsonRedisTemplate.opsForList().set(key, index, value);
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
    
        /**
         * 移除N个值为value
         *
         * @param key   键
         * @param count 移除多少个
         * @param value 值
         * @return 移除的个数
         */
    
        public long lRemove(String key, long count, Object value) {
            try {
                Long remove = jsonRedisTemplate.opsForList().remove(key, count, value);
                return remove;
            } catch (Exception e) {
                e.printStackTrace();
                return 0;
            }
    
        }
    
    }
  5. 实体类POJO

    java 复制代码
    public class Student {
        private int stuId;
        private String stuName;
        private String stuSex;
        // get,set,构造,toString等
    }
  6. Dao层:Mapper

    java 复制代码
    @Mapper
    public interface StudentMapper {
        @Delete("delete from student where stu_id = #{id}")
        public int delete(Integer id);
    
        @Select("select * from student where stu_id = #{id}")
        public Student find(Integer id);
    }
  7. 业务层:

    接口

    java 复制代码
    public interface IStudentService {
    
        public void delete(int id);
    
        public Student find(int id);
        
    }

    实现类

    java 复制代码
    @Service
    public class StudentServiceImp implements IStudentService {
    
        @Autowired(required = false)
        private StudentMapper mapper;
    
        @Autowired
        private RedisUtil redisUtil;
    
        // 删除用户策略:删除数据表中数据,然后删除缓存
        @Override
        public void delete(int id) {
            // 删除数据库
            int res = mapper.delete(id);
            String key = "student:id:"+id;
            // 判断数据库是否删除成功
            if(res != 0){
                boolean hasKey = redisUtil.hasKey(key);
                if(hasKey){
                    redisUtil.del(key);
                    System.out.println("删除了缓存中的key:" + key);
                }
            }
        }
    
        // 获取用户策略:先从缓存中获取用户,没有则取数据表中数据,再将数据写入缓存
        @Override
        public Student find(int id) {
            String key = "student:id:" + id;
    
            //1.1判断key在redis中是否存在
            boolean hasKey = redisUtil.hasKey(key);
            if (hasKey) {
                //1.2存在缓存则直接获取
                Object stu = redisUtil.get(key);
                ObjectMapper change = new ObjectMapper();
                Student student =   change.convertValue(stu,Student.class);
                System.out.println("==========从缓存中获得数据=========");
                System.out.println(student.getStuName());
                System.out.println("==============================");
                return student;
            } else {
                //1.3不存在缓存,先从数据库中获取,在保存至redis,最后返回用户
                Student student = mapper.find(id);
                System.out.println("==========从数据表中获得数据=========");
                System.out.println(student.getStuName());
                System.out.println("==============================");
                if (student != null){
                    redisUtil.set(key, student);//写入缓存
                }
                return student;
            }
        }
    }
  8. 控制器

    java 复制代码
    @RestController
    public class StudentController {
    
        @Autowired
        IStudentService service;
    
        @RequestMapping("/delete/{id}")
        public Integer delete(@PathVariable("id") int id){
            service.delete(id);
            return id;
        }
    
        @RequestMapping("/find/{id}")
        public Student find(@PathVariable("id") int id){
            Student student = service.find(id);
            return student;
        }
    
    
    }
  9. 启动服务,地址栏中测试查看控制台打印结果,(测试时一定要保证redis服务正在运行,否则存不进redis

    第一次访问localhost:8080/find/1显示从数据表中获得的数据,第二次访问显示缓存中获取的数据

SpringBoot Cache

SpringBoot Cache介绍

Spring Cache是一个框架, 实现了基于注解的缓存功能,只需要简单地加一个注解,就能实现缓存功能

Spring Cache提供了一层抽象,底层可以切换不同的cache实现。具体就是通过CacheManager接口来统一不同的缓存技术。

CacheManager缓存管理器是Spring提供的各种缓存技术抽象接口

针对不同的缓存技术需要实现不同的CacheManager:

CacheManager 描述
EhCacheCacheManager 使用EhCache作为缓存技术(Spring Cache框架操作的默认缓存)
GuavaCacheManager 使用Google的GuavaCache作为缓存技术
RedisCacheManager 使用Redis作为缓存技术

SpringBoot Cache常用注解

注解 说明
@EnableCaching 开启缓存注解功能
@Cacheable 在方法执行前spring先查看缓存中是否有数据,如果有数据,则直接返回缓存数据;若没有数据,调用方法并将方法返回值放到缓存中
@CachePut 将方法的返回值放到缓存中
@CacheEvict 将一条或多条数据从缓存中删除

使用步骤:

  1. 引入缓存启动器:spring-boot-starter-cache,spring-boot-starter-data-redis

  2. @EnableCaching:在启动类上,开启基于注解的缓存

  3. @Cacheable : 标在方法上,返回的结果会进行缓存

属性: value/cacheNames缓存的名字

​ key : 作为缓存中的Key值,可自已使用 SpEL表达式指定(不指定就是参数值), 缓存结果是

​ 方法返回值

名字 描述 示例
methodName 当前被调用的方法名 #root.methodName
target 当前被调用的目标对象 #root.target
targetClass 当前被调用的目标对象类 #root.targetClass
args 当前被调用的方法的参数列表 #root.args[0]
caches 当前方法调用使用的缓存列表(如@Cacheable(value={"cache1","cache2"})),则有两个cache #root.caches[0].name
argument name 方法参数的名字. 可以直接 #参数名 ,也可以使用 #p0或#a0 的形式,0代表参数的索引; #iban 、 #a0 、 #p0
result 方法执行后的返回值(仅当方法执行之后的判断有效,在@CachePut 使用于更新数据后可用) #result

SpringBoot Cache案例简化Redis

代码实现演示:

  1. pom文件导坐标

    xml 复制代码
    <!--redis依赖-->
    <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    
    <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-cache</artifactId>
    </dependency>
    
    <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
       <groupId>org.mybatis.spring.boot</groupId>
       <artifactId>mybatis-spring-boot-starter</artifactId>
       <version>2.0.1</version>
    </dependency>
    
    <dependency>
       <groupId>mysql</groupId>
       <artifactId>mysql-connector-java</artifactId>
       <scope>runtime</scope>
    </dependency>
    <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-test</artifactId>
       <scope>test</scope>
    </dependency>
  2. yaml或properties主配置文件

    properties 复制代码
    spring.datasource.username=root
    spring.datasource.password=123456
    spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
    spring.datasource.url=jdbc:mysql://localhost:3306/spring?serverTimezone=GMT%2B8
    
    #开启日志管理,可以查看sql语句
    logging.level.com.apesource.springboot_redis03.mapper=debug
    debug=true
    
    #配置要连接redis的地址
    spring.redis.host=localhost
    spring.redis.port=6379
  3. POJO实体类

    根据要操作的表写,演示为student

    java 复制代码
    public class Student implements Serializable{
    
        private Integer stuId;
    
        private String stuName;
    
        private String stuSex;
    
        // get、set、toString、有参、无参构造
    }
  4. Dao层StudentMapper

    java 复制代码
    public interface StudentMapper {
    
        @Select("select * from Student where stu_id = #{id}")
        public Student getStudentById(Integer id);
    
    
        @Delete("delete from student where stu_id = #{id}")
        public int deleteStudentById(Integer id);
    
        @Update("update student  set stu_name=#{stuName},stu_sex=#{stuSex} where stu_id = #{stuId}")
        public int updateById(Student student);
    
    }
  5. Service层

    演示Cache简化redis实现,业务直接写实现类,没写接口

    java 复制代码
    @Service
    public class StudentService {
    
    
        @Autowired(required = false)
        StudentMapper mapper;
    
    
    
        //根据@Cacheable注解中的cacheNames+key拼接后的值为key
        @Cacheable(cacheNames = "students",key = "#id")
        public Student findById(Integer id){
            return mapper.getStudentById(id);
        }
    
    
        @CacheEvict(cacheNames = "students",key = "#id")
        public void deleteStudentById(Integer id){
            mapper.deleteStudentById(id);
        }
    
        @CachePut(cacheNames = "students",key = "#result.stuId")
        public Student updateById(Student student){
            mapper.updateById(student);
            return student;
        }
    
    }

    在业务层的方法中,加SpringBoot Cache的注解:

    cacheNames会在缓存中开辟一块儿叫"students"的空间,以键值对的形式存放数据,键是cacheNames+key拼接组成,value就是被标注注解的方法返回值

  6. 控制器StudentController

    java 复制代码
    @RestController
    public class UserController {
    
        @Autowired
        StudentService userService;
    
        @GetMapping("/findById/{id}")
        public Student findById(@PathVariable("id") Integer id) {
            Student stu = userService.findById(id);
            return stu;
        }
    
    
    
        @GetMapping("/delete/{id}")
        public Integer delete(@PathVariable("id") Integer id) {
            userService.deleteStudentById(id);
            return id;
        }
    
        @GetMapping("/update/{id}/{name}/{hobby}")
        public Integer update(@PathVariable Integer id,@PathVariable String name,@PathVariable String sex) {
            userService.updateById(new Student(id,name,sex));
            return id;
        }
    
    }	
  7. 启动类上添加注解

    java 复制代码
    @SpringBootApplication
    @MapperScan("com.apesource.springboot_redis03")
    @EnableCaching
    public class SpringbootRedis03Application {
    
       public static void main(String[] args) {
          SpringApplication.run(SpringbootRedis03Application.class, args);
       }
    
    }
  8. 启动服务,浏览器访问localhost:8080/findById/1,访问之后刷新再次访问

    注意启动程序服务之前,需要先把redis运行起来

    第一次访问时,从数据库中获取的数据

    第二次访问,没有SQL语句,但是也得到了数据,证明cache实现了缓存的作用

相关推荐
qq_124987075334 分钟前
基于SSM的动物保护系统的设计与实现(源码+论文+部署+安装)
java·数据库·spring boot·毕业设计·ssm·计算机毕业设计
Coder_Boy_39 分钟前
基于SpringAI的在线考试系统-考试系统开发流程案例
java·数据库·人工智能·spring boot·后端
2301_818732061 小时前
前端调用控制层接口,进不去,报错415,类型不匹配
java·spring boot·spring·tomcat·intellij-idea
此生只爱蛋1 小时前
【Redis】主从复制
数据库·redis
汤姆yu4 小时前
基于springboot的尿毒症健康管理系统
java·spring boot·后端
暮色妖娆丶4 小时前
Spring 源码分析 单例 Bean 的创建过程
spring boot·后端·spring
biyezuopinvip6 小时前
基于Spring Boot的企业网盘的设计与实现(任务书)
java·spring boot·后端·vue·ssm·任务书·企业网盘的设计与实现
惊讶的猫6 小时前
redis分片集群
数据库·redis·缓存·分片集群·海量数据存储·高并发写
JavaGuide6 小时前
一款悄然崛起的国产规则引擎,让业务编排效率提升 10 倍!
java·spring boot
期待のcode6 小时前
Redis的主从复制与集群
运维·服务器·redis