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

属性拷贝MapStruct

端请求通过VO对象接收,并通过DTO对象进行流转,最后转换成DO对象与数据库DAO层进行交互,反之亦然。

当业务简单的时候,可以通过手动编码getter/setter函数来复制对象属性。但是当业务变的复杂,对象属性变得很多,那么手写复制属性代码不仅十分繁琐,非常耗时间,并且还可能容易出错。

为了解决这个痛点,在项目初期,项目的解决方法是随手写的转换工具函数:根据变量名进行反射,对基础类型和枚举的变量进行赋值。

总结下目前该工具函数的优缺点:

优点:

  1. 开发效率高,随时想要转换的时候,传入源对象以及指定class,调用下函数即可。

缺点:

  1. 项目中大量的反射会严重影响代码执行效率
  2. 由于使用了反射,所以成员变量的使用被追踪就很麻烦
  3. 转换失败只有在运行中报错才会发现
  4. 对于嵌套对象字段的情况无能为力
  5. 只能对基础类型进行复制
  6. 对字段名不一致的属性无法赋值

接下来就要介绍MapStruct 这个工具类,这个工具类之所以运行速度与硬编码差不多,这是因为MapStruct在编译期间就生成属性复制的代码,运行期间就无需使用反射或者字节码技术,从而确保了高性能。

另外,由于编译期间就生成了代码,所以如果有任何问题,编译期间就可以提前暴露,这对于开发人员来讲就可以提前解决问题,而不用等到代码应用上线了,运行之后才发现错误。

所以,为了克服项目中当前函数的被提到的五个缺点,笔者引入了MapStruct。

2. 如何引入MapStruct

只需要引入MapStruct的依赖,同时由于MapStruct需要在编译器期间生成代码,所以我们需要maven-compiler-plugin插件中配置

复制

// pom.xml<dependency><groupId>org.MapStruct</groupId><artifactId>MapStruct</artifactId><version>1.4.1.Final</version></dependency>

.高效性:

1.编译期   自动生成映射代码          

类型检查报错

2.灵活性:支持复杂映射(对象、集合列表)  

   支持属性不同字段名、类型的赋值

3.直观性:使用注解来定义映射规则     (根据需求指定返回类型、忽略属性,添加        条件判断来决定是否执行映射操作) 

 

