mapstruct个人学习记录

mapstruct核心技术学习

  • 简介
  • 入门案例
    • maven依赖
  • IDEA插件
    • 单一对象转换
      • 测试结果
  • mapping属性
  • Spring注入的方式
    • 测试
  • 集合的映射
    • set类型的映射
    • 测试
    • map类型的映射
      • 测试
    • @MapMapping
      • keyDateFormat
      • valueDateFormat
  • 枚举映射
    • 基础入门

简介

在工作中,我们经常要进行各种对象之间的转换。
PO: persistent object持久对象,对应数据库中的一条
VO: view object表现层对象,最终返回给前端的对象
DTO:data transfer object数据传输对象,如dubbo服务之间的传输的对象
po、vo、dto的详细介绍
如果这些对象的属性名相同还好,可以使用如下工具类赋值
Spring BeanUtils
Cglib BeanCopier
避免使用Apache BeanUtils,性能较差

如果属性名不同呢?如果是将多个PO对象合并成一个VO对象呢?好在有MapStruct,可以帮助我们快速转换
mapstruct官网
mapstruct技术文档

入门案例

maven依赖

 <properties><java.version>1.8</java.version><org.mapstruct.version>1.5.5.Final</org.mapstruct.version>
</properties>
<dependencies><dependency><groupId>org.mapstruct</groupId><artifactId>mapstruct</artifactId><version>${org.mapstruct.version}</version></dependency><dependency><groupId>org.mapstruct</groupId><artifactId>mapstruct-processor</artifactId><version>${org.mapstruct.version}</version></dependency>
</dependencies>        

IDEA插件

IDEA中搜索"MapStruct Support"插件,进行安装,安装成功后重启IDEA。
在这里插入图片描述

单一对象转换

import lombok.Data;
import lombok.experimental.Accessors;@Data
@Accessors(chain = true)
public class CarDTO {private String make;private int seatCount;private String type;
}
import lombok.Data;
import lombok.experimental.Accessors;@Data
@Accessors(chain = true)
public class Car {private String make;private int numberOfSeats;
}
import com.example.demo.dto.CarDTO;
import com.example.demo.po.Car;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;@Mapper
public interface CarMapper {CarMapper instance = Mappers.getMapper(CarMapper.class);/*** 表达式需要自动提示的话,需要安装IDEA插件mapstruct support* @param car* @return*/@Mapping(source = "numberOfSeats",target = "seatCount")@Mapping(target = "type",expression = "java(car.getMake())")CarDTO carToCarDto(Car car);
}
import com.example.demo.dto.CarDTO;
import com.example.demo.mapper.CarMapper;
import com.example.demo.po.Car;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = {DemoApplication.class})
public class ApplicationTest {@Testpublic void test() {CarMapper instance = CarMapper.instance;Car car = new Car();car.setMake("中国").setNumberOfSeats(1000);CarDTO carDTO = instance.carToCarDto(car);System.out.println(carDTO);}
}

测试结果

在这里插入图片描述
项目结构图
在这里插入图片描述
在target文件夹下生成了CarMapperImpl.java

package com.example.demo.mapper;import com.example.demo.dto.CarDTO;
import com.example.demo.po.Car;
import javax.annotation.Generated;@Generated(value = "org.mapstruct.ap.MappingProcessor",date = "2023-11-08T23:35:28+0800",comments = "version: 1.5.5.Final, compiler: javac, environment: Java 1.8.0_131 (Oracle Corporation)"
)
public class CarMapperImpl implements CarMapper {@Overridepublic CarDTO carToCarDto(Car car) {if ( car == null ) {return null;}CarDTO carDTO = new CarDTO();carDTO.setSeatCount( car.getNumberOfSeats() );carDTO.setMake( car.getMake() );carDTO.setType( car.getMake() );return carDTO;}
}

