Stage3-day18-Linux-Redis

什么是Redis

Redis:REmote DIctionary Server(远程字典服务器)

是完全开源免费的,用C语言编写的,遵守BSD协议,是一个高性能的(key/value)分布式内存数据库,基于内存运行并支持持久化的NoSQL数据库(Not Only SQL),是当前最热门的NoSql数据库之一,也被人们称为数据结构服务器

作用

1:内存存储和持久化:redis支持异步将内存中的数据写到硬盘上,同时不影响继续服务

2:取最新N个数据的操作,如:可以将最新的10条评论的ID放在Redis的List集合里面

3:模拟类似于HttpSession这种需要设定过期时间的功能

4:发布、订阅消息系统

5:定时器、计数器

特点

1: Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用

2: Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储

3:Redis支持数据的备份,即master-slave模式的数据备份

安装

  1. 解压后进入源码解压后的文件目录,运行 make PREFIX=/usr/app/software/redis install 具体目录按需修改
  2. 进入源码目录,里面有一份配置文件 redis.conf,然后将其拷贝到安装路径下的bin文件夹中

    扫描二维码关注公众号,回复: 6513470 查看本文章

    如:cp /usr/app/redis-3.0.0/redis.conf  /usr/app/software/redis/bin

  3. 如果没有安装gcc依赖需要先安装gcc依赖: yum -y install gcc

登录Redis

启动Redis命令,以redis.conf方式启动,前提是已经复制到安装目录下了,在启动前需要先编辑该配置文件, daemonize no 改为 daemonize yes 退出保存,该配置文件中还可以配置密码端口,库的数量等,redis默认有16个库,从0到15, 启动命令是:./redis-server redis.conf此命令指示启动了服务器,可以在外部用java等操作,但是客户端内不可操作, 想要在dos命令行内操作要用redis-cli指令(redis-client客户端) ,指令为: redis-cli -a -h -p(a:密码 h:IP地址 p:端口,全都可以省略,默认是配置文件中的密码为空,地址为127.0.0.1,要是想在外部访问需要改ip地址为0.0.0.0,端口默认为6379) 要想使用DOS客户端必须先开启服务端.

Key关键字指令

常用指令:key

Keys *:指令   查看当前这个库中所有的key值

exists key:  判断某个key值是否存在 0表示不存在 1表示存在

move  key 数据库的索引下标: 将某个值移除到指定的库中

Redis默认有16个库,我们可以通过修改redis配置文件redis.conf来改变库的数量

Select 下标 :可以切换不同的数据库: 下标可以从0到15之中选

expire key 秒数:设定指定的key的存活时间

ttl  key:查看当前的key还有多少存活时间 -1 表示永不过期,-2表示已经过期

type  key: 查看当前key的类型(key String,Object)

String类型数据指令

DOS客户端内操作可以用tab键补全

Set  key  value: 设置单一键值对(key值相同会覆盖原来的值,类似于map集合),当值不存在时是新增,当值已存在时是覆盖修改

Get  key :获取指定key的值

Del  key:删除指定名称 key

Append  key  新值: 在原有的值的基础上添加新的值

Strlen  key: 获取字符串的长度

(key值必须是数字)

Incr(value值自动加1) : incr  key

decr(value值自动减1) :decr key

incrby 递增值: incrby key 每次递增数字

decrby 递减值:decrby key  每次递减数字;

------------------------------------------------------------不常用

Getrange  : GETRANGE key  start  end: 获取value值的一部分

Setrange :SETRANGE key  起始位置  值: 从起始位置开始替换值

Setex: SETEX key名字 存活时间 值: 设定一组值同时设定存活时间;

Setnx: SETNX key名字 值: 设置永久存活的一组值。(key值冲突无法存入值--返回值为0)

Mset: mset key 值 key 值....  一次设定多组值,如果key值存在也会覆盖

Mget: mget key  key  一次获取多个key的值

Msetnx: 一次设定多组key值,如果有key值存在无法添加完成

List类型(添加  删除内容)

Lpush: 向集合中添加内容  lpush 集合的名字 值 显示的顺序和添加的顺序相反。

Rpush: 向集合中添加内容  rpush 集合的名字 值 添加顺序就是显示顺序

Lrange  集合的名字 起始位置  结束位置(-1代表到集合的末尾)

Llen: llen 集合的名字 查看集合的长度

Lpop:  lpop 集合的名称  移除集合中的第一个元素 

Rpop: rop 集合的名称移除集合中的最后一个元素

lindex : 获取制定索引的值   lindex 集合的名称  索引数值

Lrem :删除指定数量的值: lrem 集合的名称  个数 值(集合中有重复值);

Set集合

Sadd:添加值 sadd  集合名称  值....

Smembers:查看值 smembers  集合名称

Scard : 集合中元素个数  scard  集合名称

Srem : 删除集合中的某个值  srem  集合名称  值;

SPOP: 随机从集合中移除一个数据   spop 集合名称

Smove: 将集合中的某个值赋给另外一个集合: SMOVE 集合1 集合2  值;

Sdiff: 差集

Sinter:交集

Sunion:并集

Hash(哈希)(key value(key value))

