redis(Jedis)从0-100

导入依赖

   <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>3.3.0</version>
        </dependency>

开启项目就不多bb了 然后要配置redis环境之后再进行学习

hallo,world!

我们创建一个control类来进行演示

@Controller
public class JedisTestControl {

    @RequestMapping("/test")
    @ResponseBody
    public String text() {
        Jedis jedis = new Jedis("localhost", 6379);
        //redis的命令就是jedis的方法名 redis服务的返回的命令结果就是 jedis方法的返回值
        String set = jedis.set("hallo", "world");
        jedis.close();
        return set;
    }
}

在这里插入图片描述
redis的命令就是jedis的方法名 redis服务的返回的命令结果就是 jedis方法的返回值
jedis我们学的不多,但要学连接池

jedis连接池

jedis客户端

避免频繁的创建和销毁链接对象而消耗资源
我们在学习mysql连接池和线程池的时候,这种池子我们一般就维护一个不然容易混乱,而我们维护一个池子的任务交给ioc容器,所以这个池子要注入到ioc

思考怎么注入到ioc容器?

我们可以用注解,也可以写配置类,或者配置文件
但springboot不支持我们写配置文件,并且注解@component是不能写在源代码上的
所以我们选择写配置类来注入到ioc容器
在这里插入图片描述
类似于这样注解是不能写在源代码上的

编写ioc连接池配置类

@Configuration
public class IOCConfig {

    @Bean
    public JedisPool jedisPool() {
        return new JedisPool();
    }

}

@Bean:Spring的@Bean注解用于告诉方法,产生一个Bean对象,然后这个Bean对象交给Spring管理。产生这个Bean对象的方法Spring只会调用一次,随后这个Spring将会将这个Bean对象放在自己的IOC容器中;

@Configuration与@Bean结合使用:@Configuration可理解为用spring的时候xml里面的标签,@Bean可理解为用spring的时候xml里面的标签;

测试连接池配置类

在这里插入图片描述
这里我们暂时还没有配置jedisPool,默认是8个连接数量(下面附了底层源码),并且我们不归还索引,当我们点第九次时候连接就会阻塞了

jedisPool底层源码

我们通过源码可以看到最大连接数量是8

在这里插入图片描述
maxTotal:最大连接数
maxidle:最大空闲连接
minIdle:最小维护数量
jedis 是要在0-8之间进行维护的

测试连接池配置类2

 @RequestMapping("PoolTest")
    @ResponseBody
    public String test2(){
        Jedis resource = jedisPool.getResource();//连接池里最多八个,第九个连接就阻塞了
        final String set = resource.set("world", "king");
        resource.close();//关闭索引
        return set;

    }

我们这里关闭索引,并且把最大连接数设为1,无论我们用鼠标如何刷新网站他都会接收到的,但事实也是如此吗?我们压力测试一下发现在并发数高一点的时候程序还是会阻塞!
在这里插入图片描述

思考端口号为什么默认是6379?

在这里插入图片描述
== 我们ctrl+b 点进jedisPool的源码 就可以知道了==
在这里插入图片描述
我们可以在这里更改

spring-redis-mybatis

思考:我们上一个阶段学的时候只连接mysql,那我们为什么要学redis?

通俗来讲因为快
因为mysql是在硬盘上,他一定涉及到io的问题。对于访问量大的项目,并且要快的我们都要加一层redis缓存
我们现在把mysql的数据根据业务需求,做一份放在redis里,这样我们直接去redis里去查就可以了,所以我们先去redis里查,没有再去mysql里查,如果mysql里有那我直接拿并且为了以后的方便要写一份放在reids里! mysql里要是也没有那就是没有或者报错

思考:为什么不只用redis?

因为redis的持久化机制不是当内存上有一点变动就持久化,它在持久化的过程中会有问题,很罕见但如果没有MySQL做最终备份的话那数据就是真真切切的丢了。

利用项目认识redis


    @Override
    public ResponseBean<User> register(User user) {
        //先写持久层
        Jedis resource = jedisPool.getResource();

        if(usermapper.insertUser(user)){
            resource.set("user-"+user.getUsername(),JSONObject.toJSONString(user));
            resource.close();
            return new ResponseBean<>(ResponseBean.REGISTER_SUCCESS,"注册成功",user);
        }
        resource.close();
        return new ResponseBean<>(ResponseBean.REGISTER_FAIL,"注册失败",null);

    }
}

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

遇到的问题

1,数据库id没有设置自增,所以项目里id为null
2,xml标签里写了注解,导致出错 并且错误是嵌套状态的
nest的意思,除了筑巢以外还有嵌套的意思!那也就是说这一段报错实际上是一个异常嵌套着另一个异常!也就是说,是最内层的错误导致了上边每一层的错误从而抛出了异常!因此我直接去看后边一部分才解决

附一下前端代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<input type="text" id="username">
<br>
<input type="text" id="password">
<br>
<input type="button" id="btn" value="注册">