mapping属性

    /*** @Mappings 一组映射关系,值为一个数组,元素为@Mapping* @Mapping 一一对应关系* source:源属性* target:目标属性,赋值的过程是把源属性赋值给目标属性* dateFormat:用于源属性是Date,转换为String* numberFormat:用户数值类型与String类型之间的转* constant: 常量* expression:使用表达式进行属性之间的转换* ignore:忽略某个属性的赋值* qualifiedByName: 自定义的方法赋值* defaultValue:默认值* @defaultExpression 如果源数据没有设置的时候,可以指定相关表达式进行处理* 基本数据类型与包装类可以自动映射* @MappingTaget 用在方法参数的前面,使用此注解,源对象同时也会作为目标对象,用于更新* @InheritConfiguration 指定映射方法* @InheritInverseConfiguration 表示方法继承相应的反向方法的反向配置* @param car 入参* @return 返回结果*/
package com.example.demo.entity;import lombok.Data;
import lombok.experimental.Accessors;@Data
@Accessors(chain = true)
public class CarBrand {private String carBrand;
}
package com.example.demo.entity;import lombok.Data;
import lombok.experimental.Accessors;@Data
@Accessors(chain = true)
public class Brand {private String brandName;}
package com.example.demo.entity;import lombok.Data;
import lombok.experimental.Accessors;@Data
@Accessors(chain = true)
public class CarDto {private String make;private int seatCount;private String type;private CarBrand carBrand;private String date;private String price;private String extral;
}
package com.example.demo.entity;import lombok.Data;
import lombok.experimental.Accessors;import java.math.BigDecimal;
import java.util.Date;@Data
@Accessors(chain = true)
public class Car {private String make;private int numberOfSeats;private Brand brand;private Date date;private BigDecimal price;}
package com.example.demo.entity;import org.mapstruct.*;import static org.mapstruct.MappingConstants.ComponentModel.SPRING;/*** @Mapper 表示该接口作为映射接口,编译时MapStruct处理器的入口* componentModel 主要是指定实现类的类型,一般用到两个* default:默认,可以通过 Mappers.getMapper(Class) 方式获取实例对象* spring:在接口的实现类上自动添加注解 @Component,可通过 @Autowired 方式注入* uses 外部引入的转换类*/
@Mapper(componentModel = SPRING)
public interface CarMapper {/*** @Mappings 一组映射关系,值为一个数组,元素为@Mapping* @Mapping 一一对应关系* source:源属性* target:目标属性,赋值的过程是把源属性赋值给目标属性,当目标属性和源属性一致时候,source和target可以省略不写* dateFormat:用于源属性是Date,转换为String* numberFormat:用户数值类型与String类型之间的转* constant: 常量* expression:使用表达式进行属性之间的转换* ignore:忽略某个属性的赋值* qualifiedByName: 自定义的方法赋值* defaultValue:默认值* @defaultExpression 如果源数据没有设置的时候,可以指定相关表达式进行处理* 基本数据类型与包装类可以自动映射* @MappingTaget 用在方法参数的前面,使用此注解,源对象同时也会作为目标对象,用于更新* @InheritConfiguration 指定映射方法* @InheritInverseConfiguration 表示方法继承相应的反向方法的反向配置* @param car 入参* @return 返回结果*/@Mappings({@Mapping(source = "date",target = "date",dateFormat = "yyyy-MM-dd HH:mm:ss"),@Mapping(source = "price",target = "price",numberFormat = "0.00"),@Mapping(source = "numberOfSeats",target = "seatCount"),@Mapping(target = "type",constant = "hello type"),@Mapping(source = "brand",target = "carBrand",qualifiedByName = {"brand2CarBrandV2"})})CarDto carToCarDtoV2(Car car);/*** @Named 定义类/方法的名称* @param brand* @return*/@Named("brand2CarBrandV2")@Mappings({@Mapping(source = "brandName",target = "carBrand")})CarBrand brand2CarBrandV2(Brand brand);
}
package com.example.demo;import com.example.demo.entity.Brand;
import com.example.demo.entity.Car;
import com.example.demo.entity.CarDto;
import com.example.demo.entity.CarMapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;import java.math.BigDecimal;
import java.util.Date;@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = {DemoApplication.class})
public class CarMapperTest {@Autowiredprivate CarMapper carMapper;@Testpublic void test() {Car car = new Car();car.setMake("from source").setNumberOfSeats(100).setBrand(new Brand().setBrandName("保密")).setPrice(BigDecimal.valueOf(100.12345)).setDate(new Date());CarDto dto = carMapper.carToCarDtoV2(car);System.out.println(dto);}
}

