MyBatis-Plus分页拦截器,源码的重构(重构total总数的计算逻辑)
1.1创建ThreadLocal工具类(作为业务逻辑结果存放类)
package org.springblade.sample.utils;public class QueryContext {private static final ThreadLocal<Long> totalInThreadLocal = new ThreadLocal<>();public static void setTotalIn(long totalIn) {totalInThreadLocal.set(totalIn);}public static long getTotalIn() {return totalInThreadLocal.get() != null ? totalInThreadLocal.get() : 0;}public static void clear() {totalInThreadLocal.remove();}
}
2.1重构Mybatis-plus分页查询total总数逻辑(通过实现InnerInterceptor接口进行重构,代码如下,根据注释进行对应业务调整即可)
package org.springblade.sample.config;import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.core.toolkit.*;
import com.baomidou.mybatisplus.extension.parser.JsqlParserGlobal;
import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.pagination.DialectFactory;
import com.baomidou.mybatisplus.extension.plugins.pagination.DialectModel;
import com.baomidou.mybatisplus.extension.plugins.pagination.dialects.IDialect;
import com.baomidou.mybatisplus.extension.toolkit.JdbcUtils;
import com.baomidou.mybatisplus.extension.toolkit.PropertyMapper;
import com.baomidou.mybatisplus.extension.toolkit.SqlParserUtils;
import groovy.util.logging.Slf4j;
import lombok.Data;
import lombok.NoArgsConstructor;
import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.expression.Alias;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.schema.Table;
import net.sf.jsqlparser.statement.select.*;
import org.apache.ibatis.cache.CacheKey;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.LogFactory;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.mapping.ResultMap;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.sample.utils.QueryContext;import java.sql.SQLException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;/*** 分页拦截器* <p>* 默认对 left join 进行优化,虽然能优化count,但是加上分页的话如果1对多本身结果条数就是不正确的** @author hubin* @since 3.4.0*/
@lombok.extern.slf4j.Slf4j
@Data
@NoArgsConstructor
@org.springframework.context.annotation.Configuration
@Slf4j
public class PaginationInnerInterceptor implements InnerInterceptor {/*** 获取jsqlparser中count的SelectItem*/protected static final List<SelectItem> COUNT_SELECT_ITEM = Collections.singletonList(new SelectExpressionItem(new Column().withColumnName("COUNT(*)")).withAlias(new Alias("total")));protected static final Map<String, MappedStatement> countMsCache = new ConcurrentHashMap<>();protected final Log logger = LogFactory.getLog(this.getClass());/*** 表名*/private final String V_SAMPLE_COVID19 = "v_sample_covid19";private final String T_SAMPLE_COVID19 = "t_sample_covid19";private final String T_SAMPLE_FLU = "t_sample_flu";private final String T_SAMPLE_HADV = "t_sample_hadv";private final String T_SAMPLE_HMPV = "t_sample_hmpv";private final String T_SAMPLE_HPIV = "t_sample_hpiv";private final String T_SAMPLE_METAV = "t_sample_metav";private final String T_SAMPLE_RSV = "t_sample_rsv";/*** 溢出总页数后是否进行处理*/protected boolean overflow;/*** 单页分页条数限制*/protected Long maxLimit;/*** 数据库类型* <p>* 查看 {@link #findIDialect(Executor)} 逻辑*/private DbType dbType;/*** 方言实现类* <p>* 查看 {@link #findIDialect(Executor)} 逻辑*/private IDialect dialect;/*** 生成 countSql 优化掉 join* 现在只支持 left join** @since 3.4.2*/protected boolean optimizeJoin = true;public PaginationInnerInterceptor(DbType dbType) {this.dbType = dbType;}public PaginationInnerInterceptor(IDialect dialect) {this.dialect = dialect;}/**** 重构willDoQuery获取序列未上传数量(根据检索结果进行实时更新)* @param executor Executor(可能是代理对象)* @param ms MappedStatement* @param parameter parameter* @param rowBounds rowBounds* @param resultHandler resultHandler* @param boundSql boundSql*/public boolean willDoQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {IPage<?> page = ParameterUtils.findPage(parameter).orElse(null);if (page == null || page.getSize() < 0 || !page.searchCount() || resultHandler != Executor.NO_RESULT_HANDLER) {return true;}BoundSql countSql;BoundSql countSqlIn;MappedStatement countMs = buildCountMappedStatement(ms, page.countId());if (countMs != null) {countSql = countMs.getBoundSql(parameter);countSqlIn = countMs.getBoundSql(parameter);} else {countMs = buildAutoCountMappedStatement(ms);String countSqlStr = autoCountSql(page, boundSql.getSql());PluginUtils.MPBoundSql mpBoundSql = PluginUtils.mpBoundSql(boundSql);countSql = new BoundSql(countMs.getConfiguration(), countSqlStr, mpBoundSql.parameterMappings(), parameter);countSqlIn = new BoundSql(countMs.getConfiguration(), countSqlStr + " and seq_num = '0'", mpBoundSql.parameterMappings(), parameter);PluginUtils.setAdditionalParameter(countSql, mpBoundSql.additionalParameters());PluginUtils.setAdditionalParameter(countSqlIn, mpBoundSql.additionalParameters());}// 执行第一个查询 (result)CacheKey cacheKey = executor.createCacheKey(countMs, parameter, rowBounds, countSql);List<Object> result = executor.query(countMs, parameter, rowBounds, resultHandler, cacheKey, countSql);long total = 0;if (CollectionUtils.isNotEmpty(result)) {// 个别数据库 count 没数据不会返回 0Object o = result.get(0);if (o != null) {total = Long.parseLong(o.toString());}}page.setTotal(total);long totalIn = 0;//获取表名String tableName = getTableFromSql(boundSql.getSql());// 执行第二个查询 (resultIn)if (StringUtil.isNotBlank(tableName)) {//根据表名判断是否进行查询if (this.suitTableName(tableName)) {CacheKey cacheKeyIn = executor.createCacheKey(countMs, parameter, rowBounds, countSqlIn);List<Object> resultIn = executor.query(countMs, parameter, rowBounds, resultHandler, cacheKeyIn, countSqlIn);log.info("未上传序列数:{}", Long.parseLong(resultIn.get(0).toString()));if (CollectionUtils.isNotEmpty(resultIn)) {// 个别数据库 count 没数据不会返回 0Object o = resultIn.get(0);if (o != null) {totalIn = Long.parseLong(o.toString());}}}}// 将 totalIn 设置到 ThreadLocal 中QueryContext.setTotalIn(totalIn);return continuePage(page);}@Overridepublic void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {IPage<?> page = ParameterUtils.findPage(parameter).orElse(null);if (null == page) {return;}// 处理 orderBy 拼接boolean addOrdered = false;String buildSql = boundSql.getSql();List<OrderItem> orders = page.orders();if (CollectionUtils.isNotEmpty(orders)) {addOrdered = true;buildSql = this.concatOrderBy(buildSql, orders);}// size 小于 0 且不限制返回值则不构造分页sqlLong _limit = page.maxLimit() != null ? page.maxLimit() : maxLimit;if (page.getSize() < 0 && null == _limit) {if (addOrdered) {PluginUtils.mpBoundSql(boundSql).sql(buildSql);}return;}handlerLimit(page, _limit);IDialect dialect = findIDialect(executor);final Configuration configuration = ms.getConfiguration();DialectModel model = dialect.buildPaginationSql(buildSql, page.offset(), page.getSize());PluginUtils.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);}/*** 获取分页方言类的逻辑** @param executor Executor* @return 分页方言类*/protected IDialect findIDialect(Executor executor) {if (dialect != null) {return dialect;}if (dbType != null) {dialect = DialectFactory.getDialect(dbType);return dialect;}return DialectFactory.getDialect(JdbcUtils.getDbType(executor));}/*** 获取指定的 id 的 MappedStatement** @param ms MappedStatement* @param countId id* @return MappedStatement*/protected MappedStatement buildCountMappedStatement(MappedStatement ms, String countId) {if (StringUtils.isNotBlank(countId)) {final String id = ms.getId();if (!countId.contains(StringPool.DOT)) {countId = id.substring(0, id.lastIndexOf(StringPool.DOT) + 1) + countId;}final Configuration configuration = ms.getConfiguration();try {return CollectionUtils.computeIfAbsent(countMsCache, countId, key -> configuration.getMappedStatement(key, false));} catch (Exception e) {logger.warn(String.format("can not find this countId: [\"%s\"]", countId));}}return null;}/*** 构建 mp 自用自动的 MappedStatement** @param ms MappedStatement* @return MappedStatement*/protected MappedStatement buildAutoCountMappedStatement(MappedStatement ms) {final String countId = ms.getId() + "_mpCount";final Configuration configuration = ms.getConfiguration();return CollectionUtils.computeIfAbsent(countMsCache, countId, key -> {MappedStatement.Builder builder = new MappedStatement.Builder(configuration, key, ms.getSqlSource(), ms.getSqlCommandType());builder.resource(ms.getResource());builder.fetchSize(ms.getFetchSize());builder.statementType(ms.getStatementType());builder.timeout(ms.getTimeout());builder.parameterMap(ms.getParameterMap());builder.resultMaps(Collections.singletonList(new ResultMap.Builder(configuration, Constants.MYBATIS_PLUS, Long.class, Collections.emptyList()).build()));builder.resultSetType(ms.getResultSetType());builder.cache(ms.getCache());builder.flushCacheRequired(ms.isFlushCacheRequired());builder.useCache(ms.isUseCache());return builder.build();});}/*** 获取自动优化的 countSql** @param page 参数* @param sql sql* @return countSql*/protected String autoCountSql(IPage<?> page, String sql) {if (!page.optimizeCountSql()) {return lowLevelCountSql(sql);}try {Select select = (Select) JsqlParserGlobal.parse(sql);SelectBody selectBody = select.getSelectBody();// https://github.com/baomidou/mybatis-plus/issues/3920 分页增加union语法支持if (selectBody instanceof SetOperationList) {return lowLevelCountSql(sql);}PlainSelect plainSelect = (PlainSelect) select.getSelectBody();Distinct distinct = plainSelect.getDistinct();GroupByElement groupBy = plainSelect.getGroupBy();// 包含 distinct、groupBy 不优化if (null != distinct || null != groupBy) {return lowLevelCountSql(select.toString());}// 优化 order by 在非分组情况下List<OrderByElement> orderBy = plainSelect.getOrderByElements();if (CollectionUtils.isNotEmpty(orderBy)) {boolean canClean = true;for (OrderByElement order : orderBy) {// order by 里带参数,不去除order byExpression expression = order.getExpression();if (!(expression instanceof Column) && expression.toString().contains(StringPool.QUESTION_MARK)) {canClean = false;break;}}if (canClean) {plainSelect.setOrderByElements(null);}}for (SelectItem item : plainSelect.getSelectItems()) {if (item.toString().contains(StringPool.QUESTION_MARK)) {return lowLevelCountSql(select.toString());}}// 包含 join 连表,进行判断是否移除 join 连表if (optimizeJoin && page.optimizeJoinOfCountSql()) {List<Join> joins = plainSelect.getJoins();if (CollectionUtils.isNotEmpty(joins)) {boolean canRemoveJoin = true;String whereS = Optional.ofNullable(plainSelect.getWhere()).map(Expression::toString).orElse(StringPool.EMPTY);// 不区分大小写whereS = whereS.toLowerCase();for (Join join : joins) {if (!join.isLeft()) {canRemoveJoin = false;break;}FromItem rightItem = join.getRightItem();String str = "";if (rightItem instanceof Table) {Table table = (Table) rightItem;str = Optional.ofNullable(table.getAlias()).map(Alias::getName).orElse(table.getName()) + StringPool.DOT;} else if (rightItem instanceof SubSelect) {SubSelect subSelect = (SubSelect) rightItem;/* 如果 left join 是子查询,并且子查询里包含 ?(代表有入参) 或者 where 条件里包含使用 join 的表的字段作条件,就不移除 join */if (subSelect.toString().contains(StringPool.QUESTION_MARK)) {canRemoveJoin = false;break;}str = subSelect.getAlias().getName() + StringPool.DOT;}// 不区分大小写str = str.toLowerCase();if (whereS.contains(str)) {/* 如果 where 条件里包含使用 join 的表的字段作条件,就不移除 join */canRemoveJoin = false;break;}for (Expression expression : join.getOnExpressions()) {if (expression.toString().contains(StringPool.QUESTION_MARK)) {/* 如果 join 里包含 ?(代表有入参) 就不移除 join */canRemoveJoin = false;break;}}}if (canRemoveJoin) {plainSelect.setJoins(null);}}}// 优化 SQLplainSelect.setSelectItems(COUNT_SELECT_ITEM);return select.toString();} catch (JSQLParserException e) {// 无法优化使用原 SQLlogger.warn("optimize this sql to a count sql has exception, sql:\"" + sql + "\", exception:\n" + e.getCause());} catch (Exception e) {logger.warn("optimize this sql to a count sql has error, sql:\"" + sql + "\", exception:\n" + e);}return lowLevelCountSql(sql);}/*** 无法进行count优化时,降级使用此方法** @param originalSql 原始sql* @return countSql*/protected String lowLevelCountSql(String originalSql) {return SqlParserUtils.getOriginalCountSql(originalSql);}/*** 查询SQL拼接Order By** @param originalSql 需要拼接的SQL* @return ignore*/public String concatOrderBy(String originalSql, List<OrderItem> orderList) {try {Select select = (Select) JsqlParserGlobal.parse(originalSql);SelectBody selectBody = select.getSelectBody();if (selectBody instanceof PlainSelect) {PlainSelect plainSelect = (PlainSelect) selectBody;List<OrderByElement> orderByElements = plainSelect.getOrderByElements();List<OrderByElement> orderByElementsReturn = addOrderByElements(orderList, orderByElements);plainSelect.setOrderByElements(orderByElementsReturn);return select.toString();} else if (selectBody instanceof SetOperationList) {SetOperationList setOperationList = (SetOperationList) selectBody;List<OrderByElement> orderByElements = setOperationList.getOrderByElements();List<OrderByElement> orderByElementsReturn = addOrderByElements(orderList, orderByElements);setOperationList.setOrderByElements(orderByElementsReturn);return select.toString();} else if (selectBody instanceof WithItem) {// todo: don't known how to resolereturn originalSql;} else {return originalSql;}} catch (JSQLParserException e) {logger.warn("failed to concat orderBy from IPage, exception:\n" + e.getCause());} catch (Exception e) {logger.warn("failed to concat orderBy from IPage, exception:\n" + e);}return originalSql;}protected List<OrderByElement> addOrderByElements(List<OrderItem> orderList, List<OrderByElement> orderByElements) {List<OrderByElement> additionalOrderBy = orderList.stream().filter(item -> StringUtils.isNotBlank(item.getColumn())).map(item -> {OrderByElement element = new OrderByElement();element.setExpression(new Column(item.getColumn()));element.setAsc(item.isAsc());element.setAscDescPresent(true);return element;}).collect(Collectors.toList());if (CollectionUtils.isEmpty(orderByElements)) {return additionalOrderBy;}// github pull/3550 优化排序,比如:默认 order by id 前端传了name排序,设置为 order by name,idadditionalOrderBy.addAll(orderByElements);return additionalOrderBy;}/*** count 查询之后,是否继续执行分页** @param page 分页对象* @return 是否*/protected boolean continuePage(IPage<?> page) {if (page.getTotal() <= 0) {return false;}if (page.getCurrent() > page.getPages()) {if (overflow) {//溢出总页数处理handlerOverflow(page);} else {// 超过最大范围,未设置溢出逻辑中断 list 执行return false;}}return true;}/*** 处理超出分页条数限制,默认归为限制数** @param page IPage*/protected void handlerLimit(IPage<?> page, Long limit) {final long size = page.getSize();if (limit != null && limit > 0 && (size > limit || size < 0)) {page.setSize(limit);}}/*** 处理页数溢出,默认设置为第一页** @param page IPage*/protected void handlerOverflow(IPage<?> page) {page.setCurrent(1);}@Overridepublic void setProperties(Properties properties) {PropertyMapper.newInstance(properties).whenNotBlank("overflow", Boolean::parseBoolean, this::setOverflow).whenNotBlank("dbType", DbType::getDbType, this::setDbType).whenNotBlank("dialect", ClassUtils::newInstance, this::setDialect).whenNotBlank("maxLimit", Long::parseLong, this::setMaxLimit).whenNotBlank("optimizeJoin", Boolean::parseBoolean, this::setOptimizeJoin);}protected String getTableFromSql(String sql) {String regex = "(?i)from\\s+([a-zA-Z0-9_]+)";Pattern pattern = Pattern.compile(regex);Matcher matcher = pattern.matcher(sql);if (matcher.find()) {return matcher.group(1);}return null;}/*** 判断是否进行未上传序列数计算* @param tableName 表名*/private boolean suitTableName(String tableName) {switch (tableName) {case V_SAMPLE_COVID19:case T_SAMPLE_RSV:case T_SAMPLE_COVID19:case T_SAMPLE_FLU:case T_SAMPLE_HADV:case T_SAMPLE_HMPV:case T_SAMPLE_HPIV:case T_SAMPLE_METAV:return true;default:return false;}}
}
相关文章:

MyBatis-Plus分页拦截器,源码的重构(重构total总数的计算逻辑)
1.1创建ThreadLocal工具类(作为业务逻辑结果存放类) package org.springblade.sample.utils;public class QueryContext {private static final ThreadLocal<Long> totalInThreadLocal new ThreadLocal<>();public static void setTotalIn…...

记一MySQL连接速度慢的问题
某一个程序启动速度超级慢,查看日志得知是是在Init DruidDataSource ~ {dataSource-1} inited 这一段耗时最长,这一段是Druid 数据源初始化,进行连接的创建等,使用mysql命令行连接发现连接超级慢,可见是在创建连接的时…...

asp.net core webapi项目中 在生产环境中 进不去swagger
builder.WebHost.UseUrls 是 ASP.NET Core 中配置应用程序监听 URL 或端口的方法。通过使用这个方法,你可以指定应用程序应该在哪些 URL 上运行,以便接收 HTTP 请求。 1.在appsetting.json中 添加 "LaunchUrl": "http://*:327"2.在…...

逆向攻防世界CTF系列63-secret-string-400
逆向攻防世界CTF系列63-secret-string-400 丢入exeinfo,查得zip,解压得四个文件 点进Task,查看源码:Test your luck! Enter valid string and you will know flag 顺理成章地看js 定位check函数 调用了machine的loadcode 跟进…...

Datawhale AI 冬令营学习笔记-零编程基础制作井字棋小游戏
井字棋小游戏是通过豆包MarsCode实现的,没有改动任何的代码,全部是通过对话让AI进行优化和改进。 开始进入正题:进入豆包MarsCode在线IDE,直接点击上方蓝字,或复制链接打开: 豆包 MarsCode - 编程助手。 IDE界面&…...

分布式专题(10)之ShardingSphere分库分表实战指南
一、ShardingSphere产品介绍 Apache ShardingSphere 是一款分布式的数据库生态系统, 可以将任意数据库转换为分布式数据库,并通过数据分片、弹性伸缩、加密等能力对原有数据库进行增强。Apache ShardingSphere 设计哲学为 Database Plus,旨在…...

clickhouse解决suspiciously many的异常
1. 问题背景 clickhouse安装在虚拟机上,持续写入日志时,突然关机,然后重启,会出现clickhouse可以正常启动,但是查询sql语句,提示suspiciously many异常,如图所示 2. 问题修复 touch /data/cl…...
计算机的错误计算(一百九十)
摘要 用两个大模型计算cot(1.234). 其中,1.234是以弧度为单位的角度。结果保留10位有效数字。实验表明,两个的计算公式虽然不同,但是都是正确的。然而,数值计算则是有问题的---包括每一个中间运算与结果。 例1. 计算cot(1.234)…...

STM32-笔记12-实现SysTick模拟多线程流水灯
1、前言 正常STM32实现多线程,需要移植一个操作系统FreeRTOS。但是在这里不移植FreeRTOS怎么实现多线程呢?使用SysTick,那么怎么使用SysTick来模拟多线程呢?前面我们知道SysTick就是一个定时器,它不是在主函数的while循…...

牛客网刷题 ——C语言初阶——BC114 小乐乐排电梯
1.牛客网 :BC114 小乐乐排电梯 题目描述: 小乐乐学校教学楼的电梯前排了很多人,他的前面有n个人在等电梯。电梯每次可以乘坐12人,每次上下需要的时间为4分钟(上需要2分钟,下需要2分钟)。请帮助…...

web三、 window对象,延时器,定时器,时间戳,location对象(地址),本地存储-localStorage,数组去重new Set
一、window对象 window对象 是一个全局对象,也可以说是JavaScript中的 顶级对象 像document、alert()、console.log()这些都是window的属性,基本BOM的属性和方法都是window的 所有通过 var定义 在全局作用域中的 变量 、 函数 都会变成window对象的属…...

【EthIf-13】EthIfGeneral容器配置-01
1.EthIfGeneral类图结构 下面是EthIfGeneral配置参数的类图,比较重要的参数就是配置: 接收中断是否打开发送确认中断是否打开EthIf轮询周期 1.EthIfGeneral参数的含义...

‘pnpm’ 不是内部或外部命令,也不是可运行的程序或批处理文件。
‘pnpm’ 不是内部或外部命令,也不是可运行的程序或批处理文件。 1.情况: npm -v 和 node -v的都正常就是 pnpm-v 无效 检查环境变量也没看出问题 2.分析 没有正确添加环境变量 3.解决 找到npm的全局安装目录 npm list -g --depth 0这里出现了npm的全局安装…...

ECMAScript 6-11 概述
1. ECMA 介绍 ECMA(European Computer Manufacturers Association)是欧洲计算机制造商协会,目标是评估、开发和认可电信和计算机标准。1994年后改名为Ecma国际。 2. ECMAScript 是什么 ECMAScript 是由Ecma国际通过ECMA-262标准化的脚本程…...

sqlalchemy连接dm8 get_columns BIGINT VARCHAR字段不显示
问题 标题即为问题, 问题出现原因 sqlalchemy对应的sqlalchemy_dm源码需要调整 版本说明 python 3.10 dmPython 2.5.5(2.4.8也可以) sqlalchemy1.4.52 sqlalchemy_dm1.4.39 环境说明 部署环境 ubuntu20 开发环境window11 wsl2 ubuntu20 可能会出现的…...

运动控制卡网络通讯的心跳检测之C#上位机编程
本文导读 今天,正运动小助手给大家分享一下如何使用C#上位机编程实现运动控制卡网络通讯的心跳检测功能。 01 ECI2618B硬件介绍 ECI2618B经济型多轴运动控制卡是一款脉冲型、模块化的网络型运动控制卡。控制卡本身最多支持6轴,可扩展至12轴的运动控制…...

QT 控件定义为智能指针引发的bug
问题描述: std::unique_ptr<QStackedLayout> m_stacked_layout; 如上为定义; 调用: Line13ABClient::Line13ABClient(QWidget *parent) : BaseWidget(parent) { // 成员变量初始化 m_get_ready false; m_tittle_wnd…...

Scala项目(图书管理系统)
3、service BookService package org.app package serviceimport org.app.dao.{BookDAO, BorrowRecordDAO} import org.app.models.{BookModel, BorrowRecordModel}import java.time.LocalDateTime import scala.collection.mutable.ListBuffer// 图书业务逻辑层 class BookS…...

前端开发 详解 Node. js 都有哪些全局对象?
在 Node.js 中,全局对象(Global Objects)是指在任何模块中都可以直接访问的对象和变量,而不需要显式地进行导入。Node.js 提供了一些全局对象,帮助开发者在编写应用程序时更加方便地进行一些常见操作,如文件…...

2024_12_20_生活记录
年底了,提前祝各位朋友们新年快乐!我将近两年没动笔写blog了,主要确实挺忙。。。今天想简单聊聊自己的近期想法,一方面是职业规划,一方面是生信,最后是个人感悟。 职业规划 熟悉我的朋友们会了解我之前一直…...

Sequelize ORM 现有表如何使用
一、 在mysql中创建一个表 或者随便找一个现有的表 已经有了一张叫做xw_posts的表。表里的字段非常简单,大家可以自己建一下 CREATE TABLE xw_posts (id int unsigned NOT NULL AUTO_INCREMENT,name varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_…...

ArcGIS Pro 3.4新功能3:空间统计新特性,基于森林和增强分类与回归,过滤空间自相关
目录 应用 1:它是相关性还是托布勒第一定律? 应用 2:将空间带入非空间模型 结论 在 ArcGIS Pro 3.4 中,我们在新的空间组件实用程序(Moran 特征向量)工具集中发布了一个新工具 - 从字段过滤空间自相关。…...

H3C MPLS跨域optionB
实验拓扑 实验需求 如图,VPN1 和 VPN2 分别通过运营商 MPLS VPN 连接各自分支机构按照图示配置 IP 地址,VPN1 和 VPN2 连接同一个 PE 设备的私网 IP 网段存在地址复用,使用多 VRF 技术来防止 IP 冲突AS 100 和 AS 200 内部的公共网络中各自运行 OSPF 使 AS 内各设备的 Loo…...

源码分析之Openlayers中Geometry基类介绍
概述 在上一篇文章源码分析之Openlayers中Geom篇中提到Geometry类是继承于 Openlayers 中的BaseObject类(参考源码分析之Openlayers中核心BaseObject类).而Geometry类通常情况下也是作为一个抽象基类,作为Geom几何图形的基类或父类,不会在应用中去实例化它.Geometry类回去注册…...

《Vue3 三》Vue 中的 options 选项
data 选项: data 选项:属性值必须是一个函数;返回值是一个对象,返回的对象会被 Vue 的响应式系统劫持,之后对该对象的任何访问或者修改都会在劫持中被处理。 在 Vue2.x 中,data 的属性值可以是一个函数&am…...

Elasticsearch 国产化替代方案之一 Easysearch 的介绍与部署指南
一、前言 在国内数字化转型浪潮和 信创 大背景下,“替代进口”成为许多企业级应用所需要面对的重要课题,搜索领域也不例外。 Elasticsearch(简称 ES)作为一款业界领先的全文搜索和分析引擎,虽然功能强大,但…...

Pytorch | 从零构建EfficientNet对CIFAR10进行分类
Pytorch | 从零构建EfficientNet对CIFAR10进行分类 CIFAR10数据集EfficientNet设计理念网络结构性能特点应用领域发展和改进 EfficientNet结构代码详解结构代码代码详解MBConv 类初始化方法前向传播 forward 方法 EfficientNet 类初始化方法前向传播 forward 方法 训练过程和测…...

Python超能力:高级技巧让你的代码飞起来
文章一览 前言一、with1.1 基本用法1.2 示例自定义上下文管理器 二、条件表达式三、列表式推导式与 zip 结合 四、map() 函数(内置函数)map用于数据清洗1. 数据清洗:字母大小写规范2. filter() 函数 五、匿名函数 lambda5.1 lambda的参数&…...

熊军出席ACDU·中国行南京站,详解SQL管理之道
12月21日,2024 ACDU中国行在南京圆满收官,本次活动分为三个篇章——回顾历史、立足当下、展望未来,为线上线下与会观众呈现了一场跨越时空的技术盛宴,吸引了众多业内人士的关注。云和恩墨副总经理熊军出席此次活动并发表了主题演讲…...

FPGA实现MIPI转FPD-Link车载同轴视频传输方案,基于IMX327+FPD953架构,提供工程源码和技术支持
目录 1、前言工程概述免责声明 2、相关方案推荐本博主所有FPGA工程项目-->汇总目录我这里已有的 MIPI 编解码方案 3、本 MIPI CSI-RX IP 介绍4、详细设计方案设计原理框图IMX327 及其配置FPD-Link视频串化-解串方案MIPI CSI RX图像 ISP 处理图像缓存HDMI输出工程源码架构 5、…...