redis详解--springboot整合redis

1. java连接redis

思考: 我们之前操作redis都是通过命令行的客户端来操作。 在开发时都是通过java项目操作redis.

引入Redis依赖

java 复制代码
<!--引入java连接redis的驱动-->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>4.3.1</version>
        </dependency>
1.1 连接redis

最简单的连接方式,就是通过 Jedis 对象连接。代码如下:

java 复制代码
//引入Redis驱动程序
import redis.clients.jedis.Jedis;

public class RedisJava {
    public static void main(String[] args) {
        //连接Redis服务--> 默认连接本地的redis 端口号6379.
        Jedis jedis = new Jedis("172.16.7.110",6379);
        // 如果设置 Redis 服务的密码,需要进行验证,若没有则可以省去
        // jedis.auth("123456");
    }
}

所有关于redis操作的功能都在该类中Jedis

java 复制代码
//关于key的命令
        Set<String> keys = jedis.keys("*");
        System.out.println("所有的key:"+keys);

        long del = jedis.del("k1", "k2", "k3");
        System.out.println("删除key的个数:"+del);

        boolean k4 = jedis.exists("k4");
        System.out.println("判断指定的k4是否存在:"+k4);

        long k5 = jedis.expire("k5", 10);
//关于字符串类型的命令:
        String set = jedis.set("k1", "v1");
        System.out.println("存入k1的值:"+set);

        String k1 = jedis.get("k1");
        System.out.println("获取指定key的值:"+k1);

        long k2 = jedis.setnx("k2", "110");
        System.out.println("如果k2不存在,则设置k2的值:"+k2);

        long k21 = jedis.incr("k2");
        System.out.println("k2的值加1:"+k21);

        long k22 = jedis.decr("k2");
        System.out.println("k2的值减1:"+k22);

        String setex = jedis.setex("k3", 100, "v3");
        System.out.println("k3的值:"+setex);
//关于hash类型的命令:
        long hset = jedis.hset("k4", "k41", "v41");
        System.out.println("存入k4的键值对:"+hset);
        Map<String,String> map=new HashMap<>();
        map.put("name","张三");
        map.put("age","18");
        long k51 = jedis.hset("k5", map);
        System.out.println("存入k5的键值对:"+k51);
        String hget = jedis.hget("k5", "name");
        System.out.println("获取k5的name的值:"+hget);
        Map<String, String> k52 = jedis.hgetAll("k5");
        System.out.println("获取k5的所有键值对:"+k52);
1.2 java连接redis集群模式

适合ssm项目

java 复制代码
 public static void main(String[] args) {
        Set<HostAndPort> nodes=new HashSet<>();
        nodes.add(new HostAndPort("192.168.111.188",7001));
        nodes.add(new HostAndPort("192.168.111.188",7002));
        nodes.add(new HostAndPort("192.168.111.188",7003));
        nodes.add(new HostAndPort("192.168.111.188",7004));
        nodes.add(new HostAndPort("192.168.111.188",7005));
        nodes.add(new HostAndPort("192.168.111.188",7006));
        JedisCluster jedisCluster=new JedisCluster(nodes);
        jedisCluster.set("k5","666");
        System.out.println(jedisCluster.get("k5"));
    }

2. springboot整合redis

引入依赖

       <!--引入了redis整合springboot 的依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

修改配置文件

properties 复制代码
#配置redis信息
#redis服务器地址
spring.redis.host=localhost
#redis服务器端口
spring.redis.port=6379
#连接池最大连接数(使用负数表示没有限制)默认8
spring.redis.lettuce.pool.max-active=100
#连接池最大阻塞等待时间(使用负值表示没有限制)默认-1
spring.redis.lettuce.pool.max-wait=PT10S
#连接池最大空闲连接数(使用负值表示没有限制)默认8
spring.redis.lettuce.pool.max-idle=30
#连接池最小空闲连接数(使用负值表示没有限制)默认0
spring.redis.lettuce.pool.min-idle=1
#连接超时时间
spring.redis.timeout=PT10S

使用

springboot整合redis时封装了两个工具类:StringRedisTemplate和RedisTemplate.

