MyBatisPlus入门

news2024/12/28 21:30:39

目录

概述

SpringBoot继承MyBatisPlus

CRUD

        新增

        删除

        修改

        查询

条件构造器

全局配置

相关注解

ActiveRecord

插件

分页插件

防止全表删除插件

乐观锁插件

        乐观锁插件的使用

逻辑删除

使用逻辑删除

扩展

        自动填充

        Sql注入器

        代码生成器Generator

        代码生成器MyBatisX


 

部分图片来自百战程序员

概述

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

MyBatisPlus的愿景是成为MyBatis最好的搭档,就像魂斗罗中的1P、2P,基友搭配,效率翻倍。

官方网址: MyBatis-Plus

 

SpringBoot继承MyBatisPlus

1、引入MyBatisPlus的依赖

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-test</artifactId>
  <scope>test</scope>
</dependency>
<!-- MyBatisPlus -->
<dependency>
  <groupId>com.baomidou</groupId>
  <artifactId>mybatis-plus-boot-starter</artifactId>
  <version>3.5.0</version>
</dependency>
<!-- mysql驱动 -->
<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>8.0.26</version>
</dependency>
<!-- lombok -->
<dependency>
  <groupId>org.projectlombok</groupId>
  <artifactId>lombok</artifactId>
  <optional>true</optional>
</dependency>

2、在yml文件中创建数据源

# 数据源
spring:
  datasource:
   driver-class-name: com.mysql.cj.jdbc.Driver
   url: jdbc:mysql:///school?serverTimezone=UTC
   username: root
   password: root

3、创建pojo类

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
  private Integer id;
  private String name;
  private String email;
  private String gender;
  private Integer age;
}

4、创建mapper接口,继承BaseMapper,泛型为相关的pojo类

public interface StudentMapper extends BaseMapper<Student> {
}

5、在SpringBoot启动类中添加@MapperScan注解,扫描Mapper文件夹

@SpringBootApplication
@MapperScan("com.itbaizhan.mpdemo2.mapper")
public class SpringbootMpApplication {
  public static void main(String[] args) {
    SpringApplication.run(SpringbootMpApplication.class, args);
   }
}

6、测试Mapper方法

@SpringBootTest
public class StudentMapperTest {
  @Autowired
  private StudentMapper studentMapper;


  @Test
  public void testFindById(){
    Student student = studentMapper.selectById(1);
    System.out.println(student);
   }
}

 

 

CRUD

在MyBatisPlus中只需要持久层接口继承BaseMapper,并且泛型为相关pojo类,那么MyBatisPlus将会自动帮你创建相关的增删改查方法

        新增

insert方法作用为添加

  1. yml配置文件开启SQL日志打印
    # 开启SQL日志
    mybatis-plus:
      configuration:
       log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  2. 测试添加方法:
    @Test
    public void testAdd(){
      Student student = new Student(null,"baizhan","bz@bz.com","m",20);
      studentMapper.insert(student);
      // MyBatisPlus插入成功后,可直接直接获取主键的值
      System.out.println(student.getId());
    }

 

        删除

deleteById方法的作用是根据ID删除数据

deleteBatchIds方法的作用是批量删除

deleteByMap方法的作用是根据字段条件删除键为数据库列名

@Test
    public void testDelete(){
        studentMapper.deleteById(7);
    }

 

 

 

@Test
    public void testDeleteBatch(){
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        studentMapper.deleteBatchIds(list);
    }

 

 

@Test
    public void testDeleteByMap(){
        Map<String,Object> map = new HashMap<>();
        map.put("address","北京");
        studentMapper.deleteByMap(map);
    }

删除前: 

 删除后:

 

        修改

update方法作用为修改

updateById方法作用为根据Id修改

 

@Test
    public void testUpdate(){
        Student student = new Student(3,"张三","男","哈尔滨");
        studentMapper.updateById(student);

    }

修改前:

修改后:

 

        查询

selectById方法的作用是根据Id查询

selectBatchIds方法的作用是根据id批量查询

selectByMap方法的作用是根据字段条件查询

 

数据库:

 

 

@Test
    public void testSelectById(){
        Student student = studentMapper.selectById(1);
        System.out.println(student);
    }

 

 

