1. 程式人生 > >【Java】使用BeanUtils的copyProperties含過濾屬性引數(ignoreProperties)方法的應用

【Java】使用BeanUtils的copyProperties含過濾屬性引數(ignoreProperties)方法的應用

問題

需求:
來源於更新資料的一個介面,要求可以修改類中某一些欄位的值,可以僅修改一部分,沒有修改的欄位預設為不修改。

例中使用了一個檢視層的包裝物件vo,包含了需要更新的目標底層實體po的一個擴充套件子類(假設這個物件就是poi),和一些其他的無關屬性。從前端獲取到已經改好資料的vo後,需要儲存已經更新的po。


思路

使用BeanUtils.copyProperties(source, target, ignoreProperties)這個方法,將源的屬性,過濾掉一部分屬性名,複製到目標上

ignoreProperties的宣告型別是String… ignoreProperties

為獲取一個能得到屬性欄位名的陣列,需要用反射機制

過程

  1. 新建一個po物件,使用copyProperties複製poi已有值的屬性到po裡
  2. 設計一個方法獲取不為空的欄位名陣列,供過濾功能的呼叫
  3. 再使用copyProperties的過濾過載方法,將原po複製到新po

反射獲取欄位名的實現

目標是獲取不為空的欄位

/**
 * 用反射機制來得到vo中itemsCustom的不為空的屬性
 * @param objClass 為目標的Class物件,呼叫時為實體類的Class物件,並不是vo
 * @param vo
 * @return
 * @throws ClassNotFoundException 
 */
private String[] getProperties(Class objClass,ItemsQueryVo vo) throws ClassNotFoundException { //得到ItemsCustom的class類 ItemsCustom obj = vo.getItemsCustom(); List<String> properties = new ArrayList<>(); //遍歷欄位 try { //使用getDeclaredFields()方法而不是getFields()的原因是 //該方法明確的只需要匹配objClass類的欄位, //不使用obj.getClass()的原因也是如此,因為obj的類繼承自objClass的類
for(Field field: objClass.getDeclaredFields()) { //使其可以訪問private field.setAccessible(true); //如果欄位不為空 if(field.get(obj)!=null) properties.add(field.getName()); } }catch (Exception e) { /* * 如果獲取出了錯,return null的方法相當於 * 源的所有欄位都是空的,目標在外部會被完全覆蓋掉,這次更新相當於無效了 */ return null; } //轉陣列 String[] propers = new String[properties.size()]; return properties.toArray(propers); }

上段程式碼就實現了過程中的第二步

利用上述程式碼的簡單方法可以寫更多類似且更有通用性的工具