Spring Boot | Spring Boot 实现 “Redis缓存管理“

news2024/5/4 15:12:41

目录 :

  • Spring Boot 实现 "Redis缓存管理" :
    • 一、Spring Boot 支持的 "缓存组件" ( 如果 “没有” 明确指定使用自定义的 "cacheManager "或 "cacheResolver" ,此时 SpringBoot会按照“预先定义的顺序” 启动一个默认的 “缓存组件” 来进行 "缓存管理" )
    • 二、基于 "注解" 的 "Redis缓存管理" ( 是在"默认缓存管理" 项目的基础上,进行关于Redis缓存内容的 添加 ) - 案例演示 :
      • ① 添加 "Spring Data Redis 依赖启动器" ( 之前是用SpringBoot默认的 "Simple : 缓存组件" 来 进行 "缓存管理" , 现在选择使用"Redis"缓存组件来进行 "缓存管理" ,此时 将"缓存数据" 存储在 "Redis数据库"中 )
      • ② 添加 "Redis服务" 的 "连接配置信息"
      • ③ 使用@Cacheable、@CachePut、@CacheEvict注解 "定制缓存管理" ( 使用Redis缓存时,“缓存管理”的操作还是和"之前的操作"一样,用"Redis"缓存 可以理解为 : 此时将”缓存数据“ 存储在 "Redis数据库"中, 而不是 存储在"内存"中 )
      • ④ 将"缓存对象" 实现 "序列化" ( 实现序列化接口 : Serializable 接口 )
      • ⑤ 设置 "Redis缓存数据" 的 "有效期"
      • ⑥ 基于注解的 "Redis查询" "缓存测试"
    • 三、基于 "API" ( RedisTemplate类 ) 的 "Redis缓存管理"
      • 31. "RedisTemplate类"的 功能介绍 ( 通过该类可以在Java中 "操作Redis数据库 " )
      • 3.2 基于 "API" ( RedisTemplate类 ) 的 "Redis缓存管理" - 案例演示 :
        • ① 准备数据
        • ② 创建项目 + 开启Mysql服务 + 开启Redis服务
        • ③ 在配置"全局配置文件" 中 "配置信息"
        • ④ 编写 “数据库表” 对应的 “实体类” ( 要实现"序列化" )
        • ⑤ 编写 “操作数据库” 的 Repository接口文件 ( 通过该接口中的方法来 操作“Mysql数据库” )
        • ⑥ 编写 "控制器层"的 controller 对象
        • ⑦ 编写 "业务操作层"的 service 对象
        • ⑧ 基于 API ( RedisTemplate类 ) 的 "缓存管理" 测试

在这里插入图片描述

作者简介 :一只大皮卡丘,计算机专业学生,正在努力学习、努力敲代码中! 让我们一起继续努力学习!

该文章参考学习教材为:
《Spring Boot企业级开发教程》 黑马程序员 / 编著
文章以课本知识点 + 代码为主线,结合自己看书学习过程中的理解和感悟 ,最终成就了该文章

文章用于本人学习使用 , 同时希望能帮助大家。
欢迎大家点赞👍 收藏⭐ 关注💖哦!!!

(侵权可联系我,进行删除,如果雷同,纯属巧合)


Spring Boot 实现 “Redis缓存管理” :