@Test
    public void testSelectBatchIds(){
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        List<Student> students = studentMapper.selectBatchIds(list);
        students.forEach(System.out::println);
    }

 

 @Test
    public void testSelectByMap(){
        Map<String,Object> map = new HashMap<>();
        map.put("sex","男");
        List<Student> students = studentMapper.selectByMap(map);
        students.forEach(System.out::println);
    }

 

条件构造器

Mybatis-Plus通过QueryWrapper对象让用户自由的构建SQL条件,简单便捷,没有额外的负担,能够有效提高开发效率。

1QueryWrapper对象构造了Sql条件过后,传递给selectList()方法即可查询

2QueryWrapper构造的Sql条件之间默认为and连接

 

条件参数说明:

查询方式

说明

or

或条件语句

and

且条件语句

like

模糊查询 like

notLike

模糊查询 not Like

exists

exists 条件语句

notExists

not Exists 条件语句

isNull

null 值查询

isNotNull

is Not Null 查询

in

in 查询

notIn

not in 查询

groupBy

分组查询

orderBy

排序查询

having

分组后筛选

eq

等于 =

ne

不等于 <>

between

between 条件语句

gt

大于>

ge

大于等于>=

lt

小于<

le

小于等于<=

 

 

@Test
    public void testQueryWrapper(){
        QueryWrapper<Student> wrapper = new QueryWrapper<>();
        wrapper.lt("id",5).gt("id",1);
        List<Student> students = studentMapper.selectList(wrapper);
        students.forEach(System.out::println);
    }

 

全局配置

假如数据库的所有表都以tb_开头,主键都是自增的。如果针对每一个实体类都要添加相关注解比较麻烦,可以在SpringBoot配置文件中进行全局配置,该配置在所有的实体类中都生效。

mybatis-plus:

 # 全局配置

  global-config:

   db-config:

   #主键类型

    id-type: AUTO

   # 设置表名前缀

    table-prefix: tb_

   # 是否使用驼峰转下划线命名,默认开启

    table-underline: true

 

相关注解

我们将表名改为tb_student,id字段名改为sid,name字段名改为sname,此时由于名字不同无法完成映射,我们可以通过相关注解为实体类对象指定表名和列名。

@TableName

作用:指定类为哪个表的实体类

位置:类上方

 

@TableId

作用:指定实体类的属性为主键

位置:属性上方

属性:

  • value:主键字段名
  • type:主键策略

描述

NONE

无状态,不设置主键类型

AUTO

自增主键

INPUT

插入前自行设置主键值

ASSIGN_ID

默认策略,使用雪花算法自动生成主键ID,主键类型为整形或字符串。(雪花算法:微博开源的分布式ID生成算法,使用一个64位的Long类型数字作为全局唯一ID。在分布式系统中的应用十分广泛,且ID引入了时间戳,基本上保持自增)

ASSIGN_UUID

自动生成排除中划线的UUID作为主键,主键类型为字符串。

 

@TableField

作用:在属性和列名不同的情况下,指定映射关系

位置:非主键属性上方

@Data

@NoArgsConstructor

@AllArgsConstructor

@TableName("tb_student")

public class Student{

  @TableId(value="sid",type=IdType.AUTO)

  private Integer id;

  @TableField("sname")

  private String name;

  private String email;

  private String gender;

  private Integer age;

}

 

ActiveRecord

Active Record(活动记录),是一种领域模型模式,特点是一个模型类对应关系型数据库中的一个表,而模型类的一个实例对应表中的一行记录。

在MyBatisPlus中,AR模式即在实体类中封装了对数据库的访问而不通过mapper类。

用法:

1、虽然操作数据库不通过mapper类,但需要编写mapper类并继承BaseMapper

public interface StudentMapper extends BaseMapper<Student>{
}

2、实体类继承Model类,开启AR模式

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student extends Model<Student> {
    private Integer id;
    private String name;
    private String sex;
    private String address;
}

3、接下来就可以测试了

@SpringBootTest
public class StudentTest {

    @Test
    public void testFindAll(){
        Student student = new Student();
        List<Student> students = student.selectAll();
        students.forEach(System.out::println);
    }
}

 

 

