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

【Mybatis系列】Mybatis常见的分页方法以及源码理解

Mybatis-Plus的selectPage

  1. 引入依赖
        <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.1</version></dependency>
  1. 添加分页插件
@Configuration
public class MybatisConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2));return interceptor;}
}
  1. Mapper类和实体类

Mapper类

public interface UserMapper extends BaseMapper<UserInfo> {}

实体类

@Data
@EqualsAndHashCode(callSuper = false)
@TableName(value = "cls_user", autoResultMap = true)
@NoArgsConstructor
public class UserInfo {private static final long serialVersionUID = 1L;@TableId(value = "id", type = IdType.AUTO)private Integer id;@TableField("user_name")private String userName;@TableField("password")private String password;
}
  1. 使用方法
    @Overridepublic Page<UserInfo> pageQuery(String name) {return userMapper.selectPage(new Page<>(1,10), new QueryWrapper<>());}
  1. 查询示例结果
{"records": [{"id": 1,"userName": "cc","password": "12345"},{"id": 2,"userName": "cc","password": "12345"},{"id": 3,"userName": "cc","password": "12345"}],"total": 11,"size": 3,"current": 1,"orders": [],"optimizeCountSql": true,"searchCount": true,"countId": null,"maxLimit": null,"pages": 4
}

源码解析

MybatisPlusInterceptor#intercept进行查询拦截,遍历其中的InnerInterceptor,核心方法是InnerInterceptor#willDoQueryInnerInterceptor#beforeQuery

    public Object intercept(Invocation invocation) throws Throwable {Object target = invocation.getTarget();Object[] args = invocation.getArgs();if (target instanceof Executor) {Executor executor = (Executor)target;Object parameter = args[1];boolean isUpdate = args.length == 2;MappedStatement ms = (MappedStatement)args[0];if (!isUpdate && ms.getSqlCommandType() == SqlCommandType.SELECT) {RowBounds rowBounds = (RowBounds)args[2];ResultHandler resultHandler = (ResultHandler)args[3];BoundSql boundSql;if (args.length == 4) {boundSql = ms.getBoundSql(parameter);} else {boundSql = (BoundSql)args[5];}Iterator var11 = this.interceptors.iterator();while(var11.hasNext()) {InnerInterceptor query = (InnerInterceptor)var11.next();if (!query.willDoQuery(executor, ms, parameter, rowBounds, resultHandler, boundSql)) {return Collections.emptyList();}query.beforeQuery(executor, ms, parameter, rowBounds, resultHandler, boundSql);}CacheKey cacheKey = executor.createCacheKey(ms, parameter, rowBounds, boundSql);return executor.query(ms, parameter, rowBounds, resultHandler, cacheKey, boundSql);}if (isUpdate) {Iterator var8 = this.interceptors.iterator();while(var8.hasNext()) {InnerInterceptor update = (InnerInterceptor)var8.next();if (!update.willDoUpdate(executor, ms, parameter)) {return -1;}update.beforeUpdate(executor, ms, parameter);}}} else {StatementHandler sh = (StatementHandler)target;if (null == args) {Iterator var14 = this.interceptors.iterator();while(var14.hasNext()) {InnerInterceptor innerInterceptor = (InnerInterceptor)var14.next();innerInterceptor.beforeGetBoundSql(sh);}} else {Connection connections = (Connection)args[0];Integer transactionTimeout = (Integer)args[1];Iterator var18 = this.interceptors.iterator();while(var18.hasNext()) {InnerInterceptor innerInterceptor = (InnerInterceptor)var18.next();innerInterceptor.beforePrepare(sh, connections, transactionTimeout);}}}return invocation.proceed();}