一、Spring Boot 支持的 “缓存组件” ( 如果 “没有” 明确指定使用自定义的 "cacheManager "或 “cacheResolver” ,此时 SpringBoot会按照“预先定义的顺序” 启动一个默认的 “缓存组件” 来进行 “缓存管理” )

  • Spring Boot 中,数据的 "管理存储"依赖于 Spring 框架中 cache ( 缓存 ) 相关的 : org.springframework.cache.Cache
    org.springframework,cache.CacheManager ( 缓存管理器 )。

  • 如果程序中 没有 定义类型cacheManager ( 缓存管理器 ) 的 Bean 组件或者是 没有 名为 cacheResolver ( 缓存解析器 ) ,
    Spring Boot按照以下的顺序选择并启动 缓存组件

  • 选择并启用以下缓存组件( 按照指定的顺序 ) :

    Generic

    JCache (JSR -107 ) ( EhCache 3HazelcastInfinispan等 )

    EhCache 2.x

    Hazelcast

    (5) Infinispan

    (6) Couchbase

    (7) Redis

    (8) Caffeine

    (9) Simple ( 默认"缓存组件" , SpringBoot 默认使用该“缓存组件” 来 进行 “缓存管理” )


    上面我们按照 Spring Boot 缓存组件加载顺序 列举了 支持的9种缓存组件,在项目中 添加某个缓存管理组件 (例如 Redis) Spring Boot 项目会
    选择并启用对应的缓存管理器

  • 如果项目中 同时添加多个缓存组件,且 没有指定缓存管理器 /缓存解析器( cacheManager/cacheResolver ),那么 Spring Boot 按照 “指定的顺序” 来 选择使用 其中的一个 “缓存组件” 并进行“缓存管理” 。

  • Spring Boot默认的 “缓存管理” 项目 文章讲解Spring Boot默认缓存管理中,没有添加 任何缓存管理组件却能实现缓存管理。这是因为开启缓存管理后
    如果 没有指定具体的"cacheManager "或 “cacheResolver,SpringBoot 将按照 指定的顺序选择并使用缓存组件” 。

  • 如果没有任何缓存组件,会 默认使用最后一个Simple 缓存组件进行管理Simple 缓存组件Spring Boot默认缓存管理组件,它默认使用内存ConcurrentHashMap 进行 缓存存储,所以在没有添加任何第三方缓存组件的情况下也可以实现内存中的缓存管理

二、基于 “注解” 的 “Redis缓存管理” ( 是在"默认缓存管理" 项目的基础上,进行关于Redis缓存内容的 添加 ) - 案例演示 :

① 添加 “Spring Data Redis 依赖启动器” ( 之前是用SpringBoot默认的 “Simple : 缓存组件” 来 进行 “缓存管理” , 现在选择使用"Redis"缓存组件来进行 “缓存管理” ,此时 将"缓存数据" 存储在 "Redis数据库"中 )

  • Spring Boot默认的 “缓存管理” 项目基础上,( 先创建默认的“缓存管理” 项目 ,再添加"Redis缓存"相关的代码 )添加

    Spring Data Redis 依赖启动器

    <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency> 
    

② 添加 “Redis服务” 的 “连接配置信息”

  • 使用类似 Redis缓存组件进行缓存管理,缓存数据并不是Spring Boot默认缓存管理那样存储在内存中,而是需要预先搭建类似 Redis 服务数据仓库进行缓存存储。所以,这里首先需要 安装并开启 Redis 服务 : Redis的下载、安装 和 启动 ,然后 在项目的全局配置文件 : application.properties 中添加 Redis服务的 连接配置信息 :

    #Redis服务地址
    spring.data.redis.host=127.0.0.1
    #Redis服务器连接端口
    spring.data.redis.port=6379
    #Redis服务器连接密码(默认欸空)
    spring.data.redis.password=123456
    

