Redis 笔记 01

1. Redis 笔记01

Redis 是非关系型数据库 ,数据与数据之间没有关联关系


Redis 命名规范

  • key不要太长尽量不要超过1024k
  • 在一个项目中,尽量使用统一的命名规范,例如user:123:password ; 不像mysql用_ Redis使用 :分割
  • key名称区分大小写

例如: user🆔name 命名
user:1:zhangsan
user:2:lise

String 类型

  • set key value 例如:set name zhangsan
  • 如果频繁赋值,就将会覆盖掉原来的value,并且无视类型
  • setnx key value 例如:setnx age 123; setnx age 456 ;get age 结果 123
    是解决分布式锁的方式之一
  • 取值命令 get key
  • 取值命令 getrange 可选取值命令 例如: set name zhanghuihao; getrange name 0 4;
    结果zhang 从0到44截取,从0开始
  • strlen key 返回key 的长度 例如 set name zhang;
    strlen name; 结果5
  • expire key seconds 设置key的有效期 单位是s
  • ttl key 查看当前key的有效时间 -2代表失效 -1代表永久有效
  • getset key value 只能设置已经存在的key,不存在的key使用getset返回(nil).如果存在将会被重新赋值,但是会返回之前的value.例如:set name zhangsan; getset age 15 返回(nil) getset name zhanghuihao 返回(zhangsan),get name ;
    值是zhanghuihao 会被重新赋值.
  • 删除命令(不限类型) del key
  • 批量写 mset key1 value1 key2 value2 …
  • 批量读 mget key1 key2 …

注意:只能针对数字的字符串

  • incr key 每执行一次自增1 (从1开始) 例如:incr num;
    get num ;值是1,再执行 incr num ; get num ;值是2
  • decr key 同上自减
  • incrby key [数字] 按照自定义的数字增加 例如 incrby num 10 ;值是10
  • decrby key [数字] 同上

String类型运用场景:
String 类型通常用来保存单个字符串或者json字符串数字类型.String是二进制安全的,可以把图片文字的内容作为字符串存储.计数器 (常规计数,粉丝数,点赞数,微博数) 如果有100个用户同时对一个人进行点赞,点赞数不会发生变化。不会出现线程安全问题,因为 incr,decr,inceby,decrby命令都是原子性的。

Hash 类型

  • hset key filed value ;hash类型相当于java中的hashset,hashset存储数据方式是key value ;而redis也是key value 故而(filed value)相当于 value
  • hmset key filed value filed1 value1 同时在一个key 中存不同的字段值 和String类型不同
  • hget key filed
  • hmget key filed filed2 filed3 …
  • hgetall key 把key中所有的(key-value)取出来
  • del key 将整个key删除
  • hdel key filed 删除key中某个(key-value)
  • hlen key 查看 key中数据条数
  • hkeys key 获取key中的所有字段(key)
  • hsetnx key filed value 与 String类型一样
  • hincrby key filed 3 某个filed自增3(只能是数字类型)
  • hexists key filed 判断key中的某个key(字段)是否存在
  • exists key 是判断key是否存在

应用场景

hash 应用场景 :存储一个用户信息对象数据

  1. 常用于存储一个对象
  2. 不用String存储需要反序列化 而且key太多浪费内存。

Jedis 客户端

  1. springboot 整合jedis,。pom注入依赖
<dependencies>
<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!--热部署-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <optional>true</optional>
    </dependency>
    <!--小辣椒-->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>

    <!--jedis-->
    <!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>3.1.0</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
        <exclusions>
            <exclusion>
                <groupId>org.junit.vintage</groupId>
                <artifactId>junit-vintage-engine</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>
  1. yml文件/properties 配置jedisPool连接池连接信息。
server:
   port: 8080  
spring:
   redis:
      port: 6379
      host: 192.168.60.128
      password: 1234
  jedis:
     pool:
        max-active: 10
        min-idle: 2
        max-idle: 6
  1. 创建JedisConf配置类 ,相当于xml文件配置,从yml读取配置信息
