简化java代码:mapstruct + 策略模式

目录

目的

准备

注意

相同类型-属性名不同

实体类 

映射

使用

验证-查看实现类

测试

不同类型(策略模式)

 实体类

映射

工具类

使用:对象拷贝

验证-查看实现类

测试

使用:集合拷贝

测试

策略模式说明

准备-依赖


目的

简化 BeanUtils.copyProperties 属性对拷代码,自动生成空判断,结合策略模式自定义转换

集合对拷:一行代码就能完成以前 先new,再 for循环,再add的多行代码,而且也不用判空

准备

这里我将开发中经常用到的全部依赖都列举出来(若下载不下来依赖,将settings.xml替换成我博客存档的那一份),此处为了不影响观看,放在文章末尾处。

注意

写好转换之后,maven 记得 clean install,查看一下生成的实现类有没有问题

实现类在  target 里面,若target没有,执行下列操作

相同类型-属性名不同

将 下面 Doctor 中的  i1  s1  分别转给 DoctorDto 中的  i2  s2

实体类 

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Doctor {private int id;private String name;String s1;int i1;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class DoctorDto {private int id;private String name;private String s2;private int i2;
}

映射

@Mapper(componentModel = "spring")
public interface BeanConvert {BeanConvert INSTANCE = Mappers.getMapper(BeanConvert.class);/*** 不一致的属性映射*/@Mappings({@Mapping(target = "i2", source = "i1"),@Mapping(target = "s2", source = "s1")})DoctorDto toDto(Doctor doctor);
}

使用

    @GetMapping("/test")public DoctorDto get() {Doctor doctor = new Doctor();doctor.setId(1);doctor.setName("张三");doctor.setI1(1);doctor.setS1("1");return BeanConvert.INSTANCE.toDto(doctor);}

验证-查看实现类

clean install  重启

测试

可以看到 i1,s1中的值已经过来了

不同类型(策略模式)

 实体类

将下面 Sku2 中的  Long date  Integer code  分别转给 SkuDTO2 中的  Date date  String value

 一个是时间戳转换,一个是枚举转换

@Data
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE)
public class Sku2 {Long skuId;String skuCode;String skuPrice;List<String> nameList;Long date;Integer code;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE)
public class SkuDTO2 {Long skuId;String skuCode;String skuPrice;List<String> nameList;Date date;String value;
}

映射

uses 定义了两个策略,一个负责转换时间戳,一个负责转换枚举

@Mapper(componentModel = "spring", uses = {TimeConvertStrategy.class, EnumConvertStrategy.class})
public interface BeanConvert {/*** 策略模式测试*/@Mapping(target = "value", source = "code")SkuDTO2 domain2Dto(Sku2 sku2);}
@Component
public class EnumConvertStrategy {public String convert(Integer code) {return MyEnum.getByCode(code);}}
@Component
public class TimeConvertStrategy {public Date date2TimeStamp(Long timeStamp) {if (timeStamp == null) {return null;}return new Date(timeStamp);}}
public enum MyEnum {A(1,"哈哈"),B(2,"呵呵");private final Integer code;private final String msg;MyEnum(int code, String msg) {this.code = code;this.msg = msg;}public Integer getCode() {return code;}public String getMsg() {return msg;}public static String getByCode(Integer code) {if (code == null) {return null;}for (MyEnum value : MyEnum.values()) {if (value.getCode().equals(code)) {return value.getMsg();}}return null;}}

工具类

这里使用工具类,主要是辅助容器中的bean初始化的,包括我们定义的策略的初始化

