Fivk博客 - 踩坑日志
type: channel
link: https://blog.fivk.cn/category/bug/
items: 使用 MongoDB 实现分页查询与条件查询中的注意事项
items: 【踩坑日志】mybatis：Caused by: org.apache.ibatis.ognl.ParseException: Encountered " <IDENT> "AND "" at line
items: 【踩坑日志】MyBatis标签语句foreach遍历列表问题
items: 【踩坑日志】TDengine在SpringBoot项目中使用order by ts desc limit 1出现错误
items: 【踩坑日志】@MapKey is required
items: 【踩坑日志】ServiceAuthFeign#getAllowedClient(String,String) failed and no fallback available.
items: 【踩坑日志】使用vite构建vue3运行报错
items: 【踩坑日志】宝塔设置又拍云备份数据
items: 【踩坑日志】java.lang.Exception: No runnable methods
items: 【踩坑日志】Controller中使用service执行方法，一直提示NULL

使用 MongoDB 实现分页查询与条件查询中的注意事项
type: item
date: 2025-01-10T23:10:00+08:00
description: 引言[scode type="share" size="simple"]在基于Spring Data MongoDB的开发中，分页与条件查询是高频操作，但其实现细节中存在诸多易错点。本文结合代码实例与典型场景，深入剖析五大核心问题及优化方案，并补充性能优化与设计规范。[/scode]一、基础代码示例与问题背景Pageable pageable = PageRequest.of(page-1, size, Sort.by("orderNumber").descending()); Query query = new Query(); // 动态条件构建 if (orderNumber != null) { query.addCriteria(Criteria.where("orderNumber").is(Long.parseLong(orderNumber))); } if (consignee != null) { query.addCriteria(Criteria.where("consignee").regex(consignee, "i")); } if (beginTime != null || endTime != null) { handleDateRange(query, beginTime, endTime); // 日期范围处理封装 } // 总条数与分页结果查询 long total = mongoTemplate.count(query, OrderEntity.class); query.with(pageable); List<OrderEntity> entities = mongoTemplate.find(query, OrderEntity.class);二、核心问题与解决方案1. 分页操作污染总条数计算问题现象若先调用query.with(pageable)再执行count()，分页限制（如skip/limit）会导致总条数统计错误。解决方案严格分离统计与分页阶段：// 阶段一：统计总数（未分页） long total = mongoTemplate.count(query, Order.class); // 阶段二：应用分页参数 query.with(pageable); List<Order> data = mongoTemplate.find(query, Order.class);2. 类型不匹配导致查询失效典型场景数据库字段类型为Long，但Java条件传递String类型值时，因MongoDB类型强校验导致匹配失败。优化建议使用统一类型转换工具：public void addLongCriteria(Query query, String field, String value) { if (StringUtils.isNotEmpty(value)) { try { query.addCriteria(Criteria.where(field).is(Long.parseLong(value))); } catch (NumberFormatException e) { throw new IllegalArgumentException("字段["+field+"]必须为数字类型"); } } }3. 正则表达式大小写敏感问题技术细节Criteria.regex()默认大小写敏感，需显式添加"i"修饰符实现模糊匹配。扩展方案支持动态大小写控制：String regexOptions = caseSensitive ? "" : "i"; criteria.regex(value, regexOptions);4. 日期范围查询条件冲突错误示例// 错误：多次添加createdAt条件 if (beginTime != null) query.addCriteria(Criteria.where("createdAt").gte(beginTime)); if (endTime != null) query.addCriteria(Criteria.where("createdAt").lte(endTime));正确实践单条件链式构建：Criteria dateCriteria = new Criteria(); if (beginTime != null) dateCriteria.gte(beginTime); if (endTime != null) dateCriteria.lte(endTime); if (beginTime != null || endTime != null) { query.addCriteria(dateCriteria); }5. 动…

【踩坑日志】mybatis：Caused by: org.apache.ibatis.ognl.ParseException: Encountered " <IDENT> "AND "" at line
type: item
date: 2023-12-15T16:49:42+08:00
description: 报错信息 Caused by: org.apache.ibatis.ognl.ParseException: Encountered " <IDENT> "AND "" at line 1, column 19. Was expecting one of: <EOF> "," ... "=" ... "?" ... "||" ... "or" ... "&&" ... "and" ... "|" ... "bor" ... "^" ... "xor" ... "&" ... "band" ... "==" ... "eq" ... "!=" ... "neq" ... "<" ... "lt" ... ">" ... "gt" ... "<=" ... "lte" ... ">=" ... "gte" ... "in" ... "not" ... "<<" ... "shl" ... ">>" ... "shr" ... ">>>" ... "ushr" ... "+" ... "-" ... "*" ... "/" ... "%" ... "instanceof" ... "." ... "(" ... "[" ... <DYNAMIC_SUBSCRIPT> ...报错原因在mybatis中<if test="companyId != null AND companyId != ''"> AND a.company_id=#{companyId} </if> <if test="room != null AND room != ''"> AND t_sys_room.NAME=#{room} </if> <if test="deviceModel != null AND deviceModel != ''"> AND t_sys_dict.label=#{deviceModel} </if>if标签里面的 and应该是小写，而不是大写。

