当前位置: 首页 > news >正文

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使用方式

操作步骤:

  1. 导入Spring Data Redis的maven坐标

    <dependency>
    <groupId>org.springframework.boot</ groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    
  2. 配置Redis数据源

    spring:data:redis:host: localhostport: 6379password: 123456
    
  3. 编写配置类,创建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;}
    }
    
  4. 通过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将一条或多条数据从缓存中删除

具体的实现思路如下:

  1. 导入Spring Cache和Redis相关maven坐标。
  2. 在启动类上加入@EnableCaching注解, 开启缓存注解功能。
  3. 在Controller层的查询方法上加上注解@Cacheable。
  4. 在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

  1. 在导入对应jar包后,在启动类上加上注解:@EnableCaching

    @SpringBootApplication
    @EnableCaching //开启缓存注解功能
    public class SkyServerApplication {public static void main(String[] args) {SpringApplication.run(SkyServerApplication.class, args);}
    }
    
  2. 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);
    }
    
  3. Service层不变,以前怎么写现在就怎么写

    @Service
    public UserServiceImpl implements UserService {@AutoWriteprivate UserMapper  userMapper;@Overridepublic User addUser(User user){userMapper.addUser(user); return;  }
    }
    
  4. 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所对应。

  1. 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注解

将一条或多条数据从缓存中删除

  1. 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 结构数据库。 特点&#xff1a;基于内存存储&#xff0c;读写性能高 场景&#xff1a;适合存储热点数据(热点商品、资讯、新闻) Redis安装包分为Windows版和Linux版&#xff1a; Windows版 下载地址: https://gith…...

【C++】在Windows中使用Boost库——实现TCP、UDP通信

目录 一、编译Boost库 二、TCP服务端 三、TCP客户端 四、UDP连接 一、编译Boost库 1. 先去官网下载Boost库源码 2. 点击下载最新的版本 下载Windows环境的压缩包&#xff0c;然后解压 3. 在解压后的目录路径下找到“bootstrap.bat” 打开控制台&#xff0c;在“bootstrap.…...

怎么提取pdf的某一页?批量提取pdf的某一页的简单方法

怎么提取pdf的某一页&#xff1f;在日常工作与学习中&#xff0c;我们经常会遇到各式各样的PDF文件&#xff0c;它们以其良好的兼容性和稳定性&#xff0c;成为了信息传输和存储的首选格式。然而&#xff0c;在浩瀚的文档海洋中&#xff0c;有时某个PDF文件中的某一页内容尤为重…...

Github优质项目推荐(第八期)

文章目录 Github优质项目推荐 - 第八期一、【manim】&#xff0c;66.5k stars - 创建数学动画的 Python 框架二、【siyuan】&#xff0c;19.5k stars - 个人知识管理软件三、 【GetQzonehistory】&#xff0c;1.3k stars - 获取QQ空间发布的历史说说四、【SecLists】&#xff0…...

快读快写模板

原理 众所周知&#xff0c;在c中&#xff0c;用putchar和getchar输入输出字符的速度是很快的&#xff0c;因此&#xff0c;我们可以考虑把数字转化为字符&#xff0c;按位输出&#xff1b;把字符读入后转化为数字的每一位。 该快读快写可以实现对所有整数类型的输入。 templ…...

make_blobs函数

make_blobs 是 scikit-learn 库中用于生成聚类&#xff08;或分类&#xff09;数据集的函数。它通常用于生成多个高斯分布的簇状数据&#xff0c;以便进行分类或聚类算法的测试和验证。make_blobs 非常灵活&#xff0c;可以控制簇的数量、样本数量、每个簇的标准差、中心点等参…...

特斯拉Optimus:展望智能生活新篇章

近日&#xff0c;特斯拉举办了 "WE ROBOT" 发布会&#xff0c;发布会上描绘的未来社会愿景&#xff0c;让无数人为之向往。在这场吸引全球无数媒体的直播中&#xff0c;特斯拉 Optimus 人形机器人一出场就吸引了所有观众的关注。从多家媒体现场拍摄的视频可以看出来&…...

