SpringBoot整合MyBatis-Plus详解(二)

文章目录

    • SpringBoot整合MyBatis-Plus详解(二)
      • MyBatis-Plus简介
      • 条件构造器和常用接口⭐
        • Wrapper介绍
        • QueryWrapper(Mapper接口提供的)和QueryChainWrapper(Service接口提供的)
          • 案例1:组装查询条件
          • 案例2:组装排序条件
          • 案例3:组装删除条件
          • 案例4:条件的优先级
          • 案例5:指定查询的字段(默认是查询全部字段)
          • 案例6:实现子查询
        • UpdateWrapper
        • condition
          • 未使用condition
          • 使用condition来化简上面的代码(相当于if语句)
          • LambdaQueryWrapper
          • LambdaUpdateWrapper
      • MyBatis Plus插件⭐
        • 插件1:MyBatis Plus分页插件
          • 编写MyBatis Plus插件配置类
          • 测试分页
          • xml自定义分页
            • 在UserMapper中自定义接口方法
            • UserMapper.xml中编写SQL
            • 测试分页
        • 插件2:MyBatis Plus乐观锁插件
          • 模拟修改冲突
            • 数据库中增加商品表和插入数据
            • 新建实体类
            • 新建mapper接口
            • 测试
          • Mybatis Plus实现乐观锁
            • 给乐观锁标记属性加上@Version注解
            • 在配置类中配置乐观锁插件
            • 测试修改冲突
      • MyBatis Plus代码生成器⭐
        • 引入maven依赖
        • 编写代码快速生成方法(生成t_user表的代码)
      • MyBatisX插件⭐
        • 在IDEA上安装MyBatisX插件
        • MyBatisX插件功能1:Mapper和XML之间跳转
        • MyBatisX插件功能2:代码生成

SpringBoot整合MyBatis-Plus详解(二)

项目所在仓库

MyBatis-Plus简介

简介

  • MyBatis-Plus(简称 MP)是一个 MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为
    简化开发、提高效率而生

MyBatis-Plus特性

  • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
  • 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
  • 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
  • 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
  • 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
  • 支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
  • 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
  • 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
  • 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
  • 分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
  • 内置性能分析插件:可输出 SQL 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
  • 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作

MyBatis-Plus支持的数据库

  • MySQL,Oracle,DB2,H2,HSQL,SQLite,PostgreSQL,SQLServer,Phoenix,Gauss ,ClickHouse,Sybase,OceanBase,Firebird,Cubrid,Goldilocks,csiidb

MyBatis-Plus的架构设计

条件构造器和常用接口⭐

Wrapper介绍
  • Wrapper : 条件构造抽象类,最顶端父类
    • AbstractWrapper : 用于查询条件封装,生成 sql 的 where 条件
      • QueryWrapper : 查询条件封装
      • UpdateWrapper : Update 条件封装
      • AbstractLambdaWrapper : 使用Lambda 语法
        • LambdaQueryWrapper :用于Lambda语法使用的查询Wrapper
        • LambdaUpdateWrapper : Lambda 更新封装Wrapper
  • eq相等 、 ne不相等、 gt大于、 lt小于 、 ge大于等于 、 le 小于等于