【踩坑日志】MyBatis标签语句foreach遍历列表问题
type: item
date: 2023-12-06T11:18:00+08:00
description: 我以前用的foreach一般是这样的<delete id="deleteByIds"> delete from tb_brand where id in <foreach collection="array" item="id" separator="," open="(" close=")"> #{id} </foreach> </delete>这条语句时没错的，我们使用open="(" close=")"，对最外层加上了括号。但是今天我使用mybatis写一个批量查询如下语句（模拟的案例）：<insert id="batchInsert" parameterType="java.util.List"> insert into twn_nms_app_fttx.t_branch_history_trend(id, kpi_utc_sec, sample_interval, location, active_devices, evt_devices, stream_devices, total_devices, http_bytes, dist_http_err_code, dist_video_type, dist_event, grn_devices, blue_devices, ylw_devices, red_devices) values <foreach collection="list" item="item" separator="," open="(" close=")"> null, #{item.kpiutCSec}, #{item.sampleInterval}, #{item.location}, #{item.activeDevices}, #{item.evtDevices}, #{item.streamDevices}, #{item.totalDevices}, #{item.httpBytes}, #{item.distHttpErrCode}, #{item.distVideoType}, #{item.distEvent}, #{item.grnDevices}, #{item.blueDevices}, #{item.ylwDevices}, #{item.redDevices} </foreach> </insert>结果就是，当插入一条时，能够成功运行，当插入多条时就会报错，看了十多分中没结果，去上厕所恍然大悟！！好几次都是去厕所想明白的😂这个问题可能是由于在的<foreach>标签中，使用了逗号，作为分隔符。当你的列表只有一条数据时，这不会产生问题，因为只有一个值的集合被插入，没有逗号。但是，当列表有多条数据时，每个值的集合之间会被逗号分隔，并且每一条数据没有括号，只会在总的数据两边加上括号，这可能会导致SQL语句的格式错误。所以正确的语句应该是：<insert id="batchInsert" parameterType="java.util.List"> insert into twn_nms_app_fttx.t_branch_history_trend(id, kpi_utc_sec, sample_interval, location, active_devices, evt_devices, stream_devices, total_devices, http_bytes, dist_http_err_code, dist_video_type, dist_event, grn_devices, blue_devices, ylw_devices, red_devices) values <foreach collection="list" item="item" separator=","> ( null, #{item.kpiutCSec}, #{item.sampleInterval}, #{item.location}, #{item.activeDevices}, #{item.evtDevices}, #{item.streamDevices}, #{item.totalDevices}, #{item.httpBytes}, #{item.distHttpErrCode}, #{item.distVideoType}, #{item.distEvent}, #{item.grnDevices}, #{item.blueDevices}, #{item.ylwDevices}, #{item.redDevices} ) </foreach> </insert>总结：想不明白时去厕所摸鱼玩玩手机。

【踩坑日志】TDengine在SpringBoot项目中使用order by ts desc limit 1出现错误
type: item
date: 2023-10-25T15:35:00+08:00
description: 问题描述我这里是SpringBoot+Mybatis+TDengine项目，我想获取一个表中的最新数据于是有了这样一条SQL：select * from my_table_name order by ts desc limit 1但是它执行报错了### SQL: select * from tw_nms_report.stable_olt_statistics order by ts desc limit 1 ### Cause: java.sql.SQLException: Error ; uncategorized SQLException for SQL []; SQL state [null]; error code [0]; Error; nested exception is java.sql.SQLException: Error at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:84) at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81) at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81) at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:73) at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:446) at com.sun.proxy.$Proxy127.selectOne(Unknown Source) at org.mybatis.spring.SqlSessionTemplate.selectOne(SqlSessionTemplate.java:166) at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:83)我发现当被查询的表中只有一条数据时，它能正确执行，不报错。但是表中的数据如果大于两条，那么他就会报上面的错误。项目结构Java实体类package com.tw.nms.report.td.entity; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import javax.persistence.Column; import javax.persistence.Table; import java.io.Serializable; /** * @author wufan * @create 2023/10/24 * @Description Olt设备信息统计 */ @Data @EqualsAndHashCode(callSuper = false) @Table(name = "stable_olt_statistics", schema = "tw_nms_report") @ToString public class OltStatisticsTdEntity implements Serializable { // 序列化: 用于网络传输 private static final long serialVersionUID = 1L; // 时间戳 @Column(name = "ts") private String ts; // 设备总数：所有的设备数量 @Column(name = "allDevices") private Integer allDevices; // 在网设备数量：记录在网设备的数量 @Column(name = "onlineDevices") private Integer onlineDevices; // 在网设备占比：表示在网设备…