@Configuration   //相当于xml配置文件
@PropertySource("classpath:application.yml ")
public class JedisConf {
//从yml文件中读取信息
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private int port;
@Value("${spring.redis.password}")
private String password;
private int timeout = 2000;
@Value("${spring.redis.jedis.pool.max-active}")
private int maxActive;
@Value("${spring.redis.jedis.pool..min-idle}")
private int minIdle;
@Value("${spring.redis.jedis.pool..max-idle}")
private int maxIdle;

@Bean   // <bean id ="jdedisPool"  class = "redis.clients.jedis" > </bean>
public JedisPool jedisPoolFactory() {
    System.out.println("JedisPool注入开始...");
    JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
    jedisPoolConfig.setMaxIdle(maxIdle);
    jedisPoolConfig.setMinIdle(minIdle);
    jedisPoolConfig.setMaxTotal(maxActive);

    JedisPool jedisPool = new JedisPool(jedisPoolConfig, host, port, timeout,password);

    System.out.println("JedisPool注入成功...");
    return jedisPool;
    }
}

Jedis 操作Redis Sring类型数据

  1. redis有什么命令 jedis就有什么方法
  2. 模拟redis+mysql 先从redis中查询,如果存在取值 。不存在从mysql中查找,存在返回并且赋值给redis,下次查找直接从redis中找,缓解了mysql的压力。
  3. 代码如下:

service层

@Service
public class PersonServiceImpl implements PersonService {
@Autowired
private JedisPool jedisPool;
@Override
public String getString(String key) {
    Jedis jedis = jedisPool.getResource();  //获取jedis对象
    String value= "";
    //redis如果存在直接取值
    if(jedis.exists(key)){
        value = jedis.get(key);
    }else{
        System.out.println("从mysql查询");
        //查询到的值
        value ="张慧豪";
        //存在 赋值给redis
        jedis.set(key,value);
    }
    jedis.close();  //关闭连接
    return value;
    }
} 
   /**
 *  测试Sting 类型
 *  需求:用户输入一个redis数据, 有效期是20s
 *  模拟验证码
 */
@Override
public void expireStr(String key, String value) {
    Jedis jedis = jedisUtil.getJedis();
    jedis.set(key,value);
    jedis.expire(key, 20);//long
    jedisUtil.close(jedis);
}

Test类

 @Autowired
private JedisPool jedisPool;
@Autowired
private PersonService personService;
/**
 * 测试jedis操作Redis String类型数据
 */
@Test
void jedisString(){
    System.out.println(jedisPool);
    String value = personService.getString("name");
    System.out.println(value);
}
 /**
 * 测试Redis key有效期
 */
@Test
void expireStr(){
    String key ="phone";
    String value="789456";
    personService.expireStr(key,value);
}

Jedis操作 hash类型数据

工具类

@Component
public class JedisUtil {
@Autowired
JedisPool jedisPool;
public Jedis getJedis(){
    return jedisPool.getResource();
}

public void close(Jedis jedis){
    jedis.close();
  }
}

service层

 /**
 *  需求:根据ID 查询用户信息
 *  先从Redis中查找,如果存在返回
 *  不存在,从Mysql中查找,返回并且赋值给Redis
 */
//#####################TODO Hash类型演示
@Override
public Person getPersonById(int id) {
    Jedis jedis = jedisUtil.getJedis();
    String key = "person"+":"+id; //Redis中key是person,mysql表是person
    Boolean hexists = jedis.hexists(key,"id");
    Person person = new Person();
    if(hexists){
        System.out.println("从Redis中查找");
        Map<String, String> hgetAll = jedis.hgetAll(key);
        person.setAddress(hgetAll.get("address"));
        person.setAge(Integer.parseInt(hgetAll.get("age")));
        person.setName(hgetAll.get("name"));
    }else{
        System.out.println("从Mysql中查找");
        person.setAge(22);
        person.setName("张三");
        person.setAddress("太原");
        HashMap<String, String> hash = new HashMap<>();
        hash.put("id",id+"");
        hash.put("age",String.valueOf(person.getAge()));
        hash.put("name",person.getName());
        hash.put("address",person.getAddress());
        jedis.hmset(key,hash);
    }
    jedisUtil.close(jedis);
    return person;
}

