资讯详情

redis笔记

cache缓存

什么是缓存?为什么要用缓存?

内存在程序运行中保持一定时间不变的数据是缓存

简单来说Map ,List,Array 存储的数据可以理解为缓存

因此,缓存不是一项高大的技术,而是一个可以理解为存储数据的容器的概念

思考:设计缓存,存取基本功能:

  1. 数据可以存储在缓存中
  2. 可以在缓存中取出数据

分析:

缓存中存取数据的一系列问题

 1. 判断缓存是否存在于区域数据中,如果不存在,从数据库查询,然后将数据存储在缓存中  2. 数据库与数据库不一致  3. 多个缓存 

为了解决这些问题,更智能地管理缓存缓存框架 SpringCache,memacache,redis ,monggoDB(NOSQL)

NOSQL:Not Only SQL 非关系数据库

读写高并发数据

大量数据的读写操作

高可扩展性的数据

缓存不适用:基于事务支持,需要事务支持SQL结构化查询存储

概念
SpringBoot Cache

能有效降低数据库压力,提高整个系统的响应效率

如果缓存有数据,则从缓存中获取数据。如果缓存没有数据,则从数据库中读取

利用SpringAop动态代理,在项目启动时动态生成代理,从Spring3.1之后定义了Cache缓存框架和CacheManager(缓存管理器)统一实现不同的缓存技术界面,并支持基于注释的缓存方法

  1. 定义缓存组件(包括各种缓存集合操作)
  2. 使用spring缓存是抽象的,只需要注意以下两点
    1. 确认方法需要缓存和缓存策略
    2. 从缓存中读取以前缓存存储的数据
springcache使用三步:
  • 加依赖
<!--缓存 springboot--> <dependency>     <groupId>org.springframework.boot</groupId>     <artifactId>spring-boot-starter-cache</artifactId> </dependency> 
  • 开启缓存
@SpringBootApplication //(exclude = DataSourceAutoConfiguration.class)///启动项目不加载数据库 @EnableCaching //打开缓存注释 public class Springbootdemo1Application { 
        //springBoot项目主配置类      public static void main(String[] args) { 
                 SpringApplication.run(Springbootdemo1Application.class, args);     }  } 
  • 加缓存
spring框架本身的缓存:

Redis (单线程)session共享

依赖:

<!--redis 缓存-->         <dependency>             <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <!--lettuce也是redis的依赖-->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
            <version>2.3</version>
        </dependency>

通过配置文件启动服务端

redis-server lconfig/redis.conf:以配置文件启动

启动客户端

切换端口::redis-cli -p6379

查看redis进程

ps -ef|grep redis

客户端关闭服务:shutdown结束 exit退出

key命令
  1. 模糊查询 根据指定的规则查询符合条件的
Eg:keys pattern参数 (keys k*) //模糊查询 根据指定的规则查询符合条件的
  1. 删除某个key 删除多个key值是原子性操作
Eg:del key值(del k1)//删除某个key 删除多个key值是原子性操作
  1. exists 判断是否存在key值
Eg:127.0.0.1:6379> exists k3
   (integer) 1
  1. move移动key到指定库索引(indexdb)
Eg:127.0.0.1:6379> move zengbao 2
(integer) 1
  1. rename(rename key newKey)

  2. renamenx(rename key newKey)当newkey不存在时才能改名成功,存在就修改失败

  3. type(type key)判断key的类型

Eg:127.0.0.1:6379> type k3
string
  1. expire(指定过期时间) expire key second
Eg:127.0.0.1:6379> expire zengbao 30
(integer) 1
127.0.0.1:6379> ttl zengbao
(integer) 24
  1. expireat(expireat key timestamp) 以时间戳的形式设置key的过期时间
Eg:127.0.0.1:6379> expireat k3 1641516670
(integer) 1
  1. pexpireat(pexpireat key timestamp )以毫秒的形式设置key的过期时间
Eg:127.0.0.1:6379> pexpireat k3 1641516670
(integer) 1
  1. persist (persist key )移除key的失效时间
  2. ttl 计算key还有多少时间失效,返回key剩余失效时间(返回-2 表示key不存在 ,-1永不过时)
  3. pttl (pttl key )以毫秒为单位返回key的失效时间
  4. randomkey (randomkey key) 随机获取一个key值
  5. dump (dump key)对key序列化(序列化给定key)
String字符串类型

string是Redis中最基本的数据类型,一个Key对应一个value。String类型是二进制的,可以包含任何数据

Eg:数字,字符串,图片,序列化的对象

应用场景:统计网站访问量,在线人数

session共享解决方案:SpringSession+redis实现

  • 常用方法
    • incr (incr key number )
    • incrby (incrby key number) incrby key 负数 就减
    • decr (decr key number )
    • decrby (decrby key number) decrby key 负数 就增
    • append(append key value)给指定key追加value
Hash类型

Hash类型可以理解为Mapmap,本身就是一种键值对结构,value值又是一个Map结构,将多个key value 存在key中(散列)

应用场景:存储,读取,修改属性操作