StringRedisTemplate它是RedisTemplate的子类。StringRedisTemplate里面只能存放字符串的内容。

1. StringRedisTemplate
java 复制代码
@Autowired
    private StringRedisTemplate stringRedisTemplate;
//关于key的操作
    @Test
    void textkey() {
        Set<String> keys = stringRedisTemplate.keys("*");
        System.out.println("查询全部:"+keys);
        Boolean k1 = stringRedisTemplate.delete("k1");
        System.out.println("删除是否成功:"+k1);
        Boolean k2 = stringRedisTemplate.hasKey("k2");
        System.out.println("查询指定k是否存在:"+k2);
        Boolean k11 = stringRedisTemplate.expire("k1", 10, TimeUnit.SECONDS);
        System.out.println("设置过期时间的k"+k11);
    }

//关于String的操作: 在封装的StringRedisTemplate类对应每种数据类型的操作 对应相应的类来完成
    @Test
    void textString(){
        ValueOperations<String, String> opsForValue = stringRedisTemplate.opsForValue();
        //存放数据
        opsForValue.set("k1","k1");
        //存放并设置过期时间
        opsForValue.set("k2","20",2,TimeUnit.MICROSECONDS);
        //存放(有则不存放,无则存放)并设置过期时间
        Boolean aBoolean = opsForValue.setIfAbsent("k3", "v3", 2, TimeUnit.MICROSECONDS);
        System.out.println("是否设置成功:"+aBoolean);
        //获取指定k
        String k1 = opsForValue.get("k1");
        System.out.println("获取指定k"+k1);
        //设置增量
        Long k2 = opsForValue.increment("k2", 10);
        System.out.println("获取增量后的值:"+k2);
    }

 //关于Hash的操作
    @Test
    public void testHash(){
        HashOperations<String, Object, Object> forHash = 		               stringRedisTemplate.opsForHash();
        //存放数据  hset(key,field,value)
        forHash.put("user","name","ykq");
        Map<String,String> map=new HashMap<>();
        map.put("age","18");
        map.put("adrress","北京");
        forHash.putAll("user",map);
        //获取指定的元素  hget(key,field)
        Object o = forHash.get("user", "name");
        System.out.println("获取指定的元素:"+o);
        Map<Object, Object> user = forHash.entries("user");
        System.out.println("获取所有的元素:"+user);

        Set<Object> user1 = forHash.keys("user");
        System.out.println("获取所有的key:"+user1);
        List<Object> user2 = forHash.values("user");
        System.out.println("获取所有的value:"+user2);
    }
2. RedisTemplate
它属于StringRedisTemplate的父类,它的泛型默认都是Object。它可以直接存储任意类型的key和value.
java 复制代码
 @Autowired
    private RedisTemplate redisTemplate;

    @Test
    public void test01(){
        //指定key的序列化方式。
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        //指定value的序列化方式
        redisTemplate.setValueSerializer(new FastJsonRedisSerializer<>(Object.class));
		
        ValueOperations valueOperations = redisTemplate.opsForValue();
        //发现redis的database库中出现了乱码?
        // 1.key要不要序列化。要。默认使用的是jdk序列化方式 。
        valueOperations.set("k11","v11");

        System.out.println(valueOperations.get("k11"));//能否获取值。--能

        //org.springframework.data.redis.serializer.SerializationException: 序列化
        //发现报错--序列化异常---原因-User对象没有序列化
        //把内存中的数据存入磁盘---序列化过程
        valueOperations.set("k12",new User("fwx",18));

        JSONObject k12 = (JSONObject) valueOperations.get("k12");

    }

如果使用RedisTemplate每次都需要人为指定key和value的序列化

所以可以自己配置

java 复制代码
@Configuration
public class RedisTemplateConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(
            RedisConnectionFactory redisConnectionFactory)
            throws UnknownHostException {

        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);

        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
        template.setConnectionFactory(redisConnectionFactory);
        template.setKeySerializer(jackson2JsonRedisSerializer);
        template.setValueSerializer(jackson2JsonRedisSerializer);
        template.setHashKeySerializer(jackson2JsonRedisSerializer);
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }

    @Bean

    public StringRedisTemplate stringRedisTemplate(
            RedisConnectionFactory redisConnectionFactory)
            throws UnknownHostException {
        StringRedisTemplate template = new StringRedisTemplate();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
}
3. 集群模式
#集群模式
#在application配置文件中配置
spring.redis.cluster.nodes=192.168.111.188:7006,192.168.111.188:7001,192.168.111.188:7002,192.168.111.188:7003,192.168.111.188:7004,192.168.111.188:7005