package com.mdgyl.hussar.basic.supplier.changeorder.converter.struct;import com.mdgyl.common.util.DateUtils;
import com.mdgyl.hussar.basic.model.supplier.masterdata.*;
import com.mdgyl.hussar.basic.model.supplier.supplierchangeorder.*;
import com.mdgyl.hussar.basic.supplier.changeorder.domain.*;
import org.apache.commons.lang3.StringUtils;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;@Mapper
public interface ChangeOrderMapperConverter {ChangeOrderMapperConverter INSTANCE = Mappers.getMapper(ChangeOrderMapperConverter.class);@Mappings({@Mapping(target = "score", expression = "java(exchangeRateDO.getScore() == null? null:exchangeRateDO.getScore().toString())"),@Mapping(target = "operatingStartTime", expression = "java(exchangeRateDO.getOperatingStartTime() == null? null:formatDate(exchangeRateDO.getOperatingStartTime()))"),})SupplierChangeOrderModel doToModel(SupplierChangeOrderDo exchangeRateDO);@Mappings({@Mapping(target = "id", ignore = true),@Mapping(source = "tenantId", target = "tenantId"),@Mapping(target = "status", ignore = true),@Mapping(source = "id", target = "supplierDataId"),@Mapping(target = "deleteFlag", constant = "0")})SupplierChangeOrderModel converterSupplierToChangeOrder(SupplierModel supplierModel);@Mappings({@Mapping(target = "id", ignore = true),@Mapping(source = "id", target = "supplierAddressId")})SupplierChangeOrderAddressModel convertAddressesModel(SupplierAddressModel supplierAddressModel);@Mappings({@Mapping(target = "id", ignore = true),@Mapping(source = "id", target = "supplierBankId")})SupplierChangeOrderBankModel convertBankModel(SupplierBankModel supplierBankModel);@Mappings({@Mapping(target = "id", ignore = true),@Mapping(source = "id", target = "supplierContactsId"),})SupplierChangeOrderContactsModel convertContactModel(SupplierContactsModel supplierContactsModel);@Mappings({@Mapping(target = "id", ignore = true),@Mapping(source = "id", target = "supplierInfoId"),})SupplierChangeOrderInfoModel convertOderInfoModel(SupplierInfoModel supplierInfo);@Mappings({@Mapping(target = "score", expression = "java(parseBigDecimal(supplierChangeOrderModel.getScore()))"),@Mapping(target = "operatingStartTime", expression = "java(supplierChangeOrderModel.getOperatingStartTime() == null ? null : parseDate(supplierChangeOrderModel.getOperatingStartTime()))"),})SupplierChangeOrderDo converterModelToDo(SupplierChangeOrderModel supplierChangeOrderModel);@Mappings({@Mapping(target = "taxRate", expression = "java(parseBigDecimal(supplierChangeOrderModel.getTaxRate()))"),@Mapping(target = "staffSize", expression = "java(supplierChangeOrderModel.getStaffSize() == null || supplierChangeOrderModel.getStaffSize().isEmpty() ? null : new Integer(supplierChangeOrderModel.getStaffSize()))"),@Mapping(target = "numberOfInsured", expression = "java(supplierChangeOrderModel.getNumberOfInsured() == null || supplierChangeOrderModel.getNumberOfInsured().isEmpty() ? null : new Integer(supplierChangeOrderModel.getNumberOfInsured()))")})SupplierChangeOrderInfo converterInfoModelToDo(SupplierChangeOrderInfoModel supplierChangeOrderModel);SupplierChangeOrderAddress converterAddressModelToDo(SupplierChangeOrderAddressModel supplierChangeOrderAddressModel);SupplierChangeOrderBank converterBankModelToDo(SupplierChangeOrderBankModel supplierChangeOrderBankModel);SupplierChangeOrderContacts converterContactsModel(SupplierChangeOrderContactsModel supplierChangeOrderContactsModel);@Mappings({@Mapping(target = "taxRate", expression = "java(supplierInfo.getTaxRate() == null? null:supplierInfo.getTaxRate().toString())"),@Mapping(target = "staffSize", expression = "java(supplierInfo.getStaffSize() == null? null:supplierInfo.getStaffSize().toString())"),@Mapping(target = "numberOfInsured", expression = "java(supplierInfo.getNumberOfInsured() == null? null:supplierInfo.getNumberOfInsured().toString())")})SupplierChangeOrderInfoModel converterInfoDoToModel(SupplierChangeOrderInfo supplierInfo);SupplierChangeOrderAddressModel convertAddressesDoToModel(SupplierChangeOrderAddress supplierChangeOrderAddress);SupplierChangeOrderContactsModel convertContactsDoToModel(SupplierChangeOrderContacts supplierChangeOrderContacts);SupplierChangeOrderBankModel convertBankDoToModel(SupplierChangeOrderBank supplierChangeOrderContacts);@Mappings({@Mapping(source = "supplierDataId", target = "id"),@Mapping(source = "status", target = "status", ignore = true),@Mapping(target = "score", expression = "java(parseBigDecimal(changeOrderModel.getScore()))"),@Mapping(target = "operatingStartTime", expression = "java(parseLocalDateTime(changeOrderModel.getOperatingStartTime()))")})SupplierModel converterChangeOrderToSupplier(SupplierChangeOrderModel changeOrderModel);@Mappings({@Mapping(source = "supplierInfoId", target = "id"),@Mapping(target = "staffSize", expression = "java(changeOrderInfo.getStaffSize() == null|| changeOrderInfo.getStaffSize().isEmpty() ? null : Integer.parseInt(changeOrderInfo.getStaffSize()))"),@Mapping(target = "taxRate", expression = "java(parseBigDecimal(changeOrderInfo.getTaxRate()))"),@Mapping(target = "numberOfInsured", expression = "java(changeOrderInfo.getNumberOfInsured() == null || changeOrderInfo.getNumberOfInsured().isEmpty()? null : Integer.parseInt(changeOrderInfo.getNumberOfInsured()))"),})SupplierInfoModel convertOderInfoToSupplierModel(SupplierChangeOrderInfoModel changeOrderInfo);@Mappings({@Mapping(source = "supplierAddressId", target = "id")})SupplierAddressModel convertAddressesToSupplierModel(SupplierChangeOrderAddressModel supplierChangeOrderAddressModel);@Mappings({@Mapping(source = "supplierBankId", target = "id")})SupplierBankModel convertBankToSupplierModel(SupplierChangeOrderBankModel supplierBankModel);@Mappings({@Mapping(source = "supplierContactsId", target = "id"),})SupplierContactsModel convertContactToSupplierModel(SupplierChangeOrderContactsModel supplierContactsModel);default Date parseDate(String dateString) {SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");try {return format.parse(dateString);} catch (Exception e) {e.printStackTrace();return null;}}default BigDecimal parseBigDecimal(String taxRate) {if (StringUtils.isEmpty(taxRate)) {return null;}return new BigDecimal(taxRate);}default String formatDate(Date date) {SimpleDateFormat format = new SimpleDateFormat(DateUtils.YYYY_MM_DD);return format.format(date);}// 自定义方法用于解析日期字符串default LocalDate parseLocalDate(String dateString) {if (dateString == null) {return null;}DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DateUtils.YYYY_MM_DD);try {LocalDateTime dateTime = LocalDateTime.parse(dateString, formatter);return dateTime.toLocalDate();} catch (Exception e) {return null;}}// 自定义方法用于解析日期字符串default LocalDateTime parseLocalDateTime(String dateStr) {if (StringUtils.isBlank(dateStr)) {return null;}try {DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DateUtils.YYYY_MM_DD_HH_MM_SS);return LocalDateTime.parse(dateStr, formatter);} catch (Exception e) {return null;}}
}

package com.mdgyl.hussar.basic.supplier.changeorder.converter.service;import com.google.common.collect.Lists;
import com.jxdinfo.hussar.support.audit.plugin.mongodb.support.query.entity.Page;
import com.mdgyl.common.helper.CollectionHelper;
import com.mdgyl.common.helper.MapHelper;
import com.mdgyl.hussar.basic.enums.SupplierChangeOrderStatusEnum;
import com.mdgyl.hussar.basic.enums.SupplierStatusEnum;
import com.mdgyl.hussar.basic.model.supplier.masterdata.SupplierAddressModel;
import com.mdgyl.hussar.basic.model.supplier.masterdata.SupplierBankModel;
import com.mdgyl.hussar.basic.model.supplier.masterdata.SupplierContactsModel;
import com.mdgyl.hussar.basic.model.supplier.masterdata.SupplierModel;
import com.mdgyl.hussar.basic.model.supplier.supplierchangeorder.*;
import com.mdgyl.hussar.basic.supplier.changeorder.converter.struct.ChangeOrderMapperConverter;
import com.mdgyl.hussar.basic.supplier.changeorder.domain.*;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;public class ChangeOrderServiceConverter {public static SupplierChangeOrderModel converterModel(SupplierChangeOrderDo supplierChangeOrderDo) {if (supplierChangeOrderDo == null) {return null;}SupplierChangeOrderModel supplierChangeOrderModel = ChangeOrderMapperConverter.INSTANCE.doToModel(supplierChangeOrderDo);supplierChangeOrderModel.setStatus(SupplierChangeOrderStatusEnum.getDescByCode(supplierChangeOrderDo.getStatus()));return supplierChangeOrderModel;}public static Page<SupplierChangeOrderModel> converterModelPage(Page<SupplierChangeOrderDo> supplierChangeOrderDos) {if (supplierChangeOrderDos == null) {return new Page<SupplierChangeOrderModel>(); // 如果输入是 null,返回一个空的 Page}// 转换数据列表List<SupplierChangeOrderModel> modelList = supplierChangeOrderDos.getRecords().stream().map(ChangeOrderServiceConverter::converterModel).collect(Collectors.toList());// 创建并返回新的 Page<SupplierChangeOrderModel> 对象Page<SupplierChangeOrderModel> page = new Page<>(supplierChangeOrderDos.getCurrent(), supplierChangeOrderDos.getSize(), supplierChangeOrderDos.getTotal());page.setRecords(modelList);return page;}public static SupplierChangeOrderModel converterSupplierToChangeOrderModel(SupplierModel supplierModel) {if (supplierModel == null) {return null;}SupplierChangeOrderModel supplierChangeOrderModel = ChangeOrderMapperConverter.INSTANCE.converterSupplierToChangeOrder(supplierModel);SupplierStatusEnum supplierStatus = supplierModel.getStatus();supplierChangeOrderModel.setAddresses(CollectionHelper.collectNotNullList(supplierModel.getAddresses(), ChangeOrderMapperConverter.INSTANCE::convertAddressesModel));supplierChangeOrderModel.setBanks(CollectionHelper.collectNotNullList(supplierModel.getBanks(), ChangeOrderMapperConverter.INSTANCE::convertBankModel));supplierChangeOrderModel.setContacts(CollectionHelper.collectNotNullList(supplierModel.getContacts(), ChangeOrderMapperConverter.INSTANCE::convertContactModel));SupplierChangeOrderInfoModel supplierChangeOrderInfoModel = ChangeOrderMapperConverter.INSTANCE.convertOderInfoModel(supplierModel.getSupplierInfo());if (ObjectUtils.isEmpty(supplierChangeOrderInfoModel)) {supplierChangeOrderInfoModel=new SupplierChangeOrderInfoModel();supplierChangeOrderInfoModel.setSupplierDataId(supplierModel.getId());}supplierChangeOrderInfoModel.setSupplierStatus(supplierStatus);supplierChangeOrderModel.setChangeOrderInfo(supplierChangeOrderInfoModel);return supplierChangeOrderModel;}public static SupplierChangeOrderModel converterToChangeOrderModel(SupplierChangeOrderDo supplierChangeOrder, SupplierChangeOrderInfo changeOrderInfoDo, List<SupplierChangeOrderAddress> addresses, List<SupplierChangeOrderBank> banks, List<SupplierChangeOrderContacts> contacts) {if (supplierChangeOrder == null) {return null;}SupplierChangeOrderModel supplierChangeOrderModel = ChangeOrderMapperConverter.INSTANCE.doToModel(supplierChangeOrder);supplierChangeOrderModel.setAddresses(CollectionHelper.collectNotNullList(addresses, ChangeOrderMapperConverter.INSTANCE::convertAddressesDoToModel));supplierChangeOrderModel.setBanks(CollectionHelper.collectNotNullList(banks, ChangeOrderMapperConverter.INSTANCE::convertBankDoToModel));supplierChangeOrderModel.setContacts(CollectionHelper.collectNotNullList(contacts, ChangeOrderMapperConverter.INSTANCE::convertContactsDoToModel));supplierChangeOrderModel.setChangeOrderInfo(ChangeOrderMapperConverter.INSTANCE.converterInfoDoToModel(changeOrderInfoDo));return supplierChangeOrderModel;}public static SupplierChangeOrderDo converterModelToDo(SupplierChangeOrderModel supplierChangeOrderModel) {if (supplierChangeOrderModel == null) {return null;}return ChangeOrderMapperConverter.INSTANCE.converterModelToDo(supplierChangeOrderModel);}public static SupplierChangeOrderInfo converterInfoModelToDo(SupplierChangeOrderInfoModel supplierChangeOrderInfoModel) {if (supplierChangeOrderInfoModel == null) {return null;}return ChangeOrderMapperConverter.INSTANCE.converterInfoModelToDo(supplierChangeOrderInfoModel);}public static List<SupplierChangeOrderAddress> converterAddressModelToDoList(List<SupplierChangeOrderAddressModel> supplierChangeOrderAddressList) {if (CollectionUtils.isEmpty(supplierChangeOrderAddressList)) {return Lists.newArrayList();}return supplierChangeOrderAddressList.stream().map(ChangeOrderMapperConverter.INSTANCE::converterAddressModelToDo).collect(Collectors.toList());}public static List<SupplierChangeOrderBank> converterBankModelToDoList(List<SupplierChangeOrderBankModel> supplierChangeOrderBankList) {if (CollectionUtils.isEmpty(supplierChangeOrderBankList)) {return Lists.newArrayList();}return supplierChangeOrderBankList.stream().map(ChangeOrderMapperConverter.INSTANCE::converterBankModelToDo).collect(Collectors.toList());}public static List<SupplierChangeOrderContacts> converterContactsModelToDoList(List<SupplierChangeOrderContactsModel> supplierChangeOrderContactList) {if (CollectionUtils.isEmpty(supplierChangeOrderContactList)) {return Lists.newArrayList();}return supplierChangeOrderContactList.stream().map(ChangeOrderMapperConverter.INSTANCE::converterContactsModel).collect(Collectors.toList());}public static List<SupplierChangeOrderAddressModel> converterChangeOrderAddressList(List<SupplierChangeOrderAddress> addressesList) {if (CollectionUtils.isEmpty(addressesList)) {return Lists.newArrayList();}return addressesList.stream().map(ChangeOrderMapperConverter.INSTANCE::convertAddressesDoToModel).collect(Collectors.toList());}public static List<SupplierChangeOrderAddressModel> converterAddressList(List<SupplierAddressModel> addressesList) {if (CollectionUtils.isEmpty(addressesList)) {return Lists.newArrayList();}return addressesList.stream().map(ChangeOrderMapperConverter.INSTANCE::convertAddressesModel).collect(Collectors.toList());}public static List<SupplierChangeOrderBankModel> converterBankList(List<SupplierBankModel> bankList) {if (CollectionUtils.isEmpty(bankList)) {return Lists.newArrayList();}return bankList.stream().map(ChangeOrderMapperConverter.INSTANCE::convertBankModel).collect(Collectors.toList());}public static List<SupplierChangeOrderContactsModel> converterContactsList(List<SupplierContactsModel> bankList) {if (CollectionUtils.isEmpty(bankList)) {return Lists.newArrayList();}return bankList.stream().map(ChangeOrderMapperConverter.INSTANCE::convertContactModel).collect(Collectors.toList());}public static SupplierChangeOrderInfoModel converterInfoModel(SupplierChangeOrderInfo supplierInfo) {if (supplierInfo == null) {return null;}return ChangeOrderMapperConverter.INSTANCE.converterInfoDoToModel(supplierInfo);}public static List<SupplierChangeOrderContactsModel> converterChangeOrdeContactsList(List<SupplierChangeOrderContacts> contactList) {if (CollectionUtils.isEmpty(contactList)) {return Lists.newArrayList();}return contactList.stream().map(ChangeOrderMapperConverter.INSTANCE::convertContactsDoToModel).collect(Collectors.toList());}public static List<SupplierChangeOrderBankModel> converterChangeOrdeBankList(List<SupplierChangeOrderBank> banks) {if (CollectionUtils.isEmpty(banks)) {return Lists.newArrayList();}return banks.stream().map(ChangeOrderMapperConverter.INSTANCE::convertBankDoToModel).collect(Collectors.toList());}public static List<Long> getAddressDeleteIds(List<SupplierChangeOrderAddressModel> supplierAddressModels, Map<Long, SupplierChangeOrderAddressModel> addressUpdateMap) {// 对比出删除的现场考察数据return CollectionHelper.collectNotNullList(supplierAddressModels, param -> {Long addressId = param.getId();SupplierChangeOrderAddressModel supplierChangeOrderAddressModel = MapHelper.getValue(addressUpdateMap, addressId);if (supplierChangeOrderAddressModel == null) {return addressId;}return null;});}public static List<Long> getBankDeleteIds(List<SupplierChangeOrderBankModel> supplierBankModels, Map<Long, SupplierChangeOrderBankModel> bankUpdateMap) {// 对比出删除的样品检测数据return CollectionHelper.collectNotNullList(supplierBankModels, param -> {Long bankId = param.getId();SupplierChangeOrderBankModel supplierChangeOrderBankModel = MapHelper.getValue(bankUpdateMap, bankId);if (supplierChangeOrderBankModel == null) {return bankId;}return null;});}public static List<Long> getContactsDeleteIds(List<SupplierChangeOrderContactsModel> supplierContactsModels, Map<Long, SupplierChangeOrderContactsModel> contactUpdateMap) {// 对比出删除的资质审查数据return CollectionHelper.collectNotNullList(supplierContactsModels, param -> {Long contactsId = param.getId();SupplierChangeOrderContactsModel supplierChangeOrderContactsModel = MapHelper.getValue(contactUpdateMap, contactsId);if (supplierChangeOrderContactsModel == null) {return contactsId;}return null;});}public static SupplierModel converterChangeOrderToSupplierModel(SupplierChangeOrderModel changeOrderModel) {if (changeOrderModel == null) {return null;}SupplierModel supplierModel = ChangeOrderMapperConverter.INSTANCE.converterChangeOrderToSupplier(changeOrderModel);supplierModel.setStatus(changeOrderModel.getChangeOrderInfo().getSupplierStatus());supplierModel.setAddresses(CollectionHelper.collectNotNullList(changeOrderModel.getAddresses(), ChangeOrderMapperConverter.INSTANCE::convertAddressesToSupplierModel));supplierModel.setBanks(CollectionHelper.collectNotNullList(changeOrderModel.getBanks(), ChangeOrderMapperConverter.INSTANCE::convertBankToSupplierModel));supplierModel.setContacts(CollectionHelper.collectNotNullList(changeOrderModel.getContacts(), ChangeOrderMapperConverter.INSTANCE::convertContactToSupplierModel));supplierModel.setSupplierInfo(ChangeOrderMapperConverter.INSTANCE.convertOderInfoToSupplierModel(changeOrderModel.getChangeOrderInfo()));return supplierModel;}
}

相关文章:

属性拷贝MapStruct

端请求通过VO对象接收&#xff0c;并通过DTO对象进行流转&#xff0c;最后转换成DO对象与数据库DAO层进行交互&#xff0c;反之亦然。 当业务简单的时候&#xff0c;可以通过手动编码getter/setter函数来复制对象属性。但是当业务变的复杂&#xff0c;对象属性变得很多&#x…...

Chromium 添加书签功能浅析c++

1、在点击添加书签时候此UI控制逻辑代码在 chrome\browser\ui\views\bookmarks\bookmark_bar_view.cc chrome\browser\ui\views\bookmarks\bookmark_bar_view.h 可以在此看到完成 移除 按钮逻辑&#xff0c;以及书签监听事件等。。。 // Implementation for BookmarkNodeAdd…...

Spring Cloud Netflix Ribbon 负载均衡详解和案例示范

1. 引言 在传统的集中式架构中&#xff0c;负载均衡器一般是放置在服务器端的&#xff0c;例如 Nginx等。随着微服务架构的兴起&#xff0c;服务实例的数量和部署地点变得更加动态和分布式&#xff0c;这使得在客户端进行负载均衡成为了一种可行且更灵活的方案。Netflix Ribbo…...

Armeria gPRC 高级特性 - 装饰器、无框架请求、阻塞处理器、Nacos集成、负载均衡、rpc异常处理、文档服务......

文章目录 定义一个示例高级特性装饰器概述简单案例多种装饰方式 无框架请求概述使用方式 阻塞任务处理器背景概述多种使用方式 rpc 异常统一处理使用方式更详细的异常信息 Armeria 提供 gRPC 客户端多种调用方式同步调用异步调用使用装饰器 负载均衡简单案例Armeria 提供的所有…...

如何制作一个企业网站,建设网站的基本步骤有哪些?

企业网站是企业的门面和名片&#xff0c;决定网民对企业的第一印象&#xff0c;因此&#xff0c;现在很多公司想做一个属于自己网站&#xff0c;但是不知道怎么做&#xff0c;更不知道从何做起&#xff0c;更别说做成了。为了能够让大家清楚如何做一个企业网站&#xff0c;现在…...

01-python+selenium自动化测试-基础学习

前言 基于python3和selenium3做自动化测试&#xff0c;俗话说&#xff1a;工欲善其事必先利其器&#xff1b;没有金刚钻就不揽那瓷器活&#xff0c;磨刀不误砍柴工&#xff0c;因此你必须会搭建基本的开发环境&#xff0c;掌握python基本的语法和一个IDE来进行开发&#xff0c…...

【redis-05】redis保证和mysql数据一致性

redis系列整体栏目 内容链接地址【一】redis基本数据类型和使用场景https://zhenghuisheng.blog.csdn.net/article/details/142406325【二】redis的持久化机制和原理https://zhenghuisheng.blog.csdn.net/article/details/142441756【三】redis缓存穿透、缓存击穿、缓存雪崩htt…...

写一个登录判断机制py

创建一个简单的登录机制涉及到用户输入的验证和与数据库中存储的凭证的比较。以下是一个使用Python语言和SQLite数据库的示例。这个例子仅用于教学目的&#xff0c;实际应用中应该使用更安全的方法来存储和验证密码&#xff0c;比如使用密码哈希。 首先&#xff0c;你需要安装…...

特征点检测与匹配是计算机视觉中的基础任务之一,广泛应用于图像配准、物体识别、运动估计、三维重建等领域。

特征点检测与匹配是计算机视觉中的基础任务之一&#xff0c;广泛应用于图像配准、物体识别、运动估计、三维重建等领域。下面是一些关键的知识点&#xff1a; 1. 特征点检测 特征点检测的目的是从图像中找到独特的、稳定的点&#xff0c;这些点在图像变化&#xff08;如旋转、…...

python——Echarts现交互式动态可视化

数据展示 20192018201720162015201420132012北京5817.15785.91765430.78755081.264723.864027.16093661.10973314.934天津2410.252106.23972310.35522723.52667.112390.35182079.07161760.0201河北3742.673513.86433233.83322849.872649.182446.61662295.62032084.2825山西234…...

【含开题报告+文档+PPT+源码】基于SSM框架的民宿酒店预定系统的设计与实现

开题报告 随着人们旅游需求的增加&#xff0c;民宿行业呈现出快速发展的趋势。传统的住宿方式逐渐无法满足人们对个性化、舒适、便捷的需求&#xff0c;而民宿作为一种新型的住宿选择&#xff0c;逐渐受到人们的青睐。民宿的特点是具有独特的风格、便捷的地理位置、相对亲近的…...

正确理解协程

import asyncio# 定义一个异步函数&#xff08;协程&#xff09; async def say_after(delay, what):# 等待指定的时间await asyncio.sleep(delay)# 打印消息print(what)# 定义另一个异步函数 async def main():# 同时启动两个协程&#xff0c;并等待这2个协程结束await say_af…...

蒙特卡罗方法 - 采样和蒙特卡罗方法篇

序言 蒙特卡罗&#xff08; Monte Carlo \text{Monte Carlo} Monte Carlo&#xff09;方法&#xff0c;也被称为计算机随机模拟方法&#xff0c;是一种基于“随机数”的计算方法。这一方法源于美国在第二次世界大战期间研制原子弹的“曼哈顿计划”。其核心思想是使用随机数&am…...

论文阅读:InternVL v1.5| How Far Are We to GPT-4V? 通过开源模型缩小与商业多模式模型的差距

论文地址&#xff1a;https://arxiv.org/abs/2404.16821 Demo&#xff1a; https://internvl.opengvlab.com Model&#xff1a;https://huggingface.co/OpenGVLab/InternVL-Chat-V1-5 公开时间&#xff1a;2024年4月29日 InternVL1.5&#xff0c;是一个开源的多模态大型语言模…...

什么是电能表PTB认证

电能表PTB认证是指电能表产品经过德国国家计量研究所&#xff08;Physikalisch-Technische Bundesanstalt&#xff0c;简称PTB&#xff09;的认证和审核过程。PTB是德国联邦政府在计量、物理、材料和测试领域的技术专家和合作伙伴&#xff0c;拥有世界领先的技术水平和专业知识…...

C# 单例模式继承

简介&#xff1a;单例模式是软件工程中最著名的模式之一。从本质上讲&#xff0c;singleton 是一个只允许创建自身的单个实例的类&#xff0c;并且通常提供对该实例的简单访问。最常见的是&#xff0c;单例不允许在创建实例时指定任何参数 - 否则&#xff0c;对实例进行第二次请…...

ESP8266模块(WIFI STM32)

目录 一、介绍 二、传感器原理 1.原理图 2.引脚描述 3.ESP8266基础AT指令介绍 4.ESP8266基础工作模式 三、程序设计 main.c文件 esp8266.h文件 esp8266.c文件 四、实验效果 五、资料获取 项目分享 一、介绍 ESP8266是一款嵌入式系统级芯片&#xff0c;它集成了Wi…...

微信小程序学习实录9:掌握wx.chooseMedia实现多图片文件上传功能(选择图片、预览图片、上传图片)

要实现多图片上传到服务器&#xff0c;需要在小程序前端和PHP后端分别进行相应的设置。 基本流程 微信小程序提供了丰富的API来支持多图片上传功能。在微信小程序中实现多图片的选择、预览以及上传到服务器的功能&#xff1a; 1. 选择图片 使用 wx.chooseImage API 可以让用…...

助动词的分类及其缩略形式

助动词的分类及其缩略形式 1. 助动词 (auxiliary verb)2. 基本助动词 (primary auxiliary)2.1. 基本助动词 be、do 和 have2.2. 实义动词 be、do 和 have 3. 情态助动词 (modal auxiliary)3.1. 情态助动词取代情态动词 4. 半助动词 (semi-auxiliary)4.1. 不能与 it ... that-cl…...

Redis——分布式锁

在一个分布式系统中&#xff0c;只要涉及到多个节点访问同一个公共资源的时候&#xff0c;就需要加锁来实现互斥&#xff0c;从而达到线程安全的问题。 但是呢&#xff0c;分布式系统不同一些&#xff0c;因为分布式系统部署在不同的服务器上&#xff0c;很可能大量的请求打到…...

k8s从入门到放弃之Ingress七层负载

k8s从入门到放弃之Ingress七层负载 在Kubernetes&#xff08;简称K8s&#xff09;中&#xff0c;Ingress是一个API对象&#xff0c;它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress&#xff0c;你可…...

通过Wrangler CLI在worker中创建数据库和表

官方使用文档&#xff1a;Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后&#xff0c;会在本地和远程创建数据库&#xff1a; npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库&#xff1a; 现在&#xff0c;您的Cloudfla…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​&#xff0c;覆盖应用全生命周期测试需求&#xff0c;主要提供五大核心能力&#xff1a; ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

微服务商城-商品微服务

数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...

LLM基础1_语言模型如何处理文本

基于GitHub项目&#xff1a;https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken&#xff1a;OpenAI开发的专业"分词器" torch&#xff1a;Facebook开发的强力计算引擎&#xff0c;相当于超级计算器 理解词嵌入&#xff1a;给词语画"…...

自然语言处理——循环神经网络

自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元&#xff08;GRU&#xff09;长短期记忆神经网络&#xff08;LSTM&#xff09…...

3-11单元格区域边界定位(End属性)学习笔记

返回一个Range 对象&#xff0c;只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意&#xff1a;它移动的位置必须是相连的有内容的单元格…...

蓝桥杯3498 01串的熵

问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798&#xff0c; 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...

华为OD机考-机房布局

import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...