JavaWeb合集12-Redis
十二、Redis
1、Redis 入门
Redis是一个基于内存的key-valule 结构数据库。
特点:基于内存存储,读写性能高
场景:适合存储热点数据(热点商品、资讯、新闻)
Redis安装包分为Windows版和Linux版:
Windows版 下载地址: https://github.com/microsoftarchive/redis/releases
Linux版 下载地址: https://download.redis.io/releases/
Redis操作工具:https://gitee.com/qishibo/AnotherRedisDesktopManager/releases
Redis的Windows版属于绿色软件,直接解压即可使用,解压后目录结构如下:

Redis启动命令(cmd):服务名 配置文件名
redis-server.exe redis.windows.conf

启动客户端(cmd操作,可对其存取数据):
redis-cli.exe
可通过配置文件中参数的设置密码,如:requirepass 123456
2、Redis 数据类型
Redis存储的是key-value结构的数据,其中key是字符串类型,value有5种常用的数据类型。
5种常用数据类型:字符串string、哈希hash、列表list、集合set、有序集合sorted set/ zset

- 字符串(string):普通字符串,Redis中最简单的数据类型。
- 哈希(hash):也叫散列,类似于Java中的HashMap结构。可以用来存对象
- 列表(list):按照插入顺序排序,可以有重复元素,类似于Java中的LinkedList,可以永来存有顺序的数据
- 集合(set):无序集合,没有重复元素,类似于Java中的HashSet,可以进行集合间的计算(交集、并集)
- 有序集合(sorted set / zset):集合中每个元素关联一个分数(score)根据分数升序排序,没有重复元素
3、Redis常用命令
3.1 字符串操作命令
set key value //设置指定key的值(如果存在key,那么就修改value) 如:set name 小明 get key //获取指定key的值 如:get namesetex key seconds value //设置指定key的值,并将key的过期时间设为seconds秒,如:setex code 2 123setnx key value //只有在key不存在时设置key的值(如果存在key不能修改value) setnx sex 男
3.2 哈希操作命令
Redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象,常用命令:

hset key field value //将哈希表key中的字段field的值设为value
//如:hset 100 name 小明 hset 100 set 男hget key field //获取存储在哈希表中指定字段的值
//如:hget 100 name 获取属性name的value值:小明hkeys key //获取哈希表中所有字段
//如:hkeys 100 结果为:name、sethvals key //获取哈希表中所有值
//如:hvals 100 结果为:小明、男hdel key field //删除存储在哈希表中的指定字段
//如:hdel 100 sex 删除set属性
3.3 列表操作命令
Redis列表(list)是简单的字符串列表,按照插入顺序排序,常用命令

lpush key value1 [value2] //将一个或多个值插入到列表头部(left左边插入)rpush key value1 [value2] //将一个或多个值插入到列表头部(right右边插入)lrange key start stop //获取列表指定范围内的元素(下标从0开始)
//lrange key 0 -1 可返回列表里的全部数据 rpop key //移除并获取列表最后一个元素lpop key //移除并获取列表最前面一个元素llen key //获取列表长度
3.4 集合操作命令
Redis set是string类型的无序集合。集合成员是唯大-的,集合中不能出现重复的数据,常用命令:

sadd key member1 [member2] //向集合添加一个或多个成员smembers key //返回集合中的所有成员scard key //获取集合的成员数sinter key1 [key2] //返回给定所有集合的交集sunion key1 [key2] //返回所有给定集合的并集srem key member1 [member2] //删除集合中一个或多个成员
3.5 有序集合操作命令
Redis有序集合是string类型元素的集合(zset),且不允许有重复成员。每个元素都会关联一个double类型的分数。通过关联一个double类型的分数来对集合进行排序, 常用命令:

