BeanCopier copy
参考: BeanCopier copy
使用:
org.springframework.cglib.beans.BeanCopier
BeanCopier是用于在两个bean之间进行属性拷贝的。BeanCopier支持两种方式:
1、一种是不使用Converter的方式,仅对两个bean间属性名和类型完全相同的变量进行拷贝;
2、另一种则引入Converter,可以对某些特定属性值进行特殊操作。
Teacher类
import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; @Data @Builder @AllArgsConstructor @NoArgsConstructor public class Teacher { Integer id; public String name; private Integer gender; }
UserDO类
import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import java.math.BigDecimal; import java.util.Date; @Data @Builder @NoArgsConstructor @AllArgsConstructor public class UserDO { private Integer id; protected String name; // 余额 BigDecimal balance; Teacher teacher; public String pwd; public Date createTime; }
UserDTO类
import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; @Data @Builder @NoArgsConstructor @AllArgsConstructor public class UserDTO { // 类中定义,必须为包装类型,这里只是为了演示效果 private int id; protected String name; // 余额 String balance; Teacher teacher; public String otherMember; public String createTime; }
测试类
import org.junit.Test; import org.springframework.cglib.beans.BeanCopier; import java.math.BigDecimal; import java.util.Date; public class SpringBeanCopierTest { @Test public void test01() { UserDO userDO = this.getUserDO(); System.out.println(userDO); // UserDO(id=1, name=zhangsan, balance=10.24, teacher=Teacher(id=1, name=teacher1, gender=1), pwd=111111, createTime=Fri Jun 09 16:57:59 CST 2023) // false不使用转换器 BeanCopier copier = BeanCopier.create(UserDO.class, UserDTO.class, false); UserDTO userDTO = new UserDTO(); copier.copy(userDO, userDTO, null); System.out.println(userDTO); // UserDTO(id=0, name=zhangsan, balance=null, teacher=Teacher(id=1, name=teacher1, gender=1), otherMember=null, createTime=null) userDO.getTeacher().setName("teacher2"); // BeanCopier也存在浅拷贝问题 System.out.println(userDO); System.out.println(userDTO); // UserDO(id=1, name=zhangsan, balance=10.24, teacher=Teacher(id=1, name=teacher2, gender=1), pwd=111111, createTime=Fri Jun 09 16:57:59 CST 2023) // UserDTO(id=0, name=zhangsan, balance=null, teacher=Teacher(id=1, name=teacher2, gender=1), otherMember=null, createTime=null) } @Test public void test02() { UserDO userDO = this.getUserDO(); System.out.println(userDO); // UserDO(id=1, name=zhangsan, balance=10.24, teacher=Teacher(id=1, name=teacher1, gender=1), pwd=111111, createTime=Fri Jun 09 16:58:47 CST 2023) // true使用转换器 BeanCopier copier = BeanCopier.create(UserDO.class, UserDTO.class, true); UserDTO userDTO = new UserDTO(); copier.copy(userDO, userDTO, new UserDOToDTOConverter()); System.out.println(userDTO); // UserDTO(id=1, name=zhangsan, balance=10.24, teacher=Teacher(id=1, name=teacher1, gender=1), otherMember=null, createTime=2023-06-09 16:58:47) userDO.getTeacher().setName("teacher2"); // BeanCopier也存在浅拷贝问题 System.out.println(userDO); System.out.println(userDTO); // UserDO(id=1, name=zhangsan, balance=10.24, teacher=Teacher(id=1, name=teacher2, gender=1), pwd=111111, createTime=Fri Jun 09 16:58:47 CST 2023) // UserDTO(id=1, name=zhangsan, balance=10.24, teacher=Teacher(id=1, name=teacher2, gender=1), otherMember=null, createTime=2023-06-09 16:58:47) } private UserDO getUserDO() { Teacher teacher = Teacher.builder().id(1).name("teacher1").gender(1).build(); BigDecimal balance = BigDecimal.valueOf(10.24); UserDO userDO = UserDO.builder().id(1).name("zhangsan").balance(balance).teacher(teacher).pwd("111111").createTime(new Date()).build(); return userDO; } }
一 test01()不使用Converter
通过结果发现:UserDO的int类型的属性, 无法拷贝到UserDTO的Integer。.
即:BeanCopier 只拷贝名称和类型都相同的属性。
即使源类型是原始类型(int, short和char等),目标类型是其包装类型(Integer, Short和Character等),或反之:都不会被拷贝。
二 test02()使用Converter
1、一旦使用Converter,BeanCopier只使用Converter定义的规则去拷贝属性,所以在convert()方法中要考虑所有的属性;
2、毫无疑问,使用Converter会使对象拷贝速度变慢。
三 总结
当源类和目标类的属性名称、类型都相同,拷贝没问题。
当源对象和目标对象的属性名称相同、类型不同,那么名称相同而类型不同的属性不会被拷贝。注意,原始类型(int,short,char)和 他们的包装类型,在这里都被当成了不同类型,因此不会被拷贝。
源类或目标类的setter比getter少,拷贝没问题,此时setter多余,但是不会报错。
源类和目标类有相同的属性(两者的getter都存在),但是目标类的setter不存在,此时会抛出NullPointerException。
加缓存可以提升拷贝速度。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端
2017-06-09 简单的Spring Web工程跳转且传参Demo