// AR新增
@Test
public void testAdd(){
  Student student = new Student(10, "baizhan", "bz@bz.com", "m", 20);
  student.insert();
}


// AR修改
@Test
public void testUpDate(){
  // 创建实体类对象
  Student student = new Student();
  // 设置需要更新的属性
  student.setName("baby");
  // 设置需要修改的id
  student.setId(10);
  // 根据主键进行更新,没有设置的值忽略
  student.updateById();
}


// AR根据id查询
@Test
public void testFindById(){
  Student student = new Student();
  student.setId(10);
  Student student1 = student.selectById();
  System.out.println(student1);
}


// AR删除
@Test
public void testDeleteById(){
  Student student = new Student();
  student.setId(10);
  student.deleteById();
}


// AR查询所有
@Test
public void testFindAll(){
  Student student = new Student();
  List<Student> students = student.selectAll();
  students.forEach(System.out::println);
}

 

插件

MyBatis插件机制

MyBatis插件就是对Executor、StatementHandler、ParameterHandler、ResultSetHandler这四个接口上的方法进行拦截,利用JDK动态代理机制,为这些接口的实现类创建代理对象,在执行方法时,先去执行代理对象的方法,从而执行自己编写的拦截逻辑。

 

  • Executor
    MyBatis的内部执行器,它负责调用StatementHandler操作数据库,并把结果集通过 ResultSetHandler进行自动映射。
  • StatementHandler
    MyBatis直接让数据库执行sql脚本的对象。
  • ParameterHandler
    MyBatis实现Sql入参设置的对象。
  • ResultSetHandler
    MyBatis把ResultSet集合映射成POJO的接口对象。

 

MyBatisPlus常用插件

MyBatisPlus依据MyBatis插件机制,为我们提供了一些开发中常用的插件,我们在开发中使用即可。

常用插件:

  • 自动分页: PaginationInnerInterceptor
  • 防止全表更新与删除: BlockAttackInnerInterceptor
  • 乐观锁: OptimisticLockerInnerInterceptor

这些插件都实现了InnerInterceptor接口

 

分页插件

在配置类或启动类配置分页插件:


// 注册插件
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
  MybatisPlusInterceptor interceptor=new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
  return interceptor;
}

 使用:

AR模式分页查询

 @Test
    public void testPage(){
        //创建分页条件
        Page page = new Page(0,2);
        //查询构造器
        QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
        queryWrapper.lt("id",10).gt("id",0);

        Student student = new Student();
        IPage<Student> iPage = student.selectPage(page,queryWrapper);
        List<Student> records = iPage.getRecords();
        records.forEach(System.out::println);
    }

 

 

防止全表删除插件

作用:分析删除/更新语句,防止小白或者恶意进行删除/更新全表操作。

注意:

  • 该插件只支持 MySQL5.6.3 以上版本
  • 该插件只建议在开发环境中使用,不建议在生产环境使用

插件使用:

 

1、在配置类或启动类配置防止全表更新与删除插件

// 注册插件
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
  MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
  // 分页插件
  interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
  // 防止全表更新与删除插件
  interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
  return interceptor;
}

2、测试全表删除

// AR删除所有
@Test
public void testDeleteAll() {
  Student student = new Student();

//当条件构造器没有条件,代表删除所有数据

 student.delete(new QueryWrapper());
}

 

乐观锁插件

 

修改数据库中的数据时,为了避免同时被其他人修改,最好的办法就是对该数据进行加锁以防止并发。

锁的设计分为悲观锁和乐观锁:

  • 悲观锁:悲观锁对数据被外界修改持保守态度。即在整个数据处理过程中,将数据处于锁定状态。悲观锁的实现往往依靠数据库提供的锁机制。

  • 乐观锁:乐观锁在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果冲突,则返回给用户异常信息,让用户决定如何去做。

MyBatisPlus乐观锁插件实现方式:

  1. 取出记录时,获取当前version
  2. 更新时,带上这个version
  3. 执行更新时, set version = newVersion where version = oldVersion
  4. 如果version不对,就更新失败

 

        乐观锁插件的使用

