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

mybatis-plus 用法总结

MyBatis-Plus(简称 MP)是 MyBatis 的增强工具,旨在简化开发者的 CRUD 操作。它在 MyBatis 的基础上提供了更多的功能和便利性,如代码生成器、分页插件、性能分析插件等,使开发者能够更高效地进行数据库操作。MyBatis-Plus 保持了 MyBatis 原有的灵活性和易用性,同时通过一些约定和默认实现减少了重复的代码编写。

1.常见注解

MybatisPlus会根据PO实体的信息来推断出表的信息,从而生成SQL的。默认情况下:

  • MybatisPlus会把PO实体的类名驼峰转下划线作为表名

  • MybatisPlus会把PO实体的所有变量名驼峰转下划线作为表的字段名,并根据变量类型推断字段类型

  • MybatisPlus会把名为id的字段作为主键

但很多情况下,默认的实现与实际场景不符,因此MybatisPlus提供了一些注解便于我们声明表信息。

1.1.@TableName

描述:表名注解,标识实体类对应的表

@TableName("user")
public class User {private Long id;private String name;
}

1.2@TableId

主键注解,标识实体类中的主键字段

属性

类型

必须指定

默认值

描述

value

String

""

表名

type

Enum

IdType.NONE

指定主键类型

@TableName("user")
public class User {@TableIdprivate Long id;private String name;
}

IdType支持的类型有:

描述

AUTO

数据库 ID 自增

NONE

无状态,该类型为未设置主键类型(注解里等于跟随全局,全局里约等于 INPUT)

INPUT

insert 前自行 set 主键值

ASSIGN_ID

分配 ID(主键类型为 Number(Long 和 Integer)或 String)(since 3.3.0),使用接口IdentifierGenerator的方法nextId(默认实现类为DefaultIdentifierGenerator雪花算法)

ASSIGN_UUID

分配 UUID,主键类型为 String(since 3.3.0),使用接口IdentifierGenerator的方法nextUUID(默认 default 方法)

1.3@TableField

普通字段注解

@TableName("user")
public class User {@TableIdprivate Long id;private String name;private Integer age;@TableField("isMarried")private Boolean isMarried;@TableField("concat")private String concat;
}

一般情况下我们并不需要给字段添加@TableField注解,一些特殊情况除外:

  • 成员变量名与数据库字段名不一致

  • 成员变量是以isXXX命名,按照JavaBean的规范,MybatisPlus识别字段时会把is去除,这就导致与数据库不符。

  • 成员变量名与数据库一致,但是与数据库的关键字冲突。使用@TableField注解给字段名添加转义字符。

2.常见配置

大多数的配置都有默认值,因此我们都无需配置。但还有一些是没有默认值的,例如:

实体类的别名扫描包

2.1全局id类型

mybatis-plus:type-aliases-package: com.itheima.mp.domain.poglobal-config:db-config:id-type: auto # 全局id类型为自增长

2.2手写SQL

需要注意的是,MyBatisPlus也支持手写SQL的,而mapper文件的读取地址可以自己配置,默认值是classpath*:/mapper/**/*.xml,也就是说我们只要把mapper.xml文件放置这个目录下就一定会被加载。

mybatis-plus:mapper-locations: "classpath*:/mapper/**/*.xml" # Mapper.xml文件地址,当前这个是默认值。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.mp.mapper.UserMapper"></mapper>

 3.Mapper 接口

mapper提供了一些常见的crud方法,继承于BaseMapper后可直接使用

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.itheima.mp.domain.po.User;public interface UserMapper extends BaseMapper<User> {
}

3.1条件构造器

除了新增以外,修改、删除、查询的SQL语句都需要指定where条件。因此BaseMapper中提供的相关方法除了以id作为where条件以外,还支持更加复杂的where条件。

Wrapper的子类AbstractWrapper提供了where中包含的所有条件构造方法

QueryWrapper在AbstractWrapper的基础上拓展了一个select方法,允许指定查询字段:

UpdateWrapper在AbstractWrapper的基础上拓展了一个set方法,允许指定SQL中的SET部分:

3.2新增

    @Testvoid testInsert() {User user = new User();user.setId(5L);user.setUsername("Lucy");user.setPassword("123");user.setPhone("18688990011");user.setBalance(200);user.setInfo("{\"age\": 24, \"intro\": \"英文老师\", \"gender\": \"female\"}");user.setCreateTime(LocalDateTime.now());user.setUpdateTime(LocalDateTime.now());userMapper.insert(user);}

3.3通过id查询

   @Testvoid testQueryById() {User user = userMapper.selectById(5L);System.out.println("user = " + user);}

 3.4通过id批量查询

 @Testvoid testQueryByIds() {List<User> users = userMapper.selectBatchIds(List.of(1L, 2L, 3L, 4L));users.forEach(System.out::println);}

 3.5查询一行数据

若实际上有多行数据,会报错

