当前位置: 首页 > 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…...

基于大模型的招聘智能体:从创意到MVP

正在考虑下一个 SaaS 创意&#xff1f;以下是我在短短几个小时内从创意到 MVP 的过程。 以下是我将在这篇文章中介绍的内容概述&#xff1a; 为什么这个想法让我产生共鸣我是如何开始构建它的我现在的处境以及我是否会真正推出 获得 SaaS 创意并构建它并不容易。就是这样。 …...

STM32F1+HAL库+FreeTOTS学习19——软件定时器

STM32F1HAL库FreeTOTS学习19——软件定时器 1 软件定时器1.1 FreeRTOS软件定时器简介1.2 FreeRTOS软件定时器服务任务1.3 FreeRTOS软件定时器服命令队列。1.4 软件定时器的状态1.5 复位定时器1.6 软件定时器结构体 2 软件定时器配置3 软件定时器API函数3.1 xTimerCreate()和xTi…...

@RequestBody的详解和使用

RequestBody的详解和使用 提示&#xff1a;建议一定要看后面的RequestBody的核心逻辑源码以及六个重要结论&#xff01;本文前半部分的内容都是一些基- 本知识常识&#xff0c;可选择性跳过。 声明&#xff1a;本文是基于SpringBoot&#xff0c;进行的演示说明。 基础知识介…...

VMware介绍及常见使用方法

VMware 是一家全球知名的虚拟化和云计算软件提供商。以下是关于 VMware 的详细介绍: 一、主要产品和功能 VMware vSphere 服务器虚拟化平台,允许将物理服务器虚拟化为多个虚拟机(VM)。提供高可用性、资源管理、动态迁移等功能,确保业务的连续性和高效性。通过集中管理控制…...

Deepinteraction 深度交互:通过模态交互的3D对象检测

一.前提 为什么要采用跨模态的信息融合? 点云在低分辨率下提供必要的定位和几何信息&#xff0c;而图像在高分辨率下提供丰富的外观信息。 -->因此必须采用跨模态的信息融合 提出的原因? 传统的融合办法可能会由于信息融合到统一表示中的不太完美而丢失很大一部分特定…...

开展物业满意度调查的策略与注意事项

&#xff08;专业物业满意度调查公司&#xff09;在物业管理领域&#xff0c;满意度调查是一项重要的工作&#xff0c;可以帮助物业公司了解居民的需求和期望&#xff0c;及时发现并解决问题&#xff0c;提升服务质量。民安智库作为专业调查咨询机构&#xff0c;拥有丰富的实战…...

如何使用 Maven 不同环境使用不同资源文件 提升项目安全性

需求&#xff1a; 之前的文章介绍过&#xff0c;不同环境&#xff0c;配置文件可以灵活构建&#xff0c;参考Maven 不同环境灵活构建。 进一步的&#xff0c;打包时时可以进一步优化&#xff0c;即开发环境&#xff0c;构建时只将测试资源文件打包到应用中&#xff0c;进一步提…...

QT 如何置顶窗口并激活

基本上&#xff0c;客户端软件都会有置顶某个窗口的需求。置顶窗口激活窗口&#xff0c;两者不是同一个问题。有时候窗口置顶了&#xff0c;并不代表该窗口属于激活状态。本文将尝试把这两个问题一起解决了&#xff0c;请看下文&#xff1a; 一、置顶窗口 通过函数setWindowF…...

嵌入式面试刷题(day19)

Makefile和Cmake的区别 Makefile 和 CMake 都是用于构建和管理软件项目的工具,但它们有不同的设计理念和使用方式。以下是二者的主要区别: 1. 概念和工作原理 Makefile: Makefile 是 make 工具的配置文件,定义了如何编译和链接程序。它基于文件的时间戳,使用规则(规则指…...

Robot Framework命令和Tag运用

前面的文章中我们为大家介绍了市面上常见自动化测试框架的解读以及Robot Framework的环境搭建&#xff0c;本文我们继续为大家介绍Robot Framework命令和Tag的运用&#xff0c;首先我们先一起看一下Robot Framework有哪些命令。 Robot Framework命令 先来看这一条&#xff1a…...

哪里可学做网站/竞价托管推广代运营

Oracle生成流水号(SJBM_20180201_000001) 隔天重置--MYBatis集成Oracle生成流水号(SJBM_20180201_000001) 隔天重置--MYBatis集成调用使用PLSQL创建函数&#xff0c;存储过程动态生成流水号1.建立关联表TB_DPS_FLOW_NOcreate table TB_DPS_FLOW_NO(type_name VARCHAR2(100),--…...

建设工程项目查询网站/如何关闭2345网址导航

BadImageFormatException&#xff0c;未能加载正确的程序集XXX的解决办法 IDE&#xff1a;VS2010 语言&#xff1a;C# 异常&#xff1a;System.BadImageFormatException&#xff0c;未能加载正确的程序集XXX或其某一依赖项。。。 一般是由于目标程序的目标平台与其某一依赖项的…...

网页制作与网站建设宝典 第2版/seo优化网站词

功能 &#xff1a; 无需索引来访问数组元素和集合元素 String [] bookls {"你好", "黑哥", "笑一个呀"}; for(String book : books){System.out.println(book); }其中book将会自动跌送每个数组元素...

电子商务网站建设方案/百度营销中心

战舰少女R经验怎么计算呢?新版经验计算要注意些什么呢?下面小编为大家带来战舰少女R新版经验计算攻略,一起看看吧.我们以7-5~8-3(非航空战点)为基准&#xff0c;消耗20%油20%弹&#xff0c;S胜720经验。天国的 E6A E6B&#xff0c;消耗10%弹&#xff0c;S胜396经验。8-2B&…...

东莞网站建设费用/女生seo专员很难吗为什么

java并行执行多个任务: 最近做项目中,有个任务需要实现并发编程,个人参考了下网上的实现,自己实现了下并发方法,并且增加了简单的说明,希望的有需要的朋友有些帮助。 import java.util.UUID; import java.util.concurrent.CountDownLatch; import java.util.concurrent.E…...

网站商城建设合同范本/cps广告是什么意思

一、AtomicReference介绍 AtomicReference和AtomicInteger非常类似&#xff0c;不同之处就在于AtomicInteger是对整数的封装&#xff0c;而AtomicReference则对应普通的对象引用。也就是它可以保证你在修改对象引用时的线程安全性。 AtomicReference是作用是对”对象”进行原子…...