使用MyBatisPlus乐观锁插件:

1、在表中添加version列,且默认值为0

2pojo类中添加version属性,并在属性上方添加@Version属性

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student extends Model<Student> {
    private Integer id;
    private String name;
    private String sex;
    private String address;

    @Version
    private int version;
}

测试修改功能

@Test
    public void testVersion(){
        Student student = new Student();
        student.setId(1);
        student.setName("索隆");

        student.setVersion(10);
        student.updateById();

    }

通过输出的Sql语句可以发现,mybatisPlus在修改语句的后面添加了一个version条件,此时version为10,那么就根本不会修改数据库中路飞的名字 

 

逻辑删除

在实际开发中,由于数据十分重要,为了避免误删除数据导致数据无法找回,我们往往不会使用物理删除,即从数据库中直接删除数据。而是采用逻辑删除的方式,即不会真正在数据库删除数据,而是通过一个变量代表它被删除

 

deleted属性代表该数据是否删除,0代表未删除,1代表已删除。此时增删改查的Sql语句发生变化:

  • 插入: 不作限制
  • 查找: 追加where条件过滤掉已删除数据。
  • 更新: 追加where条件防止更新到已删除数据。
  • 删除: 转变为更新

 

例如:

  • 删除: update user set deleted=1 where id = 1 and deleted=0
  • 查找: select id,name,deleted from user where deleted=0

使用逻辑删除

  1. 在配置文件配置逻辑删除
    # mybatis-plus相关配置
    mybatis-plus:
     # 全局配置
      global-config:
       db-config:
       # 全局逻辑删除的字段名
        logic-delete-field: deleted
       # 逻辑已删除值(默认为 1)
        logic-delete-value: 1
       # 逻辑未删除值(默认为 0)
        logic-not-delete-value: 0

  2. 修改实体类,添加逻辑删除属性
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class Student extends Model<Student> {
        private Integer id;
        private String name;
        private String sex;
        private String address;
    
        @Version
        private int version;
    
        @TableLogic
        private int deleted;
    }
    

  3. 修改数据库表,添加一列整型deleted字段并设置默认值为0
  4. 测试删除和查询方法,会看到删除时将deleted字段变为1,查询时添加条件deleted=0

 

@Test
    public void testDelete(){
        studentMapper.deleteById(1);
    }

 

扩展

        自动填充

由于有了逻辑删除字段,那么向数据库插入数据时候,都需要设置deleted=0,而每次插入数据时都要设置该值十分繁琐,于是MyBatisPlus提供了自动填充功能。

  1. 为实体类的自动填充字段添加@TableField
    @TableLogic
    // 自动填充字段
    @TableField(fill=FieldFill.INSERT)
    private Integer deleted;
    填充策略:

描述

DEFAULT

默认不处理

INSERT

插入操作填充字段

UPDATE

更新操作填充字段

INSERT_UPDATE

插入操作和更新操作均填充字段

 

  1. 自定义填充类实现MetaObjectHandler接口,填充类需要放到Spring容器中
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

    /**
     * 插入时填充逻辑
     * @param metaObject 元对象
     */

    @Override
    public void insertFill(MetaObject metaObject) {
        /**
         * 参数1:自动填充字段名
         * 参数2:填充值
         * 参数3:元对象
         */
        this.setFieldValByName("deleted",0,metaObject);
    }


    /**
     * 更新时填充逻辑
     * @param metaObject 元对象
     */
    @Override
    public void updateFill(MetaObject metaObject) {
        this.setFieldValByName("deleted",0,metaObject);
    }
}

 测试

@Test
    public void testFindAll(){
        Student student = new Student();
        List<Student> students = student.selectAll();
        students.forEach(System.out::println);
    }

        Sql注入器

 MyBatisPlus方法是有限的,我们可以使用SQL注入器自定义全局方法,注入到全局中,这样所有的Mapper类都能使用该方法,接下来我们自定义一个deleteAll方法。

1、创建注入方法类,继承AbstractMethod

2、创建Sql自动注入器,继承AbstractSqlInject,自动注入器需要放到Spring容器中

3、在mapper接口中定义deleteAll方法

4、测试deleteAll方法