测试结果,输出如下

CarDto(make=from source, seatCount=100, type=hello type, carBrand=CarBrand(carBrand=保密), date=2023-11-11 20:22:49, price=100.12, extral=null)

Spring注入的方式

中声明INSTANCE的方式来进行调用之外,MapStruct也同时支持Spring的依赖注入机制

package com.example.MapStructDemo.dto;import lombok.Data;
import lombok.experimental.Accessors;@Data
@Accessors(chain = true)
public class CarDto {private String manufacturer;private int seatCount;
}
package com.example.MapStructDemo.po;import lombok.Data;
import lombok.experimental.Accessors;@Data
@Accessors(chain = true)
public class Car {private String make;private int numberOfSeats;
}
package com.example.MapStructDemo.mapper;import com.example.MapStructDemo.dto.CarDto;
import com.example.MapStructDemo.po.Car;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;import static org.mapstruct.MappingConstants.ComponentModel.SPRING;/*** @Mapper 只有在接口加上这个注解, MapStruct 才会去实现该接口* @Mapper 里有个 componentModel 属性,主要是指定实现类的类型,一般用到两个* default:默认,可以通过 Mappers.getMapper(Class) 方式获取实例对象* SPRING:在接口的实现类上自动添加注解 @Component,可通过 @Autowired 方式注入*/
@Mapper(componentModel = SPRING)
public interface CarMapper {@Mapping(target = "manufacturer",source = "make")@Mapping(target = "seatCount",source = "numberOfSeats")CarDto carToCarDto(Car car);}

测试

package com.example.MapStructDemo;import com.example.MapStructDemo.dto.CarDto;
import com.example.MapStructDemo.mapper.CarMapper;
import com.example.MapStructDemo.po.Car;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;@SpringBootTest
public class ApplicationTests {@Autowiredprivate CarMapper carMapper;@Testpublic void contextLoads() {Car car = new Car();car.setMake("中国").setNumberOfSeats(1000);CarDto carDto = carMapper.carToCarDto(car);System.out.println("测试结果");System.out.println(carDto);}}

在这里插入图片描述

集合的映射

set类型的映射

package com.example.MapStructDemo.mapper;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import java.util.Set;
import static org.mapstruct.MappingConstants.ComponentModel.SPRING;@Mapper(componentModel = SPRING)
public interface CarMapper {/*** 集合的映射* @param set 入参* @return Set<String>*/Set<String> integerSetToStringSet(Set<Integer> set);
}

CarMapper的实现类CarMapperImpl,会生成如下代码,集合set为null的时候,默认返回null
在这里插入图片描述

测试

package com.example.MapStructDemo;import com.example.MapStructDemo.mapper.CarMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.util.HashSet;
import java.util.Set;@SpringBootTest
public class ApplicationTests {@Autowiredprivate CarMapper carMapper;@Testpublic void test(){Set<Integer> set = new HashSet<>();for (int i=0;i<10;i++){set.add(i);}Set<String> strings = carMapper.integerSetToStringSet(set);System.out.println("集合类型的测试");strings.forEach(System.out::println);}
}

测试结果如下:
在这里插入图片描述

map类型的映射

package com.example.MapStructDemo.mapper;import org.mapstruct.MapMapping;
import org.mapstruct.Mapper;import java.util.Date;
import java.util.Map;import static org.mapstruct.MappingConstants.ComponentModel.SPRING;@Mapper(componentModel = SPRING)
public interface SourceTargetMapper {/*** map类型的映射* @param source 入参* @return Map<String, String>* map中value的值是Date类型的转换为String类型*/@MapMapping(valueDateFormat = "dd.MM.yyyy")Map<String, String> longDateMapToStringStringMap(Map<Long, Date> source);
}