【踩坑日志】@MapKey is required
type: item
date: 2023-10-24T14:34:00+08:00
description: 在mybatis的Java文件中提示@MapKey is requiredJava/** * 查询各种设备类型的数量 * @return List<Map<String, Integer>> */ List<Map<String, Object>> GroupByDeviceTypeDistribution();xml select area, count(*) as count from `twn_nms_app_fttx`.`t_fttx_olt_statistics` group by area; 看似没有问题，但是对于返回的数据中Map的key是哪个字段你却没有指定，所以我们这里需要使用@MapKey注解，来指定指端作为Map的key。我们将Java代码修改为/** * 查询各种设备类型的数量 * @return List<Map<String, Integer>> */ @MapKey("area") List<Map<String, Object>> GroupByDeviceTypeDistribution();即可。

【踩坑日志】ServiceAuthFeign#getAllowedClient(String,String) failed and no fallback available.
type: item
date: 2023-10-20T10:38:48+08:00
description: 报错信息Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled. 10:27:20.074 nms-admin-server [main] ERROR o.s.boot.SpringApplication - Application startup failed java.lang.IllegalStateException: Failed to execute CommandLineRunner at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:735) at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:716) at org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:703) at org.springframework.boot.SpringApplication.run(SpringApplication.java:304) at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:134) at com.tw.nms.admin.AdminBootstrap.main(AdminBootstrap.java:40) Caused by: com.netflix.hystrix.exception.HystrixRuntimeException: ServiceAuthFeign#getAllowedClient(String,String) failed and no fallback available. at com.netflix.hystrix.AbstractCommand$22.call(AbstractCommand.java:819) at com.netflix.hystrix.AbstractCommand$22.call(AbstractCommand.java:804) at rx.internal.operators.OperatorOnErrorResumeNextViaFunction$4.onError(OperatorOnErrorResumeNextViaFunction.java:140) at rx.internal.operators.OnSubscribeDoOnEach$DoOnEachSubscriber.onError(OnSubscribeDoOnEach.java:87) at rx.internal.operators.OnSubscribeDoOnEach$DoOnEachSubscriber.onError(OnSubscribeDoOnEach.java:87) at com.netflix.hystrix.AbstractCommand$DeprecatedOnFallbackHookApplication$1.onError(AbstractCommand.java:1472) at com.netflix.hystrix.AbstractCommand$FallbackHookApplication$1.onError(AbstractCommand.java:1397) at rx.internal.operators.OnSubscribeDoOnEach$DoOnEachSubscriber.onError(OnSubscribeDoOnEach.java:87) at rx.observers.Subscribers$5.onError(Subscribers.java:230) at rx.internal.operators.OnSubscribeThrow.call(OnSubscribeThrow.java:44) at rx.internal.operators.OnSubscribeThrow.call(OnSubscribeThrow.java:28) at rx.Observable.unsafeSubscribe(Observable.java:10211) at rx.internal.…