public class DeleteAll extends AbstractMethod {
    @Override
    public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
        //定义Sql语句
        String sql = "delete from "+ tableInfo.getTableName();
        //定义方法名
        String method = "deleteAll";
        //构建SqlSource对象,他负责将Sql传递到数据库
        SqlSource sqlSource = this.languageDriver.createSqlSource(this.configuration,sql,modelClass);
        //构建删除方法
        return this.addDeleteMappedStatement(mapperClass,method,sqlSource);
    }
}
@Component
public class MySqlInject extends AbstractSqlInjector {
    @Override
    public List<AbstractMethod> getMethodList(Class<?> mapperClass, TableInfo tableInfo) {
        List<AbstractMethod> list = new ArrayList<>();
        list.add(new DeleteAll());
        return list;
    }
}
public interface StudentMapper extends BaseMapper<Student> {
    void deleteAll();
}
@Test
    public void testDeleteAll(){
        studentMapper.deleteAll();
    }

测试,查看数据库

 

 

        代码生成器Generator

如果不想手动编写实体类等文件,MyBaitsPlus提供了代码生成器,它可以读取数据库的表信息,生成MyBaitsPlus代码供我们使用,之前我们学过MyBatis的代码生成器MyBatis Generator,这二者的区别是:

  • MBG基于xml文件配置的,MyBaitsPlus代码生成器是基于Java代码配置的
  • MBG可生成实体类、Mapper接口、Mapper映射文件;
  • MyBaitsPlus代码生成器可生成实体类、Mapper接口、Mapper映射文件、Service类、Controller类

使用:

 

1添加代码生成器所需的依赖

<!-- MyBatisPlus代码生成器 -->

<dependency>

  <groupId>com.baomidou</groupId>

  <artifactId>mybatis-plus-generator</artifactId>

  <version>3.5.1</version>

</dependency>

<!-- MyBatisPlus代码生成器需要的模板引擎 -->

<dependency>

  <groupId>org.apache.velocity</groupId>

  <artifactId>velocity-engine-core</artifactId>

  <version>2.2</version>

</dependency>

2编写代码生成器

public class MyGenerator {

  public static void main(String[] args) {

    FastAutoGenerator.create("jdbc:mysql:///school", "root", "root")

      // 全局配置

       .globalConfig(builder -> {

        builder.author("itbaizhan") // 设置作者

           .commentDate("MM-dd") // 注释日期格式

           .outputDir(System.getProperty("user.dir") + "/springboot_mybatisplus/src/main/java") // 指定输出目录(可能需要更改)

           .fileOverride(); //覆盖文件

       })

      // 包配置

       .packageConfig(builder -> {

        builder.parent("com.itbaizhan.springboot_mp") // 包名前缀(可能需要更改)

           .entity("domain") //实体类包名

           .mapper("mapper") //mapper接口包名

           .service("service") //service包名

           .controller("controller") //controller包名

           .xml("mapper"); //映射文件包名

       })

      // 策略配置

       .strategyConfig(builder -> {

        builder.addInclude("tb_student") // 设置需要生成的表名,可以有多个(可能需要更改)

           .addTablePrefix("tb_") // 设置表名前缀

           .entityBuilder() // 开始实体类配置

           .enableLombok() // 开启lombok模型

           .naming(NamingStrategy.underline_to_camel) //表名下划线转驼峰

           .columnNaming(NamingStrategy.underline_to_camel);//列名下划线转驼峰

       })

       .execute();

   }

}

运行即可生成

 

        代码生成器MyBatisX

MybatisX是一款基于IDEA的快速开发插件,为效率而生。

安装方法:打开 IDEA,进入 File -> Settings -> Plugins -> Marketplace,输入 mybatisx 搜索并安装。

生成代码

MybatisX也可以生成Mybatis代码

  1. 在IDEA中连接数据库
  2. 如下操作可以根据数据库表生成Mybaits代码

生成映射配置

  1. 在Mapper接口中编写方法
    public interface StudentMapper extends BaseMapper<Student>{
     
    List<Student> selectAllBySname(String sname);
    }
  2. 如下操作即可在映射文件中自动生成映射配置

代码跳转