map映射的实现类SourceTargetMapperImpl

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//package com.example.MapStructDemo.mapper;import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import org.springframework.stereotype.Component;@Component
public class SourceTargetMapperImpl implements SourceTargetMapper {public SourceTargetMapperImpl() {}public Map<String, String> longDateMapToStringStringMap(Map<Long, Date> source) {if (source == null) {return null;} else {Map<String, String> map = new LinkedHashMap(Math.max((int)((float)source.size() / 0.75F) + 1, 16));Iterator var3 = source.entrySet().iterator();while(var3.hasNext()) {Map.Entry<Long, Date> entry = (Map.Entry)var3.next();String key = (new DecimalFormat("")).format(entry.getKey());String value = (new SimpleDateFormat("dd.MM.yyyy")).format((Date)entry.getValue());map.put(key, value);}return map;}}
}

测试

package com.example.MapStructDemo;import com.example.MapStructDemo.mapper.SourceTargetMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.time.LocalDate;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;@SpringBootTest
public class SourceTargetMapperTests {@Autowiredprivate SourceTargetMapper sourceTargetMapper;@Testpublic void test() {Map<Long, Date> map = new HashMap<>();map.put(1L, new Date());System.out.println(map);System.out.println("map类型的映射");Map<String, String> result = sourceTargetMapper.longDateMapToStringStringMap(map);System.out.println(result);}
}

测试结果
在这里插入图片描述

@MapMapping

配置的是Map<String,String>Map<Long,Date>之间的转换

keyDateFormat

mapkey的类型是从DateString类型的转换

valueDateFormat

map中value的类型从DateString类型的转换

枚举映射

基础入门

package com.example.MapStructDemo.enums;import lombok.AllArgsConstructor;
import lombok.Getter;@AllArgsConstructor
@Getter
public enum OrderType {EXTRA,STANDARD,NORMAL
}
package com.example.MapStructDemo.enums;import lombok.AllArgsConstructor;
import lombok.Getter;@AllArgsConstructor
@Getter
public enum ExternalOrderType {SPECIAL,DEFAULT
}
package com.example.MapStructDemo.mapper;import com.example.MapStructDemo.enums.ExternalOrderType;
import com.example.MapStructDemo.enums.OrderType;
import org.mapstruct.Mapper;
import org.mapstruct.ValueMapping;
import org.mapstruct.ValueMappings;import static org.mapstruct.MappingConstants.ComponentModel.SPRING;@Mapper(componentModel = SPRING)
public interface OrderMapper {/*** 枚举类型映射* @param orderType 入参* @return ExternalOrderType*/@ValueMappings({@ValueMapping(target = "SPECIAL",source = "EXTRA"),@ValueMapping(target = "DEFAULT",source = "STANDARD"),@ValueMapping(target = "DEFAULT",source = "NORMAL")})ExternalOrderType orderTypeToExternalOrderType(OrderType orderType);
}

OrderMapper的实现类

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//package com.example.MapStructDemo.mapper;import com.example.MapStructDemo.enums.ExternalOrderType;
import com.example.MapStructDemo.enums.OrderType;
import org.springframework.stereotype.Component;@Component
public class OrderMapperImpl implements OrderMapper {public OrderMapperImpl() {}public ExternalOrderType orderTypeToExternalOrderType(OrderType orderType) {if (orderType == null) {return null;} else {ExternalOrderType externalOrderType;switch (orderType) {case EXTRA:externalOrderType = ExternalOrderType.SPECIAL;break;case STANDARD:externalOrderType = ExternalOrderType.DEFAULT;break;case NORMAL:externalOrderType = ExternalOrderType.DEFAULT;break;default:throw new IllegalArgumentException("Unexpected enum constant: " + orderType);}return externalOrderType;}}
}
package com.example.MapStructDemo;import com.example.MapStructDemo.enums.ExternalOrderType;
import com.example.MapStructDemo.enums.OrderType;
import com.example.MapStructDemo.mapper.OrderMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;@SpringBootTest
public class OrderMapperTest {@Autowiredprivate OrderMapper orderMapper;@Testpublic void test1() {System.out.println("测试结果");OrderType orderType = OrderType.EXTRA;ExternalOrderType externalOrderType = orderMapper.orderTypeToExternalOrderType(orderType);System.out.println(externalOrderType);}
}