PaginationInnerInterceptor#willDoQuery,核心逻辑就是根据参数中的Page对象构造查询总数的sql,进行sql查询,存放到Page对象中。

    public boolean willDoQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {IPage<?> page = (IPage)ParameterUtils.findPage(parameter).orElse((Object)null);if (page != null && page.getSize() >= 0L && page.searchCount()) {MappedStatement countMs = this.buildCountMappedStatement(ms, page.countId());BoundSql countSql;if (countMs != null) {countSql = countMs.getBoundSql(parameter);} else {countMs = this.buildAutoCountMappedStatement(ms);String countSqlStr = this.autoCountSql(page, boundSql.getSql());MPBoundSql mpBoundSql = PluginUtils.mpBoundSql(boundSql);countSql = new BoundSql(countMs.getConfiguration(), countSqlStr, mpBoundSql.parameterMappings(), parameter);PluginUtils.setAdditionalParameter(countSql, mpBoundSql.additionalParameters());}CacheKey cacheKey = executor.createCacheKey(countMs, parameter, rowBounds, countSql);List<Object> result = executor.query(countMs, parameter, rowBounds, resultHandler, cacheKey, countSql);long total = 0L;if (CollectionUtils.isNotEmpty(result)) {Object o = result.get(0);if (o != null) {total = Long.parseLong(o.toString());}}page.setTotal(total);return this.continuePage(page);} else {return true;}}

PaginationInnerInterceptor#beforeQuery,对原有的查询语句进行封装改造,增加limit ?,?

    public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {IPage<?> page = (IPage)ParameterUtils.findPage(parameter).orElse((Object)null);if (null != page) {boolean addOrdered = false;String buildSql = boundSql.getSql();List<OrderItem> orders = page.orders();if (CollectionUtils.isNotEmpty(orders)) {addOrdered = true;buildSql = this.concatOrderBy(buildSql, orders);}Long _limit = page.maxLimit() != null ? page.maxLimit() : this.maxLimit;if (page.getSize() < 0L && null == _limit) {if (addOrdered) {PluginUtils.mpBoundSql(boundSql).sql(buildSql);}} else {this.handlerLimit(page, _limit);IDialect dialect = this.findIDialect(executor);Configuration configuration = ms.getConfiguration();DialectModel model = dialect.buildPaginationSql(buildSql, page.offset(), page.getSize());MPBoundSql mpBoundSql = PluginUtils.mpBoundSql(boundSql);List<ParameterMapping> mappings = mpBoundSql.parameterMappings();Map<String, Object> additionalParameter = mpBoundSql.additionalParameters();model.consumers(mappings, configuration, additionalParameter);mpBoundSql.sql(model.getDialectSql());mpBoundSql.parameterMappings(mappings);}}}

PageHelper.startPage(int pageNum, int pageSize);

  1. 引入依赖
        <dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId><!-- 特别注意版本问题 --><version>1.4.5</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.2</version></dependency>
  1. Mapper类和实体类

Mapper类

public interface UserMapper extends BaseMapper<UserInfo> {}

实体类

@Data
@EqualsAndHashCode(callSuper = false)
@TableName(value = "cls_user", autoResultMap = true)
@NoArgsConstructor
public class UserInfo {private static final long serialVersionUID = 1L;@TableId(value = "id", type = IdType.AUTO)private Integer id;@TableField("user_name")private String userName;@TableField("password")private String password;
}
  1. 使用方法
    public PageInfo search() {PageHelper.startPage(1, 3);QueryWrapper<UserInfo> wrapper = new QueryWrapper();List<UserInfo> testEntityList = userMapper.selectList(wrapper);return new PageInfo<UserInfo>(testEntityList);}
  1. 运行结果
{"total": 11,"list": [{"id": 1,"userName": "cc","password": "12345"},{"id": 2,"userName": "cc","password": "12345"},{"id": 3,"userName": "cc","password": "12345"}],"pageNum": 1,"pageSize": 3,"size": 3,"startRow": 1,"endRow": 3,"pages": 4,"prePage": 0,"nextPage": 2,"isFirstPage": true,"isLastPage": false,"hasPreviousPage": false,"hasNextPage": true,"navigatePages": 8,"navigatepageNums": [1,2,3,4],"navigateFirstPage": 1,"navigateLastPage": 4
}

源码解析

  1. 引入pagehelper-spring-boot-starter,Springboot会扫描jar包中的spring.factories,自动装配机制可以看我这篇文章,原理讲的透透的,SpringBoot自动装配的实现原理。在pagehelper-spring-boot-autoconfigure的jar中有spring.factories,会引入PageHelperAutoConfiguration
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.github.pagehelper.autoconfigure.PageHelperAutoConfiguration
  1. PageHelperAutoConfiguration该类实现了InitializingBean,在启动的时候创建该对象之后会执行afterPropertiesSet,Spring的Bean的生命周期,详细了解可以看这篇文章。该类主要是添加了PageInterceptor进行拦截。