点击Mapper接口或映射文件前的小鸟图案,即可快速在Mapper接口与映射文件间跳转

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

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

相关文章

Seata 分布式事务你懂吗?学习了大咖的笔记,公司说要给我涨薪 8K

分布式事务处理过程的-ID三组件模型&#xff1a; 关于事务的基本概念 Seata 是阿里开源的分布式事务解决方案中间件&#xff0c;对业务侵入小&#xff0c;在应用中 Seata 整体事务逻辑基于两阶段提交的模型&#xff0c;核心概念包含三个角色&#xff1a; TM&#xff1a;事务发…

听说你还在自己做重复劳动?看我一键生成错误码映射

大家在工作中定义错误码的时候都是如何处理的&#xff1f; xdm 可以评论区交流交流 我看到过有的是这样定义错误码的&#xff1a; m : make(map[int]string)m[0] "OK"m[1] "链接失败"m[2] "文件类型错误"... 还看到过这样定义错误码的&#x…

腾讯云2核2G、2核4G、4核8G、8核16G、16核32G服务器价格出炉

腾讯云轻量应用服务器为轻量级的云服务器&#xff0c;使用门槛低&#xff0c;按套餐形式购买&#xff0c;轻量应用服务器套餐自带的公网带宽较大&#xff0c;4M、6M、7M、10M、14M及20M套餐可选&#xff0c;如果是云服务器CVM这个带宽价格就要贵很多了。 轻量应用服务器CPU内存…

Linux系统中如何实现串口的格式化功能方法

大家好&#xff0c;今天的话&#xff0c;主要和大家聊一聊&#xff0c;如何实现串口格式化功能实验。 目录 第一&#xff1a;串口格式化基本简介 第二&#xff1a;实验程序的操作 第三&#xff1a;具体的代码实现 第一&#xff1a;串口格式化基本简介 前面虽然实现了串口的功…

[附源码]计算机毕业设计基于vuejs的爱宠用品销售appSpringboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

【vue】中英文切换(多语言国际化)

一、安装i18n插件 npm install vue-il8n8.23.0 --save二、创建语言包文件夹与配置 &#xff08;1&#xff09;index.js中 import Vue from vue // 引入vue import VueI18n from vue-i18n // 引入i18n模块 import elementEnLocale from element-ui/lib/locale/lang/en // elem…

新手使用wvp-pro和ZLMediaKit的菜鸟说明(手把手教)

对于wvp-pro的使用&#xff0c;很多大佬都是白嫖菜鸟党&#xff0c;很多都第一次使用wvp&#xff0c;甚至第一次接触国标&#xff0c;连国标最基本流程都不清楚。所以写此文档以供各位菜鸟大佬点评指正 看此文档前提&#xff1a;&#xff08;下文ZLMediaKit简称zlm&#xff09…

springBoot中日志的使用

springBoot中日志的使用 日志基础 首先你需要知道日志门面&#xff0c;日志实现&#xff0c;日志桥接器。 基于日志实现&#xff0c;常用的有logback,log4j2&#xff0c;这两个日志实现是的创始人是同一个&#xff0c;概念差不多&#xff0c;这里以log4j2为例&#xff0c;有如…

迭代器和生成器

文章目录迭代器和生成器图解迭代器和生成器的关系迭代器容器生成器yield函数生成器表达式总结迭代器和生成器 图解迭代器和生成器的关系 图1-1​ 不管是生成器还是我们的容器&#xff0c;最终都是迭代器&#xff0c;使用next方法进行有规律的获取元素&#xff0c;不需要将元素…

免费的在线3D CAD【BimAnt】

BimAnt托管了可以免费使用的在线三维CAD&#xff0c;采用BRep内核&#xff0c;支持几何约束求解&#xff0c;支持二维草图&#xff0c;支持挤压、放样、扫掠和旋转等操作。访问地址&#xff1a;BimAnt三维CAD。 一、添加基础图元 BimAnt三维CAD支持圆柱、圆锥、球体、圆环体…

STM32的最小系统组成的详解

