java model转换_告别set和get,两大利器轻松搞定model转换

场景一:一般我们遇到需要新建model,常规做法就是创建一个类,老老实实的定义好model中的所有属性,一般来说属性对应的set方法和get方法都是少不了的,有时候还需要toString甚至equals和hashCode方法。

现在的IDE已经很成熟了,一般不会手写set和get方法,采用IDE自带的快捷方式自动生成居多。如下图所示

f31b335b815e24d870d22cfa2f1d1a16.gif

该方式相对手写方法来说,效率已经有了很大的提升,但还是有进一步的提升空间(下文会介绍)。而且该种方式维护性较差,当需要修改某个属性名称或者属性类型时,对应的set和get方法以及toString都需要调整。

场景二:大部分时候,我们都是基于当前流行的微服务架构和SSM(Spring+Spring MVC + Mybatis)框架进行开发,这时候我个人经常遇到一个问题就是model的转换问题。

不同层会有不同的model,比如DAO层的model,service层的model,对外API接口的model,还有更上层的controller层的model以及提供给前端的View model。

为了能够是接口正常调用,我们不得不处理这些model的转换,没有一个称手的工具,我们只能手写转换类,通过一个又一个的set和get方法来完成model的转换。

有时候,我们在测试接口的时候发现有些属性没有值,调试半天才发现,是因为其中一个属性忘记写set方法了。我们明知道这些工作并不需要太多的思考,但是却不得不小心翼翼的对待。

那么,是否有更加优雅的处理方式,请看下文介绍

Lombok

这是一个插件,能够很好的解决场景一中的难题

下载安装

我用的>Plugins中找到相应的插件安装并重启即可。

e8eb37b0d43f03ac35ba7480933cff8e.png

该插件的实现已经放在github上,有兴趣可以到https://github.com/mplushnikov/lombok-intellij-plugin查看

lombok使用

添加jar包依赖

在你需要的项目的pom文件中添加如下的依赖

org.projectlomboklombok1.16.18编写model

package com.jackie.wowjava.best.practice.java.orika.model;import java.util.Date;public class AuthorDTO { private String name; private Date birthday;}添加需要的注解

Lombok可以通过注解的方式实现你需要添加的方法,比如你需要添加这些属性对应的set方法,那么只要在model类上添加注解@Setter即可,相应的,如果需要get方法添加@Getter。

此外还有@ToString,@NoArgsConstructor,@AllArgsConstructor等方便使用的注解。

事实上,我们真的只需要这样添加注解的方式,就能够实现轻松调用set和get方法的需要。这样,以后如果model的属性有改变,我们只需要直接改相应的属性即可,不再需要做任何一点多余的操作。

将注解还原为具体方法

Lombok为我们提供可以将对应注解还原为对应方法的功能。

点击Refactor->Delombok选择想还原的方法即可

648ccc0a046b4550aa8df60aeee92268.gif

是不是很好用?

Orika

Orika是一个简单快速的model拷贝框架。

Orika使用

添加jar包依赖

在需要使用的项目的pom文件中添加如下依赖

ma.glasnost.orikaorika-core1.5.2创建两个需要转换的model

BookEntity

package com.jackie.wowjava.best.practice.java.orika.model;import lombok.AllArgsConstructor;import lombok.Getter;import lombok.NoArgsConstructor;import lombok.Setter;import java.util.Date;@Setter@Getter@AllArgsConstructor@NoArgsConstructorpublic class BookEntity { private String bookName; private String authorName; private Date authorBirthday; private String bookInformation; private Integer type;}BookDTO

package com.jackie.wowjava.best.practice.java.orika.model;import lombok.Getter;import lombok.Setter;@Setter@Getterpublic class BookDTO { private String bookName; private AuthorDTO author; private BookType bookType; private BookInfo bookInfo;}备注:这里的AuthorDTO、BookType和BookInfo如下

package com.jackie.wowjava.best.practice.java.orika.model;import lombok.*;import java.util.Date;@Setter@Getter@ToString@NoArgsConstructor@AllArgsConstructorpublic class AuthorDTO { private String name; private Date birthday;}package com.jackie.wowjava.best.practice.java.orika.model;public enum BookType { NOVEL(1), ESSAY(2); private int value; BookType(int value) { this.value = value; } public static BookType getBookType(int value) { BookType bookType = null; switch (value) { case 1: bookType = NOVEL; break; case 2: bookType = ESSAY; break; default: break; } return bookType; } public int getValue() { return value; }}package com.jackie.wowjava.best.practice.java.orika.model;import lombok.Getter;import lombok.Setter;@Setter@Getterpublic class BookInfo { private String ISBN; private int page;}你没看错,就是BookDTO和BookEntity这两个model,需要相互转换,Orika可以帮你搞定,具体看下面是如何实现的。

