SpringBoot整合redis+mysql

news2025/7/23 23:51:55

SpringBoot整合Redis

测试连接

添加相关依赖

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.sin</groupId>
    <artifactId>demo-springboot-redis</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo-springboot-redis</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>


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

        <!-- apache通用连接池 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>

        <!-- mysql -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <!-- mybatis -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.2</version>
        </dependency>
        
        <!-- 通用mapper -->
        <dependency>
            <groupId>tk.mybatis</groupId>
            <artifactId>mapper-spring-boot-starter</artifactId>
            <version>2.1.5</version>
        </dependency>

        <!-- lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- 解析yaml -->
        <dependency>
            <groupId>org.yaml</groupId>
            <artifactId>snakeyaml</artifactId>
            <version>1.23</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
package com.sin;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @author sin
 * @date 2022/11/25
 * @apiNote
 */
@SpringBootApplication
public class SpringRedisMySQLRun {
    public static void main(String[] args) {
        SpringApplication.run(SpringRedisMySQLRun.class,args);
        System.out.println("===============启动成功================");
    }
}

配置

## 配置端口
server:
  port: 80

spring:
  ## 配置数据库数据源
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/sindemo
    username: root
    password: 123456
  redis:
    # 地址
    host: 192.168.11.128
    # 端口
    port: 6379
    # 密码
    password: 123456
    # 超时时间 5000毫秒
    timeout: 5000
    jedis:	
		连接池
      pool:
        # 连接池最小空闲连接
        min-idle: 0
        # 连接池的最大空闲连接
        max-idle: 8
        # 连接池最大阻塞等待时间(使用负数表示没有限制)
        max-wait: -1
        # 连接池最大连接数(使用负数表示没有限制)
        max-active: 8
            

# mybatis配置
mybatis:
  # 获取配置文件的地址
  mapper-locations: classpath:/mybatis/mapper/*.xml
  # 获取实体类的地址
  type-aliases-package: com.sin.pojo
  configuration:
    # 开启驼峰命名
    map-underscore-to-camel-case: true

测试项目

package com.sin.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author sin
 * @date 2022/11/25
 * @apiNote
 */
@RestController
public class TestController {

    @RequestMapping("/test")
    public String testControler(){
        System.out.println("测试成功");
        return "测试成功";
    }
}

在这里插入图片描述

在这里插入图片描述

开启Redis服务

## 启动redis
[root@My-Server redis]# cd /usr/local/redis/bin
[root@My-Server bin]# ./redis-server /usr/local/redis/etc/redis.conf
## 进入redis
[root@My-Server bin]# cd /usr/local/redis/bin
[root@My-Server bin]# ./redis-cli
## 密码登录
127.0.0.1:6379> auth 123456
OK
127.0.0.1:6379>

连接Redis测试

在这里插入图片描述

Spring封装了RedisTemplate来操作Redis,对redis底层开发包(Jedis,JRedis,RJC)进行了一个封装,在我们的RedisTemplate中定义了五种数据结构的操作方法,异常处理,序列化,发布订阅

  • opsForValue():操作字符串。
  • opsForList():操作列表。
  • opsForHash():操作哈希。
  • opsForSet():操作集合。
  • opsForZSet():操作有序集合。

添加数据

package com.sin.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

/**
 * @author sin
 * @date 2022/11/25
 * @apiNote
 */
@RestController
public class RedisController {

    //注入RedisTemplate
    @Autowired
    private RedisTemplate redisTemplate;

    //添加数据
    @PostMapping("/addData/key={key}/value={value}")//动态地址
    public Object addData(@PathVariable("key") String key,
                          @PathVariable("value") String value){
        redisTemplate.opsForValue().set(key,value);
        System.out.println("数据添加成功"+redisTemplate);
        return "addData Success";
    }
}

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

获取数据

//根据key获取value
@GetMapping("/getData/key={key}")
public Object getData(@PathVariable("key") String key){
   Object value =  redisTemplate.opsForValue().get(key);
    System.out.println("数据为:"+value);
    return redisTemplate.opsForValue().get(key);
}

在这里插入图片描述在这里插入图片描述

Redis序列化

看到结果后是看不懂的,这个就跟它的序列化有关了。就是根据RedisTemplate将数据写入到redis中的时候会经过一个序列化操作,序列化操作后就变成了以上数据格式,这个并不影响程序,因为set写入时会有序列化操作,get获取数据时也就有着这么一个序列话操作,但是对于我们来说时很不友好的

在这里插入图片描述

在源码中我们能看到定义了各种数据类型的序列化的一个成员变量