③ 使用@Cacheable、@CachePut、@CacheEvict注解 “定制缓存管理” ( 使用Redis缓存时,“缓存管理”的操作还是和"之前的操作"一样,用"Redis"缓存 可以理解为 : 此时将”缓存数据“ 存储在 "Redis数据库"中, 而不是 存储在"内存"中 )

  • CommentService类中分别使用@Cacheable@CachePut@CacheEvict3个注解 定制缓存管理分别演示缓存数据的存储更新删除 :

  • CommentService.java

    @Service //加入到IOC容器中
    public class CommentService { //sevice业务层
    
        @Autowired
        private CommentRepository commentRepository;
    
        /**
         * @Cache()注解的使用
         */
        // #result : 表示获得 "方法" 的 "返回值" , 将查询到的数据,存储到"缓存空间"中
        @Cacheable(cacheNames = "comment",key = "#comment_id",unless = "#result == null")//SPEL表达式来设置值
        public Comment findById(int comment_id) {
            //调用commentRepository接口的祖先接口的方法来操作数据库
            Optional<Comment> option = commentRepository.findById(comment_id);
            if (option.isPresent()) { //判断其中是否有数据
                //获得其中的数据
                Comment comment = option.get();
                return comment;
            }
            return null;
        }
        
          /**
       * @CachePut()注解的使用 , 当更新数据库之后,同时将该方法的"返回值"来更新"缓存空间"中的数据
       */
      @CachePut(cacheNames = "comment",key = "#result.id") //设置该方法的"返回值"的id属性值为"key值"
      public Comment updateComment(int comment_id , String author) {
          Comment comment = findById(comment_id);
          comment.setAuthor(author);
          return  commentRepository.save(comment);
      }
        
          /**
       * @CacheEvict()注解的使用 , 在删除数据库中数据成功后,同时也删除"缓存空间"中对应的”缓存数据“
       */
      @CacheEvict(cacheNames = "comment")
      public void deleteComment(int comment_id) {
          commentRepository.deleteById(comment_id); //调用CrudRepository接口中的方法来操作数据库
      }
        
          }
    

    上面的代码中,使用 @Cacheable@CachePut@CacheEvict 注解在数据查询更新删除方法上进行了缓存管理。在查询缓存 @Cacheable 注解中,定义了 “unless ="#result==null"”表示 “查询结果” 为空不进行缓存


    其他类代码 :

    CommentController.java

    @Controller
    @ResponseBody //将相应给前端的"返回值" 转换为"指定类型" 后 存入到 "响应体" 中
    public class CommentController {
    
        @Autowired
        private CommentService commentService;
    
    
        /**
         *  根据id来查询数据
         */
        @GetMapping("/findById/{id}") //id为"路径变量"
        public Comment findById(@PathVariable("id") int comment_id) {
            System.out.println("123123123");
            Comment comment = commentService.findById(comment_id);
            return comment;
        }
    
    
        /**
         *  更新数据
         */
        @GetMapping("/updateComment/{id}")
        public Comment updateComment(@PathVariable("id") int comment_id,@PathVariable("author") String author) {
            Comment comment = commentService.updateComment(comment_id, author);
            return comment;
        }
    
    
        /**
         *  删除数据
         */
        @GetMapping("/delete/{id}")
        public void deleteComment(@PathVariable("id") int comment_id) {
            commentService.deleteComment(comment_id);
        }
    
    
    }
    

④ 将"缓存对象" 实现 “序列化” ( 实现序列化接口 : Serializable 接口 )

  • 将"缓存对象" ( Comment对象 ) 实现 “序列化” :

    在这里插入图片描述


    Comment.java :

    //指定该实现类映射的数据库表
        @Entity(name = "t_comment") //设置ORM实体类, 并指定对应的表明
    public class Comment implements Serializable { // 对"缓存对象"进行"序列化"
    
        //表示数据库表中主键对应的属性
        @Id
        @GeneratedValue(strategy= GenerationType.IDENTITY) //设置主键的生成策略 (主键自增)
        private Integer id;
    
        @Column(name = "content") //指定映射的表字段名
        private String content;
    
        @Column(name = "author")
        private String author;
    
        @Column(name = "a_id")
        private Integer aId;
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getContent() {
            return content;
        }
    
        public void setContent(String content) {
            this.content = content;
        }
    
        public String getAuthor() {
            return author;
        }
    
        public void setAuthor(String author) {
            this.author = author;
        }
    
        public Integer getaId() {
            return aId;
        }
    
        public void setaId(Integer aId) {
            this.aId = aId;
        }
    
        @Override
        public String toString() {
            return "Comment{" +
                    "id=" + id +
                    ", content='" + content + '\'' +
                    ", author='" + author + '\'' +
                    ", aId=" + aId +
                    '}';
        }
    }
    

    在进行 Redis缓存 时,如果 不对 “缓存对象” 进行 “序列化” ,在进行缓存时,会报 IllegalArgumentException非法参数异常,提示信息要求对应的 Comment实体类必须实现序列化 : 实现 JDK自带序列化接口 : Serializable 接口

    ( 一些基本数据类型不需要序列化,因为内部已经默认实现了序列化接口 )

⑤ 设置 “Redis缓存数据” 的 “有效期”

  • 设置 “Redis缓存数据” 的 “有效期” :

    在这里插入图片描述


    application.properties

    spring.application.name=chapter_15
    
    # mysql服务信息
    spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
    spring.datasource.url=jdbc:mysql://localhost:3306/springbootdata?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT&nullCatalogMeansCurrent=true
    spring.datasource.username=root
    spring.datasource.password=root
    
    #显示使用JPA进行"数据库查询"的SQL语句,用于展示操作的Sql语句
    #这个属性决定了是否应该在控制台打印出SQL查询语句
    spring.jpa.show-sql=true
    
    #Redis服务地址
    spring.data.redis.host=127.0.0.1
    #Redis服务器连接端口
    spring.data.redis.port=6379
    #Redis服务器连接密码(默认欸空)
    spring.data.redis.password=123456
    
    #对基于注解的Redis缓存数据统一设置"有效期"为 1分钟,单位为"毫秒"
    spring.cache.redis.time-to-live= 60000
    

    上述代码中,在 Spring Boot 全局配置文件中添加了“spring.cache.redis.time-to-live”属性统一配置 Redis 数据的有效期
    ( 单位为毫秒 ),
    这种方式相对来说不够灵活
    ,并且 这种设置方式中将 “基于 APl的 Redis 缓存” 实现没有效果