<script>
    document.getElementById("btn").onclick = function () {
        let elementByid = document.getElementById("username");
        let elementByid1 = document.getElementById('password');
        let user = {
            username: elementByid.value,
            password: elementByid1.value
        }
        var xmlHttpRequest = new XMLHttpRequest();
        /**
         在 JavaScript 中,使用 XMLHttpRequest 对象的 open() 方法可以建立一个 HTTP 请求。
         xhr.open(method, url, async, username, password);
         open方法包含5个参数:
         method:HTTP 请求方法,必须参数,值包括 POST、GET 和 HEAD,大小写不敏感。
         url:请求的 URL 字符串,必须参数,大部分浏览器仅支持同源请求。
         async:指定请求是否为异步方式,默认为 true。如果为 false,当状态改变时会立即调用
         onreadystatechange 属性指定的回调函数。
         username:可选参数,如果服务器需要验证,该参数指定用户名,如果未指定,当服务器需要验证时,会弹出验证窗口。
         password:可选参数,验证信息中的密码部分,如果用户名为空,则该值将被忽略。
         */
        xmlHttpRequest.open('post', '/register', true);
        //传post请求需要写
        xmlHttpRequest.setRequestHeader("Content-Type", "appliciation/json")
        //JSON.stringify 方法将某个对象转换成 JSON 字符串形式
        //发送请求
        xmlHttpRequest.send(JSON.stringify(user))


        xmlHttpRequest.onreadystatechange = function () {
            console.log(111)
            /**
             * 1.Ajax:readyState(状态值)和status(状态码)的区别
             readyState,是指运行AJAX所经历过的几种状态,无论访问是否成功都将响应的步骤,可以理解成为AJAX运行步骤,使用“ajax.readyState”获得
             status,是指无论AJAX访问是否成功,由HTTP协议根据所提交的信息,服务器所返回的HTTP头信息代码,使用“ajax.status”获得
             总体理解:可以简单的理解为state代表一个整体的状态。而status是这个大的state下面具体的小的状态。

             2.什么是readyState
             readyState是XMLHttpRequest对象的一个属性,用来标识当前XMLHttpRequest对象处于什么状态。
             readyState总共有5个状态值,分别为0~4,每个值代表了不同的含义
             0:初始化,XMLHttpRequest对象还没有完成初始化
             1:载入,XMLHttpRequest对象开始发送请求
             2:载入完成,XMLHttpRequest对象的请求发送完成
             3:解析,XMLHttpRequest对象开始读取服务器的响应
             4:完成,XMLHttpRequest对象读取服务器响应结束

             3.什么是status
             status是XMLHttpRequest对象的一个属性,表示响应的HTTP状态码
             在HTTP1.1协议下,HTTP状态码总共可分为5大类
             */
            if (xmlHttpRequest.readyState === 4 && xmlHttpRequest.status === 200) {
                var responseText = xmlHttpRequest.responseText;
                //JSON.parse()方法将JSON格式字符串转换为js对象(属性名没有双引号)
                var responseBean = JSON.parse(responseText);
                let data = responseBean.data;
                alert(data);
            }
        }
    };
</script>


</body>
</html>

lua脚本

lua简介

Lua 是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能

 mysql是多线程的 200个
redis在执行命令时候是单线程的 单线程不涉及到cpu的调动所以快
redis本身是多线程 比如执行命令是一个单线程 ,他还有一个线程去持久化这也是一个线程

为什么用lua

lua脚本可以将我们的命令打包变成一次请求响应的形式,一次处理
减小多次网络通讯的时间
lua脚本本身有流程结构语法,不那么固化,可以根据我们上一个命令的结果选择不同的redis命令去执行
保证通讯过程的线程安全

jedis 运行lua脚本

初见lua

 @Override
    public String testlua() throws IOException {
//        String luaScript="return 'hallo world'";
        String luaScript = IOUtils.resourceToString("lua/mysfirst.lua", StandardCharsets.UTF_8);
        Jedis resource = jedisPool.getResource();
        String eval = (String) resource.eval(luaScript);
        System.out.println(eval);
        resource.close();
        return eval;

    }

在这里插入图片描述
== 在项目中我们不可能让lua脚本执行一段固定的代码 我们常用的是这个==
在这里插入图片描述
lua语法就不多说了。。。感兴趣可以自己去学一下

缓存穿透

1存一个假数据,并设定过期时间(不正规)

不正规但是好用快捷,临时抱佛脚的心态

2布隆过滤器(正规)

布隆过滤器

什么是位数组?

int 类型 4字节 32 位(bit)
long 类型 8字节 64位
例子:
int[] arr = new int[]{6,2,7,14,3};
arr数组中最大值为14,考虑位的下标从0开始,需要长度为15的bit,因此每个bit代表着0~14的整数,如图所示:
在这里插入图片描述

为什么用位数组?

因为在插入和能用0或者1代表存在与否这种查找时太快了 只需要查 固定位上的0(没有) 1(有)就可以

大名鼎鼎的 BitMap(位图) (1MB = 1024KB = 1024 * 1024 Bytes = 1024 * 1024 * 8 bits)

1. 什么是BitMap

在 Redis 中,BitMap是等价于String、List等的一种数据类型,并且实现 Bitmap 的数据结构是一个简单、高效的比特位(bit)数组,可以对单个位或多个位进行设置、清除和检查等操作,通常用于表示对某些元素的状态或计数。Bitmap 可以存储 0 或 1 两种状态,每个 bit 只需要占用 1 bit 的空间,因此在占用空间方面非常节省

未完待续 明日接着更新。。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值