【踩坑日志】使用vite构建vue3运行报错
type: item
date: 2023-05-11T19:34:48+08:00
description: 今天学到vue3，使用vite构建。但是我使用npm run dev运行时就会报错X [ERROR] Unexpected end of file in JSON ../package.json:1:0: 1 │ ╵ ^ failed to load config from E:\VsCodeProject\study_vue\vue3_test\vite.config.js error when starting dev server: Error: Build failed with 1 error: ../package.json:1:0: ERROR: Unexpected end of file in JSON at failureErrorWithLog (E:\VsCodeProject\study_vue\vue3_test\node_modules\esbuild\lib\main.js:1636:15) at E:\VsCodeProject\study_vue\vue3_test\node_modules\esbuild\lib\main.js:1048:25 at runOnEndCallbacks (E:\VsCodeProject\study_vue\vue3_test\node_modules\esbuild\lib\main.js:1471:45) at buildResponseToResult (E:\VsCodeProject\study_vue\vue3_test\node_modules\esbuild\lib\main.js:1046:7) at E:\VsCodeProject\study_vue\vue3_test\node_modules\esbuild\lib\main.js:1075:16 at responseCallbacks.<computed> (E:\VsCodeProject\study_vue\vue3_test\node_modules\esbuild\lib\main.js:697:9) at handleIncomingPacket (E:\VsCodeProject\study_vue\vue3_test\node_modules\esbuild\lib\main.js:752:9) at Socket.readFromStdout (E:\VsCodeProject\study_vue\vue3_test\node_modules\esbuild\lib\main.js:673:7) at Socket.emit (node:events:513:28) at addChunk (node:internal/streams/readable:324:12)或者\ Pre-bundling them to speed up dev server page load... (this will be run only when your dependencies have changed) [vite] Error loading postcss config:server page load... SyntaxError: E:\VsCodeProject\study_vue\package.json: Unexpected end of JSON input at parse (<anonymous>) at Module._extensions..json (node:internal/modules/cjs/loader:1322:39) at Module.load (node:internal/modules/cjs/loader:1117:32) at Module._load (node:internal/modules/cjs/loader:958:12) at Module.require (node:internal/modules/cjs/loader:1141:19) at require (node:internal/modules/cjs/helpers:110:18) at Object.search (E:\VsCodeProject\study_vue\vue3_test\node_modules\lilconfig\dist\index.js:112:39) at async loadPostcssConfig (E:\VsCodeProject\study_vue\vue3_test\node_modules\vite\dist\node\utils\cssUtils.js:107:39) at async Obj…

【踩坑日志】宝塔设置又拍云备份数据
type: item
date: 2023-03-26T23:35:22+08:00
description: 这个坑踩过两次，就是设置操作员密码的时候，生成之后要点保存。

【踩坑日志】java.lang.Exception: No runnable methods
type: item
date: 2022-09-11T22:14:00+08:00
description: 报错信息java.lang.Exception: No runnable methods at org.junit.runners.BlockJUnit4ClassRunner.validateInstanceMethods(BlockJUnit4ClassRunner.java:191) at org.junit.runners.BlockJUnit4ClassRunner.collectInitializationErrors(BlockJUnit4ClassRunner.java:128) at org.junit.runners.ParentRunner.validate(ParentRunner.java:416) at org.junit.runners.ParentRunner.<init>(ParentRunner.java:84) at org.junit.runners.BlockJUnit4ClassRunner.<init>(BlockJUnit4ClassRunner.java:65) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.<init>(SpringJUnit4ClassRunner.java:137) at org.springframework.test.context.junit4.SpringRunner.<init>(SpringRunner.java:49) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:104) at org.junit.vintage.engine.discovery.DefensiveAllDefaultPossibilitiesBuilder$DefensiveAnnotatedBuilder.buildRunner(DefensiveAllDefaultPossibilitiesBuilder.java:114) at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:86) at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59) at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:26) at org.junit.vintage.engine.discovery.DefensiveAllDefaultPossibilitiesBuilder.runnerForClass(DefensiveAllDefaultPossibilitiesBuilder.java:57) at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59) at org.junit.vintage.engine.discovery.ClassSelectorResolver.resolveTestClass(ClassSelectorResolver.java:66) at org.junit.vintage.engine.discovery.ClassSelectorResolver.resolve(ClassSelectorResolver.java:47) at org.junit.platform.engine.s…

【踩坑日志】Controller中使用service执行方法，一直提示NULL
type: item
date: 2022-07-21T20:50:00+08:00
description: 报错信息java.lang.NullPointerException: null at cn.fivk.takeaway.controller.DishController.lambda$page$0(DishController.java:84) ~[classes/:na] at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) ~[na:1.8.0_321] at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1384) ~[na:1.8.0_321] at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482) ~[na:1.8.0_321] at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472) ~[na:1.8.0_321] at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) ~[na:1.8.0_321] at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:1.8.0_321] at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499) ~[na:1.8.0_321] at cn.fivk.takeaway.controller.DishController.page(DishController.java:88) ~[classes/:na] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_321] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_321] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_321] at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_321] at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) ~[spring-web-5.3.20.jar:5.3.20] at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150) ~[spring-web-5.3.20.jar:5.3.20] at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) ~[spring-webmvc-5.3.20.jar:5.3.20] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) ~[spring-webmvc-5.3.20.jar:5.3.20] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapte…