SpringBoot整合Redis完整篇

SpringBoot整合Redis完整篇

1、在springboot项目的pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.4.5</version><relativePath/></parent><groupId>com.example</groupId><artifactId>spring-boot-redis</artifactId><version>0.0.1-SNAPSHOT</version><name>spring-boot-redis</name><description>spring-boot-redis</description><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

2、在application.properties中配置redis参数

# Redis数据库索引(默认为0)
spring.redis.database=0
# Redis服务器地址
spring.redis.host=127.0.0.1
# Redis服务器连接端口
spring.redis.port=6379
# Redis服务器连接密码(默认为空)
spring.redis.password=
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.jedis.pool.max-active=10
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.jedis.pool.max-wait=-1ms
# 连接池中的最大空闲连接
spring.redis.jedis.pool.max-idle=10
# 连接池中的最小空闲连接
spring.redis.jedis.pool.min-idle=0
# 连接超时时间(毫秒)
spring.redis.timeout=1000ms

3、Redis的配置类

Spring 封装了RedisTemplate<K,V>对象来操作redis。

Spring在org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration类下配置的两

RedisTemplate的Bean。

RedisTemplate<Object, Object>

这个Bean使用JdkSerializationRedisSerializer进行序列化,即key, value需要实现Serializable接口,

redis数据格式比较难懂。

StringRedisTemplate,即RedisTemplate<String, String>

key和value都是String。当需要存储实体类时,需要先转为String,再存入Redis。一般转为Json格式的字符串,所

以使用StringRedisTemplate,需要手动将实体类转为Json格式。

ValueOperations<String, String> valueTemplate = stringTemplate.opsForValue();
Gson gson = new Gson();valueTemplate.set("StringKey1", "hello spring boot redis, String Redis");
String value = valueTemplate.get("StringKey1");
System.out.println(value);valueTemplate.set("StringKey2", gson.toJson(new Person("theName", 11)));
Person person = gson.fromJson(valueTemplate.get("StringKey2"), Person.class);
System.out.println(person);

Spring配置的两个RedisTemplate都不太方便使用,所以可以配置一个RedisTemplate<String,Object>

Bean,key使用String即可(包括Redis Hash 的key),value存取Redis时默认使用Json格式转换。

package com.example.springbootredisuse1.config;import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;import java.net.UnknownHostException;/*** @author zhangshixing* @date 2021年11月06日 9:44* redis 配置类*/
@Configuration
public class RedisConfig {@Bean@ConditionalOnMissingBean(name = "redisTemplate")public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)throws UnknownHostException {// 定义Jackson2JsonRedisSerializer序列化对象Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);ObjectMapper om = new ObjectMapper();// 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和publicom.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);// 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会报异常om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);jackson2JsonRedisSerializer.setObjectMapper(om);// 创建RedisTemplate<String, Object>对象RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();// 配置连接工厂template.setConnectionFactory(redisConnectionFactory);StringRedisSerializer stringSerial = new StringRedisSerializer();// redis key 序列化方式使用stringSerialtemplate.setKeySerializer(stringSerial);// redis value 序列化方式使用jacksontemplate.setValueSerializer(jackson2JsonRedisSerializer);// redis hash key 序列化方式使用stringSerialtemplate.setHashKeySerializer(stringSerial);// redis hash value 序列化方式使用jacksontemplate.setHashValueSerializer(jackson2JsonRedisSerializer);template.afterPropertiesSet();return template;}
}

4、Redis的工具类