⑥ 基于注解的 “Redis查询” “缓存测试”

  • 通过前面的操作,我们已经在项目中实现好了 关于 Redis 缓存管理 的 “配置” 和 “操作代码” , 并且在 项目启动类中 使用了 @EnableCaching开启了基于注解 "缓存管理" , 下面可进行 “Redis的缓存管理测试 ,访问controller类中的指定url进行 “缓存测试”。

三、基于 “API” ( RedisTemplate类 ) 的 “Redis缓存管理”

  • SpringBoot 整合 Redis 缓存实现中,除了基于注解形式Redis 缓存实现外,还有一个开发中常用的方式基于 “API” 的 “Redis缓存实现” ,下面将通过 Redis API 的方式讲解 SpringBoot 整合 Redis缓存具体实现

31. "RedisTemplate类"的 功能介绍 ( 通过该类可以在Java中 "操作Redis数据库 " )

  • RedisTemplate类 ( Redis模板类 )是 Spring 框架提供的用于与 Redis 数据库进行交互工具类 ( 通过 该类 可以在 Java 中 "操作Redis数据库 " ) 。
  • RedisTemplate 类Spring Data Redis 提供的 直接进行Redis操作Java API ( 通过该操作Redis数据库 ),可以直接注入使用,相比于Jedis 更加简便
  • RedisTemplate 可以 操作 <Object,Object >对象类型 数据,而其子类 StringRedisTemplate则是专门针对<String,String>字符串类型 的数据进行操作
  • RedisTemplate 类中提供了很多操作Redis数据库方法, 可以进行数据缓存查询缓存更新缓存修改缓存删除以及设置缓存有效期等。

3.2 基于 “API” ( RedisTemplate类 ) 的 “Redis缓存管理” - 案例演示 :

① 准备数据

先创建了一个 数据库springbootdata,然后创建了两个表 t_articlet_comment ,并向表中插入数据。
其中评论表t_commenta_id 与文章表t_article主键id 相关联 ( t_article主键作为t_comment表外键)。

springbootdata.sql

② 创建项目 + 开启Mysql服务 + 开启Redis服务
  • 在这里插入图片描述


    项目目录结构 为 :
    在这里插入图片描述

③ 在配置"全局配置文件" 中 “配置信息”
  • 在配置"全局配置文件" : application.properties 中 “配置信息” :

    application.properties

    # mysql服务信息
    spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
    spring.datasource.url=jdbc:mysql://localhost:3306/springbootdata?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT&nullCatalogMeansCurrent=true
    spring.datasource.username=root
    spring.datasource.password=root
    
    #使用JPA操作数据库时,在控制台上显示sql语句
    spring.jpa.show-sql=true
    
    #Redis服务地址
    spring.data.redis.host=127.0.0.1
    #Redis服务器连接端口
    spring.data.redis.port=6379
    #Reids服务器连接密码(默认为空)
    spring.data.redis.password=123456
    
④ 编写 “数据库表” 对应的 “实体类” ( 要实现"序列化" )
  • 编写 “数据库表” 对应的 “实体类” ( 要实现"序列化" ) :

    Comment.java

    import jakarta.persistence.*;
    
    import java.io.Serializable;
    
    //指定该实现类映射的数据库表
    @Entity(name = "t_Comment") //设置ORM实体类, 并指定对应的表明
    public class Comment implements Serializable { // implements Serializable : 进行序列化,存储数据进Redis数据库时需要
    
        //表示数据库表中主键对应的属性
        @Id
        @GeneratedValue(strategy= GenerationType.IDENTITY) //设置主键的生成策略 (主键自增)
        private Integer id;
    
        @Column(name = "content") //指定映射的表字段名
        private String content;
    
        @Column(name = "author")
        private String author;
    
        @Column(name = "a_id")
        private Integer aId;
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getContent() {
            return content;
        }
    
        public void setContent(String content) {
            this.content = content;
        }
    
        public String getAuthor() {
            return author;
        }
    
        public void setAuthor(String author) {
            this.author = author;
        }
    
        public Integer getaId() {
            return aId;
        }
    
        public void setaId(Integer aId) {
            this.aId = aId;
        }
    
        @Override
        public String toString() {
            return "Comment{" +
                    "id=" + id +
                    ", content='" + content + '\'' +
                    ", author='" + author + '\'' +
                    ", aId=" + aId +
                    '}';
        }
    }
    