/*** ApplicationContextAware 接口可以让 Bean 获取到 ApplicationContext 对象* 通过这个对象,可以获取 Spring 容器中的其他 Bean实例 或一些组件*/
@Component
public class ConvertSupport implements ApplicationContextAware {private static BeanConvert beanConvert;/*** 启动的时候,直接获取到 beanConvert 的实例*/@Overridepublic void setApplicationContext(ApplicationContext context) throws BeansException {// 这里如果没有执行,说明没有注入容器,但是我有了@Component注解,说明其未生效,主启动类@ComponentScan指定一下if (beanConvert == null) {beanConvert = context.getBean(BeanConvert.class);System.out.println("执行过这里");}}/*** 列表转换*/public static <I, O> List<O> copyList(List<I> inputList, BiFunction<BeanConvert, I, O> function) {if (CollectionUtils.isEmpty(inputList)) {return Collections.emptyList();}List<O> resultList = new ArrayList<>(inputList.size());for (I input : inputList) {resultList.add(function.apply(beanConvert, input));}return resultList;}/*** bean to bean*/public static <I, O> O castBean(I input, BiFunction<BeanConvert, I, O> function) {return function.apply(beanConvert, input);}}

使用:对象拷贝

    @GetMapping("/test2")public SkuDTO2 get2() {Sku2 sku2 = new Sku2();sku2.setSkuId(1L);sku2.setSkuCode("2");sku2.setNameList(Lists.newArrayList("测", "试"));sku2.setDate(new Date().getTime());sku2.setCode(1);return ConvertSupport.castBean(sku2, BeanConvert::domain2Dto);}

验证-查看实现类

clean install  重启

测试

使用:集合拷贝