package com.example.springbootredisuse1.utils;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;/*** @author zhangshixing* @date 2021年11月06日 9:46* redis 工具类*/
@Component
public class RedisUtils {/*** 日志对象*/private static Logger logger = LoggerFactory.getLogger(RedisUtils.class);@Autowiredprivate RedisTemplate<String, Object> redisTemplate;/*** 指定缓存失效时间** @param key  键* @param time 时间(秒)* @return*/public boolean expire(String key, long time) {try {if (time > 0) {redisTemplate.expire(key, time, TimeUnit.SECONDS);}return true;} catch (Exception e) {logger.error("RedisUtils expire(String key,long time) failure." + e.getMessage());return false;}}/*** 根据key 获取过期时间** @param key 键 不能为null* @return 时间(秒) 返回0代表为永久有效*/public long getExpire(String key) {return redisTemplate.getExpire(key, TimeUnit.SECONDS);}/*** 判断key是否存在** @param key 键* @return true 存在 false不存在*/public boolean hasKey(String key) {try {return redisTemplate.hasKey(key);} catch (Exception e) {logger.error("RedisUtils hasKey(String key) failure." + e.getMessage());return false;}}/*** 删除缓存** @param key 可以传一个值 或多个*/@SuppressWarnings("unchecked")public void del(String... key) {if (key != null && key.length > 0) {if (key.length == 1) {redisTemplate.delete(key[0]);} else {redisTemplate.delete((Collection<String>) CollectionUtils.arrayToList(key));}}}/*** 普通缓存获取** @param key 键* @return 值*/public Object get(String key) {System.out.println(key);return key == null ? null : redisTemplate.opsForValue().get(key);}/*** 普通缓存放入** @param key   键* @param value 值* @return true成功 false失败*/public boolean set(String key, Object value) {try {redisTemplate.opsForValue().set(key, value);return true;} catch (Exception e) {logger.error("RedisUtils set(String key,Object value) failure." + e.getMessage());return false;}}/*** 普通缓存放入并设置时间** @param key   键* @param value 值* @param time  时间(秒) time要大于0 如果time小于等于0 将设置无限期* @return true成功 false 失败*/public boolean set(String key, Object value, long time) {try {if (time > 0) {redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);} else {set(key, value);}return true;} catch (Exception e) {logger.error("RedisUtils set(String key,Object value,long time) failure." + e.getMessage());return false;}}/*** 递增** @param key   键* @param delta* @return*/public long incr(String key, long delta) {if (delta < 0) {throw new RuntimeException("递增因子必须大于0");}return redisTemplate.opsForValue().increment(key, delta);}/*** 递减** @param key   键* @param delta 要减少几(小于0)* @return*/public long decr(String key, long delta) {if (delta < 0) {throw new RuntimeException("递减因子必须大于0");}return redisTemplate.opsForValue().increment(key, -delta);}/*** HashGet** @param key  键 不能为null* @param item 项 不能为null* @return 值*/public Object hget(String key, String item) {return redisTemplate.opsForHash().get(key, item);}/*** 获取hashKey对应的所有键值** @param key 键* @return 对应的多个键值*/public Map<Object, Object> hmget(String key) {return redisTemplate.opsForHash().entries(key);}/*** HashSet** @param key 键* @param map 对应多个键值* @return true 成功 false 失败*/public boolean hmset(String key, Map<String, Object> map) {try {redisTemplate.opsForHash().putAll(key, map);return true;} catch (Exception e) {logger.error("RedisUtils hmset(String key, Map<String,Object> map) failure." + e.getMessage());return false;}}/*** HashSet 并设置时间** @param key  键* @param map  对应多个键值* @param time 时间(秒)* @return true成功 false失败*/public boolean hmset(String key, Map<String, Object> map, long time) {try {redisTemplate.opsForHash().putAll(key, map);if (time > 0) {expire(key, time);}return true;} catch (Exception e) {logger.error("RedisUtils hmset(String key, Map<String,Object> map, long time) failure." + e.getMessage());return false;}}/*** 向一张hash表中放入数据,如果不存在将创建** @param key   键* @param item  项* @param value 值* @return true 成功 false失败*/public boolean hset(String key, String item, Object value) {try {redisTemplate.opsForHash().put(key, item, value);return true;} catch (Exception e) {logger.error("RedisUtils hset(String key,String item,Object value) failure." + e.getMessage());return false;}}/*** 向一张hash表中放入数据,如果不存在将创建** @param key   键* @param item  项* @param value 值* @param time  时间(秒)  注意:如果已存在的hash表有时间,这里将会替换原有的时间* @return true 成功 false失败*/public boolean hset(String key, String item, Object value, long time) {try {redisTemplate.opsForHash().put(key, item, value);if (time > 0) {expire(key, time);}return true;} catch (Exception e) {logger.error("RedisUtils hset(String key,String item,Object value,long time) failure." + e.getMessage());return false;}}/*** 删除hash表中的值** @param key  键 不能为null* @param item 项 可以使多个 不能为null*/public void hdel(String key, Object... item) {redisTemplate.opsForHash().delete(key, item);}/*** 判断hash表中是否有该项的值** @param key  键 不能为null* @param item 项 不能为null* @return true 存在 false不存在*/public boolean hHasKey(String key, String item) {return redisTemplate.opsForHash().hasKey(key, item);}/*** hash递增 如果不存在,就会创建一个 并把新增后的值返回** @param key  键* @param item 项* @param by   要增加几(大于0)* @return*/public double hincr(String key, String item, double by) {return redisTemplate.opsForHash().increment(key, item, by);}/*** hash递减** @param key  键* @param item 项* @param by   要减少记(小于0)* @return*/public double hdecr(String key, String item, double by) {return redisTemplate.opsForHash().increment(key, item, -by);}/*** 根据key获取Set中的所有值** @param key 键* @return*/public Set<Object> sGet(String key) {try {return redisTemplate.opsForSet().members(key);} catch (Exception e) {logger.error("RedisUtils sGet(String key) failure." + e.getMessage());return null;}}/*** 根据value从一个set中查询,是否存在** @param key   键* @param value 值* @return true 存在 false不存在*/public boolean sHasKey(String key, Object value) {try {return redisTemplate.opsForSet().isMember(key, value);} catch (Exception e) {logger.error("RedisUtils sHasKey(String key,Object value) failure." + e.getMessage());return false;}}/*** 将数据放入set缓存** @param key    键* @param values 值 可以是多个* @return 成功个数*/public long sSet(String key, Object... values) {try {return redisTemplate.opsForSet().add(key, values);} catch (Exception e) {logger.error("RedisUtils sSet(String key, Object...values) failure." + e.getMessage());return 0;}}/*** 将set数据放入缓存** @param key    键* @param time   时间(秒)* @param values 值 可以是多个* @return 成功个数*/public long sSetAndTime(String key, long time, Object... values) {try {Long count = redisTemplate.opsForSet().add(key, values);if (time > 0) {expire(key, time);}return count;} catch (Exception e) {logger.error("RedisUtils sSetAndTime(String key,long time,Object...values) failure." + e.getMessage());return 0;}}/*** 获取set缓存的长度** @param key 键* @return*/public long sGetSetSize(String key) {try {return redisTemplate.opsForSet().size(key);} catch (Exception e) {logger.error("RedisUtils sGetSetSize(String key) failure." + e.getMessage());return 0;}}/*** 移除值为value的** @param key    键* @param values 值 可以是多个* @return 移除的个数*/public long setRemove(String key, Object... values) {try {Long count = redisTemplate.opsForSet().remove(key, values);return count;} catch (Exception e) {logger.error("RedisUtils setRemove(String key, Object ...values) failure." + e.getMessage());return 0;}}/*** 获取list缓存的内容** @param key   键* @param start 开始* @param end   结束  0 到 -1代表所有值* @return*/public List<Object> lGet(String key, long start, long end) {try {return redisTemplate.opsForList().range(key, start, end);} catch (Exception e) {logger.error("RedisUtils lGet(String key, long start, long end) failure." + e.getMessage());return null;}}/*** 获取list缓存的长度** @param key 键* @return*/public long lGetListSize(String key) {try {return redisTemplate.opsForList().size(key);} catch (Exception e) {logger.error("RedisUtils lGetListSize(String key) failure." + e.getMessage());return 0;}}/*** 通过索引 获取list中的值** @param key   键* @param index 索引  index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推* @return*/public Object lGetIndex(String key, long index) {try {return redisTemplate.opsForList().index(key, index);} catch (Exception e) {logger.error("RedisUtils lGetIndex(String key,long index) failure." + e.getMessage());return null;}}/*** 将list放入缓存** @param key   键* @param value 值* @return*/public boolean lSet(String key, Object value) {try {redisTemplate.opsForList().rightPush(key, value);return true;} catch (Exception e) {logger.error("RedisUtils lSet(String key, Object value) failure." + e.getMessage());return false;}}/*** 将list放入缓存** @param key   键* @param value 值* @param time  时间(秒)* @return*/public boolean lSet(String key, Object value, long time) {try {redisTemplate.opsForList().rightPush(key, value);if (time > 0) {expire(key, time);}return true;} catch (Exception e) {logger.error("RedisUtils lSet(String key, Object value, long time) failure." + e.getMessage());return false;}}/*** 将list放入缓存** @param key   键* @param value 值* @return*/public boolean lSet(String key, List<Object> value) {try {redisTemplate.opsForList().rightPushAll(key, value);return true;} catch (Exception e) {logger.error("RedisUtils lSet(String key, List<Object> value) failure." + e.getMessage());return false;}}/*** 将list放入缓存** @param key   键* @param value 值* @param time  时间(秒)* @return*/public boolean lSet(String key, List<Object> value, long time) {try {redisTemplate.opsForList().rightPushAll(key, value);if (time > 0) {expire(key, time);}return true;} catch (Exception e) {logger.error("RedisUtils lSet(String key, List<Object> value, long time) failure." + e.getMessage());return false;}}/*** 根据索引修改list中的某条数据** @param key   键* @param index 索引* @param value 值* @return*/public boolean lUpdateIndex(String key, long index, Object value) {try {redisTemplate.opsForList().set(key, index, value);return true;} catch (Exception e) {logger.error("RedisUtils lUpdateIndex(String key, long index,Object value) failure." + e.getMessage());return false;}}/*** 移除N个值为value** @param key   键* @param count 移除多少个* @param value 值* @return 移除的个数*/public long lRemove(String key, long count, Object value) {try {Long remove = redisTemplate.opsForList().remove(key, count, value);return remove;} catch (Exception e) {logger.error("RedisUtils lRemove(String key,long count,Object value) failure." + e.getMessage());return 0;}}
}