添加多个hash

127.0.0.1:6379> hmset user id 1 name zengbao age 2//设置多个
OK
127.0.0.1:6379> hget user name//设置一个
"zengbao"
127.0.0.1:6379> hmget user name //查询多个
1) "zengbao"

查看一整个Hash表属性key和value

127.0.0.1:6379> hgetall user
1) "id"
2) "1"
3) "name"
4) "zengbao"
5) "age"
6) "2"

判断有多少个属性

127.0.0.1:6379> hlen user
(integer) 3

查询Hash表key属性中是否存在

127.0.0.1:6379> hexists user name
(integer) 1

查询Hash表所有属性key

127.0.0.1:6379> hkeys user
1) "id"
2) "name"
3) "age"

查询Hash表所有value值

127.0.0.1:6379> hvals user
1) "1"
2) "zengbao"
3) "2"

删除Hash表中的一个属性

127.0.0.1:6379> hdel user age
(integer) 1

添加并判断是否存在若存在则添加失败(hsetnx key field value)

127.0.0.1:6379> hsetnx user age 2
(integer) 1

hincrby/hincrbyfloat key field incrment(给hash表key执行字段的整数值/浮点值添加 incrment)

127.0.0.1:6379> hincrby user age 20
(integer) 22
127.0.0.1:6379> hincrbyfloat user price 6.8#浮点型
"13.6"
List(链表)类型

list就是链表,在redis中List使用双端链表来实现,结构是有序的value值可以重复,可以通过下标取出对应value值,左右两边都能 进行插入和删除数据

应用场景:排行榜、消息队列、timeline微博时间轴(有人发微博就Lpush进去,加入时间轴展示新的列表信息)

List列表允许用户从序列的两端插入和弹出元素,列表是由多个字符串组成的有序可重复的序列,所以两端的操作效率比较高

常用方法:

基本命令
fushdb 清空当前数据库
fushall 清空所有数据库

exists  key 判断key值是否存在

append追加字符串  如果字符串不存在相当于新建字符串

截取字符串长度Strlen 

key * 获取所有key值

set key 0 赋值0
incr key值相当加一
decr key值减一
incrby  key 10 设定自动步长指定增量
decrby key 10 减10设定自动步长指定减量

range
getrange key 0 3 截取字符串0到3的字符[0-3]
getrange key 0 -1 截取全部字符串

替换
abcdefg
setrange key 1 xx 变成axxdefg 替换指定的字符串

setex set with expire 设置过期时间 
setnx set if not exist 不存在再设置 再分布式常常使用 如果不存在key 就设置成功,但如果存在就设置不成功

ttl key 查看过期时间

mset 批量设置值 mset k1 v1 k2 v2 k3 v3 同时设置多个值
mget 批量取值 mset k1  k2  k3 
msetnx 如果存在就设置失败,不存在就设置成功 原子性操作,全部成功才能成功,有一个失败就失败
user:{ 
        id}:{ 
        field}
set user:1 { 
        name:value,age:value}  设置user:1对象JSOn格式
mset user:1:name value user:1:age value 同时设置多个属性

getset 先get 后set
getset key value  如果key没有值就返回get为null但set为value值下一次get就是这个值 ,如果存在值就获取值并设置新值

cas 比较并交换
window静默运行redis服务

在redis安装目录新建 redis.bat

@echo off
redis-server.exe

再新建 redis.vbe

set ws=wscript.createobject("wscript.shell")
ws.run "redis.bat /start",0

双击 redis.vbe 文件,redis服务就已经在后台安安静静地提供服务了。虽然双击后没有交互响应,但可以在任务管理器中查看

redis:
    host: 127.0.0.1 #服务器地址
    port: 6379 #默认端口号
    password: 123456 #连接密码默认密码为空
    lettuce:
      pool:
        max-active: 8 #连接池最大连接数(使用负数表示没有限制默认为8)
        #max-wait: -1 #连接池最大阻塞等待时间(使用负数表示没有限制,默认-1)
        max-idle: 8 #连接池中最大空闲连接默认为8
        min-idle: 0 #连接池中最小空闲连接默认为0
        #最大连接池:这个连接池能占有的最大数据库连接--->当前连接池占有的最小jdbc的连接(数据库连接)
        #最小连接池:连接池一直保持的jdbc的连接-->数据库连接
        #jdbc连接就是数据库连接