redis  hash是一个键值对的集合, 是一个string类型的field和value的映射表,适合用于存储对象(key value(key,value))

Hset:存放一组键值对  hset key 值的名称  具体的值;(重复添加会覆盖原来的值)  

Hget:获取一个值: hget key 值的名称

Hmset: 设定多组键值对 HMSET customer id 1 name zs address beijing

Hmget: 获取过个键对应的值 hmget customer id name address

Hgetall: 获取所有的数据 hgetall  key值;

Hdel: 删除某个指定的key的一组value  hdel customer id

Hlen: 当前的key 有几组对应的键值对

Hexists: 判断当前key中是否有指定名称的键值对: hexists customer id;

Hkeys:获取所有的key

Hvals: 获取所有的值

Hincrby: 增加指定步长的数据  hincrby customer age 2;

Hincrbyfloat: 在原有的基础上增加指定的小数。 hincrbyfloat customer course 0.5

Hsetnx: 如果key存在不能添加到集合中,如果key不存在则添加到集合中。

Zset

zset(sorted set 有序集合) 是string类型的有序集合,也不可重复

sorted set中的每个元素都需要指定一个分数,根据分数对元素进行升序排序,如果多个元素有相同的分数,则以字典序进行升序排序,sorted set 因此非常适合实现排名

Zadd:创建集合并设定标准 zadd zset01 60 v1 70 v2 80 v3 90 v4 100 v5(等级划分的数据)

游戏 : 青铜  白银 黄金。。。

普通 vip

Zrange: 查询所有的标准 ZRANGE zset01 0 -1 , ZRANGE zset01 0 -1 withscores

ZRANGEBYSCORE :根据分数查询内容