5、RedisController

package com.example.springbootredisuse1.controller;import com.example.springbootredisuse1.utils.RedisUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;/*** @author zhangshixing* @date 2021年11月07日 10:23*/
@RequestMapping("/redis")
@RestController
public class RedisController {// redis中存储的过期时间60sprivate static int ExpireTime = 60;@Resourceprivate RedisUtils redisUtil;@RequestMapping("set")public boolean redisset(String key, String value) {return redisUtil.set(key, value);}@RequestMapping("get")public Object redisget(String key) {return redisUtil.get(key);}@RequestMapping("expire")public boolean expire(String key) {return redisUtil.expire(key, ExpireTime);}
}

6、启动类

package com.example.springbootredisuse1;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class SpringBootRedisApplication {public static void main(String[] args) {SpringApplication.run(SpringBootRedisApplication.class, args);}}

7、测试

用的Postman工具测试,也可以用浏览器或其他工具测试。

1.添加键值

在这里插入图片描述

返回:true 代表向redis中存成功

2.获取键值

在这里插入图片描述

3.设置过期时间

在这里插入图片描述

过期时间为60s,60s后再次查询:
在这里插入图片描述

发现该键已经过期,值为空。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/40028.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

分布式锁有哪些应用场景和实现?

电商网站都会遇到秒杀、特价之类的活动&#xff0c;大促活动有一个共同特点就是访问量激增&#xff0c;在高并发下会出现成千上万人抢购一个商品的场景。虽然在系统设计时会通过限流、异步、排队等方式优化&#xff0c;但整体的并发还是平时的数倍以上&#xff0c;参加活动的商…

