Redis-02:Redis基础_Key键命令_String类型_Hash类型_java连接Redis_SpringData整合Redis


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

一、Redis键key基本命令

Redis 键命令用于管理 redis 的键:

  1. 该命令用于在 key 存在时删除 key:del key
  2. 序列化给定 key ,并返回被序列化的值:dump key
  3. 检查给定 key 是否存在:exists key
  4. 查找所有符合给定模式( pattern)的 key :keys pattern
       * 代表所有
       表示代表一个字符
    在这里插入图片描述
    在这里插入图片描述
  5. 为给定 key 设置过期时间(以秒计):expire key seconds
  6. 设置 key 的过期时间以毫秒计:pexpire key milliseconds
  7. 以秒为单位,返回给定 key 的剩余生存时间(ttl, time to live) :ttl key
  8. 以毫秒为单位返回 key 的剩余的过期时间:pttl key
  9. 移除 key 的过期时间,key 将持久保持:persist key
    在这里插入图片描述
  10. 修改Key的名称:rename key newkey
    在这里插入图片描述
  11. 将当前数据库的 key 移动到给定的数据库 db 当中 :move key db
  12. 返回 key 所储存的值的类型:type key在这里插入图片描述
  13. key的命名规范:
    1、key不要太长,尽量不要超过1024字节,这不仅消耗内存,而且会降低查找的效率;
    2、key也不要太短,太短的话,key的可读性会降低;
    3、在一个项目中,key最好使用统一的命名模式,例如user:123:password;
    4、key名称区分大小写

二、Redis数据类型

1、String命令(json串)与应用场景

string是redis最基本的类型,一个key对应一个value。
string类型是二进制安全的。意思是redis的string可以包含任何数据。比如jpg图片或者序列化的对象 。
string类型是Redis最基本的数据类型,一个键最大能存储512MB。

  1. set命令用于设置给定 key 的值。如果 key 已经存储值, set就覆写旧值,且无视类型 :set key_name value
  2. get命令用于获取指定 key 的值。如果 key 不存在,返回 nil 。如果key 储存的值不是字符串类型,返回一个错误:get key_name
    在这里插入图片描述
  3. setnx(set if not exists) 命令在指定的 key 不存在时,为 key 设置指定的值:setnx key_name value
    在这里插入图片描述
  4. 用于获取存储在指定 key 中字符串的子字符串。字符串的截取范围由 start 和 end 两个偏移量决定(包括 start 和 end 在内):getrange key start end
  5. getset 命令用于设置指定 key 的值,并返回 key 的旧值,当 key 不存在时,返回 nil
    在这里插入图片描述
  6. 返回 key 所储存的字符串值的长度:strlen key
  7. 同时设置一个或多个 key-value 对: mset key value key1 value1....
  8. 获取所有(一个或多个)给定 key 的值: mget key1 key2....
    在这里插入图片描述
  9. 自增:Incr 命令将 key 中储存的数字值增1。如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行incr 操作 :inct key_name
  10. Incrby 命令将 key 中储存的数字加上指定增量值 incrby key_name 增量值
  11. decr 命令将 key 中储存的数字减1decr key_namedecrby key_name 减值
    在这里插入图片描述
  12. 字符串拼接: append 命令用于为指定的 key 追加至未尾,如果不存在,为其赋值
    append key_name value
    在这里插入图片描述

String类型的应用场景

  1. String通常用于保存单个字符串或JSON字符串数据
  2. 因String是二进制安全的,所以你完全可以把一个图片文件的内容作为字符串来存储
  3. 计数器(常规key-value缓存应用。常规计数: 微博数, 粉丝数)
    incr等指令本身就具有原子操作的特性,所以我们完全可以利用redis的incr、incrby、decr、decrby等指令来实现原子计数的效果。假如,在某种场景下有3个客户端同时读取了mynum的值(值为2),然后对其同时进行了加1的操作,那么,最后mynum的值一定是5。

2、Hash命令(一个javaBean对象)与应用场景

Redis hash 是一个string类型的field和value的映射表,hash特别适合用于存储对象。 Redis 中每个 hash 可以存储:2的32次方-1 键值对(40多亿)
可以看成具有key和value的map容器,该类型非常适合于存储值对象的信息

