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

2024-01-25 22:28

本文主要是介绍简化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>

这篇关于简化java代码:mapstruct + 策略模式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/644806

相关文章

Java中流式并行操作parallelStream的原理和使用方法

《Java中流式并行操作parallelStream的原理和使用方法》本文详细介绍了Java中的并行流(parallelStream)的原理、正确使用方法以及在实际业务中的应用案例,并指出在使用并行流... 目录Java中流式并行操作parallelStream0. 问题的产生1. 什么是parallelS

Java中Redisson 的原理深度解析

《Java中Redisson的原理深度解析》Redisson是一个高性能的Redis客户端,它通过将Redis数据结构映射为Java对象和分布式对象,实现了在Java应用中方便地使用Redis,本文... 目录前言一、核心设计理念二、核心架构与通信层1. 基于 Netty 的异步非阻塞通信2. 编解码器三、

SpringBoot基于注解实现数据库字段回填的完整方案

《SpringBoot基于注解实现数据库字段回填的完整方案》这篇文章主要为大家详细介绍了SpringBoot如何基于注解实现数据库字段回填的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以了解... 目录数据库表pom.XMLRelationFieldRelationFieldMapping基础的一些代

一篇文章彻底搞懂macOS如何决定java环境

《一篇文章彻底搞懂macOS如何决定java环境》MacOS作为一个功能强大的操作系统,为开发者提供了丰富的开发工具和框架,下面:本文主要介绍macOS如何决定java环境的相关资料,文中通过代码... 目录方法一:使用 which命令方法二:使用 Java_home工具(Apple 官方推荐)那问题来了,

Java HashMap的底层实现原理深度解析

《JavaHashMap的底层实现原理深度解析》HashMap基于数组+链表+红黑树结构,通过哈希算法和扩容机制优化性能,负载因子与树化阈值平衡效率,是Java开发必备的高效数据结构,本文给大家介绍... 目录一、概述:HashMap的宏观结构二、核心数据结构解析1. 数组(桶数组)2. 链表节点(Node

Java AOP面向切面编程的概念和实现方式

《JavaAOP面向切面编程的概念和实现方式》AOP是面向切面编程,通过动态代理将横切关注点(如日志、事务)与核心业务逻辑分离,提升代码复用性和可维护性,本文给大家介绍JavaAOP面向切面编程的概... 目录一、AOP 是什么?二、AOP 的核心概念与实现方式核心概念实现方式三、Spring AOP 的关

详解SpringBoot+Ehcache使用示例

《详解SpringBoot+Ehcache使用示例》本文介绍了SpringBoot中配置Ehcache、自定义get/set方式,并实际使用缓存的过程,文中通过示例代码介绍的非常详细,对大家的学习或者... 目录摘要概念内存与磁盘持久化存储:配置灵活性:编码示例引入依赖:配置ehcache.XML文件:配置

Java 虚拟线程的创建与使用深度解析

《Java虚拟线程的创建与使用深度解析》虚拟线程是Java19中以预览特性形式引入,Java21起正式发布的轻量级线程,本文给大家介绍Java虚拟线程的创建与使用,感兴趣的朋友一起看看吧... 目录一、虚拟线程简介1.1 什么是虚拟线程?1.2 为什么需要虚拟线程?二、虚拟线程与平台线程对比代码对比示例:三

Java中的.close()举例详解

《Java中的.close()举例详解》.close()方法只适用于通过window.open()打开的弹出窗口,对于浏览器的主窗口,如果没有得到用户允许是不能关闭的,:本文主要介绍Java中的.... 目录当你遇到以下三种情况时,一定要记得使用 .close():用法作用举例如何判断代码中的 input

前端缓存策略的自解方案全解析

《前端缓存策略的自解方案全解析》缓存从来都是前端的一个痛点,很多前端搞不清楚缓存到底是何物,:本文主要介绍前端缓存的自解方案,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录一、为什么“清缓存”成了技术圈的梗二、先给缓存“把个脉”:浏览器到底缓存了谁?三、设计思路:把“发版”做成“自愈”四、代码