model转换

我们看到两个model中包含了多种情况

属性名称完全一样的,比如bookName一个属性对应一个对象的,BookDTO中的AuthorDTO对应BookEntity中的authorName以及authorBirthday枚举类型的,比如BookEntity的type和BookDTO的BookTypeJSON类型的,比如BookEntity的bookInformation和BookDTO的bookInfo1、属性名称完全一样的属性拷贝

新建测试类OrikaTest

package com.jackie.wowjava.best.practice.java.orika;import com.alibaba.fastjson.JSON;import com.jackie.wowjava.best.practice.java.orika.model.BookDTO;import com.jackie.wowjava.best.practice.java.orika.model.BookEntity;import com.jackie.wowjava.best.practice.java.orika.model.BookInfo;import com.jackie.wowjava.best.practice.java.orika.model.BookType;import ma.glasnost.orika.MapperFactory;import ma.glasnost.orika.MappingContext;import ma.glasnost.orika.converter.BidirectionalConverter;import ma.glasnost.orika.impl.DefaultMapperFactory;import ma.glasnost.orika.metadata.Type;import java.time.LocalDate;import java.time.Month;import java.time.ZoneId;import java.util.Date;public class OrikaTest { private static final MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build(); public static void main(String[] args) { BookEntity bookEntity = new BookEntity( "银河系漫游指南", "道格拉斯·亚当斯", Date.from(LocalDate.of(1952, Month.MARCH, 11).atStartOfDay(ZoneId.systemDefault()).toInstant()), "{\"ISBN\": \"9787532754687\", \n \"page\": 279\n }", 1); BookDTO bookDTO = mapperFactory.getMapperFacade().map(bookEntity, BookDTO.class); System.out.println(JSON.toJSONString(bookDTO)); }}运行结果如下

{"bookName":"银河系漫游指南"}没错,只有名称相同的属性被转换了。

从代码来看,我们不需要做任何特殊化处理就能做到这一点,因为Orika默认就是按照名称相同就拷贝进行处理的。

2、一个属性对应一个对象的属性拷贝

这里我们是想BookDTO中的AuthorDTO对应BookEntity中的authorName以及authorBirthday。

我们只需要添加如下代码即可实现。

mapperFactory.classMap(BookDTO.class, BookEntity.class) .field("author.name", "authorName") .field("author.birthday", "authorBirthday") .byDefault() .register();运行结果如下

{"author":{"birthday":-562060800000,"name":"道格拉斯·亚当斯"},"bookName":"银河系漫游指南"}3、枚举类型的属性拷贝

这时候我们需要新建一个转换器并注册到mapperFactory上。

注册转换器代码如下

mapperFactory.getConverterFactory().registerConverter("bookTypeConvert", new BidirectionalConverter() { @Override public Integer convertTo(BookType bookType, Type type, MappingContext mappingContext) { return bookType.getValue(); } @Override public BookType convertFrom(Integer value, Type type, MappingContext mappingContext) { return BookType.getBookType(value); }});注册转换器代码如下

mapperFactory.classMap(BookDTO.class, BookEntity.class) .field("author.name", "authorName") .field("author.birthday", "authorBirthday") .fieldMap("bookType", "type").converter("bookTypeConvert").add() .byDefault() .register();运行结果如下:

{"author":{"birthday":-562060800000,"name":"道格拉斯·亚当斯"},"bookName":"银河系漫游指南","bookType":"NOVEL"}4、JSON类型的属性转换

该属性的转换原理和上述的枚举类型转换相同,需要创建转换器并注册使用

mapperFactory.getConverterFactory().registerConverter("bookInfoConvert", new BidirectionalConverter() { @Override public String convertTo(BookInfo bookInfo, Type type, MappingContext mappingContext) { return JSON.toJSONString(bookInfo); } @Override public BookInfo convertFrom(String s, Type type, MappingContext mappingContext) { return JSON.parseObject(s, BookInfo.class); }});mapperFactory.classMap(BookDTO.class, BookEntity.class) .field("author.name", "authorName") .field("author.birthday", "authorBirthday") .fieldMap("bookType", "type").converter("bookTypeConvert").add() .fieldMap("bookInfo", "bookInformation").converter("bookInfoConvert").add() .byDefault() .register();运行结果如下

{"author":{"birthday":-562060800000,"name":"道格拉斯·亚当斯"},"bookInfo":{"iSBN":"9787532754687","page":279},"bookName":"银河系漫游指南","bookType":"NOVEL"}是不是很神奇?

总结

相信有了这两大神奇Lombok和Orika,基本上实现了和set和get的真正告别。

项目地址:https://github.com/DMinerJackie/rome

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值