基于Leaflet和SpringBoot的全球国家综合检索WebGIS可视化

目录 前言 一、Java后台程序设计 1、业务层设计 2、控制层设计 二、WebGIS可视化实现 1、侧边栏展示 2、空间边界信息展示 三、标注成果展示 1、面积最大的国家 2、国土面积最小的国家 3、海拔最低的国家 4、最大的群岛国家 四、总结 前言 在前面的博文中&#xff…...

【Linux】/usr/share目录

在Linux和类Unix操作系统中&#xff0c;/usr/share 目录是一个用于存放共享数据文件的目录。这个目录遵循Filesystem Hierarchy Standard (FHS)&#xff0c;它定义了Linux系统中文件和目录的组织结构。/usr 代表 “user”&#xff0c;而 share 表示这些文件可以被系统上的多个用…...

Java中如何应用序列化 serialVersionUID 版本号呢?

文章目录 示例1&#xff1a;没有 serialVersionUID 的类输出结果&#xff1a;示例2&#xff1a;类修改后未定义 serialVersionUID可能出现的问题&#xff1a;示例3&#xff1a;显式定义 serialVersionUID总结最佳实践推荐阅读文章 为了更好地理解 serialVersionUID 的使用&…...

面部识别技术:AI 如何识别人脸

在科技飞速发展的今天&#xff0c;面部识别技术已经广泛应用于各个领域&#xff0c;从手机解锁到安防监控&#xff0c;从金融支付到门禁系统&#xff0c;面部识别技术正在改变着我们的生活方式。那么&#xff0c;AI 究竟是如何识别人脸的呢&#xff1f;让我们一起来揭开面部识别…...

全面解析文档对象模型(DOM)及其操作(DOM的概念与结构、操作DOM节点、描述DOM树的形成过程、用DOMParser解析字符串为DOM对象)

1. 引言 文档对象模型&#xff08;DOM&#xff09;是Web开发中的核心概念&#xff0c;它提供了一种结构化的方法来表示和操作HTML和XML文档。通过DOM&#xff0c;开发者可以动态地访问和更新文档的内容、结构和样式。本文将深入探讨DOM的概念与结构、操作DOM节点的方法、DOM树…...

字符串使用方法:

字符串: -- 拼接字符串 SELECT CONCAT(糯米,啊啊啊撒,删掉); -- 字符长度 SELECT LENGTH(asssssssggg); -- 转大写 SELECT UPPER(asdf); -- 转小写 SELECT LOWER(ASDFG); -- 去除左边空格 SELECT LTRIM( aaaasdrf ); -- 去除右边空格 SELECT RTRIM( aaaasdff ); -- 去除两端…...

想让前后端交互更轻松?alovajs了解一下?

作为一个前端开发者&#xff0c;我最近发现了一个超赞的请求库 alovajs&#xff0c;它真的让我眼前一亮&#xff01;说实话&#xff0c;我感觉自己找到了前端开发的新大陆。大家知道&#xff0c;在前端开发中&#xff0c;处理 Client-Server 交互一直是个老大难的问题&#xff…...

E/MicroMsg.SDK.WXMediaMessage:checkArgs fail,thumbData is invalid 图片资源太大导致分享失败

1、微信分享报&#xff1a; 2、这个问题是因为图片太大导致&#xff1a; WXWebpageObject webpage new WXWebpageObject();webpage.webpageUrl qrCodeUrl;//用 WXWebpageObject 对象初始化一个 WXMediaMessage 对象WXMediaMessage msg new WXMediaMessage(webpage);msg.tit…...

No.21 笔记 | WEB安全 - 任意文件绕过详解 part 3