测试结果
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/212906.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【rabbitMQ】rabbitMQ用户,虚拟机地址(添加,修改,删除操作)

rabbitMQ的下载&#xff0c;安装和配置 https://blog.csdn.net/m0_67930426/article/details/134892759?spm1001.2014.3001.5502 rabbitMQ控制台模拟收发消息 https://blog.csdn.net/m0_67930426/article/details/134904365?spm1001.2014.3001.5502 目录 用户 添加用户…

MyBatis 四大核心组件之 StatementHandler 源码解析

&#x1f680; 作者主页&#xff1a; 有来技术 &#x1f525; 开源项目&#xff1a; youlai-mall &#x1f343; vue3-element-admin &#x1f343; youlai-boot &#x1f33a; 仓库主页&#xff1a; Gitee &#x1f4ab; Github &#x1f4ab; GitCode &#x1f496; 欢迎点赞…

CPU设计——Triumphcore——MP_work版本

该版本用作系统寄存器的实现&#xff0c;M/S/U状态的实现与切换&#xff0c;以及load/store的虚实地址转换 设计指标 2023.12.8 2023.12.9 不实现mideleg和medeleg&#xff0c;因此一旦出现异常&#xff0c;直接切换至M态&#xff0c; 调试记录 到存储区中取PTE要额外至少…

airserver mac 7.27官方破解版2024最新安装激活图文教程

airserver mac 7.27官方破解版是一款好用的airplay投屏工具&#xff0c;可以轻松将ios荧幕镜像&#xff08;airplay&#xff09;至mac上&#xff0c;在mac平台上实现视频、音频、幻灯片等文件资源的接收及投放演示操作&#xff0c;解决iphone或ipad的屏幕录像问题&#xff0c;满…

Linux C/C++ 从内存转储中恢复64位ELF可执行文件

ELF&#xff08;Executable and Linking Format&#xff09;是一种对象文件的格式&#xff0c;它主要用于定义ELF&#xff08;Executable and Linking Format&#xff09;是一种对象文件的格式&#xff0c;它主要用于定义不同类型的对象文件中的内容以及它们的存储方式。一个EL…

作业调度算法(含详细计算过程)和进程调度算法浅析

一.作业调度 作业调度算法需要知道以下公式 周转时间完成时间 - 到达时间 带权周转时间周转时间/运行时间 注&#xff1a;带权周转时间越大&#xff0c;作业&#xff08;或进程&#xff09;越短&#xff1b;带权周转时间越小&#xff0c;作业&#xff08;或进程&#xff09;越…

Redis生产实战-Redis集群故障探测以及降级方案设计

Redis 集群故障探测 在生产环境中&#xff0c;如果 Redis 集群崩溃了&#xff0c;那么会导致大量的请求打到数据库中&#xff0c;会导致整个系统都崩溃&#xff0c;所以系统需要可以识别缓存故障&#xff0c;限流保护数据库&#xff0c;并且启动接口的降级机制 降级方案设计 …

超过 50% 的内部攻击使用特权提升漏洞

特权提升漏洞是企业内部人员在网络上进行未经授权的活动时最常见的漏洞&#xff0c;无论是出于恶意目的还是以危险的方式下载有风险的工具。 Crowdstrike 根据 2021 年 1 月至 2023 年 4 月期间收集的数据发布的一份报告显示&#xff0c;内部威胁正在上升&#xff0c;而利用权…

基于SSM的剧本杀预约系统的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

【第三届】:“玄铁杯”RISC-V应用创新大赛(基于yolov5和OpenCv算法 — 智能警戒哨兵)

文章目录 前言 一、智能警戒哨兵是什么&#xff1f; 二、方案流程图 三、硬件方案 四、软件方案 五、演示视频链接 总结 前言 最近参加了第三届“玄铁杯”RISC-V应用创新大赛&#xff0c;我的创意题目是基于 yolov5和OpenCv算法 — 智能警戒哨兵 先介绍一下比赛&#xf…