⑤ 编写 “操作数据库” 的 Repository接口文件 ( 通过该接口中的方法来 操作“Mysql数据库” )
  • 编写 “操作数据库” 的 Repository接口文件 :

    CommentRepository.java

    import com.myh.chapter_17.domain.Comment;
    import org.springframework.data.jpa.repository.JpaRepository;
    import org.springframework.data.jpa.repository.Query;
    
    //Repository接口中为操作数据库的方法
    /*
      继承了JpaRepository接口,其中有操作数据库的curd方法,也用方法关键字的形式来操作数据库,或者使用@Query注解的方式来操作数据库
     */
    public interface CommentRepository extends JpaRepository<Comment,Integer> {
    
    }
    
⑥ 编写 "控制器层"的 controller 对象
  • 编写 "控制器层"的 controller 对象 :

    ApiCommentController.java

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.*;
    
    @RestController // 将该类加入到IOC容器中 + 将方法的返回值转换为指定的类型 存储到响应体中
    @RequestMapping("/api")
    public class ApiCommentController { //控制层操作类
    
        @Autowired
        private ApiCommentService apiCommentService;
    
        /**
         * 查询数据
         */
        @GetMapping("/get/{id}") //传递的参数为: 路径变量
        public Comment findById(@PathVariable("id")  int comment_id) {
            Comment comment = apiCommentService.findById(comment_id);
            return comment;
        }
    
        /**
         * 更新数据
         */
        @GetMapping("/update/{id}/{author}")
        public Comment updateComment(@PathVariable("id")  int comment_id,@PathVariable("author")  String author) {
            Comment updateComment = apiCommentService.updateComment(comment_id, author);
            return updateComment;
        }
    
        /**
         * 删除数据
         */
        @GetMapping("/delete/{id}")
        public void deleteComment(@PathVariable("id")  int comment_id) {
           apiCommentService.deleteComment(comment_id);
        }
    
    
    }
    
⑦ 编写 "业务操作层"的 service 对象
  • 编写 "业务操作层"的 service 对象 :

    ApiCommentService.java

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.data.redis.core.ValueOperations;
    import org.springframework.stereotype.Service;
    
    import java.util.Optional;
    import java.util.concurrent.TimeUnit;
    
    @Service //加入到IOC容器中
    public class ApiCommentService { //业务操作类
    
        @Autowired
        private CommentRepository commentRepository;  //该接口继承了JPA相关的接口,通过其中的方法可操作Mysql数据库
    
        @Autowired
        private RedisTemplate redisTemplate; //通过该类可在Java中操作Redis数据库
    
        /**
           从Mysql数据库中查询到数据后,将该数据存储到缓存中 (存储到Redis数据库中 )
         */
       public Comment findById(int comment_id) {
           //从Redis数据库中获取"缓存数据"
           ValueOperations valueOperations = redisTemplate.opsForValue();
           Object object = valueOperations.get(comment_id);
           if (object != null) {//如果在Redis数据库中查询数据则返回
               return (Comment) object;
           } else {
               //Reids中(缓存中)没有,进行数据库查询
               Optional<Comment> optional = commentRepository.findById(comment_id);
               //判断从数据库中是否查询到数据
               if (optional.isPresent()) {
                   //获得该数据
                   Comment comment = optional.get();
                   //将从Mysql数据库中的查询结果进行"缓存" ( 缓存到Redis数据库中 ) , 设置有效期为1天
                   //设置的为Redis中的字符串数据
                   valueOperations.set(comment_id, comment, 1, TimeUnit.DAYS); //有效期为1天
                   return comment;
               } else {
                   return null;
               }
           }
       }
    
    
        /**
          更新Mysql数据库中的数据后,也更新缓存中的数据 (即同时也更新Redis数据库中的数据)
         */
        public Comment updateComment(int comment_id,String author) {
            Comment comment = findById(comment_id);
            comment.setAuthor(author);
            comment = commentRepository.save(comment);
    
            //更新Mysql数据库中数据后,同时也更新缓存中的数据 ( 即更新Redis中的数据 )
            ValueOperations valueOperations = redisTemplate.opsForValue();
            valueOperations.set(comment_id,comment);
    
            return comment;
        }
    
    
        /**
         * 删除Mysql数据库中数据后,也删除Redis中的缓存数据
         */
        public void deleteComment(int comment_id) {
            //commentRepository.deleteById(comment_id);
            System.out.println("Mysql数据库中对应的数据删除成功.....");
    
            //删除Mysql数据库中数据后,也删除Redis数据库中的"缓存数据"
            Boolean commentId = redisTemplate.delete(comment_id);
            if (commentId) {
                System.out.println("Redis数据库中对应的缓存数据-删除成功.....");
            }
        }
    
    }
    