例如Person的属性:id,age,name)

  1. 为指定的key设定field value :hset key field value
  2. 获取存储在hash中的值,根据field得到value:hget key field
    在这里插入图片描述
  3. 同时将多个 field-value (域-值)对设置到哈希表 key 中:hmset key field value field1 value1 .....
  4. 获取key所有给定字段的值 :hmget key filed field1......
  5. 返回HASH表中所有的字段和值 :hgetall key
    在这里插入图片描述
  6. 获取所有哈希表中的字段:hkeys key
  7. 获取哈希表中字段的数量:hlen key
    在这里插入图片描述
  8. 删除一个或多个hash表字段 :hdel key field1 field2...
  9. 只有在字段 field 不存在时,设置哈希表字段的值:hsetnx key filed value
  10. 为哈希表 key 中的指定字段的整数值加上增量:hincrby key field increment
    在这里插入图片描述
  11. 为哈希表 key 中的指定字段的浮点数值加上增量 :hincrbyfloat key field increment
  12. 查看哈希表 key 中,指定的字段是否存在:hexists key field
    在这里插入图片描述
    在这里插入图片描述

hash类型应用场景:存储一个对象数据

  1. 为什么不用string存储一个对象?
    hash是最接近关系数据库结构的数据类型,可以将数据库一条记录或程序中一个对象转换成hashmap存放在redis中。
  2. 用户ID为查找的key,存储的value用户对象包含姓名,年龄,生日等信息,如果用普通的key/value结构来存储,主要有以下2种存储方式:
      第一种方式将用户ID作为查找key,把其他信息封装成一个对象以序列化的方式存储,这种方式的缺点是,增加了序列化/反序列化的开销,并且在需要修改其中一项信息时,需要把整个对象取回,并且修改操作需要对并发进行保护,引入CAS等复杂问题。
     第二种方法是这个用户信息对象有多少成员就存成多少个key-value对,用用户ID+对应属性的名称作为唯一标识来取得对应属性的值,虽然省去了序列化开销和并发问题,但是用户ID为重复存储,如果存在大量这样的数据,内存浪费还是非常可观的。
  3. 总结:
    Redis提供的Hash很好的解决了这个问题,Redis的Hash实际是内部存储的Value为一个HashMap,并提供了直接存取这个Map成员的接口

三、java连接Redis

在官方网站列一些Java客户端访问,有:Jedis/Redisson/Jredis/JDBC-Redis等,其中官方推荐使用Jedis和Redisson。常用Jedis。

1、开始在 Java 中使用 Redis 前, 我们需要确保已经安装了 redis 服务及 Java redis 驱动,且你的机器上能正常使用 Java。

<!--jedis客户端依赖jar-->
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>3.1.0</version>
</dependency>

2、使用jedis客户端连接linux系统上的redis服务:

public class RedisDemo {
    /**
     * java通过Jedis客户端操作redis服务器
     * @param args
     */
    public static void main(String[] args) {
        //连接jedis服务器
        String host = "192.168.157.130";
        int port = 6379;
        Jedis jedis = new Jedis(host,port);
        //redis服务的密码
        jedis.auth("hengheng");
        //测试redis连接是否成功
        System.out.println(jedis.ping());
    }

3、想要连接成功,需要使用linux防护墙开放redis的端口:

firewall-cmd --list-ports
firewall-cmd --zone=public --add-port=6379/tcp --permanent
firewall-cmd --reload

在这里插入图片描述
4、Java操作Redis的String类型:

    /**
     * 测试字符串String
     */
    @Test
    public void test1(){
        //获取redis连接
        Jedis jedis = new Jedis("192.168.157.130",6379);
        jedis.auth("hengheng");
        jedis.set("strName","字符串的值");
        String strName = jedis.get("strName");
        System.out.println(strName);
        jedis.close();
    }

    /**
     * Rsdis的作用:为了减轻数据库MySql的压力
     * 需求:判断某key是否存在,如果存在就从Redis中查询
     *      如果不存在,就查询数据库,将要查询的数据存入redis中
     */
    @Test
    public void test2(){
        Jedis jedis = new Jedis("192.168.157.130",6379);
        jedis.auth("hengheng");
        String key = "applicationName";
        if(jedis.exists(key)){
            String result = jedis.get(key);
            System.out.println("Redis数据库中查询到:"+result);
        }else{
            //在数据库中查询
            String result = "哈哈";
            jedis.set(key,result);
            System.out.println("数据库查询的值结果:"+result);
        }
    }

5、Java jedis连接池优化以及工具类编写:

public class RedisPoolUtil {
    private static JedisPool pool;
    static {
        //1.连接池Redis Pool的基本配置信息
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxTotal(8);//最大连接数
        poolConfig.setMaxIdle(8);//最大空闲数

        //2.连接池
        String host = "192.168.157.130";
        int port = 6379;
        pool = new JedisPool(poolConfig,host,port);
    }
    