&#xff08;一&#xff09;空格绕过 原理 Windows系统将文件名中的空格视为空&#xff0c;但程序检测代码无法自动删除空格&#xff0c;使攻击者可借此绕过黑名单限制。基于黑名单验证的代码分析 代码未对上传文件的文件名进行去空格处理&#xff0c;存在安全隐患。相关代码逻…...

咸鱼自动发货 免费无需授权

下载&#xff1a;&#xff08;两个都可以下&#xff0c;自己选择&#xff09; https://pan.quark.cn/s/1e3039e322ad https://pan.xunlei.com/s/VO9ww89ZNkEg_Fq1wRr-fk9ZA1?pwd8x9s# 不是闲管家 闲鱼自动发货&#xff08;PC端&#xff09; 暂不支持密&#xff0c;免费使…...

Netty核心组件

1.Channel Channel可以理解为是socket连接&#xff0c;在客户端与服务端连接的时候就会建立一个Channel&#xff0c;它负责基本的IO操作&#xff08;binf()、connect()、rad()、write()等&#xff09;&#xff1b; 1.1 Channel的作用 通过Channel可获得当前网络连接的通道状态…...

Windows中如何安装SSH

主要内容 一、参考资料二、主要过程法一&#xff1a;通过「设置」安装法二&#xff1a;使用 PowerShell进行安装在 Windows 中配置 OpenSSH 服务器过程截图 一、参考资料 Windows10 打开ssh服务&#xff0c;报错“The service name is invalid ” windows开启ssh服务教程 在 W…...

在linux上部署ollama+open-webu,且局域网访问教程

在linux上部署ollamaopen-webu&#xff0c;且局域网访问教程 运行ollamaopen-webui安装open-webui &#xff08;待实现&#xff09;下一期将加入内网穿透&#xff0c;实现外网访问功能 本文主要介绍如何在Windows系统快速部署Ollama开源大语言模型运行工具&#xff0c;并使用Op…...

网络编程(Modbus进阶)

思维导图 Modbus RTU&#xff08;先学一点理论&#xff09; 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议&#xff0c;由 Modicon 公司&#xff08;现施耐德电气&#xff09;于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0&#xff1a;开发环境同步测试 cookie 至 localhost&#xff0c;便于本地请求服务携带 cookie 参考地址&#xff1a;https://juejin.cn/post/7139354571712757767 里面有源码下载下来&#xff0c;加在到扩展即可使用FeHelp…...

手游刚开服就被攻击怎么办?如何防御DDoS?

开服初期是手游最脆弱的阶段&#xff0c;极易成为DDoS攻击的目标。一旦遭遇攻击&#xff0c;可能导致服务器瘫痪、玩家流失&#xff0c;甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案&#xff0c;帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

深入理解JavaScript设计模式之单例模式

目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式&#xff08;Singleton Pattern&#…...

MODBUS TCP转CANopen 技术赋能高效协同作业

在现代工业自动化领域&#xff0c;MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步&#xff0c;这两种通讯协议也正在被逐步融合&#xff0c;形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台

🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...

docker 部署发现spring.profiles.active 问题

报错&#xff1a; org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)

上一章用到了V2 的概念&#xff0c;其实 Fiori当中还有 V4&#xff0c;咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务)&#xff0c;代理中间件&#xff08;ui5-middleware-simpleproxy&#xff09;-CSDN博客…...

三分算法与DeepSeek辅助证明是单峰函数

前置 单峰函数有唯一的最大值&#xff0c;最大值左侧的数值严格单调递增&#xff0c;最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值&#xff0c;最小值左侧的数值严格单调递减&#xff0c;最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...

Caliper 配置文件解析:fisco-bcos.json

config.yaml 文件 config.yaml 是 Caliper 的主配置文件,通常包含以下内容: test:name: fisco-bcos-test # 测试名称description: Performance test of FISCO-BCOS # 测试描述workers:type: local # 工作进程类型number: 5 # 工作进程数量monitor:type: - docker- pro…...