QueryWrapper(Mapper接口提供的)和QueryChainWrapper(Service接口提供的)
案例1:组装查询条件
	@Testvoid test01(){//查询用户名包含a,年龄在20到30之间,并且邮箱不为null的用户信息//SELECT id,username AS name,age,email,is_deleted FROM t_user WHERE is_deleted=0 AND (username LIKE ? AND age BETWEEN ? AND ? AND email IS NOT NULL)//方式1:QueryWrapper
//        QueryWrapper<User> queryWrapper=new QueryWrapper<>();
//
//        queryWrapper.like("username","a")
//                .between("age",20,30)
//                .isNotNull("email");
//
//
//        List<User> users = userMapper.selectList(queryWrapper);
//
//        users.forEach(System.out::println);//方式2:QueryChainWrapperQueryChainWrapper<User> chainWrapper = userService.query().like("username", "a").between("age", 20, 30).isNotNull("email");List<User> users = chainWrapper.list();users.forEach(System.out::println);}
案例2:组装排序条件
	@Testvoid test02(){//按年龄降序查询用户,如果年龄相同则按id升序排列// SELECT uid,username AS name,age,email,is_deleted FROM t_user WHERE is_deleted=0 ORDER BY age DESC,uid ASC//方式1:QueryWrapper
//        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
//        queryWrapper.orderByDesc("age")
//                .orderByAsc("uid");
//
//        List<User> users = userMapper.selectList(queryWrapper);
//
//        users.forEach(System.out::println);//方式2:QueryChainWrapperQueryChainWrapper<User> userQueryChainWrapper = userService.query().orderByDesc("age").orderByAsc("uid");List<User> userList = userQueryChainWrapper.list();userList.forEach(System.out::println);}
案例3:组装删除条件
	@Testvoid test03(){//删除email为空的用户//DELETE FROM t_user WHERE (email IS NULL)//QueryWrapperQueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.isNull("email");userMapper.delete(queryWrapper);}
案例4:条件的优先级
	@Testvoid test04(){//将(年龄大于20并且用户名中包含有a)或邮箱为null的用户信息修改//UPDATE t_user SET age=?, email=? WHERE (username LIKE ? AND (age > ? OR email IS NULL))//lambda表达式内的逻辑优先运算QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.like("username","a").and(i -> i.gt("age", 20).or().isNull("email"));User user = new User();user.setAge(18);user.setEmail("666333@qq.com");userMapper.update(user,queryWrapper);}
案例5:指定查询的字段(默认是查询全部字段)
	@Testvoid test05(){//查询用户信息的username和age字段//SELECT username,age FROM t_user WHERE is_deleted=0//方式1:QueryWrapper
//        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
//
//        queryWrapper
//                .select("username","age"); //指定查询的字段(默认是查找全部字段)
//
//        List<User> users = userMapper.selectList(queryWrapper);
//
//        users.forEach(System.out::println);//方式2:QueryChainWrapperList<User> list = userService.query().select("username", "age") //指定查询的字段(默认是查找全部字段).list(); //list方法直接拿到结果集list.forEach(System.out::println);}
案例6:实现子查询
	@Testvoid test06(){//查询id小于等于3的用户信息//SELECT uid,username AS name,age,email,is_deleted FROM t_user WHERE is_deleted=0 AND (uid IN (select uid from t_user where uid <= 3))//方式1:QueryWrapper
//        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
//        queryWrapper.inSql("uid","select uid from t_user where uid <= 3");
//
//        List<User> users = userMapper.selectList(queryWrapper);
//
//        users.forEach(System.out::println);//方式2:QueryChainWrapperList<User> userList = userService.query().inSql("uid", "select uid from t_user where uid <= 3").list();userList.forEach(System.out::println);}
UpdateWrapper
@Test
void test07()
{//好处:当我们使用了UpdateWrapper时,不需要传入entity了,可以通过set方法修改值//UPDATE t_user SET username=?,age=? WHERE is_deleted=0 AND (uid = ?)UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();updateWrapper.set("username","新名字111").set("age",32).eq("uid",5L);userMapper.update(null,updateWrapper);}
condition
未使用condition
@Test
void test08()
{String username=null;Integer smallAge=15;Integer bigAge=30;//SELECT uid,username AS name,age,email,is_deleted FROM t_user WHERE is_deleted=0 AND (age >= ? AND age <= ?)QueryWrapper<User> queryWrapper = new QueryWrapper<>();if (StringUtils.isNotBlank(username)) { //如果用户名不为空,则添加下面的条件queryWrapper.like("username",username);}if(smallAge != null){queryWrapper.ge("age",smallAge);}if(bigAge != null){queryWrapper.le("age",bigAge);}userMapper.selectList(queryWrapper);}
使用condition来化简上面的代码(相当于if语句)

在这里插入图片描述

@Test
void test09()
{String username=null;Integer smallAge=15;Integer bigAge=30;//SELECT uid,username AS name,age,email,is_deleted FROM t_user WHERE is_deleted=0 AND (age >= ? AND age <= ?)QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.like(StringUtils.isNotBlank(username),"username",username).ge(smallAge!=null,"age",smallAge).le(bigAge!=null,"age",bigAge);userMapper.selectList(queryWrapper);}
LambdaQueryWrapper
  • 好处就是:使用lambda表达式来代替表的字段,防止我们在开发中写表的字段错误。
@Test
void test10(){String username=null;Integer smallAge=15;Integer bigAge=30;LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();lambdaQueryWrapper.like(StringUtils.isNotBlank(username),User::getName,username);lambdaQueryWrapper.ge(smallAge!=null,User::getAge,smallAge);lambdaQueryWrapper.le(bigAge!=null,User::getAge,bigAge);userMapper.selectList(lambdaQueryWrapper);}
LambdaUpdateWrapper
  • 好处就是:使用lambda表达式来代替表的字段,防止我们在开发中写表的字段错误。
@Test
void test11(){LambdaUpdateWrapper<User> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();lambdaUpdateWrapper.set(User::getName,"新名字222").set(User::getAge,55).eq(User::getUid,5L);userMapper.update(null,lambdaUpdateWrapper);}

MyBatis Plus插件⭐

插件1:MyBatis Plus分页插件
编写MyBatis Plus插件配置类
package com.boot.config;import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** @author youzhengjie 2022-08-17 20:44:12*///Mybatis-Plus配置类
@Configuration
public class MybatisPlusConfiguration {//mybatis-plus插件都要添加到这个mybatis-plus拦截器上面去。@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor(){MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();//配置分页插件PaginationInnerInterceptor,指定数据库类型为MYSQLmybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));return mybatisPlusInterceptor;}}
测试分页
	@Testvoid testPage01(){//例如:total(总的数据记录数)=10,size(每一页的记录数大小)=5//那么就可以分成(10/5=2)页,分别是第1页和第2页,current就是当前页,因为只有2页,所以current只能写1或者2.//SELECT uid,username AS name,age,email,is_deleted FROM t_user WHERE is_deleted=0 LIMIT ?,?Page<User> userPage = new Page<>(2,5);//第一种写法:
//        userMapper.selectPage(userPage,null);//第二种写法:userService.page(userPage,null);//获取分页数据List<User> list = userPage.getRecords();list.forEach(System.out::println);System.out.println("当前页:"+userPage.getCurrent());System.out.println("每页显示的条数:"+userPage.getSize());System.out.println("总记录数:"+userPage.getTotal());System.out.println("总页数:"+userPage.getPages());System.out.println("是否有上一页:"+userPage.hasPrevious());System.out.println("是否有下一页:"+userPage.hasNext());}
xml自定义分页
在UserMapper中自定义接口方法
package com.boot.dao;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.boot.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;/*** @author youzhengjie 2022-08-15 18:42:11*/@Mapper
@Repository
// BaseMapper的泛型就是我们需要操作的实体类User
public interface UserMapper extends BaseMapper<User> {/*** 根据年龄查询用户列表,分页显示* @param page 分页对象,xml中可以从里面进行取值,传递参数 Page 即自动分页(注意page必须放在第一位)* @param age 年龄*/Page<User> selectPageVo(@Param("page") Page<User> page, @Param("age") Integer age);}
UserMapper.xml中编写SQL
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.boot.dao.UserMapper"><select id="selectPageVo" resultType="com.boot.entity.User">select * from t_user where age=#{age}</select></mapper>
测试分页
@Test
void testPage02(){Page<User> userPage = new Page<>(1,5);//调用刚刚我们自定义的方法//select * from t_user where age=? LIMIT ?userMapper.selectPageVo(userPage,20);//获取分页数据List<User> list = userPage.getRecords();list.forEach(System.out::println);System.out.println("当前页:"+userPage.getCurrent());System.out.println("每页显示的条数:"+userPage.getSize());System.out.println("总记录数:"+userPage.getTotal());System.out.println("总页数:"+userPage.getPages());System.out.println("是否有上一页:"+userPage.hasPrevious());System.out.println("是否有下一页:"+userPage.hasNext());}
插件2:MyBatis Plus乐观锁插件
模拟修改冲突
数据库中增加商品表和插入数据
CREATE TABLE t_product
(id BIGINT(20) NOT NULL COMMENT '主键ID',name VARCHAR(30) NULL DEFAULT NULL COMMENT '商品名称',number INT(11) DEFAULT 1 COMMENT '商品数量',version INT(11) DEFAULT 0 COMMENT '乐观锁版本号',PRIMARY KEY (id)
);INSERT INTO t_product (id, name, number) VALUES (1, 'iphone13 pro', 0);
新建实体类
package com.boot.entity;import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;import java.io.Serializable;/*** @author youzhengjie 2022-08-17 21:56:17*/@TableName("t_product")
//lombok注解
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class Product implements Serializable {@TableId("id")private Long id;@TableField("name")private String name;@TableField("number")private int number;private int version;}
新建mapper接口
package com.boot.dao;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.boot.entity.Product;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;/*** @author youzhengjie 2022-08-17 22:12:21*/
@Mapper
@Repository
public interface ProductMapper extends BaseMapper<Product> {}
测试
  • 测试前先查看商品库存:

在这里插入图片描述

  • 开始执行测试代码:
	@Testvoid test03(){//A用户获取到的Product p1 = productMapper.selectById(1L);//B用户获取到的Product p2 = productMapper.selectById(1L);//A用户修改库存p1.setNumber(p1.getNumber()+20);productMapper.update(p1,null);//B用户修改库存p2.setNumber(p2.getNumber()+30);productMapper.update(p2,null);}
  • 查看输出日志:

在这里插入图片描述

  • 再次查看数据库:

在这里插入图片描述

Mybatis Plus实现乐观锁
给乐观锁标记属性加上@Version注解

在这里插入图片描述

在配置类中配置乐观锁插件
package com.boot.config;import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** @author youzhengjie 2022-08-17 20:44:12*///Mybatis-Plus配置类
@Configuration
public class MybatisPlusConfiguration {//mybatis-plus插件都要添加到这个mybatis-plus拦截器上面去。@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor(){MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();//配置分页插件PaginationInnerInterceptor,指定数据库类型为MYSQLmybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));//配置乐观锁插件mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());return mybatisPlusInterceptor;}}

在这里插入图片描述

测试修改冲突
	@Testvoid test03(){//A用户获取到的Product p1 = productMapper.selectById(1L);//B用户获取到的Product p2 = productMapper.selectById(1L);//A用户修改库存p1.setNumber(p1.getNumber()+20);productMapper.update(p1,null);//B用户修改库存p2.setNumber(p2.getNumber()+30);productMapper.update(p2,null);}
  • 查看输出日志:

在这里插入图片描述

  • 查看数据库:

在这里插入图片描述

MyBatis Plus代码生成器⭐

引入maven依赖
<!--        mybatis-plus代码生成器--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>3.5.2</version></dependency>
<!--       freemarker依赖 (mybatis-plus指定freemarker引擎时一定要引入这个依赖,不然会报错) --><dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId><version>2.3.31</version></dependency>

在这里插入图片描述

编写代码快速生成方法(生成t_user表的代码)
  • 查看我们的t_user表:

在这里插入图片描述

  • 开始执行代码生成程序(通过t_user表生成代码):
package com.boot.generate;import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;import java.util.Collections;/*** @author youzhengjie 2022-08-20 00:28:34* mybatis-plus代码生成器程序*/
public class FastGeneratorTest {public static void main(String[] args) {FastAutoGenerator//mysql的数据源配置.create("jdbc:mysql://localhost:3306/mybatis_plus-db?serverTimezone=GMT%2B8&characterEncoding=utf-8&useSSL=false", "root", "18420163207").globalConfig(builder -> {builder.author("youzhengjie") // 设置作者.enableSwagger() // 开启 swagger 模式.fileOverride() // 覆盖已生成文件.outputDir("D://mybatis-plus-generator"); // 指定输出目录}).packageConfig(builder -> {builder.parent("com.boot") // 设置父包名.moduleName("gen") // 设置父包模块名.pathInfo(Collections.singletonMap(OutputFile.xml, "D://mybatis-plus-generator")); // 设置mapperXml生成路径}).strategyConfig(builder -> {builder//设置需要生成的表名(该表必须要在我们指定的mysql中存在,mybatis-plus才会根据这个表来生成代码).addInclude("t_user")// 设置过滤表前缀.addTablePrefix("t_", "c_");}).templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板.execute(); //执行}}
  • 输出日志:

在这里插入图片描述

  • 查看刚刚生成的代码结构:

在这里插入图片描述

MyBatisX插件⭐

在IDEA上安装MyBatisX插件

在这里插入图片描述

MyBatisX插件功能1:Mapper和XML之间跳转
  • 随便进入一个Mapper接口(然后点击跳转):

在这里插入图片描述

  • 点击XML文件的图标也可以实现跳转。

在这里插入图片描述

MyBatisX插件功能2:代码生成
  • 1:随便进入Mapper接口,输出你想生成的方法:

在这里插入图片描述在这里插入图片描述

在这里插入图片描述

  • 2:查看生成的方法和代码:

在这里插入图片描述

在这里插入图片描述

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

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

相关文章

Unity报错:Microsoft Visual C# Compiler version

Unity报错:Microsoft Visual C# Compiler version 问题解决方案总结 问题 Microsoft Visual C# Compiler version 2.9.1.65535 (9d34608e) Copyright © Microsoft Corporation 切换版本或者使用老项目的时候可能会出现这个报错&#xff0c;这个报错就是项目设置的问题 …

【HarmonyOS】元服务卡片展示动态数据,并定点更新卡片数据

【关键字】 元服务卡片、卡片展示动态数据、更新卡片数据 【写在前面】 本篇文章主要介绍开发元服务卡片时&#xff0c;如何实现卡片中动态显示数据功能&#xff0c;并实现定时数据刷新。本篇文章通过实现定时刷新卡片中日期数据为例&#xff0c;讲述展示动态数据与更新数据功…

C++前缀和算法的应用:从栈中取出 K 个硬币的最大面值和 原理源码测试用例

本文涉及的基础知识点 C算法&#xff1a;前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 题目 一张桌子上总共有 n 个硬币 栈 。每个栈有 正整数 个带面值的硬币。 每一次操作中&#xff0c;你可以从任意一个栈的 顶部 取出 1 个硬币&#xff0c;从栈中移除…

深入探究ASEMI肖特基二极管MBR60100PT的材质

编辑-Z 在电子零件领域中&#xff0c;肖特基二极管MBR60100PT因其出色的性能和广泛的应用而显得尤为关键。理解其材质不仅有助于我们深入理解其运作原理&#xff0c;也有助于我们做出更合适的电子设计。那么&#xff0c;肖特基二极管MBR60100PT是什么材质呢? 首先&#xff0c…

电厂数据可视化三维大屏展示平台加强企业安全防范

园区可视化大屏是一种新型的信息化手段&#xff0c;能够将园区内各项数据信息以图像的形式直观呈现在大屏幕上&#xff0c;便于管理员和员工进行实时监控、分析和决策。本文将从以下几个方面介绍园区可视化大屏的作用和应用。 VR数字孪生园区系统是通过将实际园区的各种数据和信…

Vue 父子组件传参、插槽

setup 函数中有两个主要的参数&#xff1a;props、context 。 props 用于接收父组件传递过来的数据&#xff0c;父传子。 context 指的是 setup 的上下文&#xff0c;它有三个属性&#xff1a;attrs、slots、emit 。 attrs 用于&#xff1a;当父组件传递过来的数据&#xff…

网络协议--BOOTP:引导程序协议

16.1 引言 在第5章我们介绍了一个无盘系统&#xff0c;它在不知道自身IP地址的情况下&#xff0c;在进行系统引导时能够通过RARP来获取它的IP地址。然而使用RARP有两个问题&#xff1a;&#xff08;1&#xff09;IP地址是返回的唯一结果&#xff1b;&#xff08;2&#xff09;…

布隆过滤器(Bloom Filter)初学习

目录 1、布隆过滤器是什么 2、布隆过滤器的优缺点 3、使用场景 4、⭐基于Redis的布隆过滤器插件安装 4.1 下载布隆过滤器 4.2 创建文件夹并上传文件 4.3 安装gcc 4.4 解压RedisBloom压缩包 4.5 在解压好的文件夹下输入make 4.6 将编译的好的插件拷贝到docker redis容…

Windows下安装Anaconda、Pycharm以及iflycode插件图解

目录 一、下载Anaconda、Pycharm以及iflycode插件 二、创建相关文件夹 三、Pycharm社区版安装详细步骤 四、Anaconda安装详细步骤 五、配置Pycharm 六、安装iflycode插件 Anaconda是一款集成的Python环境&#xff0c;anaconda可以看做Python的一个集成安装&#xff0c;安…

Openssl数据安全传输平台011:base64的使用

文章目录 1 base641.1 概念1.2 应用场景 2 base64 算法 &#xff08;重要&#xff09;3 openssl 中base64的使用3.1 BIO 操作3.2 base64 编码 -> bio链的写操作3.3 base64 解码 -> bio链的读操作 1 base64 1.1 概念 Base64是一种基于64个可打印字符来表示二进制数据的表…

聊聊“JVM 调优JVM 性能优化”是怎么个事?

所谓“调优”就是一个诊断和处理手段&#xff0c;最终的目标是让系统的处理能力&#xff0c;也就是“性能”达到最优化。 计算机系统中&#xff0c;性能相关的资源主要分为这几类&#xff1a; CPU&#xff1a;CPU 是系统最关键的计算资源&#xff0c;在单位时间内有限&#xf…

IDEA 断点高阶

一、按钮介绍 1.1 补充 返回断点处&#xff1a; 设置debug配置&#xff1a; 二、增加/切换debugger视图 三、window快捷键 所在行处&#xff1a; CtrlF8断点属性编辑&#xff1a; CtrlShiftF8 四、一些常用的高级功能 4.1 查看对象内存-Attach memory agent 1.勾选Atta…

react的table合并行时,出现border-bottom重复问题

背景&#xff1a; 需求是呈现一个表格&#xff0c;根据操作人跟操作时间是否相同来进行合并行数据 数据结构&#xff1a; 经过跟后端的同事商量&#xff0c;需要在每一行数据中返回rowSpanNum的值&#xff0c;前端在column中根据值来判断是否满足合并行&#xff08;没有合并行…

基于FPGA的图像PSNR质量评估计算实现,包含testbench和MATLAB辅助验证程序

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 设置较大的干扰&#xff0c;PSNR15。 设置较小的干扰&#xff0c;PSNR25。 2.算法运行软件版本 matlab2022a vivado2019.2 3.部分核心程序 ti…

SDL窗口创建以及简单显示(1)

项目创建步骤 1. 使用Qt Creator创建一个C项目 2. 将SDL库文件放到源文件目录下 在项目pro文件中添加库文件 win32{INCLUDEPATH $$PWD/SDL2-2.0.10/includeLIBS $$PWD/SDL2-2.0.10/lib/x86/SDL2.lib } 使用SDL创建一个窗口 #include <stdio.h>#include <SDL.h>…

只需这个下毒小工具,让Stable Diffusion彻底崩溃!狗变猫,车变牛,AI侵权打响反击战

作者 | 谢年年 文生图模型如DALL-E、Midjourney和Stable Diffusion等越来越火热&#xff0c;只需要一句话几秒钟就可以生成质量不逊艺术家辛辛苦苦创作数月的图片。 艺术家们表示很气但又无能为力。 大模型研究测试传送门 GPT-4传送门&#xff08;免墙&#xff0c;可直接测试…

HCIA数据通信——交换机(Vlan间的通信与安全)

前言 之前的提到了交换机的概念和实验。不过交换机的一些功能还没有说完&#xff0c;我们的实验也仅仅是阻止相同地址段的IP地址互通&#xff0c;也没有用到子接口和路由器。显然&#xff0c;那样的配置过于简单。 端口安全 Port Security&#xff08;端口安全&#xff09;的功…

关于高并发你必须知道的几个概念

&#x1f388;个人公众号:&#x1f388; :✨✨✨ 可为编程✨ &#x1f35f;&#x1f35f; &#x1f511;个人信条:&#x1f511; 为与不为皆为可为&#x1f335; &#x1f349;本篇简介:&#x1f349; 本篇记录高并发必须知道的几个概念&#xff0c;如有出入还望指正。 关注公众…

Java-数据类型

Java-数据类型 一、字面常量二、数据类型&#xff08;1&#xff09;基本数据类型 三、变量1、变量概念2、语法格式&#xff08;1&#xff09;语法&#xff1a;&#xff08;2&#xff09;示例&#xff1a; 3、整型变量&#xff08;1&#xff09;整型变量&#xff08;int&#xf…

CentOS 搭建本地 yum 源方式 安装 httpd 服务

CentOS 搭建本地 yum 源方式 安装 httpd 服务 修改 yum 源 挂载光驱 mkdir -p /mnt/cdrom mount /dev/cdrom /mnt/cdromvi /etc/fstab追加以下内容&#xff1a; /dev/cdrom /mnt/cdrom iso9660 defaults 0 0手动修改CentOS-Base.repo 备份 yum 源配置文件 mv /etc/yum.re…