经常使用STM32开发的工程师对于它的开发环境的最小系统是必须要有所了解的&#xff0c;特别是硬件工程师在设计硬件的时候对这个最小系统就要更加的深入了解了&#xff0c;如果最小系统的搭建都有问题&#xff0c;那以后的使用很难避免不出现问题。 话不多说&#xff0c;进入正…

【自省】使用Executors.xxx违反阿里Java代码规范,那还不写定时任务了?

一、背景 在《分布式锁主动续期的入门级实现-自省 | 简约而不简单》中通过【自省】的方式讨论了关于分布式锁自动续期功能的入门级实现方式&#xff0c;简单同步一下上下文&#xff1a; 客户端抢到分布式锁之后开始执行任务&#xff0c;执行完毕后再释放分布式锁。持锁后因客…

微服务守护神-Sentinel-热点-授权-系统规则

引言 书接上篇 微服务守护神-Sentinel-降级规则 &#xff0c;上面介绍了Sentinel降级规则&#xff0c;本篇继续来Sentinel的热点、授权、系统规则。 热点规则 何为热点&#xff1f;热点即经常访问的数据。很多时候我们希望统计某些热点数据中访问频次最高的 Top K 数据&…

# String-security(配置异常处理器,封装JWT工具类)

1 JWT是做什么的? 为了在前后端分离项目中使用 JWT &#xff0c;我们需要达到 2 个目标&#xff1a; 在用户登录认证成功后&#xff0c;需要返回一个含有 JWT token 的 json 串。 在用户发起的请求中&#xff0c;如果携带了正确合法的 JWT token &#xff0c;后台需要放行&a…

ELK日志分析系统

目录 一.ELK概述 1.1 ELK简介 1.2 ELK日志组件 1.2.1 ELK组件介绍 1.3 日志处理步骤 二. Elasticsearch 集群部署 2.1 关闭防火墙 ​2.2 ELK Elasticsearch 集群部署&#xff08;在Node1&#xff0c;Node2节点上操作&#xff09; ​ 2.2.1 更改主机名​ 2.2.2 配置域名…

RCE漏洞简介

今天继续给大家介绍渗透测试相关知识&#xff0c;本文主要内容是RCE漏洞简介。 免责声明&#xff1a; 本文所介绍的内容仅做学习交流使用&#xff0c;严禁利用文中技术进行非法行为&#xff0c;否则造成一切严重后果自负&#xff01; 再次强调&#xff1a;严禁对未授权设备进行…

高级篇之如何升级5GCPE固件

高级篇之如何升级5GCPE固件1. 准备工作2. 安装5GCPE串口驱动3. 升级固件3.1 选择固件3.2 选择串口号3.3 下载固件3.4 下载固件意外情况4. 重新启动结束&#xff01;LINKPI-5GCPE是LINKPI推出的可以做户外移动直播的 5G无线网关&#xff0c;可以支持三种模式&#xff1a; 网卡模…

计算机网络-分组交换与电路交换

有志者&#xff0c;事竟成 文章持续更新&#xff0c;可以关注【小奇JAVA面试】第一时间阅读&#xff0c;回复【资料】获取福利&#xff0c;回复【项目】获取项目源码&#xff0c;回复【简历模板】获取简历模板&#xff0c;回复【学习路线图】获取学习路线图。 文章目录一、分组…

普乐蛙VR航天科技馆太空体验馆VR太空舱体验馆vr飞碟遨游太空

什么是航天航空主题馆 普乐蛙VR航天航空体验馆系列 普乐蛙VR航天航空主题馆可以根据客户的需求&#xff0c;用航天航空的科技氛围方案进行布置&#xff0c;大多用最新的黑科技&#xff0c;让整个馆充满科技科幻的感觉&#xff0c;使人沉浸&#xff0c;容易进入主题。馆内设置不…

MySQL函数:列转行CONCAT、CONCAT_WS、GROUP_CONCAT的使用(精要)

前言 很久没有接触Mysql了。 今天心血来潮&#xff0c;突然想了解一下Mysql列转行&#xff0c;看了一些文章&#xff0c;重点不清晰&#xff0c;遂有下文&#xff01; Mysql官网、 社区版下载&#xff08; Windows版_mysql.8.0.31下载 &#xff09; 概述 Mysql内部提供了列转…