MybatisPlus批量更新的小插曲

文章讲述了在商城项目中,开发环境与测试环境因表结构不一致导致订单状态同步时,订单明细记录出现问题。通过添加日志和对比环境设计,发现环境因素对数据库结构的影响,强调了保持环境一致性的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

插曲背景

在商城项目中涉及订单业务,有两个主要的表:订单表order和订单明细表order_detail。

  • order表:主要存储订单的主要信息,订单总金额,收货人信息,订单状态等;
  • order_detail表:主要存储订单购买的商品明细信息,每个SKU一条记录;

order表和order_detail表的主键id都是自增的,order表有一个sn字段,order_detail表有一个order_sn字段,这两个表通过sn和order_sn两个字段进行关联,实现业务:1个订单有多少条订单明细记录。

插曲描述

项目增加一个状态同步需求:更新order记录的状态status,同时更新对应的订单明细记录的status。

在开发环境联调测试都是ok的:下单 -> 更新订单状态。然后,在sit测试环境出现一种奇怪的现象,执行状态更新操作之后,指定订单对应的所有的订单明细记录数据全部都变成一样了,且每条记录的id均为0。

因为之前订单功能是已上线的,且数据库变更的管理采用flyway组件,同样的代码在不同的环境执行效果不一样,只能猜测是环境不一样导致的。

开发人员没有sit环境数据库的更新权限,只有只读权限。

问题排查

在更新逻辑代码中增加执行日志输出,重新提测之后。观察操作执行的日志,发现:在【下单】操作之后,生成的订单明细记录id均为0;继续执行更新操作时,所有的订单明细记录数据全部更新为相同的数据。批量更新使用MybatisPlus的updateBatchById方法。

针对上述情况,第一反应是原本自增的id字段值为啥都是0?查看一下sit环境order_detail表的设计语句,发现id字段没有被设置为:自增。再核对了开发环境order_detail表的设计语句,id字段是自增的。

造成问题的原因出来了:sit环境和dev环境的表结构不一致了。将sit环境order_detail表的id设置为自增,重新测试该需求功能,好了!

问题反思

  1. 越让人放心省力的方法,一旦出现问题,越不好排查问题(通过flyway保证各个环境的数据表结构一致,也要小心使用);
  2. 敢于质疑,由于一开始并没有想到会是环境不同导致的问题,一致代码层面排查,所以浪费了时间,比如:修改可疑的代码,增加日志输出等工作。
### 如何在Elasticsearch中配置和集成爬虫 要在Elasticsearch (ES) 中实现爬虫的功能,通常会借助第三方工具或框架来抓取网页数据并将这些数据存储到 ES 的索引中。以下是详细的说明: #### 1. 使用 Elastic Enterprise Search 配置爬虫 Elastic 提供了一个名为 **Enterprise Search** 的产品,它支持通过内置的 Web Crawler 功能自动抓取网站内容并将其同步到 Elasticsearch 索引中[^2]。 - 安装和启动 Elastic Stack 后,在 Kibana 控制台中启用 **Web Crawler** 插件。 - 创建一个新的爬虫任务,并指定目标站点 URL、访问权限以及需要排除的内容路径。 - 设置定时计划以定期更新索引中的数据。 此方法适合于企业级应用,尤其是当您希望通过官方渠道获取技术支持和服务时。 ```yaml # 示例:Kibana 中定义 web crawler job 的部分参数设置 { "name": "example-crawl-job", "seeds": ["https://www.example.com"], "access_control_rules": [ {"allow_patterns": ["*"], "disallow_patterns": []} ], "scheduling": { "interval": "PT1H" } } ``` --- #### 2. 自定义开发基于 Python 或 Java 的爬虫程序并与 ES 对接 如果需求更加复杂或者希望拥有更高的灵活性,则可以考虑自己编写爬虫脚本并通过 API 接口向 ES 发送采集的数据。 ##### (a)Python 实现方案 利用 Scrapy 框架作为主要抓手,配合 `elasticsearch-py` 库上传文档至远程集群实例。 ```python import scrapy from elasticsearch import Elasticsearch class MySpider(scrapy.Spider): name = 'my_spider' start_urls = ['http://example.org'] es_client = Elasticsearch(["http://localhost:9200"]) def parse(self, response): title = response.css('title::text').get() content = ''.join(response.xpath('//body//text()').extract()) doc = { 'url': response.url, 'title': title.strip(), 'content': content.strip() } self.es_client.index(index="webpages", document=doc) if __name__ == "__main__": from scrapy.crawler import CrawlerProcess process = CrawlerProcess(settings={ 'LOG_LEVEL': 'INFO', 'DOWNLOAD_DELAY': 1 }) process.crawl(MySpider) process.start() ``` > 注解:上述代码片段展示了如何构建基本的 Spider 类型对象,并将解析后的页面元信息推送到本地运行的服务端点上[^3]。 ##### (b)Java Spring Boot 整合方式 对于采用微服务架构的应用环境来说,可能更倾向于选用后者——即把整个逻辑封装进 RESTful 微服务体系之中去执行操作流程。 下面给出一段简化的例子用于演示目的: ```java @SpringBootApplication public class Application { @Autowired private RestHighLevelClient client; public static void main(String[] args){ SpringApplication.run(Application.class,args); } @Bean(destroyMethod = "close") public RestHighLevelClient elasticSearchClient(){ return new RestHighLevelClient( RestClient.builder(new HttpHost("localhost",9200,"http")) ); } } @Service @ComponentScan(basePackages={"com.mycompany"}) public class CrawlerService implements CommandLineRunner{ @Override public void run(String...args)throws Exception{ // TODO Implement crawling logic here... IndexRequest request=new IndexRequest("articles"); Map<String,Object> jsonMap=new HashMap<>(); jsonMap.put("author","John Doe"); jsonMap.put("postDate",new Date()); jsonMap.put("messageText","trying out Elasticsearch"); request.source(jsonMap); try{ IndexResponse indexResponse=this.client.index(request, RequestOptions.DEFAULT); System.out.println("Indexed with version "+indexResponse.getVersion()); }catch(IOException e){ throw new RuntimeException(e.getMessage(),e); } } } ``` 在这里需要注意的是实际项目当中应当引入合适的依赖项比如 Jsoup 来简化 HTML 解析过程;另外还需要妥善处理异常情况下的重试机制等问题[^3]。 --- #### 总结 无论是选择直接运用官方提供的插件还是自行搭建专属解决方案都各有优劣之处。前者能够快速部署上线而无需过多关注底层细节;后者虽然前期投入较大但却具备更强适应能力满足特定业务场景的要求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

萧十一郎君

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值