docker容器配置MySQL与远程连接设置(纯步骤)

以下为ubuntu20.04环境&#xff0c;默认已安装docker&#xff0c;没安装的网上随便找个教程就好了 拉去mysql镜像 docker pull mysql这样是默认拉取最新的版本latest 这样是指定版本拉取 docker pull mysql:5.7查看已安装的mysql镜像 docker images通过镜像生成容器 docke…

大数据HCIE成神之路之数据预处理(1)——缺失值处理

缺失值处理 1.1 删除1.1.1 实验任务1.1.1.1 实验背景1.1.1.2 实验目标1.1.1.3 实验数据解析 1.1.2 实验思路1.1.3 实验操作步骤1.1.4 结果验证 1.2 填充1.2.1 实验任务1.2.1.1 实验背景1.2.1.2 实验目标1.2.1.3 实验数据解析 1.2.2 实验思路1.2.3 实验操作步骤1.2.4 结果验证 1…

【STM32】ADC模数转换器

1 ADC简介 ADC&#xff08;Analog-Digital Converter&#xff09;模拟-数字转换器 ADC可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量&#xff0c;建立模拟电路到数字电路的桥梁 STM32是数字电路&#xff0c;只有高低电平&#xff0c;没有几V电压的概念&#xff…

安装 DevEco Studio 后不能用本地 Node.js 打开

安装 DevEco Studio 后第一次打开时&#xff0c;不能用本地 Node.js 打开 答&#xff1a;因为本地 Node.js 文件夹名字中有空格 Node.js路径只能包含字母、数字、“。”、“_”、“-”、“:”和“V” 解决方法&#xff1a; 1.修改文件夹名称 2.重新下载 注意&#xff1a;找一…

1-3算法基础-标准模板库STL

1.pair pair用于存储两个不同类型的值&#xff08;元素&#xff09;作为一个单元。它通常用于将两个值捆绑在一起&#xff0c;以便一起传递或返回。 #include <iostream> #include <utility> using namespace std; int main() {pair<int, string> person m…

ThingWorx 9.2 Windows安装

参考官方文档安装配置 1 PostgreSQL 13.X 2 Java, Apache Tomcat, and ThingWorx PTC Help Center 参考这里安装 数据库 C:\ThingworxPostgresqlStorage 设置为任何人可以full control 数据库初始化 pgadmin4 创建用户twadmin并记录口令password Admin Userpostgres Thin…

漏刻有时百度地图API实战开发(9)Echarts使用bmap.js实现轨迹动画效果

Bmap.js是Echarts和百度地图相结合开发的一款JavaScript API&#xff0c;它可以帮助用户在web应用中获取包括地图中心点、地图缩放级别、地图当前视野范围、地图上标注点等在内的地图信息&#xff0c;并且支持在地图上添加控件&#xff0c;提供包括智能路线规划、智能导航(驾车…

C# WPF上位机开发(通讯协议的编写)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 作为上位机&#xff0c;它很重要的一个部分就是需要和外面的设备进行数据沟通的。很多时候&#xff0c;也就是在这个沟通的过程当中&#xff0c;上…

PyQt下使用OpenCV实现人脸检测与识别

背景&#xff1a; 一 数字图像处理与识别警务应用模型 基于前期所学知识&#xff0c;与公安实践相结合&#xff0c;综合设计数字图像处理与识别警务应用模型,从下列4个研究课题中选择2个进行实验实现&#xff1a;图像增强与复原、人脸检测与识别、虹膜内外圆检测与分割、车牌…

Html转PDF,前端JS实现Html页面导出PDF(html2canvas+jspdf)

Html转PDF&#xff0c;前端JS实现Html页面导出PDF&#xff08;html2canvasjspdf&#xff09; 文章目录 Html转PDF&#xff0c;前端JS实现Html页面导出PDF&#xff08;html2canvasjspdf&#xff09;一、背景介绍二、疑问三、所使用技术html2canvasjspdf 四、展示开始1、效果展示…