if (defaultSerializer == null) { //当defaultSerializer为null

    //当为null时这里就会设定为JdkSerializationRedisSerializer,就会用jdk的序列化
   defaultSerializer = new JdkSerializationRedisSerializer(	
         classLoader != null ? classLoader : this.getClass().getClassLoader());
}
if (keySerializer == null) {//当keySerializer为null时,
    //这里就直接把defaultSerializer给keySerializer
   keySerializer = defaultSerializer;
   defaultUsed = true;
}

我们没有定义,它就用的jdk的序列化将数据传输过来的

package com.sin.conf;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;

/**
 * @author sin
 * @date 2022/11/25
 * @apiNote
 */
@Configuration //表示该类为配置类
public class RedisConfig {

    @Bean
    public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory connectionFactory){
        //实例化RedisTemplate
        RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();
        //设置连接工厂
        redisTemplate.setConnectionFactory(connectionFactory);

        //指定k,v的序列化方式(json)
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);

        //默认序列化为json格式
        redisTemplate.setDefaultSerializer(jackson2JsonRedisSerializer);

        return redisTemplate;
    }
}

Json序列化

在这里插入图片描述

package com.sin.conf;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.StringRedisSerializer;

/**
 * @author sin
 * @date 2022/11/25
 * @apiNote
 */
@Configuration //表示该类为配置类
public class RedisConfig {

    @Bean
    public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory connectionFactory){
        //实例化RedisTemplate
        RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();
        //设置连接工厂
        redisTemplate.setConnectionFactory(connectionFactory);

        //指定k,v的序列化方式(json)
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);

//        //默认序列化为json格式
//        redisTemplate.setDefaultSerializer(jackson2JsonRedisSerializer);
        //key设置为String类型
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        //value设置为Json格式
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);

        return redisTemplate;
    }
}

key为String格式,value为Json格式
在这里插入图片描述

Springboot整合redis使用

RedisConfig

package com.sin.demo.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
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.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.*;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 * redis配置类
 *
 */
@EnableCaching
@Configuration//标记该类为配置类,
public class RedisConfig {
    /**
     * 对读写的数据进行序列化操作
     * @param factory 连接工厂,
     * @return
     */
    @Bean
    public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory factory){

        //实例化redisTemplate
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        //设置连接工厂
        redisTemplate.setConnectionFactory(factory);
        Jackson2JsonRedisSerializer<Object> redisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);

        //ObjectMapper以json进行读写操作
        ObjectMapper mapper = new ObjectMapper();
        //指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public
        mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        redisSerializer.setObjectMapper(mapper);

        //设置默认的序列化
        //redisTemplate.setDefaultSerializer(new StringRedisSerializer());

        //实际开发中key为字符串序列化,value为json序列化
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(redisSerializer);

        //hash序列化
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(redisSerializer);
        redisTemplate.afterPropertiesSet();

        return redisTemplate;
    }

    /**
     * 对redis操作String数据类型
     * @param redisTemplate
     * @return
     */
    @Bean
    public ValueOperations<String,Object> valueOperations(RedisTemplate<String,Object> redisTemplate){
        return redisTemplate.opsForValue();
    }

    /**
     * Redis操作List数据类型
     * @param redisTemplate
     * @return
     */
    @Bean
    public ListOperations<String,Object> listOperations(RedisTemplate<String,Object> redisTemplate){
        return redisTemplate.opsForList();
    }

    /**
     * Redis操作Hash数据类型
     * @param redisTemplate
     * @return
     */
    @Bean
    public HashOperations<String,String,Object> hashOperations(RedisTemplate<String,Object> redisTemplate){
        return redisTemplate.opsForHash();
    }

    /**
     * Redis操作set数据类型
     * @param redisTemplate
     * @return
     */
    @Bean
    public SetOperations<String,Object> setOperations(RedisTemplate<String,Object> redisTemplate){
        return redisTemplate.opsForSet();
    }

    /**
     * Redis操作zSet数据类型
     * @param redisTemplate
     * @return
     */
    public ZSetOperations<String,Object> zSetOperations(RedisTemplate<String,Object> redisTemplate){
        return redisTemplate.opsForZSet();
    }

}

RedisTemplate封装

package com.sin.demo.util;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import sun.security.ec.point.ProjectivePoint;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * redisTemplate封装
 */