⑧ 基于 API ( RedisTemplate类 ) 的 “缓存管理” 测试
  • 基于 API ( RedisTemplate类 ) 的 “缓存管理” 测试 :
    访问 controller类中的url进行测试即可

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

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

相关文章

浅谈本地缓存的几种方案选型

一、摘要 说到缓存&#xff0c;面试官基本上会绕不开以下几个话题&#xff01; 项目中哪些地方用到了缓存&#xff1f;为什么要使用缓存&#xff1f;怎么使用它的&#xff1f;引入缓存后会带来哪些问题&#xff1f; 这些问题&#xff0c;基本上是互联网公司面试时必问的一些…

STM32,复位和时钟控制

外部时钟 HSE 以后需要用到什么就这样直接拿去配就行了

【Linux网络】FTP服务

目录 一、FTP简介 1.FTP-文件传输协议 2.FTP的两种模式 二、安装配置FTP 1.安装环境 2.对文件的操作 3.切换目录 4.设置匿名用户 5.图形化界面登录 6.白名单与黑名单 重点与难点 一、FTP简介 1.FTP-文件传输协议 FTP是FileTransferProtocol&#xff08;文件传输协…

【C++干货基地】深度理解C++中的高效内存管理方式 new delete

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 引入 哈喽各位铁汁们好啊&#xff0c;我是博主鸽芷咕《C干货基地》是由我的襄阳家乡零食基地有感而发&#xff0c;不知道各位的…

【八股】Java基础、集合、JVM

面向对象三大特性 1 封装&#xff1a; 将 方法 和 属性 写到同一个类中&#xff0c;并将属性 私有化&#xff0c;生成 get set方法&#xff0c;外部访问属性需要通过get和set方法,内部可以直接访问属性&#xff0c;这样的一个类我们认为它完成了封装。 2 继承&#xff1a; 子…

【3GPP】【核心网】【LTE】S1MME流程字段分析(一)

1. 欢迎大家订阅和关注&#xff0c;精讲3GPP通信协议&#xff08;2G/3G/4G/5G/IMS&#xff09;知识点&#xff0c;专栏会持续更新中.....敬请期待&#xff01; 目录 1. Attach(23.401 5.3.2) 2. Service Request(23.401 5.3.4) 3. TAU (23.401 5.3.3) 3.1 Tracking Area Up…

《大话数据结构》12 图的相关算法

我有天早晨准备出门&#xff0c;发现钥匙不见了。昨晚还看到它&#xff0c;所以确定钥匙在家里。一定是我那三岁不到的儿子拿着玩&#xff0c;不知道丢到哪个犄角旮旯去了&#xff0c;问他也说不清楚。我现在必须得找到它&#xff0c;你们说&#xff0c;我应该如何找&#xff1…

华为OD机试 - 智能驾驶 - 广度优先搜索(Java 2024 C卷 200分)

华为OD机试 2024C卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;A卷B卷C卷&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;每一题都有详细的答题思路、详细的代码注释、样例测试…

「 网络安全常用术语解读 」什么是0day、1day、nday漏洞

1. 引言 漏洞攻击的时间窗口被称为漏洞窗口&#xff08;window of vulnerability&#xff09;。一般来说&#xff0c;漏洞窗口持续的时间越长&#xff0c;攻击者可以利用漏洞进行攻击的可能性就越大。 2. 0day 漏洞 0day 漏洞&#xff0c;又被称为"零日漏洞"&…