WebRTC音视频通话-实现GPUImage视频美颜滤镜效果iOS

WebRTC音视频通话-实现GPUImage视频美颜滤镜效果 在WebRTC音视频通话的GPUImage美颜效果图如下 可以看下 之前搭建ossrs服务&#xff0c;可以查看&#xff1a;https://blog.csdn.net/gloryFlow/article/details/132257196 之前实现iOS端调用ossrs音视频通话&#xff0c;可以查…

将单个训练数据集文件拆分为:image文件和label文件(pytorch学习+蚂蚁蜜蜂数据集)

蚂蚁蜜蜂分类数据集下载链接&#xff1a;https://download.pytorch.org/tutorial/hymenoptera_data.zip 要实现如图操作&#xff1a; 将ants分为ants_image和ants_label 将bees分成bees_image和bees_label 创建ants_label和bees_label&#xff0c;并且以图片名作为txt文件的…

【机器学习】sklearn数据集的使用,数据集的获取和划分

「作者主页」&#xff1a;士别三日wyx 「作者简介」&#xff1a;CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」&#xff1a;对网络安全感兴趣的小伙伴可以关注专栏《网络安全入门到精通》 sklearn数据集 二、安装sklearn二、获取数据集三、…

mac录屏工具,录屏没有声音的解决办法

