MybatisPlus拓展篇
文章目录
- 逻辑删除
- 通用枚举
- 字段类型处理器
- 自动填充功能
- 防全表更新与删除插件
- MybatisX快速开发插件
- 插件安装
- 逆向工程
- 常见需求代码生成
- 乐观锁
- 问题引入
- 乐观锁的使用
- 效果测试
- 代码生成器
- 执行SQL分析打印
- 多数据源
逻辑删除
- 逻辑删除的操作就是增加一个字段表示这个数据的状态,如果一条数据需要删除,我们通过改变这条数据的状态来实现,这样既可以表示这条数据是删除的状态,又保留了数据以便以后统计。
- 在表中增加一列字段,表示是否删除的状态,这里使用的字段类型为int类型,通过1表示该条数据可用,0表示该条数据不可用。
- 实体类添加一个字段为Integer,用于对应表中的字段
@Data @AllArgsConstructor @NoArgsConstructor public class User extends Model<User> {private Long id;private String name;private Integer age;private String email;@TableLogic(value = "1",delval = "0")private Integer status; }
- 测试逻辑删除效果
@Test
void logicDelete(){userMapper.deleteById(7L);
}
- 还可以通过全局配置来实现逻辑删除的效果
通用枚举
- 当想要表示一组信息,这组信息只能从一些固定的值中进行选择,不能随意写,在这种场景下,枚举就非常的合适。
- 在表中添加一个字段,表示性别,使用int来描述,因为int类型可以通过0和1这两个值来表示两个不同的性别
- 编写枚举类
public enum GenderEnum {MAN(0,"男"),WOMAN(1,"女");@EnumValueprivate Integer gender;private String genderName;GenderEnum(Integer gender, String genderName) {this.gender = gender;this.genderName = genderName;}
}
- 实体类添加相关字段
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User extends Model<User> {private Long id;private String name;private Integer age;private String email;private GenderEnum gender;private Integer status;
}
- 添加数据
@Test
void enumTest(){User user = new User();user.setName("liu");user.setAge(29);user.setEmail("liu@powernode.com");user.setGenderEnum(GenderEnum.MAN);user.setStatus(1);userMapper.insert(user);
}
字段类型处理器
- 在某些场景下,在实体类中是使用Map集合作为属性接收前端传递过来的数据的,但是这些数据存储在数据库时,使用的是json格式的数据进行存储,json本质是一个字符串,就是varchar类型。那怎么做到实体类的Map类型和数据库的varchar类型的互相转换,这里就需要使用到字段类型处理器来完成。
- 实体类
@Data @AllArgsConstructor @NoArgsConstructor public class User extends Model<User> {private Long id;private String name;private Integer age;private String email;private GenderEnum gender;private Integer status;private Map<String,String> contact;//联系方式 }
- 在数据库中添加一个字段,为varchar类型
- 为实体类添加上对应的注解,实现使用字段类型处理器进行不同类型数据转换
@Data @AllArgsConstructor @NoArgsConstructor @TableName(autoResultMap = true)//查询时将json字符串封装为Map集合 public class User extends Model<User> {private Long id;private String name;private Integer age;private String email;private GenderEnum gender;private Integer status;@TableField(typeHandler = FastjsonTypeHandler.class)//指定字段类型处理器private Map<String,String> contact;//联系方式 }
- 引入字段类型处理器依赖Fastjson
<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.76</version> </dependency>
自动填充功能
- 在项目中有一些属性,如果我们不希望每次都填充的话,我们可以设置为自动填充,比如常见的时间,创建时间和更新时间可以设置为自动填充。
- 在实体类中,添加对应字段,并为需要自动填充的属性指定填充时机
@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName(autoResultMap = true)
public class User extends Model<User> {@TableIdprivate Long id;private String name;private Integer age;private String email;private Integer status;private GenderEnum gender;@TableField(typeHandler = FastjsonTypeHandler.class)private Map<String,String> contact;@TableField(fill = FieldFill.INSERT)private Date createTime;@TableField(fill = FieldFill.INSERT_UPDATE)private Date updateTime;
}
- 编写自动填充处理器,指定填充策略
@Component public class MyMetaHandler implements MetaObjectHandler {@Overridepublic void insertFill(MetaObject metaObject) {setFieldValByName("createTime",new Date(),metaObject);setFieldValByName("updateTime",new Date(),metaObject);}@Overridepublic void updateFill(MetaObject metaObject) {setFieldValByName("updateTime",new Date(),metaObject);} }
- 设置一下mysql时区,更新yml连接配置
set GLOBAL time_zone='+8:00'
select NOW();
防全表更新与删除插件
- 在实际开发中,全表更新和删除是非常危险的操作,在MybatisPlus中,提供了插件和防止这种危险操作的发生。
- 实现步骤:
- 注入MybatisPlusInterceptor类,并配置BlockAttackInnerInterceptor拦截器
@Configuration
public class MybatisPlusConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());return interceptor;}
}
- 测试全表更新,会出现抛出异常,防止了全表更新
@SpringBootTest
public class QueryTest {@Autowiredprivate UserService userService;@Testvoid allUpdate(){User user = new User();user.setId(999L);user.setName("wang");user.setEmail("wang@powernode.com");userService.saveOrUpdate(user,null);}
}
MybatisX快速开发插件
插件安装
- MybatisX是一款IDEA提供的插件,目的是为了我们简化Mybatis以及MybatisPlus框架而生。
- 在IDEA中安装插件
- 首先选择
File -> Settings->Plugins
- 搜索MybatisX,点击安装
- 重启IDEA,让该插件生效,至此MybatisX插件就安装完毕
- 插件安装好以后,我们来看一下插件的功能
- Mapper接口和映射文件的跳转功能
逆向工程
- 逆向工程就是通过数据库表结构,逆向产生Java工程的结构,包括以下几点:
- 实体类
- Mapper接口
- Mapper映射文件
- Service接口
- Service实现类
- 实现步骤:
- 首先使用IDEA连接mysql,填写连接信息,测试连接通过
- 找到表右键,选择插件的逆向工程选项
- 编写逆向工程配置信息
- 编写生成信息
常见需求代码生成
- 虽然Mapper接口中提供了一些常见方法,我们可以直接使用这些常见的方法来完成sql操作,但是对于实际场景中各种复杂的操作需求来说,依然是不够用的,所以MybatisX提供了更多的方法,以及可以根据这些方法直接生成对应的sql语句,这样使得开发变得更加的简单。
- 可以根据名称联想常见的操作
@Mapper
public interface UserMapper extends BaseMapper<User> {//添加操作int insertSelective(User user);//删除操作int deleteByNameAndAge(@Param("name") String name, @Param("age") Integer age);//修改操作int updateNameByAge(@Param("name") String name, @Param("age") Integer age);//查询操作List<User> selectAllByAgeBetween(@Param("beginAge") Integer beginAge, @Param("endAge") Integer endAge);
}
- 在映射配置文件中,会生成对应的sql,并不需要我们编写
<insert id="insertSelective">insert into powershop_user<trim prefix="(" suffix=")" suffixOverrides=","><if test="id != null">id,</if><if test="name != null">name,</if><if test="age != null">age,</if><if test="email != null">email,</if></trim>values<trim prefix="(" suffix=")" suffixOverrides=","><if test="id != null">#{id,jdbcType=BIGINT},</if><if test="name != null">#{name,jdbcType=VARCHAR},</if><if test="age != null">#{age,jdbcType=INTEGER},</if><if test="email != null">#{email,jdbcType=VARCHAR},</if></trim>
</insert><delete id="deleteByNameAndAge">deletefrom powershop_userwhere name = #{name,jdbcType=VARCHAR}AND age = #{age,jdbcType=NUMERIC}
</delete><update id="updateNameByAge">update powershop_userset name = #{name,jdbcType=VARCHAR}where age = #{age,jdbcType=NUMERIC}
</update><select id="selectAllByAgeBetween" resultMap="BaseResultMap">select<include refid="Base_Column_List"/>from powershop_userwhereage between #{beginAge,jdbcType=INTEGER} and #{endAge,jdbcType=INTEGER}
</select>
乐观锁
问题引入
- 并发请求就是在同一时刻有多个请求同时请求服务器资源,如果是获取信息,没什么问题,但是如果是对于信息做修改操作呢,那就会出现问题。
- 比如目前商品的库存只剩余1件了,这个时候有多个用户都想要购买这件商品,都发起了购买商品的请求,那么能让这多个用户都购买到么,肯定是不行的,因为多个用户都买到了这件商品,那么就会出现超卖问题,库存不够是没法发货的。所以在开发中就要解决这种超卖的问题。
核心问题:一个请求在执行的过程中,其他请求不能改变数据,如果是一次完整的请求,在该请求的过程中其他请求没有对于这个数据产生修改操作,那么这个请求是能够正常修改数据的。如果该请求在改变数据的过程中,已经有其他请求改变了数据,那该请求就不去改变这条数据
-
想要解决这类问题,最常见的就是加锁的思想,锁可以用验证在请求的执行过程中,是否有数据发生改变。
-
常见的数据库锁类型有两种,悲观锁和乐观锁。一次完成的修改操作是,先查询数据,然后修改数据。
- 悲观锁:悲观锁是在查询的时候就锁定数据,在这次请求未完成之前,不会释放锁。等到这次请求完毕以后,再释放锁,释放了锁以后,其他请求才可以对于这条数据完成读写。
- 悲观锁的优缺点:能够保证读取到的信息就是当前的信息,保证了信息的正确性,但是并发效率很低。
- 在实际开发中使用悲观锁的场景很少,因为在并发时我们是要保证效率的。
- 乐观锁:乐观锁是通过表字段完成设计的,核心思想是,在读取的时候不加锁,其他请求依然可以读取到这个数据,在修改的时候判断一个数据是否有被修改过,如果有被修改过,那本次请求的修改操作失效。
-
具体的通过sql是实现
Update 表 set 字段 = 新值,version = version + 1 where version = 1
- 这样做的操作是不会对于数据读取产生影响,并发的效率较高。但是可能目前看到的数据并不是真实信息数据,是被修改之前的,但是在很多场景下是可以容忍的,并不是产生很大影响。
乐观锁的使用
- 在数据库表中添加一个字段version,表示版本,默认值是1
- 找到实体类,添加对应的属性,并使用@Version标注为这是一个乐观锁字段信息
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {private Long id;private String name;private Integer age;private String email;@Versionprivate Integer version;
}
- 通过拦截器的配置,让每条修改的sql语句在执行的时候,都加上版本控制的功能
@Configuration
public class MybatisPlusConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor(){MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());return interceptor;}
}
效果测试
- 接下来模拟一下,当出现多个修改请求的时候,是否能够做到乐观锁的效果。
- 乐观锁的效果是,一个请求在修改的过程中,是允许另一个请求查询的,但是修改时会通过版本号是否改变来决定是否修改,如果版本号变了,证明已经有请求修改过数据了,那这次修改不生效,如果版本号没有发生变化,那就完成修改。
@Test
void updateTest2(){//模拟操作1的查询操作User user1 = userMapper.selectById(6L);//模拟操作2的查询操作User user2 = userMapper.selectById(6L);//模拟操作2的修改操作user2.setName("lisi");userMapper.updateById(user2);//模拟操作1的修改操作user1.setName("zhangsan");userMapper.updateById(user1);
}
- 代码的执行过程
- 操作1的查询:此时版本为2
- 操作2的查询:此时版本为2
- 操作2的修改:此时检查版本,版本没有变化,所以完成修改,并将版本改为3
- 操作1的修改:此时检查版本,版本已经有最初获取的版本信息发生了变化,所以杜绝修改
- 操作1的查询:此时版本为2
代码生成器
- 代码生成器和逆向工程的区别在于,代码生成器可以生成更多的结构,更多的内容,允许我们能够配置生成的选项更多。
- 引入依赖
<!--代码生成器依赖--> <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>3.5.3</version> </dependency><!--freemarker模板依赖--> <dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId><version>2.3.31</version> </dependency>
- 编写代码生成器代码
- 示例一:
public class CodeGenerator {/*SELECT table_nameFROM information_schema.tablesWHERE table_schema = 'xxx'ORDER BY table_name DESC;*/public static String scanner(String tip) {Scanner scanner = new Scanner(System.in);StringBuilder help = new StringBuilder();help.append("请输入" + tip + ":");System.out.println(help.toString());if (scanner.hasNext()) {String ipt = scanner.next();if (!ipt.equals("")) {return ipt;}}throw new MybatisPlusException("请输入正确的" + tip + "!");}public static void main(String[] args) {// 代码生成器AutoGenerator mpg = new AutoGenerator();// 全局配置GlobalConfig gc = new GlobalConfig();String projectPath = System.getProperty("user.dir");gc.setOutputDir(projectPath + "/src/main/java");//设置代码生成路径gc.setFileOverride(true);//是否覆盖以前文件gc.setOpen(false);//是否打开生成目录gc.setAuthor("xxx");//设置项目作者名称gc.setIdType(IdType.AUTO);//设置主键策略gc.setBaseResultMap(true);//生成基本ResultMapgc.setBaseColumnList(true);//生成基本ColumnListgc.setServiceName("%sService");//去掉服务默认前缀gc.setDateType(DateType.ONLY_DATE);//设置时间类型mpg.setGlobalConfig(gc);// 数据源配置DataSourceConfig dsc = new DataSourceConfig();dsc.setUrl("jdbc:mysql://localhost:3306/care_home?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8");dsc.setDriverName("com.mysql.cj.jdbc.Driver");dsc.setUsername("root");dsc.setPassword("xxx");mpg.setDataSource(dsc);// 包配置PackageConfig pc = new PackageConfig();pc.setParent("com.test");pc.setMapper("com/test/mapper");pc.setXml("mapper.xml");pc.setEntity("com/test/pojo");pc.setService("com/test/service");pc.setServiceImpl("service.impl");pc.setController("com/test/controller");mpg.setPackageInfo(pc);// 策略配置StrategyConfig sc = new StrategyConfig();sc.setNaming(NamingStrategy.underline_to_camel);sc.setColumnNaming(NamingStrategy.underline_to_camel);sc.setEntityLombokModel(true); //自动lomboksc.setRestControllerStyle(true);sc.setControllerMappingHyphenStyle(true);sc.setLogicDeleteFieldName("deleted");//设置逻辑删除//设置自动填充配置TableFill gmt_create = new TableFill("create_time", FieldFill.INSERT);TableFill gmt_modified = new TableFill("update_time", FieldFill.INSERT_UPDATE);ArrayList<TableFill> tableFills=new ArrayList<>();tableFills.add(gmt_create);tableFills.add(gmt_modified);sc.setTableFillList(tableFills);//乐观锁sc.setVersionFieldName("version");sc.setRestControllerStyle(true);//驼峰命名// sc.setTablePrefix("tbl_"); 设置表名前缀sc.setInclude(scanner("表名,多个英文逗号分割").split(","));mpg.setStrategy(sc);// 生成代码mpg.execute();}}
- 示例二:
/*** @author 缘友一世* date 2023/7/19-16:09*/
public class CodeGenerator {public static void main(String[] args) {String projectPath = System.getProperty("user.dir"); // 获取当前项目的绝对路径String MainPath=projectPath+"/src/main/java";String url="jdbc:mysql://localhost:3306/db2?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useUnicode=true&useSSL=false";String username="root";String password="xxx";String author="yang";String moduleName="system";String mapperLocation=projectPath+"/src/main/resources/mapper/"+moduleName;String parentPackageName="com.yang";/*CREATE TABLE x_user (id int(11) NOT NULL AUTO_INCREMENT,username varchar(50) NOT NULL ,password varchar(100) DEFAULT NULL,email varchar(50) DEFAULT NULL,phone varchar(20) DEFAULT NULL,status int(1) DEFAULT NULL,avatar varchar(200) DEFAULT NULL,deleted INT(1) DEFAULT 0,PRIMARY KEY (id))ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;DELETE FROM x_userWHERE id > 20;*//** SELECT table_nameFROM information_schema.tablesWHERE table_schema = 'xxx'ORDER BY table_name DESC; */String tables="x_user";FastAutoGenerator.create(url, username, password).globalConfig(builder -> {builder.author(author) // 设置作者//.enableSwagger() // 开启 swagger 模式//.fileOverride() // 覆盖已生成文件.outputDir(MainPath); // 指定输出目录}).dataSourceConfig(builder -> builder.typeConvertHandler((globalConfig, typeRegistry, metaInfo) -> {int typeCode = metaInfo.getJdbcType().TYPE_CODE;if (typeCode == Types.SMALLINT) {// 自定义类型转换return DbColumnType.INTEGER;}return typeRegistry.getColumnType(metaInfo);})).packageConfig(builder -> {builder.parent(parentPackageName) // 设置父包名.moduleName(moduleName) // 设置父包模块名.pathInfo(Collections.singletonMap(OutputFile.xml, mapperLocation)); // 设置mapperXml生成路径}).strategyConfig(builder -> {builder.addInclude(tables) // 设置需要生成的表名.addTablePrefix("x_"); // 设置过滤表前缀}).templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板.execute();}}
执行SQL分析打印
- 可以使用MybatisPlus提供的SQL分析打印的功能,来获取SQL语句执行的时间。
- 由于该功能依赖于p6spy组件,所以需要在pom.xml中先引入该组件
<dependency><groupId>p6spy</groupId><artifactId>p6spy</artifactId><version>3.9.1</version> </dependency>
- 在application.yml中进行配置
spring:datasource:driver-class-name: com.p6spy.engine.spy.P6SpyDriverurl: jdbc:p6spy:mysql
- 在resources下,创建 spy.properties配置文件
#3.2.1以上使用modulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory# 自定义日志打印
logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger#日志输出到控制台
appender=com.baomidou.mybatisplus.extension.p6spy.StdoutLogger# 使用日志系统记录 sql
#appender=com.p6spy.engine.spy.appender.Slf4JLogger# 设置 p6spy driver 代理
deregisterdrivers=true# 取消JDBC URL前缀
useprefix=true# 配置记录 Log 例外,可去掉的结果集error,info,batch,debug,statement,commit,rollback,result,resultset.
excludecategories=info,debug,result,commit,resultset# 日期格式
dateformat=yyyy-MM-dd HH:mm:ss# 实际驱动可多个
#driverlist=org.h2.Driver# 是否开启慢SQL记录
outagedetection=true# 慢SQL记录标准 2 秒
outagedetectioninterval=2
- 测试:执行查询所有的操作,可以看到sql语句的执行时间
多数据源
- 分库分表:当一个项目的数据库的数据十分庞大时,在完成SQL操作的时候,需要检索的数据就会更多,我们会遇到性能问题,会出现SQL执行效率低的问题。
- 针对这个问题,我们的解决方案是,将一个数据库中的数据,拆分到多个数据库中,从而减少单个数据库的数据量,从分摊访问请求的压力和减少单个数据库数据量这两个方面,都提升了效率。
- 在MybatisPlus中,如何演示数据源切换的效果
- 先创建一个新的模块,将之前模块中的内容复制过来
- 引入依赖
<dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId><version>3.1.0</version>
</dependency>
- 创建新的数据库,提供多数据源环境
- 编写配置文件,指定多数据源信息
spring:datasource:dynamic:primary: masterstrict: falsedatasource:master:username: rootpassword: xxxurl: jdbc:mysql://localhost:3306/mybatisplus?serverTimezone=UTC&characterEncoding=utf8&useUnicode=true&useSSL=falsedriver-class-name: com.mysql.cj.jdbc.Driverslave_1:username: rootpassword: xxxurl: jdbc:mysql://localhost:3306/mybatisplus2?serverTimezone=UTC&characterEncoding=utf8&useUnicode=true&useSSL=falsedriver-class-name: com.mysql.cj.jdbc.Driver
- 创建多个Service,分别使用@DS注解描述不同的数据源信息
@Service
@DS("master")
public class UserServiceImpl extends ServiceImpl<UserMapper,User> implements UserService {
}
@Service
@DS("slave_1")
public class UserServiceImpl2 extends ServiceImpl<UserMapper, User> implements UserService{
}
- 测试service多数据源环境执行结果
@SpringBootTest
class Mp03ApplicationTests {@Autowiredprivate UserServiceImpl userServiceImpl;@Autowiredprivate UserServiceImpl2 userServiceImpl2;@Testpublic void select(){User user = userServiceImpl.getById(1L);System.out.println(user);}@Testpublic void select2(){User user = userServiceImpl2.getById(1L);System.out.println(user);}
}
- 观察测试结果,发现结果可以从两个数据源中获取
相关文章:

MybatisPlus拓展篇
文章目录 逻辑删除通用枚举字段类型处理器自动填充功能防全表更新与删除插件MybatisX快速开发插件插件安装逆向工程常见需求代码生成 乐观锁问题引入乐观锁的使用效果测试 代码生成器执行SQL分析打印多数据源 逻辑删除 逻辑删除的操作就是增加一个字段表示这个数据的状态&…...
设置k8s中节点node的ROLES值,K8S集群怎么修改node1的集群ROLES
设置k8s中节点node的ROLES值 1.查看集群 [rootk8s-master ~]# kubectl get nodes NAME STATUS ROLES AGE VERSION k8s-master Ready control-plane,master 54d v1.23.8 k8s-node1 Ready <none> 54d v1.…...

【*1900 图论】CF1328 E
Problem - E - Codeforces 题意: 思路: 注意到题目的性质:满足条件的路径个数是极少的,因为每个点离路径的距离<1 先考虑一条链,那么直接就选最深那个点作为端点即可 为什么,因为我们需要遍历所有点…...
微信开发者工具 miniprogram_npm 未找到
背景 微信开发者工具中,打开集成了vant-weapp的项目,构建npm时,报错\miniprogram_npm\ 未找到。 问题 微信开发者工具,工具----->构建npm时,提示 message:发生错误 Error: D:\some\path\miniprogram…...

计算机视觉(三)未有深度学习之前
文章目录 图像分割基于阈值、基于边缘基于区域、基于图论 人脸检测Haar-like特征级联分类器 行人检测HOGSVMDPM 图像分割 把图像划分成若干互不相交的区域。经典的数字图像分割算法一般是基于灰度值的两个基本特征之一:不连续性和相似性。 基于阈值、基于边缘 基于…...
二十六、媒体查询2
目录: 媒体查询介绍网页常用分界点 一、媒体查询介绍 媒体特性: width 视口的宽度 height 视口的高度 一般设计的时候,高度不考虑,只考虑宽度 //当视口的宽度是500像素的时候,变颜色media (width: 500px) {body{background-colo…...

Themis 国库建设计划启动,开启去中心化新征程
在未来的金融领域,去中心化金融(DeFi)正在成为一种重要的趋势。在这股DeFi热潮中,作为Filecoin 生态下的一颗璀璨明珠,Themis 上线仅2个月,多项数据便稳居Filecoin-FVM榜首,TVL更是牢牢处于File…...

uni-app:模态框的实现(弹窗实现)
效果图 代码 标签 <template><view><!-- 按钮用于触发模态框的显示 --><button click"showModal true">显示模态框</button><!-- 模态框组件 --><view class"modal" v-if"showModal"><view cla…...

第九章:stack类
系列文章目录 文章目录 系列文章目录前言stack的介绍stack的使用成员函数使用stack 总结 前言 stack是容器适配器,底层封装了STL容器。 stack的介绍 stack的文档介绍 stack是一种容器适配器,专门用在具有后进先出操作的上下文环境中,其删除…...

FSM:Full Surround Monodepth from Multiple Cameras
参考代码:None 介绍 深度估计任务作为基础环境感知任务,在基础上构建的3D感知才能更加准确,并且泛化能力更强。单目的自监督深度估计已经有MonoDepth、ManyDepth这些经典深度估计模型了,而这篇文章是对多目自监督深度估计进行探…...

idea 安装 插件jrebel 报错LS client not configured.
这个报错找了好久,有博主说版本不对,我脑子没反应过来以为是随便换一个低版本的就行,没想到只能是2022.4.1 这个版本才行 一定要用jrebel 2022.4.1的插件版本!!!!! 插件下载地址&…...

Raki的读paper小记:RWKV: Reinventing RNNs for the Transformer Era
Abstract&Introduction&Related Work 研究任务 基础模型架构已有方法和相关工作 RNN,CNN,Transformer稀疏注意力(Beltagy等人,2020年;Kitaev等人,2020年;Guo等人,2022年&am…...

PaddleOCR #PP-OCR常见异常扫雷
异常一:ModuleNotFoundError: No module named ‘tools.infer’ 实验案例: PaddleOCR #使用PaddleOCR进行光学字符识别(PP-OCR文本检测识别) 参考代码: 图片文本检测实验时,运行代码出现异常:M…...
Qt加载字体文件
本文记录如何使用 Qt 加载外部字体文件,并遍历字体名称和样式名称。 bool LoadFont(const QString& fontPath) {const int fontId QFontDatabase::addApplicationFont(fontPath);if (fontId -1) {return false;}// 遍历字体名和样式名 #if QT_VERSION > QT…...

3ds MAX绘制简单动画
建立一个长方体和茶壶: 在界面右下角点击时间配置: 这是动画制作的必要步骤 选择【自动】,接下来,我们只要在对应的帧改变窗口中图形的位置,就能自动记录该时刻的模样 这就意味着,我们通过电脑记录某几个…...

页面访问控制远程仓库
页面访问权限控制 什么是jwt身份认证 在前后端分离模式的开发中,服务器如何知道来访者的身份呢? 在登录后,服务器会响应给用户一个 令牌 (token)令牌中会包括该用户的id等唯一标识浏览器收到令牌后,自己…...

小程序 user agent stylesheet 覆盖了page下wxss背景色
如下图: login页面的page下的背景色,被:user agent stylesheet覆盖。 分析与解决: 1、user agent stylesheet是浏览器默认样式表,是浏览器默认样式。 2、不同浏览器的默认样式不同个,甚至同种浏览器不同版…...
Vue.js高阶学习和常用知识(二)
目录 1. Vue 实例2. 组件3. 指令4. 计算属性5. 监听器6. 生命周期钩子 Vue.js 是一个流行的 Web 前端框架,它由 Evan You 于 2014 年创建。Vue.js 的设计目标是简单、灵活和易于使用,同时具有高性能和可扩展性。 Vue.js 基于组件化的思想,将页…...

html实现蜂窝菜单
效果图 CSS样式 keyframes _fade-in_mkmxd_1 {0% {filter: blur(20px);opacity: 0}to {filter: none;opacity: 1} } keyframes _drop-in_mkmxd_1 {0% {transform: var(--transform) translateY(-100px) translateZ(400px)}to {transform: var(--transform)} } ._examples_mkmx…...
云原生训练营课程大纲
第一部分:Go 语****言基础 模块一:Go 语言特性 教学目标: 理解 Go 语言基本语法 理解 Go 语言常用数据类型 理解 Go 语言常用小技巧 深入理解 Go 语言的多线程编程 针对的用户痛点: 云原生从业者因为未熟练掌握 Go 语言&#…...

3.3.1_1 检错编码(奇偶校验码)
从这节课开始,我们会探讨数据链路层的差错控制功能,差错控制功能的主要目标是要发现并且解决一个帧内部的位错误,我们需要使用特殊的编码技术去发现帧内部的位错误,当我们发现位错误之后,通常来说有两种解决方案。第一…...

CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

对WWDC 2025 Keynote 内容的预测
借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...
【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)
升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点,但无自动故障转移能力,Master宕机后需人工切换,期间消息可能无法读取。Slave仅存储数据,无法主动升级为Master响应请求ÿ…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...
LRU 缓存机制详解与实现(Java版) + 力扣解决
📌 LRU 缓存机制详解与实现(Java版) 一、📖 问题背景 在日常开发中,我们经常会使用 缓存(Cache) 来提升性能。但由于内存有限,缓存不可能无限增长,于是需要策略决定&am…...

[ACTF2020 新生赛]Include 1(php://filter伪协议)
题目 做法 启动靶机,点进去 点进去 查看URL,有 ?fileflag.php说明存在文件包含,原理是php://filter 协议 当它与包含函数结合时,php://filter流会被当作php文件执行。 用php://filter加编码,能让PHP把文件内容…...
Linux系统部署KES
1、安装准备 1.版本说明V008R006C009B0014 V008:是version产品的大版本。 R006:是release产品特性版本。 C009:是通用版 B0014:是build开发过程中的构建版本2.硬件要求 #安全版和企业版 内存:1GB 以上 硬盘…...