YUNBEE云贝-Oracle 19c OCM 5月19日

Oracle 19c OCM认证大师培训 - 课程体系 - 云贝教育 (yunbee.net) 19c OCM考试类别&#xff1f; Oracle 19c OCM认证大师直考(2天考试&#xff0c;4个模块&#xff0c;每个模块3小时) Oracle 19c OCM认证大师升级考(1天考试&#xff0c;2个模块&#xff0c;每个模块3小时) 在…

Day1--什么是网络安全?网络安全常用术语

目录 1. 什么是网络安全&#xff1f; 信息系统&#xff08;Information System&#xff09; 信息系统安全三要素&#xff08;CIA&#xff09; 网络空间安全管理流程 网络安全管理 2. 网络安全的常用术语 3. 网络安全形势 4. 中国网络安全产业现状 1. 什么是网络安全&am…

pnpm install报错 Value of “this“ must be of type URLSearchParams

执行pnpm install的时候就报错Value of “this” must be of type URLSearchParams 由于之前执行没有出现过这个问题&#xff0c;最近在使用vue3所以使用了高版本的node&#xff0c;怀疑是node版本的问题。 解决&#xff1a; 检查node版本 node -v当前使用的是20.11.0的 修改…

婚恋app系统开发相亲交友小程序源码单身交友app软件下载客户管理系统婚恋交友平台管理系统源码h5聊天室源码

在数字化时代&#xff0c;婚恋相亲交友小程序以其便捷、高效、智能的特点&#xff0c;受到了越来越多人的青睐。红娘婚恋相亲交友系统源码&#xff0c;凭借其对微信小程序、微信公众号、H5以及APP的全方位支持&#xff0c;成为了婚恋市场的明星产品。 首先&#xff0c;婚恋相亲…

力扣HOT100 - 124. 二叉树中的最大路径和

解题思路&#xff1a; class Solution {int max Integer.MIN_VALUE;public int maxPathSum(TreeNode root) {maxGain(root);return max;}public int maxGain(TreeNode node) {if (node null) return 0;int leftGain Math.max(maxGain(node.left), 0);int rightGain Math.ma…

go+react实现远程vCenter虚拟机管理终端

文章目录 React-VcenterDemoQuick Start React-Vcenter 基于go & react实现远程vSphere vcenter虚拟机终端console页面&#xff0c;提供与vcenter管理中的Launch Web Console相同的功能。 项目地址&#xff1a;react-vcenter Demo URL: http://localhost:3000 Quick St…

Unity 踩坑记录 Rigidbody 刚体重力失效

playerSetting > physics > Gravity > 设置 Y 的值为负数

《苍穹外卖》Day07部分知识点记录

一、菜品缓存 减少查询数据库的次数&#xff0c;优化性能 客户端&#xff1a; package com.sky.controller.user;import com.sky.constant.StatusConstant; import com.sky.entity.Dish; import com.sky.result.Result; import com.sky.service.DishService; import com.sky…

使用微软Phi-3-mini模型快速创建生成式AI应用

微软Phi-3大语言模型是微软研究院推出的新一代系列先进的小语言模型。Phi-3系列包括phi-3-mini、phi-3-small和phi-3-medium三个不同规模的版本。这些模型在保持较小的参数规模的同时&#xff0c;通过精心设计的训练数据集和优化的算法&#xff0c;实现了与大型模型相媲美的语言…

软件测试之【软件测试概论三】

读者大大们好呀&#xff01;&#xff01;!☀️☀️☀️ &#x1f525; 欢迎来到我的博客 &#x1f440;期待大大的关注哦❗️❗️❗️ &#x1f680;欢迎收看我的主页文章➡️寻至善的主页 文章目录 前言测试用例的前因后果测试用例的设计方法黑盒测试用例设计方法&#x1f525…

JavaEE 初阶篇-深入了解 I/O 流(FileInputStream 与 FileOutputStream 、Reader 与 Writer)

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 I/O 流概述 2.0 文件字节输入流(FileInputStream) 2.1 创建 FileInputStream 对象 2.2 读取数据 2.3 关闭流 3.0 文件字节输出流(FileOutputStream) 3.1 创建 Fi…