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 }
