java DTO对象与PO对象的相互转换
2018-09-27 10:27:50
前言:
在实际开发中往往需要DTO对象与PO对象的相互转换;
先说说什么是VO、DTO、DO、PO对象吧,
概念:
VO(View Object):视图对象,用于展示层,它的作用是把某个指定页面(或组件)的所有数据封装起来。
DTO(Data Transfer Object):数据传输对象,这个概念来源于J2EE的设计模式,原来的目的是为了EJB的分布式应用提供粗粒度的数据实体,以减少分布式调用的次数,从而提高分布式调用的性能和降低网络负载,但在这里,我泛指用于展示层与服务层之间的数据传输对象。
DO(Domain Object):领域对象,就是从现实世界中抽象出来的有形或无形的业务实体。
PO(Persistent Object):持久化对象,它跟持久层(通常是关系型数据库)的数据结构形成一一对应的映射关系,如果持久层是关系型数据库,那么,数据表中的每个字段(或若干个)就对应PO的一个(或若干个)属性。
下面看个例子:
PO对象Student:
1 /** 2 * @author libo 3 * @date 2018年9月20日 下午8:44:33 4 */ 5 public class Student { 6 7 private Integer id; 8 private String name; 9 private Integer age; 10 private String address; 11 12 public Integer getId() { 13 return id; 14 } 15 public void setId(Integer id) { 16 this.id = id; 17 } 18 public String getName() { 19 return name; 20 } 21 public void setName(String name) { 22 this.name = name; 23 } 24 public Integer getAge() { 25 return age; 26 } 27 public void setAge(Integer age) { 28 this.age = age; 29 } 30 public String getAddress() { 31 return address; 32 } 33 public void setAddress(String address) { 34 this.address = address; 35 } 36 @Override 37 public String toString() { 38 return "Student [id=" + id + ", name=" + name + ", age=" + age + ", address=" + address + "]"; 39 } 40 41 42 }
DTO对象StudentDTO:
1 /** 2 * @author libo 3 * @date 2018年9月20日 下午8:45:56 4 */ 5 public class StudentDTO extends Student{ 6 7 private Integer starAge; 8 private Integer endAge; 9 10 public Integer getStarAge() { 11 return starAge; 12 } 13 public void setStarAge(Integer starAge) { 14 this.starAge = starAge; 15 } 16 public Integer getEndAge() { 17 return endAge; 18 } 19 public void setEndAge(Integer endAge) { 20 this.endAge = endAge; 21 } 22 @Override 23 public String toString() { 24 return "StudentDTO [starAge=" + starAge + ", endAge=" + endAge + "]"+super.toString(); 25 } 26 27 28 }
相信这已经知道了什么是DTO、PO对象了,现在言归正传,通过反射实现相互转换。也就是共有的属性但类型不同的相互转换。赋值给相同属性名的属性中去。
上代码:这里是可以相互转换的,第一个转第二个无论是否DTO
1 import java.lang.reflect.Field; 2 import java.lang.reflect.Method; 3 import java.util.Arrays; 4 import org.junit.Test; 5 6 /** 7 * 通过反射将Po对象转DTO对象 8 * 9 * @author libo 10 * @date 2018年9月20日 下午6:40:07 11 */ 12 public class PoToDTO { 13 14 /** 15 * 将po对象的属性值赋值给dto对象相同属性名的属性 16 * 此方法能将第一个转第二个无论是否DTO 17 * @param po 赋值的对象 18 * @param dto 被赋值的对象 19 * @return 20 * @throws Exception 21 */ 22 public Object poToDto(Object po, Object dto) throws Exception { 23 Class poClass = po.getClass(); 24 Class dtoClass = dto.getClass(); 25 // 取得po对象的所有属性 26 Field[] poFields = poClass.getDeclaredFields(); 27 //取父类的所有属性 28 Field[] superPoFields = poClass.getSuperclass().getDeclaredFields(); 29 //合并数组 30 poFields = (Field[]) mergeArray(poFields,superPoFields); 31 32 // 遍历拼接dto的set方法字段表示 33 for (Field f : poFields) { 34 String fieldName = f.getName(); 35 //取得当前get,set字符串表达形式 36 String dtoSetMethodName = "set" + firstToBig(fieldName); 37 String poGetMethodName = "get"+firstToBig(fieldName); 38 39 //System.out.println(fieldName + "=====" + dtoSetMethodName); 40 // 取得DTO对象的set方法 41 Method dtoSetMethod=null; 42 try { 43 dtoSetMethod = dtoClass.getMethod(dtoSetMethodName, f.getType()); 44 }catch (NoSuchMethodException e) {//如果不存在此方法跳过, 45 continue; 46 } 47 //取得Po对象的get方法 48 Method poGetMethod = poClass.getMethod(poGetMethodName, null); 49 // 将po对象的属性值set到dto对象中去 50 dtoSetMethod.invoke(dto, poGetMethod.invoke(po, null)); 51 } 52 return dto; 53 54 } 55 56 /** 57 * 合并数组 58 * @param a 59 * @param b 60 * @return 61 */ 62 public Object[] mergeArray(Object[] a,Object[] b) { 63 Object[] c = Arrays.copyOf(a, a.length+b.length); 64 System.arraycopy(b, 0, c, a.length, b.length); 65 return c; 66 } 67 68 /** 69 * 首字母大写 70 * 71 * @param fieldName 72 * @return 73 */ 74 public String firstToBig(String fieldName) { 75 if (fieldName != null && fieldName != "") { 76 fieldName = fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1); 77 } 78 return fieldName; 79 } 80 81 @Test 82 public void test() { 83 Student stu = new Student(); 84 stu.setId(1); 85 stu.setName("李波"); 86 stu.setAge(22); 87 stu.setAddress("郴州"); 88 89 StudentDTO stuDto = new StudentDTO(); 90 System.out.println("之前===="+stuDto); 91 try { 92 stuDto = (StudentDTO) poToDto(stu, stuDto); 93 System.out.println("之后===="+stuDto); 94 } catch (Exception e) { 95 e.printStackTrace(); 96 } 97 } 98 99 @Test//测试将dto转po 100 public void test2() { 101 StudentDTO stuDTO = new StudentDTO(); 102 stuDTO.setId(1); 103 stuDTO.setName("李波"); 104 stuDTO.setAge(22); 105 stuDTO.setAddress("郴州"); 106 107 Student stu = new Student(); 108 Student ss = stuDTO; 109 System.out.println("之前===="+stu); 110 try { 111 stu = (Student) poToDto(stuDTO, stu); 112 System.out.println("之后===="+stu); 113 } catch (Exception e) { 114 e.printStackTrace(); 115 } 116 } 117 }