service接口上用注解
 /** * @Caching是:@Cacheable,@Cacheput,@CacheEvict注解的组合 * 其拥有三个属性cacheable,put,evict * 分别用于指定@Cacheable,@Cacheput,@CacheEvict注解 * 作用: * 当使用指定名字查询数据库后数据保存到缓存 * 只要是对应的属性id username age 就会直接查询缓存,而不是查询数据库 * * 1.缓存击穿 大量并发访问同时查询正好缓存过期的数据 * 2.缓存雪崩 大量key同时过期 会引发 * 3.缓存穿透 查询空值(查询空数据)会引发 * @param id * @return */
    @Caching(
            //key可以使用Spring表达式语言(SqEL)来指定
            /** * methodName --->key="#root.methodName"methodName方法名 root当前对象 * 当前被调用的方法 * target --->key="#root.target" 当前被调用的目标对象 * targetClass ---->key="#root.targetClass" 当前被调用的目标对象类 * "#a0","#root.p0" 方法参数的名字 0 表示参数的索引 * result --> 方法执行后的返回值(判断后有效) * key="#id" === key="#p0" */
            cacheable = { 
        @Cacheable(value = "cacheDemo",key = "#result+'dataMap'")},
            put ={ 
        @CachePut(value = "cacheDemo",key = "#result.id")}

            )
    Emp findEmpById(Integer id);
CacheTest类
@Component
public class DataCache { 
        

    private Map<Long, String> dataMap = new HashMap<>();

    //初始化数据
    @PostConstruct
    public void init(){ 
        
        dataMap.put(1L,"广州");
        dataMap.put(2L,"深圳");
        dataMap.put(3L,"上海");
        dataMap.put(4L,"北京");
        dataMap.put(5L,"河北");
    }

    /** * 查询,如果数据没有在缓存那么就从DataMap中取,并将数据缓存,并将缓存的数据存储 * ,如果缓存了 *@Cacheable 属性: * value:指定缓存组件的名字 * key:缓存数据使用的key 默认使用方法中的key 可以用他来指定 * keyGenerator:作用与key一样 ,二选一 * cacheManager :缓存管理器 * cacheResolver :缓存解析器(反序列化) * condition :用于指定缓存条件 ,condition = "#id>3" id值大于三才缓存 * unless 否定缓存 当unless为true不缓存 * sync 是否使用异步模式 * @param id * @return */
    @Cacheable(value = "cacheDemo",key = "#id+'_dataMap'")//cacheDemo::1dataMap(key值) value根据key值查找
    public String query(Long id){ 
        
        System.out.println("当前时间"+DateUtil.now()+"查询query ID 的值"+id);
        return dataMap.get(id);
    }
    /** * 更新 * 更新值到数据库,并且缓存更新,缓存中的存储的值 * @CachePut注解作用:主要针对方法配置能够根据方法的请求参数对其结果 * 进行缓存简单来说就是用户更新缓存数据 * 注意点: * 更新操作注解中的key和value必须与要更新缓存相同(保持一致) * value = "cacheDemo",key = "#id+'_dataMap'"这个要与查询@Cacheable中的那些名字相同 * CachePut要和Cacheable一致 */
    @CachePut(value = "cacheDemo",key = "#id+'_dataMap'")
    public String put(Long id,String value){ 
        
        System.out.println("当前时间"+DateUtil.now()+"更新 ID 的值"+id);
        dataMap.put(id,value);
        return value;
    }

    /** * 删除dataMap里面的数据,并且删除缓存cacheDemo的数据 * allEntries = true 删除所有缓存中的数据 * @CacheEvict清除缓存,删除数据库 * key:指定要清除缓存中的某条数据 * allEntries = true :删除所有缓存中的数据 * ,beforeInvocation = true 在方法执行之前清除缓存 * ,beforeInvocation = false 在方法执行之后清除缓存 * beforeInvocation = true 再方法之前使用的好处 * 如果方法出现异常缓存依旧会删除 */
    @CacheEvict(value = "cacheDemo",key = "#id+'_dataMap'")
    public void remove(Long id){ 
        
        dataMap.remove(id);
    }

}

Spring Data Redis

Spring -data-redis 是spring-data模块的一部分用来支持spring管理项目对redis的操作,使用Java操作redis 最常用的多jedis,但并不是只有jedis,还是jdbc-redis这些都是redis的Java客户端

Spring-data-redis 提供了客户端的抽象,在开发中可以忽略具体的客户端的操作带来的影响,其本身就是spring生态的一部分,比起jedis更加方便

特征:

  • 自动管理连接池
  • 提供了一个高度封装RedisTemplate类
  • 针对Jedis客户端的大量Api进行归类封装、把同一类型操作封装成Operation接口,支持Redis中的五种数据类型 String ,List,Hash,Set(),zSet,针对数据序列化和反序列化,提供了多种可以选择的策略()接口
    • JdkSerializationRedisSerializer //存储java对象
    • StringRedisSerializer //字符串
    • Jackson2JsonRedisSerializer //将对象序列化成JSON格式存储在Redis中,需要Jackson.json.jar的支持
  • 在这个Spring-data-redis 中封装了对标redis中五种数据类型操作的方法 中 的五种类型
    • opsForValue:对应String(字符串)
    • opsForZset::对应有序集合
    • opsForHash:对应哈希表hash
    • opsForList:对应list(列表)
    • opsForSet:对应无序集合
数据序列化(序列的目的是方便跨平台)

程序中数据的传输是以字节方式进行,所以数据读写操作必须要序列化操作

  1. 序列化:把对象转化为可传输的字节序列过程(存数据)
  2. 反序列化:把字节序列还原为对象的过

标签: 1903连接器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台