mac录屏工具&#xff0c;录屏没有声音的解决办法 在使用macbook录制屏幕时&#xff0c;发现自带的录屏工具QuickTime Player没有声音&#xff0c;于是尝试了多款录屏工具&#xff0c;对其做一些经验总结&#xff08;省流&#xff1a;APP Store直接可以免费下载使用Omi录屏专家…

第三课-界面介绍SD-Stable Diffusion 教程

前言 我们已经安装好了SD&#xff0c;这篇文章不介绍难以理解的原理&#xff0c;说使用。以后再介绍原理。 我的想法是&#xff0c;先学会画&#xff0c;然后明白原理&#xff0c;再去提高技术。 我失败过&#xff0c;知道三天打鱼两天晒网的痛苦&#xff0c;和很多人一样试了…

TiDB数据库从入门到精通系列之六:使用 TiCDC 将 TiDB 的数据同步到 Apache Kafka

TiDB数据库从入门到精通系列之六&#xff1a;使用 TiCDC 将 TiDB 的数据同步到 Apache Kafka 一、技术流程二、搭建环境三、创建Kafka changefeed四、写入数据以产生变更日志五、配置 Flink 消费 Kafka 数据 一、技术流程 快速搭建 TiCDC 集群、Kafka 集群和 Flink 集群创建 c…

【网络编程系列】网络编程实战

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kuan 的首页,持续学…

jvm内存溢出排查(使用idea自带的内存泄漏分析工具)

文章目录 1.确保生成内存溢出文件2.使用idea自带的内存泄漏分析工具3.具体实验一下 1.确保生成内存溢出文件 想分析堆内存溢出&#xff0c;一定在运行jar包时就写上参数-XX:HeapDumpOnOutOfMemoryError&#xff0c;可以看我之前关于如何运行jar包的文章。若你没有写。可以写上…

Python学习笔记_基础篇(九)_面向对象编程

本篇内容: 1、反射2、面向对象编程3、面向对象三大特性4、类成员5、类成员修饰符6、类的特殊成员7、单例模式 反射 python中的反射功能是由以下四个内置函数提供&#xff1a;hasattr、getattr、setattr、delattr&#xff0c;改四个函数分别用于对对象内部执行&#xff1a;检…