@Component
public class RedisUtil {
    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    public RedisUtil(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    /**
     * 指定缓存失效时间
     * @param key
     * @param time
     * @return
     */
    public boolean expire(String key,long time){
        try {
            if (time > 0) {
                redisTemplate.expire(key, time, TimeUnit.SECONDS);
            }
            return true;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 指定key过期时间
     * @param key
     * @return
     */
    public long getExpire(String key){
        return redisTemplate.getExpire(key,TimeUnit.SECONDS);
    }

    /**
     * 判断key是否存在
     * @param key
     * @return
     */
    public boolean hasKey(String key){
        try {
            return redisTemplate.hasKey(key);
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 删除缓存
     * @param key
     */
    @SuppressWarnings("unchecked")
    public void del(String ... key){
        if(key!=null&&key.length>0){
            if(key.length==1){
                redisTemplate.delete(key[0]);
            }else {
                redisTemplate.delete((Collection<String>) CollectionUtils.arrayToList(key));
            }
        }
    }


    //=====================================================Redis的String数据类型操作=========================================

    /**
     * 普通缓存的获取
     * @param key
     * @return
     */
    public Object get(String key){
        return key==null?null:redisTemplate.opsForValue().get(key);
    }

    /**
     * 普通缓存的存放
     * @param key
     * @param value
     * @return
     */
    public boolean set(String key,Object value){
        try{
            redisTemplate.opsForValue().set(key,value);
            return true;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 普通缓存放入并设置时间
     * @param key
     * @param value
     * @param time
     * @return
     */
    public boolean set(String key,Object value,long time){
        try{
            if(time>0){
                redisTemplate.opsForValue().set(key,value,time,TimeUnit.SECONDS);
            }else {
                set(key,value);
            }
            return true;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 递增
     * @param key
     * @param delta
     * @return
     */
    public long incr(String key,long delta){
        if (delta<0){
            throw new RuntimeException("递增的条件必须大于0");
        }
        return redisTemplate.opsForValue().increment(key,delta);
    }


    /**
     * 递减
     * @param key
     * @param delta
     * @return
     */
    public long decr(String key,long delta){
        if (delta<0){
            throw new RuntimeException("递减的条件不许大于0");

        }
        return redisTemplate.opsForValue().decrement(key,-delta);
    }

    //===============================================redis的Hash数据类型操作====================================================

    /**
     * Hashget
     * @param key 不能为null
     * @param itme 不能为null
     * @return
     */
    public Object hget(String key,String itme ){
        return redisTemplate.opsForHash().get(key,itme);
    }

    /**
     * 获取hashkey对应的所有键值
     * @param key
     * @return
     */
    public Map<Object,Object> hmget(String key){
        return redisTemplate.opsForHash().entries(key);
    }

    /**
     * HashSet
     */
    public boolean hmset (String key,Map<String,Object> map){
        try {
            redisTemplate.opsForHash().putAll(key,map);
            return true;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }

    /**
     * Hashset 设置时间
     * @param key
     * @param map
     * @param time
     * @return
     */
    public boolean hmset(String key,Map<String,Object>map,long time){
        try{
            redisTemplate.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
     */
    public boolean hset(String key,String item,String value){
        try{
            redisTemplate.opsForHash().put(key,item,value);
            return true;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }

    }

    /**
     * 向一张hash表中放入数据,如果不存在就将其创建,对时间的操作
     * @param key
     * @param item
     * @param value
     * @param time
     * @return
     */
    public boolean hset(String key,String item,String value,long time){
        try{
            redisTemplate.opsForHash().put(key,item,value);
            if (time>0){
                expire(key,time);
            }
            return true;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }

    }

    /**
     * 删除hash表中的值
     * @param key
     * @param item
     */
    public void hdel(String key,Object ... item){
        redisTemplate.opsForHash().delete(key,item);
    }

    /**
     * 判断Hash表中是否有该项的值
     * @param key
     * @param item
     * @return
     */
    public boolean hHasKey(String key,String item){
        return redisTemplate.opsForHash().hasKey(key,item);
    }

    /**
     * hash递增,如果不存在,就会创建一个,并把新增后的值返回
     * @param key
     * @param item
     * @param by  要增加几(大于0)
     * @return
     */
    public double hincr(String key,String item,double by){
        return redisTemplate.opsForHash().increment(key,item,by);
    }

    /**
     * 递减操作
     * @param key
     * @param item
     * @param by 要减少几(小于0)
     * @return
     */
    public double hdecr(String key,String item,double by){
        return redisTemplate.opsForHash().increment(key,item,by);
    }

    //===============================================redis的set数据类型操作====================================================

    /**
     * 根据key获取set中的所有值
     * @param key
     * @return
     */
    public Set<Object> sGet(String key){
        try {
            return redisTemplate.opsForSet().members(key);
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 根据value从一个set中查询,是否存在
     * @param key
     * @param value
     * @return
     */
    public boolean sHasKey(String key,Object value){
        try {
            return redisTemplate.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 redisTemplate.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 = redisTemplate.opsForSet().add(key, values);
            if(time>0){
                expire(key,time);
            }
            return count;
        }catch (Exception e){
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * 获取set缓存的长度
     * @param key
     * @return
     */
    public long sGetSetSize(String key){
        try {
            return redisTemplate.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 = redisTemplate.opsForSet().remove(key, values);
            return count;
        }catch (Exception e){
            e.printStackTrace();
            return 0;
        }
    }

    //===============================================redis的list数据类型操作====================================================

    /**
     * 获取list缓存的内容
     * @param key
     * @param start 开始
     * @param end 结束(0到-1表示所有值)
     * @return
     */
    public List<Object> lGet(String key,long start,long end){
        try {
            return redisTemplate.opsForList().range(key,start,end);
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取list缓存的长度
     * @param key
     * @return
     */
    public long lGetListSize(String key){
        try {
            return redisTemplate.opsForList().size(key);
        }catch (Exception e){
            e.printStackTrace();
            return 0;
        }
    }


    /**
     * 通过索引,获取list中的值
     * @param key
     * @param index 索引,index>=0时,0表示开头,1表示第二个元素;index《=0时,-1表示末尾,-2表示第二个元素,
     * @return
     */
    public Object lGetIndex(String key,long index){
        try{
            return redisTemplate.opsForList().index(key,index);
        }catch (Exception e ){
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 将list放入缓存
     * @param key
     * @param value
     * @return
     */
    public boolean lSet(String key,Object value){
        try {
            redisTemplate.opsForList().rightPush(key,value);
            return true;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }


    /**
     * 将list放入缓存中,对时间操作
     * @param key
     * @param value
     * @param time
     * @return
     */
    public boolean lSet(String key,Object value,long time){
        try {
            redisTemplate.opsForList().rightPush(key,value);
            if (time>0){
                expire(key,time);
            }
            return true;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 将list放入缓存
     * @param key
     * @param values
     * @return
     */
    public boolean lSetList(String key,List<Object> values){
        try {
            redisTemplate.opsForList().rightPushAll(key,values);
            return true;

        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 将list放入缓存中,对时间操作
     * @param key
     * @param values
     * @param time
     * @return
     */
    public boolean lSetList(String key,List<Object> values ,long time){
        try {
            redisTemplate.opsForList().rightPushAll(key,values);
            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 {
            redisTemplate.opsForList().set(key,index,value);
            return true;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 移除n个值
     * @param key
     * @param count
     * @param value
     * @return
     */
    public long lRemove(String key,long count,Object value){
        try{
            return redisTemplate.opsForList().remove(key,count,value);
        }catch (Exception e){
            e.printStackTrace();
            return 0;
        }
    }

}

编写实体类

public class Student {
    private Integer id;
    private String name ;
    private Integer age;
    private String dept;//班级
    set,get方法
    }

RedisController类

package com.sin.controller;

import com.sin.pojo.Student;
import com.sin.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * @author sin
 * @date 2022/11/25
 * @apiNote
 */
@RestController
public class RedisController {

    //注入RedisTemplate
    @Autowired
    private RedisTemplate redisTemplate;


    @Autowired
    private RedisUtil redisUtil;

    //添加数据
    @PostMapping("/addData/key={key}/value={value}")//动态地址
    public Object addData(@PathVariable("key") String key,
                          @PathVariable("value") String value){
        redisTemplate.opsForValue().set(key,value);
        System.out.println("数据添加成功"+redisTemplate);
        return "addData Success";
    }

    //根据key获取value
    @GetMapping("/getData/key={key}")
    public Object getData(@PathVariable("key") String key){
       Object value =  redisTemplate.opsForValue().get(key);
        System.out.println("数据为:"+value);
        return redisTemplate.opsForValue().get(key);
    }



    /**
     * 添加list对象数据到redis中
     * @return
     */
    @RequestMapping(value = "/setList")
    public boolean setList(){
        List<Object> stuList = new ArrayList<>();
        Student student = new Student();
        student.setId(1);
        student.setAge(23);
        student.setDept("saas");
        student.setName("张三");

        Student student1 = new Student();
        student1.setId(2);
        student1.setAge(22);
        student1.setDept("微服务");
        student1.setName("李四");

        Student student2 = new Student();
        student2.setId(3);
        student2.setAge(23);
        student2.setDept("saas");
        student2.setName("王五");

        Student student3 = new Student();
        student3.setId(4);
        student3.setAge(24);
        student3.setDept("微服务");
        student3.setName("赵六");

        stuList.add(student);
        stuList.add(student1);
        stuList.add(student2);
        stuList.add(student3);
        return redisUtil.lSetList("student",stuList);
    }

    /**
     * 获取全部数据
     * @return
     */
    @RequestMapping(value = "getList")
    public  Object getList(){
        return redisUtil.lGet("student",0,-1);
    }

}

在这里插入图片描述
在这里插入图片描述

SpringBoot整合Redis+Mybatis

​ SpringBoot+SpringMVC+redis+mysql来实现项目中的crud操作,redis做缓存数据库,针对频繁需要查询或者解决单点问题都会把数据库到redis来分配服务器压力。

实体类

create table demo_user(
    id int(10) auto_increment primary key not null ,
    user_name varchar(40) not null ,
    password varchar(10) not null ,
    sex int(10) not null );
    
    alter table demo_user charset  = utf8;

alter table demo_user convert to character set utf8;
public class DemoUser implements Serializable {


  private long id;
  private String userName;
  private String password;
  private long sex;
  
    // setter getter方法
}

dao层

package com.sin.mapper;

import com.sin.pojo.DemoUser;
import org.apache.ibatis.annotations.*;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
 * dao层
 */
@Repository
@Mapper
public interface DemoUserMapper {
    //用户列表
    @Select("select * from demo_user")
    @Results({
            @Result(property = "userName",column = "user_name"),
            @Result(property = "password",column = "password")
    })
    List<DemoUser> queryAll();

    //根据id获取demo_user
    @Select("select * from demo_user where id = #{id}")
    @Results({
            @Result(property = "userName",column = "user_name"),
            @Result(property = "password",column = "password")
    })
    DemoUser findUserById(int id);
    
    @Options(useGeneratedKeys = true,keyProperty = "id",keyColumn = "id")
    @Insert("insert into demo_user(id,user_name,password,sex)values" +
            "(#{id},#{userName},#{password},#{sex})")
    int add(DemoUser user);

    @Select("select * from demo_user where user_name = #{userName} ")
    @Results({
            @Result(property = "userName",column = "user_name"),
            @Result(property = "password",column = "password")
    })
    DemoUser findUserByName(String userName);

    //根据id修改demoUser
    @Update("update demo_user set user_name=#{userName},password=#{password}," +
            "sex=#{sex} where id=#{id}")
    int updateUser(DemoUser demoUser);

    //删除用户
    @Delete("delete from demo_user where id = #{id}")
    int deleteUserById(int id);


}

config

package com.sin.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.boot.autoconfigure.cache.CacheProperties;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisInvalidSubscriptionException;
import org.springframework.data.redis.core.*;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.time.Duration;

/**
 * redis 配置类
 * 配置redisTemplate序列化
 */
public class RedisConfig extends CachingConfigurerSupport {
    /**
     *  选择redis作为默认缓存工具
     *
     */
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory){
        //设置缓存时间为一个小时
        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofHours(1));
        return RedisCacheManager.builder(RedisCacheWriter.lockingRedisCacheWriter(redisConnectionFactory))
                .cacheDefaults(redisCacheConfiguration).build();
    }

    /**
     * 配置redisTemplate相关配置
     *
     */
    @Bean
    public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory factory){
        RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();
        //配置连接工厂
        redisTemplate.setConnectionFactory(factory);

        //使用Jackson2JsonRedisSerializer来序列化何反序列化redis的value值
        Jackson2JsonRedisSerializer jsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);

        ObjectMapper objectMapper = new ObjectMapper();
        //指定要序列化的域,field,get和set,以及修饰符范围,ANY都是有private和public
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        //指定序列化输入的类型,类必须时非final修饰的,
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jsonRedisSerializer.setObjectMapper(objectMapper);

        //值采用json序列化
        redisTemplate.setValueSerializer(jsonRedisSerializer);
        //使用StringRedisSerrializer来序列化和反序列化redis的key值
        redisTemplate.setKeySerializer(new StringRedisSerializer());

        //设置hash key 和value序列化模式
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(jsonRedisSerializer);
        redisTemplate.afterPropertiesSet();

        return redisTemplate;
    }


    /*
     * 对hash类型的数据操作
     */
    @Bean
    public HashOperations<String,String,Object> hashOperations(RedisTemplate<String,Object> redisTemplate){
        return redisTemplate.opsForHash();
    }

    /**
     * 对redis 字符串String类型数据操作
     */
    @Bean
    public ValueOperations<String,Object> valueOperations(RedisTemplate<String,Object> redisTemplate){
        return redisTemplate.opsForValue();
    }
    /**
     * 对redis 链表list类型数据操作
     */
    @Bean
    public ListOperations<String,Object>listOperations(RedisTemplate<String,Object> redisTemplate){
        return redisTemplate.opsForList();
    }
    /**
     * 对redis 无序集合set类型数据操作
     */
    @Bean
    public SetOperations<String,Object> setOperations(RedisTemplate<String,Object> redisTemplate){
        return redisTemplate.opsForSet();
    }

    /**
     * 对redis 有序结合zset类型数据操作
     */
    @Bean
    public ZSetOperations<String,Object> zSetOperations(RedisTemplate<String,Object> redisTemplate){
        return redisTemplate.opsForZSet();
    }

}

service

public interface DemoUserService {

    //查询全部
    List<DemoUser> queryAll();
    //根据id查询
    DemoUser findUserById(int id);
    //根据id进行修改
    int updateUser(DemoUser demoUser);
    //根据id进行删除
    int deleteUserById(int id);
    
    //添加数据
    int addUser(DemoUser user);
}

impl

package com.sin.service.impl;

import com.sin.mapper.DemoUserMapper;
import com.sin.pojo.DemoUser;
import com.sin.service.DemoUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
public class DemoUserServiceImpl implements DemoUserService {

    @Autowired
    private DemoUserMapper demoUserMapper;
    @Autowired
    private RedisTemplate redisTemplate;


    //查询全部操作
    @Override
    public List<DemoUser> queryAll() {
        return demoUserMapper.queryAll();
    }

    /**
     * 根据id进行查询
     * 获取用户策略,先从缓存中获取用户,没有则读取mysql数据,再将读取的数据写入缓存中
     */
    @Override
    public DemoUser findUserById(int id) {
        String key = "user_" + id;
        ValueOperations<String,DemoUser> operations = redisTemplate.opsForValue();
        //判断redis中是否有键为key的缓存
        boolean haskey = redisTemplate.hasKey(key);
        if (haskey){
            DemoUser user = operations.get(key);
            System.out.println("从缓存中获取的数据:"+user.getUserName());
            System.out.println("----------------------------------");
            return user;
        }else {
            DemoUser user = demoUserMapper.findUserById(id);
            System.out.println("查询数据库中的数据"+ user.getUserName());
            System.out.println("--------------------写入数据------------------");
            //写入数据
            operations.set(key,user,5, TimeUnit.HOURS);
            return user;
        }
    }

    /**
     * 更新用户
     * 先更新数据库,成功之后,删除原来的缓存,再更新缓存
     * @param demoUser
     * @return
     */
    @Override
    public int updateUser(DemoUser demoUser) {
        ValueOperations<String,DemoUser> operations = redisTemplate.opsForValue();
        int result = demoUserMapper.updateUser(demoUser);
        if (result!=0){
            String key = "user_"+demoUser.getId();
            boolean haskey = redisTemplate.hasKey(key);
            if (haskey){
                redisTemplate.delete(key);
                System.out.println("删除缓存中的key----"+key);
            }
            //将更新后的数据加入缓存中
            DemoUser demoUserNew = demoUserMapper.findUserById((int) demoUser.getId());
            if (demoUserNew != null){
                operations.set(key,demoUserNew,3,TimeUnit.HOURS);
            }
        }
        return result;
    }

    /**
     * 根据id删除
     * 删除数据表中的数据,然后删除缓存
     * @param id
     * @return
     */
    @Override
    public int deleteUserById(int id) {
        int result = demoUserMapper.deleteUserById(id);
        String key = "user_" + id;
        if (result != 0){
            boolean haskey = redisTemplate.hasKey(key);
            if (haskey){
                redisTemplate.delete(key);
                System.out.println("删除了缓存中的key"+ key);
            }
        }
        return result;
    }
     @Override
    public int addUser(DemoUser user) {
        DemoUser user1 = demoUserMapper.findUserByName(user.getUserName());
        int result;
        if (user1 != null){
            result = 0;
            return result;
        }else{
            ValueOperations<String,Object> operations = redisTemplate.opsForValue();
            result = demoUserMapper.add(user);
            if (result != 0 ){
                String key  = "user_" +user.getId();
                boolean haskey = redisTemplate.hasKey(key);
                if(haskey){
                    redisTemplate.delete(key);
                }
                if (user != null){
                    operations.set(key,user,3,TimeUnit.HOURS);
                }
            }
            return result;
        }

    }
}

controller

package com.sin.controller;

import com.sin.pojo.DemoUser;
import com.sin.service.DemoUserService;
import org.apache.catalina.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.sql.Timestamp;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
public class DemoUserController {

    @Autowired
    private DemoUserService demoUserService;

    @RequestMapping("/queryAll")
    public List<DemoUser> queryAll(){
        List<DemoUser> list = demoUserService.queryAll();
        return list;
    }
    @RequestMapping("/addUser")
    public String addUser(){
        DemoUser user = new DemoUser();
        user.setUserName("李四");
        user.setPassword("12112");
        user.setSex(1);
        user.setBirthday( new Date());
        int resutl= demoUserService.addUser(user);
        if (resutl != 0){
            return "add DemoUser success";

        }
        return "add demouser fail";
    }


    @RequestMapping("/findUserById")
    public Map<String,Object> findUserById(@RequestParam int id){
        DemoUser user = demoUserService.findUserById(id);
        Map<String,Object> result = new HashMap<>();
        result.put("id",user.getId());
        result.put("username",user.getUserName());
        result.put("pwd",user.getPassword());
        result.put("sex",user.getSex());
        result.put("birthday",user.getBirthday());
        return result;
    }

    @RequestMapping("/updateUser")
    public String updateUser(){
        DemoUser user = new DemoUser();
        user.setId(1);
        user.setUserName("张三");
        user.setPassword("123456");
        user.setSex(18);
        user.setBirthday((Timestamp) new Date());

        int result = demoUserService.updateUser(user);

        if (result != 0){
            return "update user success";
        }
        return "fall";
    }


    @RequestMapping("/deleteUserById")
    public String deleteUserById(@RequestParam int id){
        int result = demoUserService.deleteUserById(id);
        if (result != 0){
            return "delete Success";
        }
        return "delete fall";
    }




}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/35478.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【TFS-CLUB社区 第7期赠书活动】〖从零开始利用Excel与Python进行数据分析 自动化办公实战宝典〗等你来拿,参与评论,即可有机获得

文章目录❤️‍&#x1f525; 赠书活动 - 《从零开始利用Excel与Python进行数据分析 自动化办公实战宝典》❤️‍&#x1f525; 编辑推荐❤️‍&#x1f525; 抽奖方式与截止时间❤️‍&#x1f525; 赠书活动 → 获奖名单❤️‍&#x1f525; 赠书活动 - 《从零开始利用Excel与…

【数据结构】二叉树的前中后序遍历

二叉树的三种遍历1. 创建一棵简单的二叉树1.1 二叉树结构体实现1.2 创造一个二叉树结点的函数1.3 手动创造一棵二叉树2.为什么要遍历&#xff1f;3.最重要的知识&#xff1a;由二叉树引出的子问题分析4.遍历4.1 前序遍历4.2 中序遍历4.3 后序遍历5.总结1. 创建一棵简单的二叉树…

基于springboot车辆充电桩设计与实现的源码+文档

摘 要 随着信息化时代的到来&#xff0c;管理系统都趋向于智能化、系统化&#xff0c;车辆充电桩管理系统也不例外&#xff0c;但目前国内仍都使用人工管理&#xff0c;市场规模越来越大&#xff0c;同时信息量也越来越庞大&#xff0c;人工管理显然已无法应对时代的变化&…

18.3 内存池概念、代码实现和详细分析

一&#xff1a;内存池的概念和实现原理概述 malloc&#xff1a;内存浪费&#xff0c;频繁分配小块内存&#xff0c;浪费更加明显。 “内存池”要解决什么问题&#xff1f; 1、减少malloc()的次数&#xff0c;减少malloc()调用次数就意味着减少对内存的浪费 2、减少malloc()的…

JavaEE高阶---SpringBoot的创建和使用

一 : 什么是SpringBoot? Spring的诞生是为了简化 Java 程序的开发的,Spring Boot 的诞生是为了简化 Spring 程序开发的.Spring Boot 是所有基于 Spring 开发的项目的起点 . Spring Boot 的设计是为了让你尽可能快的跑起来 Spring 应用程序并且尽可能减少你的配置文件 . Sprin…

深度学习系列2——Pytorch 图像分类(AlexNet)

1. 概述 本文主要是参照 B 站 UP 主 霹雳吧啦Wz 的视频学习笔记&#xff0c;参考的相关资料在文末参照栏给出&#xff0c;包括实现代码和文中用的一些图片。 整个工程已经上传个人的 github https://github.com/lovewinds13/QYQXDeepLearning &#xff0c;下载即可直接测试&a…

你了解PMP考试新考纲的内容吗?

2021年新版PMP考纲变化趋势 随着时代发展&#xff0c;PMP认证本身也通过改版不断调整定位&#xff0c;与全球项目管理趋势相匹配&#xff0c;确保在全球项目管理专业领域保持“黄金标准”。 新版本变化如下&#xff1a; 五大过程组变为三大板块。之前一直沿用的“启动、规划…

Transformer时间序列预测

介绍&#xff1a; 提示&#xff1a;Transformer-decoder 总体介绍 本文将介绍一个 Transformer-decoder 架构&#xff0c;用于预测Woodsense提供的湿度时间序列数据集。该项目是先前项目的后续项目&#xff0c;该项目涉及在同一数据集上训练一个简单的 LSTM。人们认为 LSTM 在…

阿里P8总结的Nacos入门笔记,从安装到进阶小白也能轻松学会

前言 都说程序员工资高、待遇好&#xff0c; 2022 金九银十到了&#xff0c;你的小目标是 30K、40K&#xff0c;还是 16薪的 20K&#xff1f;作为一名 Java 开发工程师&#xff0c;当能力可以满足公司业务需求时&#xff0c;拿到超预期的 Offer 并不算难。然而&#xff0c;提升…

GPC规范-SCP02

SPC02 流程 SPC02 指令 命令&#xff1a; 响应&#xff1a; 举例回复&#xff1a; 密钥分散数据&#xff1a; 0000FFFFFFFFFFFFFFFF Key Info&#xff1a; 20 02&#xff08;scp02&#xff09; Card挑战数&#xff1a; 001AC6619BE83082 Card加密值&#xff1a; 7…

leetcode刷题(133)——剑指 Offer 07. 重建二叉树

输入某二叉树的前序遍历和中序遍历的结果&#xff0c;请构建该二叉树并返回其根节点。 假设输入的前序遍历和中序遍历的结果中都不含重复的数字。 示例 1: Input: preorder [3,9,20,15,7], inorder [9,3,15,20,7] Output: [3,9,20,null,null,15,7]示例 2: Input: preord…

(十一)笔记.net学习表达式目录树Expression

&#xff08;十一&#xff09;笔记.net学习表达式目录树Expression1.什么是表达式目录树&#xff08;1&#xff09;Func和表达式的不同&#xff08;2&#xff09;表达式树拆解&#xff08;3&#xff09;自己拼装表达式目录2.动态拼装表达式目录和扩展应用3.解析表达式目录&…

阿里云服务器采用AMD CPU处理器ECS实例规格详解

阿里云服务器有AMD CPU处理器&#xff0c;阿里云服务器ECS通用型g7a、计算型c7a和内存型r7a采用2.55 GHz主频的AMD EPYCTM MILAN处理器&#xff0c;单核睿频最高3.5 GHz&#xff1b;通用型g6a、计算型c6a和内存型r6a采用2.6 GHz主频的AMD EPYCTM ROME处理器&#xff0c;睿频3.3…

MySQL读取的记录和我想象的不一致——事物隔离级别和MVCC

本篇是《MySQL是怎样运行的》读书笔记&#xff0c;主要分析并发的事务在运行过程中会出现一些可能引发一致性问题的现象。 文章目录1.事务的特性简介1.1 原子性&#xff08;Atomicity&#xff09;1.2 隔离性&#xff08;Isolation&#xff09;1.3 一致性&#xff08;Consistenc…

JUC基础

synchronized 复习虚假唤醒什么是虚假唤醒虚假唤醒产生的原因&#xff1f;解决虚假唤醒&#xff1f;Lock接口ReentrantLock 和 synchronized 的区别Lock 实现线程通信Lock 实现线程定制化通信集合线程安全ArrayListHashSetHashMapsynchronized 锁的范围多线程锁公平锁和非公平锁…

CameraMetadata 知识学习整理

一、涉及的相关代码路径 system/media/camera/src/camera_metadata.c // metadata的核心内容&#xff0c;包含metadata内存分配&#xff0c;扩容规则&#xff0c;update, find等 system/media/camera/src/camera_metadata_tag_info.c // 所有android原生tag的在内存里面sect…

22/11/24

1&#xff0c;单调队列&#xff1b; (76条消息) 单调队列专题_Dull丶的博客-CSDN博客 2&#xff0c;kmp算法&#xff1b; 先是自己和自己匹配&#xff0c;求出ne数组&#xff0c;然后和另一串匹配&#xff0c;进行求解&#xff1b; 循环里三步&#xff1a;while&#xff0c…

【Lilishop商城】No2-3.确定软件架构搭建二(本篇包括接口规范、日志处理)

仅涉及后端&#xff0c;全部目录看顶部专栏&#xff0c;代码、文档、接口路径在&#xff1a; 【Lilishop商城】记录一下B2B2C商城系统学习笔记~_清晨敲代码的博客-CSDN博客 全篇只介绍重点架构逻辑&#xff0c;具体编写看源代码就行&#xff0c;读起来也不复杂~ 谨慎&#xf…

【数据聚类】基于粒子群、遗传和差分算法实现数据聚类附matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;修心和技术同步精进&#xff0c;matlab项目合作可私信。 &#x1f34e;个人主页&#xff1a;Matlab科研工作室 &#x1f34a;个人信条&#xff1a;格物致知。 更多Matlab仿真内容点击&#x1f447; 智能优化算法 …

【App自动化测试】(十)特殊控件Toast识别

目录1. toast介绍2. toast定位3. 实例演示前言&#xff1a; 本文为在霍格沃兹测试开发学社中学习到的一些技术写出来分享给大家&#xff0c;希望有志同道合的小伙伴可以一起交流技术&#xff0c;一起进步~ &#x1f618; 1. toast介绍 Toast&#xff0c;简易的消息提示框。为了…