    public static Jedis getJedis(){
        //3.从连接池中获取连接
        Jedis jedis = pool.getResource();
        jedis.auth("hengheng");
        return jedis;
    }
    
    //关闭连接功能
    public static void close(Jedis jedis){
        jedis.close();
    }
}

6、java操作Redis的Hash类型:

User实体类:

@Data
public class User {
    private Integer id;
    private String username;
    private String password;
    private String name;
    private Integer age;

    public static String getKeyName(){
        return "user:";
    }
}

Redis操作Hash类型数据:

    /**
     * jedis完成对hash类型的操作
     * 需求:hash存储一个对象
     * 判断Redis中是否存在key,如果存在,直接返回对应值
     * 如果不存在,查询数据库,将查询的数据库存入redis并返回给用户
     */
    @Test
    public void test4(){
        Jedis jedis = RedisPoolUtil.getJedis();
        String id="1";
        String key = User.getKeyName()+id;
        if(jedis.exists(key)){
            //redis中取出该对象
            Map<String, String> map = jedis.hgetAll(key);
            User user = new User();
            user.setId(Integer.parseInt(map.get("id")));
            user.setName(map.get("name"));
            user.setAge(Integer.parseInt(map.get("age")));
            user.setUsername(map.get("username"));
            user.setPassword(map.get("password"));
            System.out.println("Redis缓存中:"+user);
        }else{
            //mysql中取出该对象
            User user = new User();
            user.setName("张三");
            user.setAge(19);
            user.setId(1);
            user.setUsername("zhangsan");
            user.setPassword("123");

            //将filed-value存放在HashMap中
            HashMap<String, String> map = new HashMap<>();
            map.put("id",user.getId()+"");
            map.put("name",user.getName());
            map.put("age",user.getAge()+"");
            map.put("username",user.getUsername());
            map.put("password",user.getPassword());
            jedis.hmset(key,map);
            System.out.println("数据库中:"+user);
        }
    }

四、SpringData整合Redis

Spring data 提供了RedisTemplate模版 ,它封装了redis连接池管理的逻辑,业务代码无须关心获取,释放连接逻辑;spring redis同时支持了Jedis,Jredis,rjc 客户端操作。

在这里插入图片描述
1、编写spring-redis配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc">

    <!--开启注解扫描-->
    <context:component-scan base-package="service.impl"/>

    <!--配置Jedis连接池信息-->
    <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <!--最大连接数-->
       <property name="maxTotal" value="50"/>
        <!--最大剩余数-->
        <property name="maxIdle" value="5"/>
    </bean>

    <!--Spring整合Jedis-->
    <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
        <property name="hostName" value="192.168.157.130"/>
        <property name="port" value="6379"/>
        <property name="password" value="hengheng"/>

        <!--自定义连接池配置-->
        <property name="poolConfig" ref="jedisPoolConfig"></property>
    </bean>

    <!--RedisTemplate-->
    <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
        <property name="connectionFactory" ref="jedisConnectionFactory"/>

        <!--key进行序列化设置,默认JDK改为String-->
        <property name="keySerializer">
            <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
        </property>

        <!--value进行序列化设置,默认JDK改为String-->
        <property name="valueSerializer">
            <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
        </property>
    </bean>
</beans>

2、编写Service层:

public interface UserService {
    public String getString(String key);
}
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    RedisTemplate<String,String> redisTemplate;

    @Override
    public String getString(String key) {
    	//获取String类型
        ValueOperations<String, String> string = redisTemplate.opsForValue();

        //redisTemplate.expire("java1802",2, TimeUnit.HOURS);

        string.set("java1803","这是一个测试数据",2,TimeUnit.HOURS);

        if(redisTemplate.hasKey(key)){
            System.out.println("redis中取出。。。");
           return string.get(key);
        }else{
            String result = "RedisTemplate模板";
            string.set(key,result);
            return result;
        }
    }
}

3、编写测试类:

public class RedisTemplateTest {
    @Test
    public void test(){
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-redis.xml");
        UserService bean = context.getBean(UserServiceImpl.class);
        String key = "applicationName";
        String result = bean.getString(key);
        System.out.println(result);
    }
}
发布了665 篇原创文章 · 获赞 115 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/qq_42764468/article/details/104667727
今日推荐