zadd key score1 member1 [score2 member2] //向有序集合添加一个或多个成员zrange key start stop [WITHSCORES] //通过索引区间返回有序集合中指定区间内的成员
//加上WITHSCORES 可以输出对应的member,zrange key 0 -1 输出全部的scorezincrby key increment member //有序集合中对指定成员的分数加上增量ZREM key member [member ...] //移除有序集合中的一个或多个成员
3.6 通用命令
Redis的通用命令是不分数据类型的,都可以使用的命令:
keys pattern //查找所有符合给定模式(pattern)的key(正则表达式)exists key //检查给定key是否存在type key //返回key所储存的值的类型del key1 [key2] //该命令用于在key存在时删除key
4、在java中如何操作Redis
4.1 Redis的java客户端
Redis的Java客户端很多,常用的几种:Jedis(官方推荐的)、Lettuce、Spring Data Redis。
Spring Data Redis是Spring的一部分,对Redis底层开发包进行了高度封装。在Spring项目中,可以使用Spring Data Redis来简化操作。
4.2 Spring Date Redis使用方式
操作步骤:
-
导入Spring Data Redis的maven坐标
<dependency> <groupId>org.springframework.boot</ groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> -
配置Redis数据源
spring:data:redis:host: localhostport: 6379password: 123456 -
编写配置类,创建Redis Template对象
// redis配置类 @Configuration @Slf4j public class RedisConfiguration {// 配置redisTemplate@Beanpublic RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory){log.info("redisTemplate初始化中...");RedisTemplate redisTemplate = new RedisTemplate();// 设置redis的连接工厂对象redisTemplate.setConnectionFactory(redisConnectionFactory);// 设置redis字符串类型的key的序列化器StringRedisSerializer stringSerializer = new StringRedisSerializer();redisTemplate.setKeySerializer(stringSerializer); //字符串类型的key设置为StringredisTemplate.setHashKeySerializer(stringSerializer); //哈希类型的key设置为String// 设置Redis中value的序列化器(对象类型)Jackson2JsonRedisSerializer<Object> jacksonSerializer = new Jackson2JsonRedisSerializer<>(Object.class);redisTemplate.setValueSerializer(jacksonSerializer); redisTemplate.setHashValueSerializer(jacksonSerializer);// 触发 afterPropertiesSet 方法redisTemplate.afterPropertiesSet();return redisTemplate;} } -
通过Redis Template对象操作Redis
@SpringBootTest public class RedisTest {@Autowiredprivate RedisTemplate redisTemplate;@Testvoid testRedis() {//创建一个字符串类型的redis操作对象ValueOperations valueOperations = redisTemplate.opsForValue();// 创建一个哈希类型的redis操作对象HashOperations hashOperations = redisTemplate.opsForHash();// 创建一个列表类型的redis操作对象ListOperations listOperations = redisTemplate.opsForList();//创建一个集合类型的redis操作对象SetOperations setOperations = redisTemplate.opsForSet();//创建一个有序集合类型的redis操作对象ZSetOperations zSetOperations = redisTemplate.opsForZSet();}}
4.2.1 Redis字符存取串类型操作
@Testvoid stringRedis(){/*** String类型Redis:set、get、setnx、setex*///创建一个字符串类型的redis操作对象ValueOperations valueOperations =redisTemplate.opsForValue();// 设置值valueOperations.set("name","yzhy");// 获取值String name =(String) valueOperations.get("name");System.out.println(name);// 设置值并设置过期时间(10分钟)valueOperations.set("code","12345",10, TimeUnit.MINUTES);// 设置值,如果key不存在,则设置值valueOperations.setIfAbsent("code", "4321");}
4.2.2 Redis操作Hash类型存取操作
@Testvoid ridisHash(){/*** Hash类型Redis:hset、hget、hkeys、hvals、hlen、hdel*/// 创建一个哈希类型的redis操作对象HashOperations hashOperations =redisTemplate.opsForHash();// 设置值hashOperations.put("user","name","yhzy");hashOperations.put("user","age","18");hashOperations.put("user","sex","男");//取值String age = (String) hashOperations.get("user","age");System.out.println(age);// 取keys的集合Set keys = hashOperations.keys("user");for (Object key : keys) {System.out.println(key);}//取values的集合List values = hashOperations.values("user");for(Object value : values){System.out.println(value);}// 取hash的长度Long size = hashOperations.size("user");System.out.println(size);// 删除hashOperations.delete("user","age");}
}
4.2.3 Redis操作List数据类型
@Testvoid redisList(){/*** List类型Redis:lpush、rpush、lpop、rpop、lrange、lrem、lset、lindex、llen*/ListOperations listOperations = redisTemplate.opsForList();listOperations.rightPush("list","小明");listOperations.rightPush("list","小梅");listOperations.leftPushAll("list","小红","小刚");String name = (String) listOperations.index("list",0);System.out.println(name);List<String> list =listOperations.range("list",0,-1);for (String s : list) {System.out.println(s);}Long size = listOperations.size("list");System.out.println(size);listOperations.leftPop("list");}
}
4.2.4 Redis操作Set集合数据类型
@Testvoid redisSet(){/*** Set类型Redis:sadd、srem、smembers、scard、sismember、srandmember、sinter、sunion*/// 创建一个集合类型的redis操作对象SetOperations setOper= redisTemplate.opsForSet();setOper.add("fruitName1","苹果","香蕉","橘子");setOper.add("fruitName2","苹果","草莓","葡萄");Set<String> fruitNames= setOper.members("fruitName1");for (String fruitName : fruitNames){System.out.println(fruitName);}System.out.println(setOper.size("fruitName1"));// 判断是否包含System.out.println(setOper.isMember("fruitName1","香蕉"));// 求交集Set<String> fruitIntersect = setOper.intersect("fruitName1","fruitName2");for (String fruit : fruitIntersect){System.out.println(fruit);}System.out.println("=====================");// 求并集Set<String> fruitUnion = setOper.union("fruitName1","fruitName2");for (String fruit : fruitUnion){System.out.println(fruit);}}
4.2.5 Redis有序集合数据类型操作
@Testvoid redisZSet(){/*** ZSet类型Redis:zadd、zrem、zrange、zrevrange、zcard、zscore、zrank、zrevrank、zcount、zrangebyscore、zremrangebyrank、zremrangebyscore*/// 创建一个有序集合类型的redis操作对象ZSetOperations zSetOper= redisTemplate.opsForZSet();zSetOper.add("scors","小明",100);zSetOper.add("scors","小红",90);zSetOper.add("scors","小刚",98);System.out.println(zSetOper.size("scors"));System.out.println(zSetOper.score("scors","小刚"));//默认升序排序Set scors = zSetOper.range("scors",0,-1);for (Object o : scors){System.out.println(o);}System.out.println("======================");// 倒序Set scors1 = zSetOper.reverseRange("scors",0,-1);for (Object o : scors1){System.out.println(o);}// 删除zSetOper.remove("scors","小刚","小红");}
4.2.6 Redis通用命令
@Testvoid redisCommon(){/*** Redis通用操作:keys、etits、type、del*/// 获取所有的key(正则表达式)Set<String> keys = redisTemplate.keys("*");for (String key : keys) {System.out.print(redisTemplate.type(key)+" ");System.out.println(key);}// 判断key是否存在Boolean isExist = redisTemplate.hasKey("name");System.out.println(isExist);// 删除对应keyredisTemplate.delete("name");}
5、场景运用设计
5.1 存储营业状态
外卖商家,右自己的外卖管理端,可以添加菜品对外售卖,售卖前,需要将店铺的营业状态从打样中设置为营业中,其中这个状态,是保存到Redis中的。(0代表:打样中;1代表:营业中)
@RestController
@RequestMapping("/admin/shop")
public class ShopController {private static final String KEY="SHOP_STATUS_KEY";@Autowiredprivate RedisTemplate redisTemplate;/*** 设置店铺状态* @param status* @return*/@Operation(summary = "设置店铺状态")@PutMapping("/{status}")public Result setShopStatus(@PathVariable Integer status) {redisTemplate.opsForValue().set(KEY,status);return Result.success("设置成功",status);}/*** 获取店铺状态* @return*/@Operation(summary = "获取店铺状态")@GetMapping("/status")public Result getShopStatus(){Integer status =(Integer) redisTemplate.opsForValue().get(KEY);return Result.success("获取成功",status);}
}
5.2 存储和清除菜品数据
菜品分类喝套餐分类进行存储,其中分类ID作为存储的key,分类里面包含的数据作为value,来存储。
每当通过菜品分类id或者套餐分类id,来对数据进行查询时,进行先查询Redis里面是否有对应的数据,如果没有才查询数据库,从数据库里面查询出来的结果,再缓存到Redis中。
如果,对菜品,或者套装进行增删改操作时,就会将Redis中对应的一组key进行清除,如
(dish_*、setmeal_*)
//查询数据@RestController("userDishController")
@RequestMapping("/user/dish")
public class DishController {@Autowiredprivate RedisTemplate redisTemplate;@Autowiredprivate DishService dishService;@Operation(summary = "根据分类ID菜品列表")@GetMapping("/list")public Result list(Long categoryId){//1、构建KeyString key = "dish_"+categoryId;//2、查询Redis缓存List<DishVO> list = (List<DishVO>) redisTemplate.opsForValue().get(key);//3、判断缓存是否存在,存在就获取缓存,并返回if(list!=null && list.size()>0){return Result.success(list);}//4、缓存不存在,查询数据库Dish dish = new Dish();dish.setCategoryId(categoryId);list = dishService.getDishWithFlavorListByCategoryId(dish);//5、将查询结果保存到Redis缓存中(存什么类型的数据,就用什么类型的变量接收)redisTemplate.opsForValue().set(key,list);return Result.success(list);}
}
//清除缓存
@RestController
@RequestMapping("/admin/dish")
@Slf4j
public class DishController {@Autowiredprivate RedisTemplate redisTemplate;@Autowiredprivate DishService dishService;/*** 添加菜品* @param dishDto* @return*/@Operation(summary = "添加菜品")@PostMappingpublic Result addDish(@RequestBody DishDTO dishDto) {int insert = dishService.addDish(dishDto);if (insert==0) {return Result.error("添加菜品失败");}//单独清除对应key的缓存String key="dish_"+dishDto.getCategoryId();clearCache(key);return Result.success();}/*** 批量删除菜品* @param ids* @return*/@Operation(summary = "批量删除菜品")@DeleteMappingpublic Result deleteDish(@RequestParam List<Long> ids) {int delete = dishService.deleteBatch(ids);if (delete==0){return Result.error("删除失败");}//清理全部key以dish_开头缓存clearCache("dish_*");return Result.success();}@Operation(summary = "修改菜品")@PutMappingpublic Result updateDishWithFlavor(@RequestBody DishDTO dishDto){log.info("修改菜品:"+dishDto.toString());int updateNum=dishService.updateDishWithFlavor(dishDto);if (updateNum==0){return Result.error("修改失败");}//清理全部key以dish_开头缓存clearCache("dish_*");return Result.success();}/*** 清理缓存* @param pattern*/private void clearCache(String pattern){//1、查询出要清理对应缓存的keys,keys方法的参数可以匹配一个通配符,如:dish_*Set<String> keys = redisTemplate.keys(pattern);//2、清理缓存(可以传入一个集合)redisTemplate.delete(keys);}
}
6、Spring Cache
Spring Cache是一个框架, 实现了基于注解的缓存功能,只需要简单地加一个注解,就能实现缓存功能。
Spring Cache提供了一层抽象, 底层可以切换不同的缓存实现,例如:EHCache、Caffeine、Redis。
它会自动识别你所使用的缓存,只需要你导入对应缓存的jar包,如果你想使用Redis,做为缓存工具的话,你就导入Redis的jar包;如果你想使用EHCache作为缓存的话,你就导入 EHCache 的jar包。
<!--Spring Cache-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
<version>2.7.3</version>
</dependency>
| Spring Cache提供的注解 | 说明 |
|---|---|
| @EnableCaching | 开启缓存注解功能,通常加再启动类上面 |
| @Cacheable | 通常加到方法上,在方法执行前先查询缓存中是否有数据,如果有数据,则直接返回缓存数据;如果没有缓存数据,则调用方法并将方法返回值放到缓存中。 |
| @CachePut | 加到方法上,将方法的放回值放到缓存中,只放不取 |
| @CacheEvict | 将一条或多条数据从缓存中删除 |
具体的实现思路如下:
- 导入Spring Cache和Redis相关maven坐标。
- 在启动类上加入@EnableCaching注解, 开启缓存注解功能。
- 在Controller层的查询方法上加上注解@Cacheable。
- 在Controller层的保存、删除、更新等方法上加上注解@CacheEvict。
6.1 @CachePut 注解
加到方法上,将方法的放回值放到缓存中,只放不取;使用步骤,及其注意事项
格式:
@CachePut(cacheName="userCache",key="#user.id")cacheName:就是Redis(或其他缓存工具)的key的前半部分,可以任意字符串,通常是:类名+Cache
key:就是Redis(或其他缓存工具)的key的后半部分,是动态的,这里使用的是Spring表达式来获取到对象的id属性,作为后半部分。#表示Spring表达式;user表示,形参里的user对象;id表示将数据添加到数据库后,返回到形参中user对象里id属性的值。
完整的key,中间由双冒号分隔如:userCache::1、userCache::2
-
在导入对应jar包后,在启动类上加上注解:@EnableCaching
@SpringBootApplication @EnableCaching //开启缓存注解功能 public class SkyServerApplication {public static void main(String[] args) {SpringApplication.run(SkyServerApplication.class, args);} } -
Mapper层
@Mapper public interface UserMapper {@Insert("insert into user(name,sex,age) values(#{name},#{sex},#{age})")@Options(useGenteratedKeys=true,keyProperty="id") //插入数据完成后将id返回到对象中void addUser(User user); } -
Service层不变,以前怎么写现在就怎么写
@Service public UserServiceImpl implements UserService {@AutoWriteprivate UserMapper userMapper;@Overridepublic User addUser(User user){userMapper.addUser(user); return; } } -
Controller层
将注解加入到Controller成的方法上
@RestController @RequestMapping("/user") public class UserController {@Autowiredprivate UserService userService;/** cacheName:就是Redis(或其他缓存工具)的key的前半部分,可以任意字符串,通常是:类名+Cache key:就是Redis(或其他缓存工具)的key的后半部分,是动态的,这里使用的是Spring表达式来获取到对象的id属性,作为后半部分。#表示Spring表达式;user表示,形参里的user;id表示将数据添加到数据库后,返回到user对象里id属性的值。 完整的key,中间由双冒号分隔如:userCache::1、userCache::2*/@PostMapping@CachePut(cacheName="userCache",key="#user.id") //最常使用//@CachePut(cacheName="userCache",key="#result.id") //表示返回结果中的user对象的id//@CachePut(cacheName="userCache",key="#p0.id") //表示形参中的第一个参数中的id//@CachePut(cacheName="userCache",key="#a0.id") //表示形参中的第一个参数中的idpublic Result adduser(@RequesBody User user){userService.addUser(user)return Result.success(user);}}
6.2 @Cacheable注解
在方法执行前先查询缓存中是否有数据,如果有数据,则直接返回缓存数据;如果没有缓存数据,则调用方法并将方法返回值放到缓存中。
格式:
@CachePut(cacheName="userCache",key="#id"),key的值要根据形参来变化,保证与存储的key所对应。
- Controller层
@RestController
@RequestMapping("/user")
public class UserController {@Autowiredprivate UserService userService;@GetMapping// //如果有缓存就获取对应key的缓存,如果没有就执行方法,获取数据库数据存入缓存@Cacheable(cacheName="userCache",key="#id") //生成的key如:userCache::2public Result getUserById(Long id){User user= userService.getUserById(id)return Result.success(user);}}
6.3 @CacheEvict注解
将一条或多条数据从缓存中删除
-
Controller层
@RestController @RequestMapping("/user") public class UserController {@Autowiredprivate UserService userService;/**删除指定key的缓存数据*/@DeleteMapping// 将对应key的缓存进行清除@CacheEvict(cacheName="userCache",key="#id") //生成的key如:userCache::2public Result deleteUserById(Long id){User user= userService.deleteUserById(id)return Result.success();}/**删除以某某key开头的全部缓存数据,这里是以:userCache开头的全部数据*/@DeleteMapping@CacheEvict(cacheName="userCache",allEntries=true) //生成的key如:userCache::*public Result deleteAllUser(){User user= userService.deleteAllUser()return Result.success();}}
相关文章:
JavaWeb合集12-Redis
十二、Redis 1、Redis 入门 Redis是一个基于内存的key-valule 结构数据库。 特点:基于内存存储,读写性能高 场景:适合存储热点数据(热点商品、资讯、新闻) Redis安装包分为Windows版和Linux版: Windows版 下载地址: https://gith…...
【C++】在Windows中使用Boost库——实现TCP、UDP通信
目录 一、编译Boost库 二、TCP服务端 三、TCP客户端 四、UDP连接 一、编译Boost库 1. 先去官网下载Boost库源码 2. 点击下载最新的版本 下载Windows环境的压缩包,然后解压 3. 在解压后的目录路径下找到“bootstrap.bat” 打开控制台,在“bootstrap.…...
怎么提取pdf的某一页?批量提取pdf的某一页的简单方法
怎么提取pdf的某一页?在日常工作与学习中,我们经常会遇到各式各样的PDF文件,它们以其良好的兼容性和稳定性,成为了信息传输和存储的首选格式。然而,在浩瀚的文档海洋中,有时某个PDF文件中的某一页内容尤为重…...
Github优质项目推荐(第八期)
文章目录 Github优质项目推荐 - 第八期一、【manim】,66.5k stars - 创建数学动画的 Python 框架二、【siyuan】,19.5k stars - 个人知识管理软件三、 【GetQzonehistory】,1.3k stars - 获取QQ空间发布的历史说说四、【SecLists】࿰…...
快读快写模板
原理 众所周知,在c中,用putchar和getchar输入输出字符的速度是很快的,因此,我们可以考虑把数字转化为字符,按位输出;把字符读入后转化为数字的每一位。 该快读快写可以实现对所有整数类型的输入。 templ…...
make_blobs函数
make_blobs 是 scikit-learn 库中用于生成聚类(或分类)数据集的函数。它通常用于生成多个高斯分布的簇状数据,以便进行分类或聚类算法的测试和验证。make_blobs 非常灵活,可以控制簇的数量、样本数量、每个簇的标准差、中心点等参…...
特斯拉Optimus:展望智能生活新篇章
近日,特斯拉举办了 "WE ROBOT" 发布会,发布会上描绘的未来社会愿景,让无数人为之向往。在这场吸引全球无数媒体的直播中,特斯拉 Optimus 人形机器人一出场就吸引了所有观众的关注。从多家媒体现场拍摄的视频可以看出来&…...
基于Leaflet和SpringBoot的全球国家综合检索WebGIS可视化
目录 前言 一、Java后台程序设计 1、业务层设计 2、控制层设计 二、WebGIS可视化实现 1、侧边栏展示 2、空间边界信息展示 三、标注成果展示 1、面积最大的国家 2、国土面积最小的国家 3、海拔最低的国家 4、最大的群岛国家 四、总结 前言 在前面的博文中ÿ…...
【Linux】/usr/share目录
在Linux和类Unix操作系统中,/usr/share 目录是一个用于存放共享数据文件的目录。这个目录遵循Filesystem Hierarchy Standard (FHS),它定义了Linux系统中文件和目录的组织结构。/usr 代表 “user”,而 share 表示这些文件可以被系统上的多个用…...
Java中如何应用序列化 serialVersionUID 版本号呢?
文章目录 示例1:没有 serialVersionUID 的类输出结果:示例2:类修改后未定义 serialVersionUID可能出现的问题:示例3:显式定义 serialVersionUID总结最佳实践推荐阅读文章 为了更好地理解 serialVersionUID 的使用&…...
面部识别技术:AI 如何识别人脸
在科技飞速发展的今天,面部识别技术已经广泛应用于各个领域,从手机解锁到安防监控,从金融支付到门禁系统,面部识别技术正在改变着我们的生活方式。那么,AI 究竟是如何识别人脸的呢?让我们一起来揭开面部识别…...
全面解析文档对象模型(DOM)及其操作(DOM的概念与结构、操作DOM节点、描述DOM树的形成过程、用DOMParser解析字符串为DOM对象)
1. 引言 文档对象模型(DOM)是Web开发中的核心概念,它提供了一种结构化的方法来表示和操作HTML和XML文档。通过DOM,开发者可以动态地访问和更新文档的内容、结构和样式。本文将深入探讨DOM的概念与结构、操作DOM节点的方法、DOM树…...
字符串使用方法:
字符串: -- 拼接字符串 SELECT CONCAT(糯米,啊啊啊撒,删掉); -- 字符长度 SELECT LENGTH(asssssssggg); -- 转大写 SELECT UPPER(asdf); -- 转小写 SELECT LOWER(ASDFG); -- 去除左边空格 SELECT LTRIM( aaaasdrf ); -- 去除右边空格 SELECT RTRIM( aaaasdff ); -- 去除两端…...
想让前后端交互更轻松?alovajs了解一下?
作为一个前端开发者,我最近发现了一个超赞的请求库 alovajs,它真的让我眼前一亮!说实话,我感觉自己找到了前端开发的新大陆。大家知道,在前端开发中,处理 Client-Server 交互一直是个老大难的问题ÿ…...
E/MicroMsg.SDK.WXMediaMessage:checkArgs fail,thumbData is invalid 图片资源太大导致分享失败
1、微信分享报: 2、这个问题是因为图片太大导致: WXWebpageObject webpage new WXWebpageObject();webpage.webpageUrl qrCodeUrl;//用 WXWebpageObject 对象初始化一个 WXMediaMessage 对象WXMediaMessage msg new WXMediaMessage(webpage);msg.tit…...
No.21 笔记 | WEB安全 - 任意文件绕过详解 part 3
(一)空格绕过 原理 Windows系统将文件名中的空格视为空,但程序检测代码无法自动删除空格,使攻击者可借此绕过黑名单限制。基于黑名单验证的代码分析 代码未对上传文件的文件名进行去空格处理,存在安全隐患。相关代码逻…...
咸鱼自动发货 免费无需授权
下载:(两个都可以下,自己选择) https://pan.quark.cn/s/1e3039e322ad https://pan.xunlei.com/s/VO9ww89ZNkEg_Fq1wRr-fk9ZA1?pwd8x9s# 不是闲管家 闲鱼自动发货(PC端) 暂不支持密,免费使…...
Netty核心组件
1.Channel Channel可以理解为是socket连接,在客户端与服务端连接的时候就会建立一个Channel,它负责基本的IO操作(binf()、connect()、rad()、write()等); 1.1 Channel的作用 通过Channel可获得当前网络连接的通道状态…...
Windows中如何安装SSH
主要内容 一、参考资料二、主要过程法一:通过「设置」安装法二:使用 PowerShell进行安装在 Windows 中配置 OpenSSH 服务器过程截图 一、参考资料 Windows10 打开ssh服务,报错“The service name is invalid ” windows开启ssh服务教程 在 W…...
在linux上部署ollama+open-webu,且局域网访问教程
在linux上部署ollamaopen-webu,且局域网访问教程 运行ollamaopen-webui安装open-webui (待实现)下一期将加入内网穿透,实现外网访问功能 本文主要介绍如何在Windows系统快速部署Ollama开源大语言模型运行工具,并使用Op…...
Python|GIF 解析与构建(5):手搓截屏和帧率控制
目录 Python|GIF 解析与构建(5):手搓截屏和帧率控制 一、引言 二、技术实现:手搓截屏模块 2.1 核心原理 2.2 代码解析:ScreenshotData类 2.2.1 截图函数:capture_screen 三、技术实现&…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...
(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...
前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...
Ascend NPU上适配Step-Audio模型
1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统,支持多语言对话(如 中文,英文,日语),语音情感(如 开心,悲伤)&#x…...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...
Mysql8 忘记密码重置,以及问题解决
1.使用免密登录 找到配置MySQL文件,我的文件路径是/etc/mysql/my.cnf,有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...
Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...