测试类

  /**
 * 测试Jedis 操作Redis Hash类型数据
 */
@Test
void getByid(){
    Person personById = personService.getPersonById(1001);
    System.out.println(personById.toString());
}

lettuce客户端

  1. springboot整合lettuce maven导入jar包
     <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    <!--redis 必须依赖pool2-->
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-pool2</artifactId>
    </dependency>
  1. 配置yml/properties文件
 server:
     port: 8081
 spring:
     redis:
        port: 6379
        host: 192.168.60.128
        password: 1234
     lettuce:
        pool:
           max-active: 10
           max-idle: 6
           min-idle: 2
     timeout: 2000
  1. 写配置文件LettuceConf (注意:lettuce是引入的starter-data-redis jar包 springboot已经写好了配置类)

自动配置信息位置

spring-boot-autoconfigure:x.x.x.RELEASE
spring-boot-auoconfigure-x.x.x.RELEASE.jar
org.springframework.boot.autoconfigure
data
redis 
RedisAutoConfiguration/RedisProperties 

RedisAutoConfiguration配置信息:
 @Bean
@ConditionalOnMissingBean(
    name = {"redisTemplate"}
)
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
    RedisTemplate<Object, Object> template = new RedisTemplate();
    template.setConnectionFactory(redisConnectionFactory);
    return template;
}

但是自动配置的RedisTemplate<Object, Object> redisTemplate 不能满足用户要求,需要用户自己配置添加需求。例如:反序列化。

手动配置如下

@Configuration
public class RedisConfig {
@Bean   //取代了RedisAutoConfiguration类中的 RedisTemplate
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
    RedisTemplate<Object, Object> template = new RedisTemplate();
    template.setConnectionFactory(redisConnectionFactory);
    return template;
  }
}

lettuce测试Redis中的String类型数据

Redis 有什么命令 jedis就有什么方法
* lettuce —> RedisTemplate 是对Jedis等客户端的进一步封装,故而与命令不对应
实体层

@Data
public class User {
private String id ;
private String name;
private String age;
}

service层

 @Autowired
private RedisTemplate<Object,Object> redisTemplate;

/**
 * Redis 有什么命令 jedis就有什么方法
 * lettuce ---> RedisTemplate 是对Jedis等客户端的进一步封装,故而与命令不对应
 * @return
 */
@Override
public String getString(String key) {
    String value="";
   if(redisTemplate.hasKey(key)) {
      log.info("从Redis中获取值");
       value = redisTemplate.opsForValue().get(key).toString();
   }else{
       log.info("从Mysql中获取值");
       value="testStr";
       System.out.println("查询到的值为"+value);
       //存入到redis
       redisTemplate.opsForValue().set(key,value);
   }
    return value;
}
/**
 *  模拟时间 存 2小时 而Jedis只能针对秒
 */
public void saveVal(String key ,String value){
    redisTemplate.opsForValue().set(key,value);
    //2  timeunit 单位小时
    redisTemplate.expire(key,2, TimeUnit.HOURS) ;
}

测试类

@Autowired
private RedisTemplate<Object,Object> redisTemplate;
@Autowired
private UserService userService;
@Test
void contextLoads() {
}
@Test
void testConn(){
    System.out.println(redisTemplate);
}
@Test
void getStr(){
    String user = userService.getString("user");
    System.out.println(user);
}
@Test
void saveVal(){
    userService.saveVal("phone","456789");
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值