@Testvoid testSelectOne() {QueryWrapper<User> wrapper = new QueryWrapper<User>().eq("username", "特定用户名");User user = userMapper.selectOne(wrapper);System.out.println("user = " + user);}

3.6查询记录数

   @Testvoid testCount() {QueryWrapper<User> wrapper = new QueryWrapper<User>().like("username", "o");long count = userMapper.selectCount(wrapper);System.out.println("符合条件的用户数量: " + count);}

3.7Map查询

 @Testvoid testSelectByMap() {Map<String, Object> map = new HashMap<>();map.put("username", "Jack");map.put("phone", "13900112224");List<User> users = userMapper.selectByMap(map);users.forEach(System.out::println);}

3.8多条件构造查询

    @Testvoid testQueryWrapper() {// 1.构建查询条件 where name like "%o%" AND balance >= 1000QueryWrapper<User> wrapper = new QueryWrapper<User>().select("id", "username", "info", "balance").like("username", "o").ge("balance", 1000);// 2.查询数据List<User> users = userMapper.selectList(wrapper);users.forEach(System.out::println);}@Testvoid testLambdaQueryWrapper() {// 1.构建条件 WHERE username LIKE "%o%" AND balance >= 1000QueryWrapper<User> wrapper = new QueryWrapper<>();wrapper.lambda().select(User::getId, User::getUsername, User::getInfo, User::getBalance).like(User::getUsername, "o").ge(User::getBalance, 1000);// 2.查询List<User> users = userMapper.selectList(wrapper);users.forEach(System.out::println);}

3.9分页查询

  @Testvoid testPageQuery() {Page<User> page = new Page<>(1, 10); // 第一页,每页10条记录QueryWrapper<User> wrapper = new QueryWrapper<User>().orderByDesc("id");IPage<User> result = userMapper.selectPage(page, wrapper);result.getRecords().forEach(System.out::println);System.out.println("总记录数: " + result.getTotal());}

 3.10通过id更新

user中必须设置id,不然更新不了,没有设置默认为null。以为没有id=null的值,故不更新

其他参数没有设置,不会进行修改

   @Testvoid testUpdateById() {User user = new User();user.setId(5L);user.setBalance(20000);userMapper.updateById(user);}

 3.11构造条件更新

    @Testvoid testUpdateByQueryWrapper() {// 1.构建查询条件 where name = "Jack"QueryWrapper<User> wrapper = new QueryWrapper<User>().eq("username", "Jack");// 2.更新数据,user中非null字段都会作为set语句User user = new User();user.setBalance(2000);userMapper.update(user, wrapper);}

3.12自定义SQL更新

  @Testvoid testUpdateWrapper() {List<Long> ids = List.of(1L, 2L, 4L);// 1.生成SQLUpdateWrapper<User> wrapper = new UpdateWrapper<User>().setSql("balance = balance - 200") // SET balance = balance - 200.in("id", ids); // WHERE id in (1, 2, 4)// 2.更新,注意第一个参数可以给null,也就是不填更新字段和数据,// 而是基于UpdateWrapper中的setSQL来更新userMapper.update(null, wrapper);}

 3.13通过id删除

    @Testvoid testDeleteUser() {userMapper.deleteById(5L); //删除}

3.14通过id批量删除

    @Testvoid testDeleteUsers() {userMapper.deleteBatchIds(List.of(1L, 2L, 3L, 4L)); //批量删除}

4.Service 接口

mybatis-plus在service接口中同样也提供了基础的crud方法,在接口在需要继承IService类

import com.baomidou.mybatisplus.extension.service.IService;
import com.itheima.mp.domain.po.User;public interface IUserService extends IService<User> {// 拓展自定义方法
}

 实现IUserService接口,并指定mapper接口

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.mp.domain.po.User;
import com.itheima.mp.domain.po.service.IUserService;
import com.itheima.mp.mapper.UserMapper;
import org.springframework.stereotype.Service;@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>implements IUserService {
}

4.1save新增

  • save是新增单个元素

  • saveBatch是批量新增

  • saveOrUpdate是根据id判断,如果数据存在就更新,不存在则新增

  • saveOrUpdateBatch是批量的新增或修改

4.2remove删除:

  • removeById:根据id删除

  • removeByIds:根据id批量删除

  • removeByMap:根据Map中的键值对为条件删除

  • remove(Wrapper<T>):根据Wrapper条件删除

  • removeBatchByIds

4.3update修改:

  • updateById:根据id修改

  • update(Wrapper<T>):根据UpdateWrapper修改,Wrapper中包含setwhere部分

  • update(T,Wrapper<T>):按照T内的数据修改与Wrapper匹配到的数据

  • updateBatchById:根据id批量修改

4.4查询一条Get:

  • getById:根据id查询1条数据

  • getOne(Wrapper<T>):根据Wrapper查询1条数据

  • getBaseMapper:获取Service内的BaseMapper实现,某些时候需要直接调用Mapper内的自定义SQL时可以用这个方法获取到Mapper

4.5批量查询List:

  • listByIds:根据id批量查询

  • list(Wrapper<T>):根据Wrapper条件查询多条数据

  • list():查询所有

4.6计数Count

  • count():统计所有数量

  • count(Wrapper<T>):统计符合Wrapper条件的数据数量

4.7分页

@Service
public class UserService extends ServiceImpl<UserMapper, User> {/*** 根据用户名获取用户列表的分页数据** @param currentPage 当前页码* @param pageSize 每页大小* @param username 用户名* @return 分页后的用户列表*/public IPage<User> getUserPageByName(int currentPage, int pageSize, String username) {// 创建分页对象Page<User> page = new Page<>(currentPage, pageSize);// 创建查询条件QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.like("username", username); // 使用 like 进行模糊匹配// 执行分页查询,带条件return this.page(page, queryWrapper);}
}

5.静态工具

有的时候Service之间也会相互调用,为了避免出现循环依赖问题,MybatisPlus提供一个静态工具类:Db,其中的一些静态方法与IService中方法签名基本一致,也可以帮助我们实现CRUD功能。Db中的静态方法,必须

示例:

User.class表示查询user表中,id为1的值

@Test
void testDbGet() {User user = Db.getById(1L, User.class);System.out.println(user);
}

利用Db实现复杂条件查询

@Test
void testDbList() {List<User> list = Db.lambdaQuery(User.class).like(User::getUsername, "o").ge(User::getBalance, 1000).list();list.forEach(System.out::println);
}

我们采用了Db的静态方法,因此避免了注入其他service,减少了循环依赖的风险。

6.逻辑删除

用户注销账号后,我们往往不会真正的删除该用户,而是通过一个字段表示用户在逻辑上已经删除了。但是这样的操作,在以后业务查询上,都需要确认用户有没有删除,造成不必要的麻烦。假如deleted(1删除,0未删除)字段,我们仅需要在配置文件中进行下述配置,mybatis-plus就会自动进行判断

mybatis-plus:global-config:db-config:logic-delete-field: deleted # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)logic-delete-value: 1 # 逻辑已删除值(默认为 1)logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)

注意,只有MybatisPlus生成的SQL语句才支持自动的逻辑删除,自定义SQL需要自己手动处理逻辑删除。

7.定义枚举

import com.baomidou.mybatisplus.annotation.EnumValue;
import lombok.Getter;@Getter
public enum UserStatus {NORMAL(1, "正常"),FREEZE(2, "冻结");@EnumValue //标记枚举属性private final int value;@JsonValue //标记JSON序列化时展示的字段private final String desc;UserStatus(int value, String desc) {this.value = value;this.desc = desc;}
}

要让MybatisPlus处理枚举与数据库类型自动转换,我们必须告诉MybatisPlus,枚举中的哪个字段的值作为数据库值。 MybatisPlus提供了@EnumValue注解来标记枚举属性,并且在UserStatus枚举中通过@JsonValue注解标记JSON序列化时展示的字段

 配置枚举处理

mybatis-plus:configuration:default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler

8.JSON类型处理器

数据库的user表中有一个info字段,是JSON类型:

{"age": 20, "intro": "佛系青年", "gender": "male"}

而目前User实体类中却是String类型:

这样一来,我们要读取info中的属性时就非常不方便。如果要方便获取,info的类型最好是一个Map或者实体类。

而一旦我们把info改为对象类型,就需要在写入数据库时手动转为String,再读取数据库时,手动转换为对象,这会非常麻烦。

因此MybatisPlus提供了很多特殊类型字段的类型处理器,解决特殊字段类型与数据库类型转换的问题。例如处理JSON就可以使用JacksonTypeHandler处理器。

接下来,我们就来看看这个处理器该如何使用。

定义实体

首先,我们定义一个单独实体类来与info字段的属性匹配:

import lombok.Data;@Data
public class UserInfo {private Integer age;private String intro;private String gender;
}

3.4.2.使用类型处理器

接下来,将User类的info字段修改为UserInfo类型,并声明类型处理器:

   /*** 详细信息*/@TableField(typeHandler = JacksonTypeHandler.class)private UserInfo info;

9.配置加密

目前我们配置文件中的很多参数都是明文,如果开发人员发生流动,很容易导致敏感信息的泄露。所以MybatisPlus支持配置文件的加密和解密功能。

我们以数据库的用户名和密码为例。

生成秘钥

首先,我们利用AES工具生成一个随机秘钥,然后对用户名、密码加密:

    @Testvoid contextLoads() {// 生成 16 位随机 AES 密钥String randomKey = AES.generateRandomKey();System.out.println("randomKey = " + randomKey);// 利用密钥对用户名加密String username = AES.encrypt("root", randomKey);System.out.println("username = " + username);// 利用密钥对用户名加密String password = AES.encrypt("MySQL123", randomKey);System.out.println("password = " + password);}

randomKey = 6234633a66fb399f

username = px2bAbnUfiY8K/IgsKvscg==

password = FGvCSEaOuga3ulDAsxw68Q==

spring:datasource:url: jdbc:mysql://127.0.0.1:3306/mp?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=truedriver-class-name: com.mysql.cj.jdbc.Driverusername: mpw:QWWVnk1Oal3258x5rVhaeQ== # 密文要以 mpw:开头password: mpw:EUFmeH3cNAzdRGdOQcabWg== # 密文要以 mpw:开头

 10.分页插件

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;@Configuration
public class MybatisConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {// 初始化核心插件MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();// 添加分页插件interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));return interceptor;}
}
@Test
void testPageQuery() {// 1.分页查询,new Page()的两个参数分别是:页码、每页大小Page<User> p = userService.page(new Page<>(2, 2));// 2.总条数System.out.println("total = " + p.getTotal());// 3.总页数System.out.println("pages = " + p.getPages());// 4.数据List<User> records = p.getRecords();records.forEach(System.out::println);
}

这里用到了分页参数,Page,即可以支持分页参数,也可以支持排序参数。

int pageNo = 1, pageSize = 5;
// 分页参数
Page<User> page = Page.of(pageNo, pageSize);
// 排序参数, 通过OrderItem来指定
page.addOrder(new OrderItem("balance", false));userService.page(page);

分页实体PageDTO

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;import java.util.List;@Data
@ApiModel(description = "分页结果")
public class PageDTO<T> {@ApiModelProperty("总条数")private Long total;@ApiModelProperty("总页数")private Long pages;@ApiModelProperty("集合")private List<T> list;
}

定义分页查询时,查询的页号。用于前端的参数

@Data
@ApiModel(description = "分页查询实体")
public class PageQuery {@ApiModelProperty("页码")private Long pageNo;@ApiModelProperty("页面大小")private Long pageSize;@ApiModelProperty("排序字段")private String sortBy;@ApiModelProperty("是否升序")private Boolean isAsc;
}

11.自动填充

我们在设计表时,一般都需要保存数据的创建时间和更新时间,为了不必要的麻烦,每次都需要设置,我们可以使用mybatis-plus提供的进行自动填充

 构造抽象类

后续所有的实体类,都可以继承这个基础的实体类,以提高代码的复用性

在需要自动创建更新的属性上,加上@TableField注解

public abstract class BasePojo {//文件创建,自动填充。需要实现MetaObjectHandle接口,进行处理@TableField(fill = FieldFill.INSERT)private Date created;//文件更新,自动填充@TableField(fill = FieldFill.INSERT_UPDATE)private Date updated;
}

实现MetaObjectHandle接口

package com.tanhua.sso.handler;import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;import java.util.Date;@Component
public class MyMetaObjectHandler implements MetaObjectHandler {@Overridepublic void insertFill(MetaObject metaObject) {// 使用严格模式插入填充,如果字段为null则进行填充this.strictInsertFill(metaObject, "created", Date.class, new Date()); // 创建时间this.strictInsertFill(metaObject, "updated", Date.class, new Date()); // 更新时间}@Overridepublic void updateFill(MetaObject metaObject) {// 使用严格模式更新填充,总是设置更新时间this.strictUpdateFill(metaObject, "updated", Date.class, new Date());}
}

版本兼容性问题

若业务中mybatis-plus版本较低,可能不含strict方法,可以采用以下写法

package com.tanhua.sso.handler;import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;import java.util.Date;@Component
public class MyMetaObjectHandler implements MetaObjectHandler {@Overridepublic void insertFill(MetaObject metaObject) {//字段为空,自动填充字段Object created = getFieldValByName("created", metaObject);if(null==created){setFieldValByName("created",new Date(),metaObject);}Object updated = getFieldValByName("updated", metaObject);if(null==updated){setFieldValByName("updated",new Date(),metaObject);}}@Overridepublic void updateFill(MetaObject metaObject) {//更新数据时,更新字段setFieldValByName("updated",new Date(),metaObject);}
}

相关文章:

mybatis-plus 用法总结

MyBatis-Plus&#xff08;简称 MP&#xff09;是 MyBatis 的增强工具&#xff0c;旨在简化开发者的 CRUD 操作。它在 MyBatis 的基础上提供了更多的功能和便利性&#xff0c;如代码生成器、分页插件、性能分析插件等&#xff0c;使开发者能够更高效地进行数据库操作。MyBatis-P…...

华为开源自研AI框架昇思MindSpore应用案例:ICNet用于实时的语义分割

ICNet用于实时的语义分割 ICNet 被广泛应用于实时的语义分割领域。它在处理图像数据时&#xff0c;能够以较高的效率进行语义分割操作&#xff0c;为相关领域的研究和实际应用提供了有力的支持。ICNet 的实时性使其在众多场景中都具有很大的优势&#xff0c;例如在视频处理、自…...

CAN201 Introduction to Networking(计算机网络)Pt.2 传输层

文章目录 3. Transport Layer&#xff08;传输层&#xff09;3.1 Multiplexing and demultiplexing&#xff08;多路复用和多路分解&#xff09;3.2 Connectionless transport&#xff1a;UDP3.3 Principles of reliable data transfer3.4 Pipelined communication3.5 TCP: con…...

HashMap

一、什么是 基于哈希表的数据结构允许以O(1)的时间复杂度进行元素的插入&#xff0c;查询和删除 二、底层结构 1.数据结构 在1.8以后&#xff0c;数组链表红黑树 数组&#xff1a;HashMap底层是一个数组&#xff0c;每个数组元素存放一个链表或红黑树&#xff08;在JDK 1.…...

JavaScript甘特图 dhtmlx-gantt

背景 需求是在后台中&#xff0c;需要用甘特图去展示管理任务相关视图&#xff0c;并且不用依赖vue&#xff0c;兼容JavaScript原生开发。最终使用dhtmlx-gantt&#xff0c;一个半开源的库&#xff0c;基础功能免费&#xff0c;更多功能付费。 甘特图需求如图&#xff1a; 调…...

基于无线传感器网络的无线光照强度采集系统(附详细使用教程+完整代码+原理图+完整课设报告)

&#x1f38a;项目专栏&#xff1a;【Zigbee课程设计系列文章】&#xff08;附详细使用教程完整代码原理图完整课设报告&#xff09; 前言 &#x1f451;由于无线传感器网络&#xff08;也即是Zigbee&#xff09;作为&#x1f310;物联网工程的一门必修专业课&#xff0c;具有…...

单元测试中创建多个线程测试 ThreadLocal

单元测试中创建多个线程测试 ThreadLocal 在单元测试中&#xff0c;可以通过以下方式创建多个线程来测试 ThreadLocal 的行为。 目标 验证 ThreadLocal 在多线程环境下是否能正确隔离每个线程的数据。 实现步骤 定义需要测试的类 包含 ThreadLocal 对象的类&#xff0c;提供…...

【 Sonarqube】可视化Java项目单元测试覆盖率统计框架搭建

一、项目背景&#xff1a; 一个小公司的朋友反应他们那边Java项目单元测试有&#xff0c;但还没有可视化统计覆盖率数据&#xff0c;没法统计就不能直观的看到单测的覆盖率&#xff0c;Java的覆盖率统计框架还是比较成熟&#xff0c;部署起来也不是很难&#xff0c;下面我们逐…...

安装CentOS(新手教程超详细)

安装CentOS 1. 安装虚拟机 1.1下载虚拟机软件 VMware(VMware by Broadcom - Cloud Computing for the Enterprise) 我们使用的是VMware Workstation VirtualBox(Downloads – Oracle VirtualBox) 如果使用的是Windows系统&#xff0c;下载带for Windows hosts的版本 1.2…...

一起来看--红黑树

【欢迎关注编码小哥&#xff0c;学习更多实用的编程方法和技巧】 红黑树是一种自平衡的二叉搜索树&#xff0c;广泛应用于计算机科学中&#xff0c;尤其是在实现关联数组和集合时。它的设计旨在确保在最坏情况下&#xff0c;基本动态集合操作&#xff08;如插入、删除和查找&am…...

【Hackthebox 中英 Write-Up】通过 POST 请求绕过前端限制:基于 Cookie 的认证与数据提取实操指南

Bypassing Frontend Restrictions with POST Requests: A Practical Guide to Cookie-Based Authentication and Data Extraction 通过 POST 请求绕过前端限制 Objective | 目标 The purpose of this exercise is to understand how POST requests work and how to authentica…...

comctl32.dll没有被指定在window运行怎么解决?

一、文件丢失问题&#xff1a;comctl32.dll没有被指定在Windows上运行怎么解决&#xff1f; comctl32.dll是Windows操作系统中的一个重要组件&#xff0c;它负责提供用户界面元素&#xff0c;如按钮、对话框和列表视图等。当系统提示“comctl32.dll没有被指定在Windows上运行”…...

EC-Final 2024游记

长篇流水账预警 Day -&#xff1f; 某天上乒乓课时看到懋神群里了我们队问有时间打ec吗&#xff0c;才知道我们最终还是进ec了&#xff0c;也成为了我们学校唯一一支没有金牌的ec队伍&#xff0c;然而此时整个队伍板子都扔了&#xff0c;一个多月没做过题&#xff0c;我脑子就…...

我的Opencv

1.安装Opencv pip install opencv-python 2.读取图像 3.写图像 4. 显示图像 5.waitKey() 6.读视频并播放视频 7.写视频 8. 获取摄像头视频 9.色彩转换 # BGR to GRAY imgGRAY cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # BGR to RGB imgRGB cv2.cvtColor(img, cv2.COLOR_…...

Pandas-缺失数据处理

文章目录 一. 简介1. 缺失数据简介2. NaN简介① 查看NaN&#xff0c;NAN&#xff0c;nan② 两个NaN也不相等③ isnull/isna方法④ notnull/notna 二. 加载缺失值1. 来源2. 加载数据&#xff0c;不包含默认缺失值3.加载数据&#xff0c;手动指定缺失值 三.处理缺失值1. 加载数据…...

windows编译llama.cpp GPU版本

Build 指南 https://github.com/ggerganov/llama.cpp/blob/master/docs/build.md 一、Prerequire 具体步骤&#xff08;以及遇到的坑&#xff09;&#xff1a; 如果你要使用CUDA&#xff0c;请确保已安装。 1.安装 最新的 cmake, git, anaconda&#xff0c; pip 配置pyt…...

绝美的数据处理图-三坐标轴-散点图-堆叠图-数据可视化图

clc clear close all %% 读取数据 load(MyColor.mat) %读取颜色包for iloop 1:25 %提取工作表数据data0(iloop) {readtable(data.xlsx,sheet,iloop)}; end%% 解析数据 countzeros(23,14); for iloop 1:25index(iloop) { cell2mat(table2array(data0{1,iloop}(1,1)))};data(i…...

计算机网络500题2024-2025学年度第一学期复习题库(选择、判断、填空)

一、单选题 1、&#xff08; &#xff09;是实现两个同种网络互连的设备 A. 网桥 B. 网关 C. 集线器 D. 路由器 2、10M以太网有三种接口标准&#xff0c;其中10BASE-T采用&#xff08; &#xff09; A. 双绞线 B. 粗同轴电缆 C. 细同轴电缆 D. 光纤 3、HDLC是哪…...

python学opencv|读取图像(二十二)使用cv2.polylines()绘制多边形

【1】引言 前序学习进程中&#xff0c;已经掌握了使用pythonopencv绘制线段、矩形和圆形的基本操作&#xff0c;相关链接包括且不限于&#xff1a; python学opencv|读取图像&#xff08;十八&#xff09;使用cv2.line创造线段-CSDN博客 python学opencv|读取图像&#xff08;…...

skywalking配置项indexReplicasNumber不生效问题

indexReplicasNumber: 的配置原来是 indexReplicasNumber: ${SW_STORAGE_ES_INDEX_REPLICAS_NUMBER:0}&#xff0c; 修改为 indexReplicasNumber: ${SW_STORAGE_ES_INDEX_REPLICAS_NUMBER:1} 但从es查询索引显示的副本数还是0&#xff0c;删除es中的数据&#xff0c;重启sk…...

2024年终回顾

前言 很久没有更新博客&#xff0c;因为工作内容主要是内场开发&#xff0c;后来有点和互联网脱轨&#xff0c;断断续续上来看一下。这个总结应该也很简单&#xff0c;涉及以下的几个内容进行逐一说明 一、就业问题 这个问题可能很尖锐&#xff0c;从大环境来说&#xff0c;去…...

【深度学习】卷积网络代码实战ResNet

ResNet (Residual Network) 是由微软研究院的何凯明等人在2015年提出的一种深度卷积神经网络结构。ResNet的设计目标是解决深层网络训练中的梯度消失和梯度爆炸问题&#xff0c;进一步提高网络的表现。下面是一个ResNet模型实现&#xff0c;使用PyTorch框架来展示如何实现基本的…...

算法基础一:冒泡排序

一、冒泡排序 1、定义 冒泡排序&#xff08;英语&#xff1a;Bubble Sort&#xff09;是一种简单的排序算法。它重复地走访过要排序的数列&#xff0c;一次比较两个元素&#xff0c;如果他们的顺序&#xff08;如从大到小、首字母从A到Z&#xff09;错误就把他们交换过来。 …...

第 29 章 - ES 源码篇 - 网络 IO 模型及其实现概述

前言 本文介绍了 ES 使用的网络模型&#xff0c;并介绍 transport&#xff0c;http 接收、响应请求的代码入口。 网络 IO 模型 Node 在初始化的时候&#xff0c;会创建网络模块。网络模块会加载 Netty4Plugin plugin。 而后由 Netty4Plugin 创建对应的 transports&#xff0…...

工作流引擎之Flowable

一、概述 Flowable是一个使用Java编写的轻量级业务流程引擎&#xff0c;专为处理复杂业务流程而设计。作为业务流程管理&#xff08;BPM&#xff09;领域的重要工具&#xff0c;Flowable不仅支持BPMN 2.0标准的流程定义&#xff0c;还提供了丰富的API接口和可视化工具&#xf…...

学习threejs,THREE.CircleGeometry 二维平面圆形几何体

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言1.1 ☘️THREE.CircleGeometry 圆形…...

网络编程UDP—socket实现(C++)

网络编程UDP—socket实现 前言UDP客户端和服务端UDP使用场景UDP socket C代码示例服务端接收数据示例&#xff08;bindrecvfrom 阻塞式接收信息&#xff09;&#xff1a;bind 绑定-监听 函数为什么一般都是监听所有网络接口呢&#xff1f;为什么需要用inet_addr进行转换&#x…...

个人用途虚拟机VM 17安装Ubuntu 16.04.5 图解

1.安装环境软件准备工作 1&#xff09;下载 免费版VMware Pro 17 https://softwareupdate.vmware.com/cds/vmw-desktop/ws/17.6.1/24319023/windows/core/VMware-workstation-17.6.1-24319023.exe.tar 2&#xff09;Ubuntu 16.04.5 LTS 64位 64-bit PC (AMD64) desktop imag…...

音视频入门基础:MPEG2-TS专题(23)——通过FFprobe显示TS流每个packet的信息

音视频入门基础&#xff1a;MPEG2-TS专题系列文章&#xff1a; 音视频入门基础&#xff1a;MPEG2-TS专题&#xff08;1&#xff09;——MPEG2-TS官方文档下载 音视频入门基础&#xff1a;MPEG2-TS专题&#xff08;2&#xff09;——使用FFmpeg命令生成ts文件 音视频入门基础…...

安卓project级别build.gradle和主module的build.gradle

以穿山甲为例讲解 如下图 gradle和gradle插件对应关系 Android Gradle 插件 8.7 版本说明 | Android Studio | Android Developers gradle对应在项目里的配置为 gradle插件对应的位置为...

【Qt】多元素控件:QListWidget、QTableWidget、QTreeWidget

目录 QListWidget 核心属性&#xff1a; 核心方法&#xff1a; 核心信号&#xff1a; 例子&#xff1a; QListWidgetItem QTableWidget 核心方法&#xff1a; 核心信号 QTableWidgetItem 例子&#xff1a; QTreeWidget 核心方法&#xff1a; 核心信号&#xff1a…...

服务器nfs文件共享

1. 配置 NFS 服务器(NFS Server) 在 Ubuntu/Debian 上: sudo apt update sudo apt install nfs-kernel-server在 CentOS/RHEL 上: sudo yum install nfs-utils1.2 创建共享目录 选择一个要共享的目录,并确保该目录的权限正确设置。例如,假设我们要共享 /srv/nfs 目录…...

【hackmyvm】soul靶机wp

tags: HMVrbash绕过图片隐写PHP配置解析 1. 基本信息^toc 文章目录 1. 基本信息^toc2. 信息收集3. 图片解密3.1. 爆破用户名3.2. 绕过rbash3.3. 提权检测 4. 获取webshell4.1. 修改php配置 5. www-data提权gabriel6. gabriel提取到Peter7. Peter提权root 靶机链接 https://ha…...

安装winserver2008R2虚拟机步骤

一、服务器系统介绍 1.1什么是服务器&#xff1f; 服务器英文名称为“Server”&#xff0c;指的是网络环境下为客户机(Client)提供某种服务的专用计算机&#xff0c;服务器安装有网络操作系统(如Windows 2000 Server、Linux、Unix等)和各种服务器应用系统软件(如Web服务、电子…...

跟着 8.6k Star 的开源数据库,搞 RAG!

过去 9 年里&#xff0c;HelloGitHub 月刊累计收录了 3000 多个开源项目。然而&#xff0c;随着项目数量的增加&#xff0c;不少用户反馈&#xff1a;“搜索功能不好用&#xff0c;找不到想要的项目&#xff01;” 这让我意识到&#xff0c;仅仅收录项目是不够的&#xff0c;还…...

RCE漏洞

一、课程知识点 1、远程代码执行漏洞原理与利用 2、常见的代码执行函数 3、常见的命令执行函数 4、常见的绕过姿势 5、命令执行漏洞防范 二、技术目标 1、掌握命令执行漏洞的原理 2、掌握 PHP 命令执行和代码执行的相关函数 3、掌握常见的绕过姿势 4、掌握代码执行漏洞防御措施…...

数据通信系统的主要性能指标

1.码元速率 n 误码率 2.数据传输速率 n 误比特率 3.时延 n 往返时间 RTT 1. 码元速率 n 码元 ( Code element) n 码元是 数字信号的计量单位 &#xff08; Signal element &#xff09;&#xff0c; 又称为符号&#xff08; Symbol &#xff09;。 n 码元 是指在使用时域表示…...

C语言中的贪心算法

贪心算法&#xff08;Greedy Algorithm&#xff09;是一种在每一步选择中都采取当前最优解的算法&#xff0c;希望通过局部最优解的选择&#xff0c;最终得到全局最优解。它常用于解决最优化问题&#xff0c;如最小生成树、最短路径等。本文将从理论到实践&#xff0c;逐步引导…...

使用envoyfilter添加请求头

该envoyfilter实现了这样一个功能&#xff0c;如果请求头中含有Sw8&#xff0c;则添加请求头HasSw8: true。 1. 内嵌lua脚本 apiVersion: networking.istio.io/v1alpha3 kind: EnvoyFilter metadata:name: add-header-filternamespace: demo-bookinfo # 可根据实际情况调整命…...

【机器学习】回归

文章目录 1. 如何训练回归问题2. 泛化能力3. 误差来源4. 正则化5. 交叉验证 1. 如何训练回归问题 第一步&#xff1a;定义模型 线性模型&#xff1a; y ^ b ∑ j w j x j \hat{y} b \sum_{j} w_j x_j y^​b∑j​wj​xj​ 其中&#xff0c;( w ) 是权重&#xff0c;( b )…...

Elasticsearch名词解释

文章目录 1.什么是Elasticsearch?2.什么是elastic stack(ELK)?3.什么是Lucene?4.什么是文档(document)&#xff1f;5.什么是词条(term)&#xff1f;6.什么是正向索引&#xff1f;7.什么是倒排索引&#xff1f;8.ES中的索引(index)9.映射(Mapping)10.DSL11.elastcisearch与my…...

把Huggingface下载的arrow数据集转化为json格式

Arrow2json 使用默认的Huggingface路径 以allenai/tulu-3-sft-mixture数据集为例。 使用load_dataset即可&#xff1a; from datasets import load_dataset# 加载数据集 dataset load_dataset("allenai/tulu-3-sft-mixture")# 指定保存路径 output_dir "~/…...

手机联系人 查询 添加操作

Android——添加联系人_android 添加联系人-CSDN博客 上面连接添加联系人已测试 是可以 Android : 获取、添加、手机联系人-ContentResolver简单应用_contentresolver 添加联系人-CSDN博客...

kkFileView集成springboot:使用自定义预览接口(非minio预览接口),发现无法预览资源

目录 1、背景2、原因分析3、解决办法 1、背景 按照项目验收要求&#xff0c;需要对minio中存储的数据进行加密 之前提供给kkFileView的预览地址都是获取的minio预览地址 由于minio中的资源进行了加密处理&#xff0c;所以我们自定义预览接口&#xff08;进行解密操作&#xff…...

C++ 设计模式:观察者模式(Observer Pattern)

链接&#xff1a;C 设计模式 链接&#xff1a;C 设计模式 - 模板方法 链接&#xff1a;C 设计模式 - 策略模式 观察者模式&#xff08;Observer Pattern&#xff09;是一种行为设计模式&#xff0c;它定义了一种一对多的依赖关系&#xff0c;让多个观察者对象同时监听某一个主…...

Mono 和 IL2Cpp的区别

Mono特征: 标准项目中有Assembly-CSharp.dll , 但在更复杂的项目或特定配置中,可能会有其他.dll或结构变更 在游戏的数据目录下看到一系列的.dll文件,这些文件的语言一般为中间语言 CE附加 , 查看是否有Mono.dll相关模块 目录有MonoBleedingEdge文件夹 IL2Cpp 标准项目应该…...

Windows平台ROBOT安装

Windows环境下ROBOT的安装,按照下文进行部署ROBOT的前提是你的python已安装并且环境变量已设置好. 一、安装setuptools 1、下载后安装 https://pypi.python.org/pypi/setuptools/ 下载你需要的包 setuptools-75.6.0.tar.gz 解压下载的包在命令行中进入该包,敲击如下命令后…...

DevOps实战:用Kubernetes和Argo打造自动化CI/CD流程(2)

DevOps实战&#xff1a;用Kubernetes和Argo打造自动化CI/CD流程&#xff08;2&#xff09; 背景 Tips 翻遍国内外的文档&#xff0c;关于 Argo 作为 CI/CD 当前所有开源的文档&#xff0c;博客&#xff0c;argo官方文档。得出的结论是&#xff1a; argo官方给出的例子都相对…...

深入浅出 MyBatis | CRUD 操作、配置解析

3、CRUD 3.1 namespace namespace 中的包名要和 Dao/Mapper 接口的包名一致&#xff01; 比如将 UserDao 改名为 UserMapper 运行发现抱错&#xff0c;这是因为 UserMapper.xml 中没有同步更改 namespace 成功运行 给出 UserMapper 中的所有接口&#xff0c;接下来一一对…...

Hutool 发送 HTTP 请求的几种常见写法

最简单的 GET 请求&#xff1a; String result HttpUtil.get("https://www.baidu.com");带参数的 GET 请求&#xff1a; // 方法1: 直接拼接URL参数 String result HttpUtil.get("https://www.baidu.com?name张三&age18");// 方法2: 使用 HashMap…...