ZRANGEBYSCORE zset01 60 90 (注意如果前面添加”(” 表示不包含节点的意思) withscores limit 起始位置 数量.

Zrem :删除元素 zrem 集合  某score下对应的value值。ZREM zset01 v5

Zcard: 统计有几个键值对 zcard 集合

Zcount: zcount 集合 数值1 数值2  统计区间的值

Zrank : 统计对应的下标  zrank 集合名 values

Zscore : zscore  集合名  values 获取对应的分数

Java连接redis

1.首先要设置redis.conf配置文件中的IP地址为0.0.0.0 

2.放行6379端口: firewall-cmd --zone=public --add-port=6379/tcp --permanent 重启防火墙,systemctl restart firewalld.service,接着重启Redis服务 : redis-cli shutdown 然后 redis-server redis.conf

3.如果需要设置密码,java中也需要相应的设置连接密码

操作程序分为三步: 创建连接 -- 执行操作 -- 释放资源

1.普通连接方法

package com.offcn.test;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.offcn.bean.User;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import java.io.IOException;
import java.util.Set;
import java.util.UUID;

public class Test1 {

    @Test//保存操作
    public void test1(){
        //建立连接,创建jedis对象:Redis所在服务器ip和reids的端口号
        Jedis jedis = new Jedis("192.168.146.128",6379);
        //jedis设置登录密码,可以不写
//        jedis.auth("设置密码");
        //实现保存操作
        String key = "user";
        String value = "{\"uname\":\"zhangfei\",\"upwd\":\"123\"}";
        jedis.set(key,value);
        //释放资源
        jedis.close();
    }

    @Test//获取操作
    public void test2() throws IOException {
        //建立连接
        Jedis jedis = new Jedis("192.168.146.128",6379);
        //获取数据
        String user = jedis.get("user");
        System.out.println(user);
        ObjectMapper objectMapper = new ObjectMapper();
        User user1 = objectMapper.readValue(user, User.class);
        System.out.println(user1);
        //释放资源
        jedis.close();
    }

    @Test//使用jedis连接池保存数据
    public void test3() throws JsonProcessingException {
        //创建jedis连接池
        JedisPool jedisPool = new JedisPool("192.168.146.128",6379);
        //从池子中获取连接
        Jedis resource = jedisPool.getResource();
        //完成保存操作
        User user = new User();
        user.setUname("关羽");
        user.setUpwd("123");
        ObjectMapper objectMapper = new ObjectMapper();
        String s1 = objectMapper.writeValueAsString(user);
        UUID uuid = UUID.randomUUID();
        String s2 = uuid.toString().substring(0, 4);
        resource.set(s2,s1);
        //释放资源
        resource.close();
    }

    @Test//使用jedis连接池获取数据
    public void test4(){
        //创建jedis连接池
        JedisPool jedisPool = new JedisPool("192.168.146.128",6379);
        //从池子中获取连接
        Jedis resource = jedisPool.getResource();
        //获取数据
        String s = resource.get("e31e");
        System.out.println(s);
        //释放资源
        resource.close();
    }

    @Test//模拟一个业务层的方法
    public void test5(){
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        JedisPool pool = (JedisPool) context.getBean("pool");
        Jedis resource = pool.getResource();
        System.out.println(resource);
    }

}

2.连接池方式

package com.offcn.test;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.offcn.bean.User;
import org.junit.Test;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import java.io.IOException;
import java.util.Set;

public class Test2 {

    @Test//向redis缓存中保存数据
    public void test1() throws JsonProcessingException {
        //redis类似于连接数据库的步骤,其实redis就是一个数据库,他把数据保存到内存中
        //建立连接
        Jedis jedis = new Jedis("192.168.146.128",6379);
        //创建我们要保存的数据
        User user = new User();
        user.setUname("熊大");
        user.setUpwd("123");
        ObjectMapper objectMapper = new ObjectMapper();
        String s = objectMapper.writeValueAsString(user);
        //执行保存操作
        jedis.set("key1", s);
        //释放资源
        jedis.close();
    }

    @Test//获取jedis中的数据
    public void test2() throws IOException {
        //创建连接
        Jedis jedis = new Jedis("192.168.146.128",6379);
        //读取数据
        String value1 = jedis.get("key1");
        ObjectMapper objectMapper = new ObjectMapper();
        User user = objectMapper.readValue(value1, User.class);
        System.out.println(user.getUname()+"=="+user.getUpwd());
        //获取所有的key
        Set<String> keys = jedis.keys("*");
        for(String s:keys){
            System.out.println(s);
        }
        //释放资源
        jedis.close();
    }

    @Test//使用连接池保存数据到redis中
    public void test3() throws JsonProcessingException {
        //获取连接池
        JedisPool pool = new JedisPool("192.168.146.128",6379);
        //从连接池中获取jedis连接
        Jedis resource = pool.getResource();
        //创建资源并保存
        User user = new User();
        user.setUname("熊二");
        user.setUpwd("456");
        ObjectMapper objectMapper = new ObjectMapper();
        String s = objectMapper.writeValueAsString(user);
        //执行保存操作
        resource.set("key2",s);
        //释放资源
        resource.close();
    }

    @Test//使用连接池获取jedis中的值
    public void test4() throws IOException {
        //创建连接池
        JedisPool pool = new JedisPool("192.168.146.128",6379);
        //从连接池中获取连接
        Jedis resource = pool.getResource();
        //执行获取操作
        String value2 = resource.get("key2");
        //用jackson转化为对象
        ObjectMapper mapper = new ObjectMapper();
        User user = mapper.readValue(value2, User.class);
        System.out.println(user);
        //释放资源
        resource.close();
    }
}

Spring整合Redis

在业务层,新增一个Redis框架,作用是用来保存业务数据,或者从Redis库中获取业务数据,Redis是内存数据库,MySQL/Oracle是非内存数据库;所以如果把常用的不经常变化的业务数据保存到Redis库,那么就可以在业务层当调用这些数据的时候,不需要向MySQL等数据库发送SQL实现查询,只需要从Redis中直接获取即可,这样就可以提高效率

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       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/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--spring整合Redis-->
    <!--配置jedis池的参数-->
    <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <!-- 最大连接数 -->
        <property name="maxTotal" value="10"/>
        <!-- 空闲连接数 -->
        <property name="maxIdle" value="2"/>
        <!-- 设置链接池的连接耗尽时,是否等待 -->
        <property name="blockWhenExhausted" value="true"/>
        <!-- 最大等待时间 -->
        <property name="maxWaitMillis" value="30000"/>
        <!-- 获取到连接时,是否检查链接的有效性 -->
        <property name="testOnBorrow" value="true"/>
    </bean>

    <!--由参数把池造出来-->
    <bean id="pool" class="redis.clients.jedis.JedisPool">
        <!--参数注入-->
        <constructor-arg name="poolConfig" ref="poolConfig"></constructor-arg>
        <!--ip注入-->
        <constructor-arg name="host" value="192.168.146.132"></constructor-arg>
        <!--端口注入-->
        <constructor-arg name="port" value="6379"></constructor-arg>
    </bean>
</beans>

模拟一个业务层方法

package com.offcn.test;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import com.offcn.bean.User;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.util.UUID;

public class Test1 {

    @Test
    public void test5(){
        //此单元模拟一个业务层的方法
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-redis.xml");
        JedisPool pool = (JedisPool) context.getBean("pool");
        Jedis resource = pool.getResource();
        System.out.println(resource);
    }
}

Spring整合mybatis,实现自定义二级缓存

Mybatis二级缓存原理

Mybatis的二级缓存是指mapper映射文件。二级缓存的作用域是同一个namespace下的mapper映射文件内容,多个SqlSession共享。Mybatis需要手动设置启动二级缓存。

在同一个namespace下的mapper文件中,执行相同的查询SQL,第一次会去查询数据库,并写到缓存中;第二次直接从缓存中取。当执行SQL时两次查询中间发生了增删改操作,则二级缓存清空。

二级缓存是mapper级别的。Mybatis默认是没有开启二级缓存。

第一次调用mapper下的SQL去查询用户信息。查询到的信息会存到该mapper对应的二级缓存区域内。

第二次调用相同namespace下的mapper映射文件中相同的SQL去查询用户信息。会去对应的二级缓存内取结果。

如果调用相同namespace下的mapper映射文件中的增删改SQL,并执行了commit操作。此时会清空该namespace下的二级缓存。

猜你喜欢

转载自blog.csdn.net/qq_42837554/article/details/90648184