public class PageHelperAutoConfiguration implements InitializingBean {@Overridepublic void afterPropertiesSet() throws Exception {PageInterceptor interceptor = new PageInterceptor();interceptor.setProperties(this.properties);for (SqlSessionFactory sqlSessionFactory : sqlSessionFactoryList) {org.apache.ibatis.session.Configuration configuration = sqlSessionFactory.getConfiguration();if (!containsInterceptor(configuration, interceptor)) {configuration.addInterceptor(interceptor);}}}
}
  1. PageInterceptor#intercept,该方法是拦截查询语句,分别组装查询总数的sql和分页查询的sql。
    public Object intercept(Invocation invocation) throws Throwable {try {Object[] args = invocation.getArgs();MappedStatement ms = (MappedStatement) args[0];Object parameter = args[1];RowBounds rowBounds = (RowBounds) args[2];ResultHandler resultHandler = (ResultHandler) args[3];Executor executor = (Executor) invocation.getTarget();CacheKey cacheKey;BoundSql boundSql;//由于逻辑关系,只会进入一次if (args.length == 4) {//4 个参数时boundSql = ms.getBoundSql(parameter);cacheKey = executor.createCacheKey(ms, parameter, rowBounds, boundSql);} else {//6 个参数时cacheKey = (CacheKey) args[4];boundSql = (BoundSql) args[5];}checkDialectExists();//对 boundSql 的拦截处理if (dialect instanceof BoundSqlInterceptor.Chain) {boundSql = ((BoundSqlInterceptor.Chain) dialect).doBoundSql(BoundSqlInterceptor.Type.ORIGINAL, boundSql, cacheKey);}List resultList;//调用方法判断是否需要进行分页,如果不需要,直接返回结果if (!dialect.skip(ms, parameter, rowBounds)) {//开启debug时,输出触发当前分页执行时的PageHelper调用堆栈// 如果和当前调用堆栈不一致,说明在启用分页后没有消费,当前线程再次执行时消费,调用堆栈显示的方法使用不安全debugStackTraceLog();//判断是否需要进行 count 查询if (dialect.beforeCount(ms, parameter, rowBounds)) {//查询总数Long count = count(executor, ms, parameter, rowBounds, null, boundSql);//处理查询总数,返回 true 时继续分页查询,false 时直接返回if (!dialect.afterCount(count, parameter, rowBounds)) {//当查询总数为 0 时,直接返回空的结果return dialect.afterPage(new ArrayList(), parameter, rowBounds);}}resultList = ExecutorUtil.pageQuery(dialect, executor,ms, parameter, rowBounds, resultHandler, boundSql, cacheKey);} else {//rowBounds用参数值,不使用分页插件处理时,仍然支持默认的内存分页resultList = executor.query(ms, parameter, rowBounds, resultHandler, cacheKey, boundSql);}return dialect.afterPage(resultList, parameter, rowBounds);} finally {if (dialect != null) {dialect.afterAll();}}}
  1. PageHelper.startPage,核心就是组装Page对象存放到线程变量中。那么会导致线程污染吗?拦截器中有remove的操作吗?看到线程变量,最关心的点应该就是使用ThreadLocal可能会导致内存泄露,线程变量ThreadLocal详解,该篇对ThreadLocal的相关知识点讲的明明白白。
    public static <E> Page<E> startPage(int pageNum, int pageSize, boolean count, Boolean reasonable, Boolean pageSizeZero) {Page<E> page = new Page<E>(pageNum, pageSize, count);page.setReasonable(reasonable);page.setPageSizeZero(pageSizeZero);//当已经执行过orderBy的时候Page<E> oldPage = getLocalPage();if (oldPage != null && oldPage.isOrderByOnly()) {page.setOrderBy(oldPage.getOrderBy());}setLocalPage(page);return page;}
  1. PageHelper#skip,PageHelper判断是否需要分页查询。如果Page对象是null,则选择跳过分页查询的逻辑
    public boolean skip(MappedStatement ms, Object parameterObject, RowBounds rowBounds) {Page page = pageParams.getPage(parameterObject, rowBounds);if (page == null) {return true;} else {//设置默认的 count 列if (StringUtil.isEmpty(page.getCountColumn())) {page.setCountColumn(pageParams.getCountColumn());}autoDialect.initDelegateDialect(ms, page.getDialectClass());return false;}}

PageParams#getPage,会从线程变量中获取Page对象,进行组装

    public Page getPage(Object parameterObject, RowBounds rowBounds) {Page page = PageHelper.getLocalPage();if (page == null) {if (rowBounds != RowBounds.DEFAULT) {if (offsetAsPageNum) {page = new Page(rowBounds.getOffset(), rowBounds.getLimit(), rowBoundsWithCount);} else {page = new Page(new int[]{rowBounds.getOffset(), rowBounds.getLimit()}, rowBoundsWithCount);//offsetAsPageNum=false的时候,由于PageNum问题,不能使用reasonable,这里会强制为falsepage.setReasonable(false);}if (rowBounds instanceof PageRowBounds) {PageRowBounds pageRowBounds = (PageRowBounds) rowBounds;page.setCount(pageRowBounds.getCount() == null || pageRowBounds.getCount());}} else if (parameterObject instanceof IPage || supportMethodsArguments) {try {page = PageObjectUtil.getPageFromObject(parameterObject, false);} catch (Exception e) {return null;}}if (page == null) {return null;}PageHelper.setLocalPage(page);}//分页合理化if (page.getReasonable() == null) {page.setReasonable(reasonable);}//当设置为true的时候,如果pagesize设置为0(或RowBounds的limit=0),就不执行分页,返回全部结果if (page.getPageSizeZero() == null) {page.setPageSizeZero(pageSizeZero);}if (page.getKeepOrderBy() == null) {page.setKeepOrderBy(keepOrderBy);}if (page.getKeepSubSelectOrderBy() == null) {page.setKeepSubSelectOrderBy(keepSubSelectOrderBy);}return page;}
  1. PageHelper#afterAll,清除线程变量。所以PageInterceptor已经帮我们把线程变量给清除了,不会产生线程污染。
    @Overridepublic void afterAll() {//这个方法即使不分页也会被执行,所以要判断 nullAbstractHelperDialect delegate = autoDialect.getDelegate();if (delegate != null) {delegate.afterAll();autoDialect.clearDelegate();}clearPage();}

Mybatisplus的PageHelper

  1. 引入依赖
        <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus</artifactId><version>2.1.9</version></dependency>
  1. 引入Mybatis配置
@Configuration
public class MybatisPlusConfig {@Beanpublic PaginationInterceptor paginationInterceptor() {PaginationInterceptor paginationInterceptor = new PaginationInterceptor();}
  1. 分页查询,PageHelper是com.baomidou.mybatisplus.plugins.pagination.PageHelper
	@RequestMapping("/list")public Pagination search() {Wrapper wrapper = new EntityWrapper();PageHelper.startPage(1, 10);List<TestEntity> testEntityList = testMapper.selectList(wrapper);Pagination pagination = PageHelper.getPagination();PageHelper.remove();return pagination;}

源码解析

  1. PaginationInterceptor#intercept,核心也是从PageHelper中获取线程变量,对象封装存储在线程变量中。
    public Object intercept(Invocation invocation) throws Throwable {StatementHandler statementHandler = (StatementHandler)PluginUtils.realTarget(invocation.getTarget());MetaObject metaObject = SystemMetaObject.forObject(statementHandler);this.sqlParser(metaObject);MappedStatement mappedStatement = (MappedStatement)metaObject.getValue("delegate.mappedStatement");if (!SqlCommandType.SELECT.equals(mappedStatement.getSqlCommandType())) {return invocation.proceed();} else {RowBounds rowBounds = (RowBounds)metaObject.getValue("delegate.rowBounds");if (rowBounds == null || rowBounds == RowBounds.DEFAULT) {if (!this.localPage) {return invocation.proceed();}rowBounds = PageHelper.getPagination();if (rowBounds == null) {return invocation.proceed();}}BoundSql boundSql = (BoundSql)metaObject.getValue("delegate.boundSql");String originalSql = boundSql.getSql();Connection connection = (Connection)invocation.getArgs()[0];DBType dbType = StringUtils.isNotEmpty(this.dialectType) ? DBType.getDBType(this.dialectType) : JdbcUtils.getDbType(connection.getMetaData().getURL());if (rowBounds instanceof Pagination) {Pagination page = (Pagination)rowBounds;boolean orderBy = true;if (page.isSearchCount()) {SqlInfo sqlInfo = SqlUtils.getOptimizeCountSql(page.isOptimizeCountSql(), this.sqlParser, originalSql);orderBy = sqlInfo.isOrderBy();this.queryTotal(this.overflowCurrent, sqlInfo.getSql(), mappedStatement, boundSql, page, connection);if (page.getTotal() <= 0) {return invocation.proceed();}}String buildSql = SqlUtils.concatOrderBy(originalSql, page, orderBy);originalSql = DialectFactory.buildPaginationSql(page, buildSql, dbType, this.dialectClazz);} else {originalSql = DialectFactory.buildPaginationSql((RowBounds)rowBounds, originalSql, dbType, this.dialectClazz);}metaObject.setValue("delegate.boundSql.sql", originalSql);metaObject.setValue("delegate.rowBounds.offset", 0);metaObject.setValue("delegate.rowBounds.limit", 2147483647);return invocation.proceed();}}

总结一下

  1. Mybatis-Plus的selectPage是我最喜欢用的,不需要引入额外的jar包;pagehelper-spring-boot-starter中的PageHelper.startPage,封装形式也很简单。

  2. Mybatisplus的PageHelper真的是大坑,在项目中我以为是pagehelper-spring-boot-starter类的PageHelper,结果查询结果中pages返回的数据一直是0,跟踪源码发现PageHelper获取的Page对象为null,不进行分页查询。跟踪设置环境变量的方法,发现原来是调用的MybatisPlus老版本的PageHelper,关键的是Mybatis-Plus使用PageHelper和pagehelper-spring-boot-starter使用PageHelper格式会如此的相似。这意味着不看包名,很容易搞混。这种出现一样的类名很容易出现你以为用的是A包,实际上用的是B包的情况。
    在这里插入图片描述

相关文章:

【Mybatis系列】Mybatis常见的分页方法以及源码理解

Mybatis-Plus的selectPage 引入依赖 <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.1</version></dependency>添加分页插件 Configuration public class My…...

Java面向对象:多态特性的学习

本文介绍了Java面向对象多态特性, 多态的介绍. 多态的实现条件–1.发生继承.2.发生重写(重写与重载的区别)3.向上转型与向下转型.4.静态绑定和动态绑定5. 实现多态 举例总结多态的优缺点 避免在构造方法内调用被重写的方法… Java面向对象:多态特性的学习一.什么是多态?二.多态…...

id函数 / 可变类型变量 / 不可变类型变量 / +=操作

前言 再说正文之前&#xff0c;需要大家先了解一下对象&#xff0c;指针和引用的含义&#xff0c;不懂得同学可以参考我上一篇博客“(12条消息) 引用是否有地址的讨论的_xx_xjm的博客-CSDN博客” 正文 一&#xff1a;python中一切皆对象 “python中一切皆对象”这句话我相信…...

aws apigateway 使用apigateway集成lambda

参考资料 代理集成&#xff0c;https://docs.aws.amazon.com/zh_cn/apigateway/latest/developerguide/api-gateway-create-api-as-simple-proxy-for-lambda.html非代理集成&#xff0c;https://docs.aws.amazon.com/zh_cn/apigateway/latest/developerguide/getting-started-…...

Linux SPI 驱动实验

目录 一、Linux 下 SPI 驱动框架简介 1、SPI 主机驱动 2、SPI 设备驱动 SPI 设备数据收发处理流程 3、SPI 设备和驱动匹配过程 二、添加SPI 设备信息 1、添加 ICM20608 所使用的 IO 2、 在 ecspi3 节点追加 icm20608 子节点 三、编写 ICM20608 驱动 1、修改makefile​…...

[1.4]计算机系统概述——操作系统的体系结构

第一章 计算机系统概述 操作系统的体系结构 大内核/单内核/宏内核微内核 通过之前的学习&#xff0c;我们知道计算机系统的层次结构是这样的。 但是操作系统的内部其实还可以再进一步地划分。 一部分是内核的功能&#xff0c;一部分是非内核的功能。 操作系统最核心的功能&…...

FPGA的GigE Vision IP相机图像采集方案设计,转换为千兆UDP,支持10G MAC

1 概述 GigE Vision是一个比较复杂的协议&#xff0c;要在FPGA中完全实现具有较大的难度。如果FPGA作为接收端希望实现GigE Vision相机的配置和图像采集功能&#xff0c;则只需要实现其中小部分功能即可。本文对原有GigE Vision协议的结构进行了裁剪&#xff0c;仅保留设备搜索…...

大数据相关面试题

linux 常见linux高级命令&#xff1f; top、iotopnetstatdf -hjmap -heaptarrpmps -efshell 用过的shell工具&#xff1f; awk Awk 命令详解 - 简书 awk是行处理器: 相比较屏幕处理的优点&#xff0c;在处理庞大文件时不会出现内存溢出或是处理缓慢的问题&#xff0c;通常用来…...

AI绘画第二步,抄作业复现超赞的效果!

上一篇&#xff0c;讲了如何安装AI绘画软件&#xff0c;但是装完后发现生成效果很渣&#xff01;而网上那些效果都很赞。真的是理想很丰满&#xff0c;现实很骨感。今天就是来聊聊如何抄作业&#xff0c;最大程度的还原那些超赞的效果。换一种说法就是&#xff0c;教大家如何使…...

Python的并发编程

我们将一个正在运行的程序称为进程。每个进程都有它自己的系统状态&#xff0c;包含内存状态、打开文件列表、追踪指令执行情况的程序指针以及一个保存局部变量的调用栈。通常情况下&#xff0c;一个进程依照一个单序列控制流顺序执行&#xff0c;这个控制流被称为该进程的主线…...

【Linux】基本系统维护命令

&#x1f60a;&#x1f60a;作者简介&#x1f60a;&#x1f60a; &#xff1a; 大家好&#xff0c;我是南瓜籽&#xff0c;一个在校大二学生&#xff0c;我将会持续分享C/C相关知识。 &#x1f389;&#x1f389;个人主页&#x1f389;&#x1f389; &#xff1a; 南瓜籽的主页…...

高数:数列的收敛

数列特点无限个数特定顺序数列和集合区别集合可以乱序&#xff0c;数列不行集合出现重复元素依然相同&#xff0c;数列出现新的重复元素就不相等[1&#xff0c;2&#xff0c;3&#xff0c;4][1&#xff0c;2&#xff0c;3&#xff0c;3&#xff0c;4]对集合来说相等&#xff0c…...

不平凡的一天——

作者&#xff1a;指针不指南吗 专栏&#xff1a;个人日常记录 &#x1f43e;或许会很慢&#xff0c;但是不可以停下来&#x1f43e; 文章目录1.自我介绍2.上学期3.不凡的一天4.新学期写个博客&#xff0c;简单记录一下&#xff0c;新学期加油&#xff01;&#xff01;&#xff…...

【Java基础】Map遍历的5种方式

目录 创建一个集合 方式一&#xff1a;Iterator 迭代器遍历 map.entrySet().iterator(); map.keySet().iterator(); 方式二&#xff1a;For Each方式遍历 map.forEach(BiConsumer action) 方式三&#xff1a;获取Collection集合 map.values().forEach() 方式四&#x…...

第十四届蓝桥杯三月真题刷题训练——第 2 天

目录 题目1&#xff1a;奇数倍数 代码: 题目2&#xff1a;求值 代码: 题目3&#xff1a;求和 代码: 题目4&#xff1a;数位排序 代码: 题目1&#xff1a;奇数倍数 题目描述 本题为填空题&#xff0c;只需要算出结果后&#xff0c;在代码中使用输出语句将所填结果输出即…...

自然语言处理历史最全预训练模型(部署)汇集分享

什么是预训练模型&#xff1f;预练模型是其他人为解决类似问题而创建的且已经训练好的模型。代替从头开始建立模型来解决类似的问题&#xff0c;我们可以使用在其他问题上训练过的模型作为起点。预训练的模型在相似的应用程序中可能不是100&#xff05;准确的。本文整理了自然语…...

csdn写文章自定义表格怎么做

前言 CSDN写文章时&#xff0c;经常会用到表格&#xff0c;不同于Word文档中直接插入表格&#xff08;自定义几行几列&#xff09;&#xff0c;使用CSDN自带的md文本编辑器时&#xff0c;很难快速插入想要的表格样式&#xff0c;追究原因&#xff0c;也是因为md的语法问题&…...

Pytorch处理数据与训练网络问题汇总(协同训练)

基础语法 模型训练 【Swin-Unet】官方代码预训练权重加载函数load_from() 实际上由于SwinUnet是一个encoder-decoder对称的结构&#xff0c;因此加载权重时&#xff0c;作者并没有像通常那样仅仅加载encoder部分而不加载decoder部分&#xff0c;而是同时将encoder的权重对称地…...

机器学习:基于神经网络对用户评论情感分析预测

机器学习&#xff1a;基于神经网络对用户评论情感分析预测 作者&#xff1a;AOAIYI 作者简介&#xff1a;Python领域新星作者、多项比赛获奖者&#xff1a;AOAIYI首页 &#x1f60a;&#x1f60a;&#x1f60a;如果觉得文章不错或能帮助到你学习&#xff0c;可以点赞&#x1f4…...

Vue3之组件间传值避坑指南

组件间传值的两个坑 我们都知道父组件可以把值传递到自组件中&#xff0c;但是有时候子组件需要修改这个父组件传递过来的这个值&#xff0c;我们可以想象下能修改成功吗&#xff1f;这是坑之一。我们在组件间传值的时候&#xff0c;都是一个属性名对应一个值&#xff0c;接收…...

高频面试之3Zookeeper

高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个&#xff1f;3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制&#xff08;过半机制&#xff0…...

镜像里切换为普通用户

如果你登录远程虚拟机默认就是 root 用户&#xff0c;但你不希望用 root 权限运行 ns-3&#xff08;这是对的&#xff0c;ns3 工具会拒绝 root&#xff09;&#xff0c;你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案&#xff1a;创建非 roo…...

基于Docker Compose部署Java微服务项目

一. 创建根项目 根项目&#xff08;父项目&#xff09;主要用于依赖管理 一些需要注意的点&#xff1a; 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件&#xff0c;否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...

相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

uniapp中使用aixos 报错

问题&#xff1a; 在uniapp中使用aixos&#xff0c;运行后报如下错误&#xff1a; AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...

在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?

uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件&#xff0c;用于在原生应用中加载 HTML 页面&#xff1a; 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...

快速排序算法改进:随机快排-荷兰国旗划分详解

随机快速排序-荷兰国旗划分算法详解 一、基础知识回顾1.1 快速排序简介1.2 荷兰国旗问题 二、随机快排 - 荷兰国旗划分原理2.1 随机化枢轴选择2.2 荷兰国旗划分过程2.3 结合随机快排与荷兰国旗划分 三、代码实现3.1 Python实现3.2 Java实现3.3 C实现 四、性能分析4.1 时间复杂度…...

【汇编逆向系列】六、函数调用包含多个参数之多个整型-参数压栈顺序,rcx,rdx,r8,r9寄存器

从本章节开始&#xff0c;进入到函数有多个参数的情况&#xff0c;前面几个章节中介绍了整型和浮点型使用了不同的寄存器在进行函数传参&#xff0c;ECX是整型的第一个参数的寄存器&#xff0c;那么多个参数的情况下函数如何传参&#xff0c;下面展开介绍参数为整型时候的几种情…...

CppCon 2015 学习:Simple, Extensible Pattern Matching in C++14

什么是 Pattern Matching&#xff08;模式匹配&#xff09; ❝ 模式匹配就是一种“描述式”的写法&#xff0c;不需要你手动判断、提取数据&#xff0c;而是直接描述你希望的数据结构是什么样子&#xff0c;系统自动判断并提取。❞ 你给的定义拆解&#xff1a; ✴ Instead of …...

Docker环境下安装 Elasticsearch + IK 分词器 + Pinyin插件 + Kibana(适配7.10.1)

做RAG自己打算使用esmilvus自己开发一个&#xff0c;安装时好像网上没有比较新的安装方法&#xff0c;然后找了个旧的方法对应试试&#xff1a; &#x1f680; 本文将手把手教你在 Docker 环境中部署 Elasticsearch 7.10.1 IK分词器 拼音插件 Kibana&#xff0c;适配中文搜索…...