    @GetMapping("/test3")public List<DoctorDto> get3() {List<Doctor> list = Lists.newArrayList(new Doctor(1, "张三", "1", 1),new Doctor(2, "李四", "2", 2),new Doctor(3, "王五", "3", 3));return ConvertSupport.copyList(list, BeanConvert::toDto);}

此后,一行代码就能完成以前 先new,再 for循环,再add的多行代码,而且也不用判空

测试

策略模式说明

上面使用的是用来处理不同类型,平常去除 if else 的使用方式:

先定义两个 策略,和上面类似,spring管理后,通过策略内部判断决定怎么走,方法再抽象出一层

/*** 策略1*/
@Component
public class Situation1 implements Situation {private static final String value = "用户传过来的值为1";/*** 判断进入哪个策略(if)*/@Overridepublic Boolean judge(String val) {return value.equals(val);}/*** 逻辑处理*/@Overridepublic int logic(int a, int b) {return a + b;}
}
/*** 策略2*/
@Component
public class Situation2 implements Situation {private static final String value = "用户传过来的值为2";/*** 判断进入哪个策略(if)*/@Overridepublic Boolean judge(String val) {return value.equals(val);}/*** 逻辑处理*/@Overridepublic int logic(int a, int b) {return a - b;}
}
public interface Situation {/*** 判断进入哪个策略(if)*/Boolean judge(String val);/*** 逻辑处理*/int logic(int a, int b);
}
@RestController
public class StrategyTest {@Autowiredprivate ApplicationContext applicationContext;@GetMapping("/test/st")public void test() {String value = "用户传过来的值为2";Map<String, Situation> beans = applicationContext.getBeansOfType(Situation.class);beans.forEach((k, Strategy) -> {// 判断用户传过来的值,从而决定进入哪个策略if (Strategy.judge(value)) {int num = Strategy.logic(8, 2);System.out.println(num);}});}
}

准备-依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.6.1</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.mytest</groupId><artifactId>springboot-demo</artifactId><version>0.0.1-SNAPSHOT</version><name>springboot-demo</name><description>springboot-demo</description><properties><org.mapstruct.version>1.5.0.RC1</org.mapstruct.version><org.projectlombok.version>1.18.22</org.projectlombok.version><lombok-mapstruct-binding.version>0.2.0</lombok-mapstruct-binding.version><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--HuTool为我们提供的一些便捷工具。--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>4.1.14</version></dependency><!--Valid--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId><version>2.3.2.RELEASE</version></dependency><!--自定义注解--><dependency><groupId>javax.validation</groupId><artifactId>validation-api</artifactId><version>2.0.1.Final</version></dependency><!-- 定时任务 --><dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz</artifactId><exclusions><exclusion><groupId>com.mchange</groupId><artifactId>c3p0</artifactId></exclusion></exclusions></dependency><!-- 解析客户端操作系统、浏览器等 --><dependency><groupId>eu.bitwalker</groupId><artifactId>UserAgentUtils</artifactId><version>1.21</version></dependency><!-- pagehelper 分页插件 注意 pagehelper 和 spring-boot-starter-parent 版本,容易出现循环依赖 一般通过加@Lazy解决,这里通过版本号解决--><dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId><version>1.4.1</version></dependency><!--HttpUtils需要的所有依赖--><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.15</version></dependency><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency><!--mybatisplus--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.1</version></dependency><!--DateTime 需要的依赖,由于没有版本号管理,如果不写version,上面有一处会爆红--><dependency><groupId>joda-time</groupId><artifactId>joda-time</artifactId><version>2.9.4</version></dependency><!--代码生成器--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>3.4.1</version></dependency><!--velocity模板引擎--><dependency><groupId>org.apache.velocity</groupId><artifactId>velocity-engine-core</artifactId><version>2.3</version></dependency><!-- easyexcel依赖 --><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.0.5</version></dependency><dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-base</artifactId><version>4.3.0</version></dependency><dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-web</artifactId><version>4.3.0</version></dependency><dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-annotation</artifactId><version>4.3.0</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.16</version></dependency><!--Lists.partition 需要的依赖--><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>25.1-jre</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><exclusions><exclusion><groupId>io.lettuce</groupId><artifactId>lettuce-core</artifactId></exclusion></exclusions></dependency><!--        &lt;!&ndash;jedis,redis客户端&ndash;&gt;--><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId></dependency><!--        &lt;!&ndash;使用redisson作为所有分布式锁,分布式对象等功能框架,也可以使用springboot的方式,就不用自己@Configuration了&ndash;&gt;--><dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.13.3</version></dependency><!--mysql驱动--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.17</version></dependency><dependency><groupId>org.mapstruct</groupId><artifactId>mapstruct</artifactId><version>${org.mapstruct.version}</version></dependency><!-- 特别注意 mapstruct 和 lombok 的顺序,顺序出问题,实现类就不映射了 --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>${org.projectlombok.version}</version><scope>provided</scope></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.10</version></dependency><!--CollectionUtils依赖--><dependency><groupId>commons-collections</groupId><artifactId>commons-collections</artifactId><version>3.2.2</version></dependency><dependency><groupId>com.google.code.google-collections</groupId><artifactId>google-collect</artifactId><version>snapshot-20080530</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency><!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12 -->
<!--        <dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId></dependency>--><dependency><groupId>com.alibaba</groupId><artifactId>transmittable-thread-local</artifactId><version>2.11.5</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>21.0</version></dependency><dependency><groupId>javax.persistence</groupId><artifactId>persistence-api</artifactId><version>1.0</version></dependency><!--注意:3.0.0 版本   http://localhost:8081/swagger-ui.html   页面可能登陆不上去--><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.9.2</version></dependency><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>2.9.2</version></dependency></dependencies><!-- 特别注意 mapstruct 和 lombok 的顺序,顺序出问题,实现类就不映射了 --><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version><configuration><source>1.8</source><target>1.8</target><annotationProcessorPaths><path><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>${org.projectlombok.version}</version></path><!-- This is needed when using Lombok 1.18.16 and above --><path><groupId>org.projectlombok</groupId><artifactId>lombok-mapstruct-binding</artifactId><version>${lombok-mapstruct-binding.version}</version></path><!-- Mapstruct should follow the lombok path(s) --><path><groupId>org.mapstruct</groupId><artifactId>mapstruct-processor</artifactId><version>${org.mapstruct.version}</version></path></annotationProcessorPaths></configuration></plugin></plugins><resources><resource><directory>src/main/java</directory><includes><include>**/*.properties</include><include>**/*.xml</include><include>**/*.yml</include></includes><filtering>false</filtering></resource><resource><directory>src/main/resources</directory><includes><include>**/*.properties</include><include>**/*.xml</include><include>**/*.yml</include></includes><filtering>false</filtering></resource></resources></build></project>

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

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

相关文章

【RL】(task4)DDPG算法、TD3算法

note 文章目录 note一、DDPG算法二、TD3算法时间安排Reference 一、DDPG算法 DDPG&#xff08;Deep Deterministic Policy Gradient&#xff09;算法 DDPG算法是一种结合了深度学习和确定性策略梯度的算法。它主要解决的是在连续动作空间中&#xff0c;智能体&#xff08;age…

Axios取消请求:AbortController

AbortController AbortController() 构造函数创建了一个新的 AbortController 实例。MDN官网给出了一个利用AbortController取消下载视频的例子。 核心逻辑是&#xff1a;利用AbortController接口的只读属性signal标记fetch请求&#xff1b;然后在需要取消请求的时候&#xff0…

python算法与数据结构---单调栈与实践

单调栈 单调栈是一个栈&#xff0c;里面的元素的大小按照它们所在栈的位置&#xff0c;满足一定的单调性&#xff1b; 性质&#xff1a; 单调递减栈能找到左边第一个比当前元素大的元素&#xff1b;单调递增栈能找到左边第一个比当前元素小的元素&#xff1b; 应用场景 一般用…

Ubuntu22.04安装4090显卡驱动

1、安装完Ubuntu系统&#xff0c;打完所有补丁后再进行后续操作 2、下载系统所需要的版本的NV显卡驱动&#xff0c;本次由于使用CUDA12.1&#xff0c;故选用的驱动版本为NVIDIA-Linux-x86_64-530.41.03.run 3、卸载NV驱动&#xff08;只是保险起见&#xff0c;并不是一定会卸…

微信小程序登录获取手机号教程(超详细)

1. 背景介绍&#xff1a; 在我们开发微信小程序时&#xff0c;登录时&#xff0c;需要获取用户手机号作为唯一标识&#xff0c;下面我介绍一下获取手机号的教程。 本篇文章介绍后端获取方法&#xff1a; 前端工作 后端工作 前端 新建Page页面&#xff0c;在xxx.wxml中加入…

Shell脚本④循环语句for、while、until

目录 一.for 1. 九九乘法表 2.求1到10奇数和 3.累计加到100 &#xff08;1&#xff09;方法一 &#xff08;2&#xff09;方法2 二.while 1.猜价格小游戏 2.累加到100的方法三 三.until循环 1.累加到100方法四 四.嵌套循环 五.循环语句中break、exit和continue 1…

如何把标书制作精美

标书&#xff0c;作为一种正式的文件&#xff0c;其制作需要我们花费心思。精美、专业的标书不仅能准确传达信息&#xff0c;还能给阅读者留下深刻印象。那么&#xff0c;如何才能制作出精美的标书呢&#xff1f;接下来&#xff0c;我会从五个方面为您详细解析。 一、内容至上 …

RabbitMQ简单模式和工作模式

RabbitMQ 是一个消息队列中间件&#xff0c;用于在分布式系统中进行消息传递。在 RabbitMQ 中&#xff0c;有几种工作模式&#xff0c;其中简单模式和工作模式是其中两种基本的模式之一。 简单模式&#xff08;Simple Mode&#xff09;&#xff1a; 在简单模式中&#xff0c;有…

前端 - 视觉呈现技术

前言 不知道大家有没有在微信中看见过&#xff0c;那种特别炫酷的h5&#xff0c;从事前端工作的伙伴看着这么炫酷的效果&#xff0c;又不知如何实现。本文就带你走进前端高阶视觉特效。 特效 视觉呈现做的最熟的&#xff0c;我觉得应是视频了&#xff0c;每个视频工具都能根…

使用封装函数判断素数

#include<stdio.h> int judgeprime(int n) //判断是不是素数 { int i 0; int j 1; //默认素数&#xff0c;判断之后若不是素数&#xff0c;返回j0&#xff0c;否则返回j1 for (i 2; i < n; i) {if (n%i 0) //有其他共因数&#xff0c;不为素数{j 0;break;} }…

26.删除排序数组中的重复项(力扣LeetCode)

26.删除排序数组中的重复项 题目描述 给你一个 非严格递增排列 的数组 nums &#xff0c;请你 原地 删除重复出现的元素&#xff0c;使每个元素 只出现一次 &#xff0c;返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。 考虑 nu…

v-if 导致 elementui 表单校验失效问题解决

问题 在使用 elementui 表单的过程中&#xff0c;某些表单项需要通过 v-if 来判断是否展示&#xff0c;但是这些表单项出现了检验失效的问题。 解决方法 1、给需要 v-if 判断的表单项添加 key 值 <el-form ref"form" :model"form"><el-form-i…

【Unity学习笔记】创建人物控制器

人物左右移动 1 导入模型&#xff0c;如果没有模型&#xff0c;则在 窗口-资产商店-free sample 找到人物模型 2 在 窗口-包管理中 导入自己的模型 3 在自己的资产文件夹中找到Prefabs Base HighQuality MaleFree1模型&#xff0c;导入到场景中 4 Assets中创建C#项目 写入如下…

四、MySQL之DML DQL

有关数据表的DML操作 INSERT 针对于数据的插入DELETE 针对于数据的删除UPDATE 针对于数据的修改 4.1 INSERT语句 INSERT INTO 表名 [(列名1,列名2,....)] VALUES (值1&#xff0c;值2&#xff0c;...); 默认情况下&#xff0c;一条插入命令只针对一行进行影响INSERT INTO 表…

Leetcode:二分搜索树层次遍历

题目&#xff1a; 给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09;。 示例&#xff1a; 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;[[3],[9,…

使用阿里云的oss对象存储服务实现图片上传(前端vue后端java详解)

一&#xff1a;前期准备&#xff1a; 1.1&#xff1a;注册阿里云账号&#xff0c;开启对象存储oss功能&#xff0c;创建一个bucket&#xff08;百度教程多的是&#xff0c;跟着创建一个就行&#xff0c;创建时注意存储类型是标准存储&#xff0c;读写权限是公共读&#xff09;…

《吐血整理》高级系列教程-吃透Fiddler抓包教程(24)-Fiddler如何优雅地在正式和测试环境之间来回切换-中篇

1.简介 在开发或者测试的过程中&#xff0c;由于项目环境比较多&#xff0c;往往需要来来回回地反复切换&#xff0c;那么如何优雅地切换呢&#xff1f;宏哥今天介绍几种方法供小伙伴或者童鞋们进行参考。 2.实际工作场景 2.1问题场景 &#xff08;1&#xff09;已发布线上…

YOLOv8改进 | Conv篇 | 利用DualConv二次创新C2f提出一种轻量化结构(轻量化创新)

一、本文介绍 本文给大家带来的改进机制是利用DualConv改进C2f提出一种轻量化的C2f,DualConv是一种创新的卷积网络结构,旨在构建轻量级的深度神经网络。它通过结合33和11的卷积核处理相同的输入特征映射通道,优化了信息处理和特征提取。DualConv利用组卷积技术高效排列卷积…

2024美赛数学建模D题思路模型代码论文

2024美赛数学建模各题思路模型代码&#xff1a;开赛后第一时间更新&#xff0c;更新见文末 一、2023题目重述 Homer是棒球运动中的术语&#xff0c;是非正式的美式英语单词。令人惊讶的是&#xff0c;Homer&#xff08;本垒打&#xff09;在剑桥词典网站的搜索次数超过79000次…

JavaScript基础之输入输出与变量常量详解

输入和输出 输出和输入也可理解为人和计算机的交互&#xff0c;用户通过键盘、鼠标等向计算机输入信息&#xff0c;计算机处理后再展示结果给用户&#xff0c;这便是一次输入和输出的过程。 举例说明&#xff1a;如按键盘上的方向键&#xff0c;向上/下键可以滚动页面&#x…