解决 adb install 错误INSTALL_FAILED_UPDATE_INCOMPATIBLE

最近给游戏出包&#xff0c;平台要求 v1 签名吧&#xff0c;AS 打包后&#xff0c;adb 执行安装到手机&#xff0c;我用的设备是google pixel6 , android 系统 13&#xff0c; 提示如下&#xff1a; adb install -r v5_android_202308161046.apk Performing Streamed Install a…

单片机第一季:零基础13——AD和DA转换

1&#xff0c;AD转换基本概念 51 单片机系统内部运算时用的全部是数字量&#xff0c;即0 和1&#xff0c;因此对单片机系统而言&#xff0c;无法直接操作模拟量&#xff0c;必须将模拟量转换成数字量。所谓数字量&#xff0c;就是用一系列0 和1 组成的二进制代码表示某个信号大…

Linux -- 进阶 Autofs自动挂载服务 实验详解

服务端创建共享目录&#xff0c; 客户端实现自动挂载 第一步 &#xff1a; 客户端&#xff0c;服务端 均关闭安全软件 [rootserver ~]# setenforce 0 [rootserver ~]# systemctl stop firewalld [rootnode1 ~]# setenforce 0 [rootnode1 ~]# systemctl stop firewalld 第二…

MyBaits(单独使用,与整合无关)小白版

文章目录 概述比较配置写xml加载上面配置并执行加载配置的方法方式一 执行方法方式一方式二(MyBatis映射器) 写配置文件的映射文件设置对象的别名&#xff08;简写&#xff09;获取自动生成的主键 查询结果和java的映射规则基本类型映射&#xff1a;简单对象映射&#xff1a;嵌…

加盐加密算法

MD5加密加盐加密项目密码升级 MD5加密 MD5一系列公式进行复杂数学运算&#xff1b;特点&#xff1a;&#xff08;用途校验和、计算hash值方式、加密&#xff09; 1&#xff1a;定长&#xff1b;无论原始数据多长&#xff1b;算出的结果都是4或者8字节的版本。 2&#xff1a;冲…

Java多线程实战

Java多线程实战 java多线程&#xff08;超详细&#xff09; java自定义线程池总结 Java创建线程方式 方法1&#xff0c;继承Thread类 方法2&#xff0c;实现Runable接口 方法2-2&#xff0c;匿名内部类形式lambda表达式 方法3&#xff0c;实现Callable接口&#xff0c;允许…

【深入理解Linux内核锁】三、原子操作

我的圈子: 高级工程师聚集地 我是董哥,高级嵌入式软件开发工程师,从事嵌入式Linux驱动开发和系统开发,曾就职于世界500强企业! 创作理念:专注分享高质量嵌入式文章,让大家读有所得! 文章目录 1、原子操作思想2、整型变量原子操作2.1 API接口2.2 API实现2.2.1 原子变量结…

log4j:WARN No appenders could be found for logger问题

本文将idea场景下的使用。 IDEA中&#xff0c;将配置文件命名为log4j.properties&#xff08;该命名才会被自动加载&#xff09;&#xff0c; 并放到某个目录下&#xff08;通常放到resources目录&#xff09;&#xff0c;并在resources上右键&#xff0c;找到Mark Directory a…

微信程序 自定义遮罩层遮不住底部tabbar解决

一、先上效果 二 方法 1、自定义底部tabbar 实现&#xff1a; https://developers.weixin.qq.com/miniprogram/dev/framework/ability/custom-tabbar.html 官网去抄 简单写下&#xff1a;在代码根目录下添加入口文件 除了js 文件的list 需要调整 其他原封不动 代码&#xf…

【路由协议】使用按需路由协议和数据包注入的即时网络模拟传递率(PDR)、总消耗能量和节点消耗能量以及延迟研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…