3. 案例--短信业务

java 复制代码
public class SendMsgUtil {
    /**
     * 使用AK&SK初始化账号Client
     * @return Client
     * @throws Exception
     */
    
    public static Client createClient() throws Exception {
        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
                // 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID。
                .setAccessKeyId("aliyun的账号")

                // 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
                .setAccessKeySecret("aliyun的密钥");
        // Endpoint 请参考 https://api.aliyun.com/product/Dysmsapi
        config.endpoint = "dysmsapi.aliyuncs.com";
        return new com.aliyun.teaopenapi.Client(config);
    }

    /**
     * API 相关
     * @return OpenApi.Params
     */
    public static com.aliyun.teaopenapi.models.Params createApiInfo() throws Exception {
        com.aliyun.teaopenapi.models.Params params = new com.aliyun.teaopenapi.models.Params()
                // 接口名称
                .setAction("SendSms")
                // 接口版本
                .setVersion("2017-05-25")
                // 接口协议
                .setProtocol("HTTPS")
                // 接口 HTTP 方法
                .setMethod("POST")
                .setAuthType("AK")
                .setStyle("RPC")
                // 接口 PATH
                .setPathname("/")
                // 接口请求体内容格式
                .setReqBodyType("json")
                // 接口响应体内容格式
                .setBodyType("json");
        return params;
    }

    public static String sendCode(String phone) throws Exception {
        com.aliyun.teaopenapi.Client client = createClient();
        com.aliyun.teaopenapi.models.Params params = createApiInfo();
        // query params
        java.util.Map<String, Object> queries = new java.util.HashMap<>();
        queries.put("PhoneNumbers", "13388569043");
        queries.put("SignName", "短信服务的签名");
        queries.put("TemplateCode", "短信服务的模板"); //您正在申请手机注册,验证码为:${code},5分钟内有效!
        String code="123456";
        queries.put("TemplateParam", "{\"code\":\""+code+"\"}");
        // runtime options
        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
        com.aliyun.teaopenapi.models.OpenApiRequest request = new com.aliyun.teaopenapi.models.OpenApiRequest()
                .setQuery(com.aliyun.openapiutil.Client.query(queries));
        // 复制代码运行请自行打印 API 的返回值
        // 返回值为 Map 类型,可从 Map 中获得三类数据:响应体 body、响应头 headers、HTTP 返回的状态码 statusCode
        client.callApi(params, request, runtime);
        return code;
    }
}
相关推荐
飞的肖2 分钟前
前端使用 Element Plus架构vue3.0实现图片拖拉拽,后等比压缩,上传到Spring Boot后端
前端·spring boot·架构
Q_19284999064 分钟前
基于Spring Boot的摄影器材租赁回收系统
java·spring boot·后端
miss writer7 分钟前
Redis分布式锁释放锁是否必须用lua脚本?
redis·分布式·lua
gb42152871 小时前
springboot中Jackson库和jsonpath库的区别和联系。
java·spring boot·后端
亽仒凣凣1 小时前
Windows安装Redis图文教程
数据库·windows·redis
希忘auto3 小时前
详解Redis的常用命令
redis·1024程序员节
岁月变迁呀9 小时前
Redis梳理
数据库·redis·缓存
黄油饼卷咖喱鸡就味增汤拌孜然羊肉炒饭10 小时前
SpringBoot如何实现缓存预热?
java·spring boot·spring·缓存·程序员
Code apprenticeship12 小时前
怎么利用Redis实现延时队列?
数据库·redis·缓存
百度智能云技术站12 小时前
广告投放系统成本降低 70%+,基于 Redis 容量型数据库 PegaDB 的方案设计和业务实践
数据库·redis·oracle