(六)泛型-泛型應用之不同實體間同名屬性的自動賦值-BeanUtils 的使用

前言

在 Java 中,爲了更好的實踐分層思想,會把會區分 VO-展示層實體,DTO-數據傳輸層實體,DO-業務層主體,PO-持久層實體等等。儘管他們名字不同,功能也有所不同,但是對於同一個業務主體來說,其相關的實體屬性都是大同小異的,這個時候我們可以使用 get/set 方法來操作不過實在是一種下策。本文介紹 BeanUtils 工具類的使用,也是泛型實踐的一個例子。

BeanUtils 不光存在於 Spring

本文介紹的 BeanUtils 是取自 Spring-beans 包中的工具方法,但是並非只有 Spring 爲我們提供了這種功能的工具類

apache

apache 基金會也爲我們提供了具有類似功能的工具類。下面是 apache 提供的工具類的 Maven 依賴,其具體使用本文不會涉及,感興趣讀者可以自己研究一下。

<dependency>
    <groupId>commons-beanutils</groupId>
    <artifactId>commons-beanutils</artifactId>
    <version>1.9.3</version>
</dependency>
cglib

cglib 也爲我們提供了類似的功能

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>4.3.0.RELEASE</version>
</dependency>
BeanCopier beanCopier=
BeanCopier.create(source.getClass(), target.getClass(), false);
beanCopier.copy(source, target, null);
Spring 提供的 BeanUtils 用法舉例
Maven 依賴

本文 Spring 版本爲 4.3.0.RELEASE

 <dependency>    
      <groupId>org.springframework</groupId>    
      <artifactId>spring-beans</artifactId>    
      <version>4.3.0.RELEASE</version>    
  </dependency>    
工具類路徑

本文是 泛型使用的舉例,所以強烈建議讀者看一下源碼是怎麼實現的

org.springframework.beans.BeanUtils
源實體-一個模擬VO
/**
 * 模擬來自前端的實體
 * @author jecket
 *
 */
public class SourceVO {

    private String userName;
    private String passWord;
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public String getPassWord() {
        return passWord;
    }
    public void setPassWord(String passWord) {
        this.passWord = passWord;
    }
    @Override
    public String toString() {
        return "SourceVO [userName=" + userName + ", passWord=" + passWord
                + "]";
    }

}
目標實體-一個模擬DO
/**
 * 模擬後臺對應數據庫的實體
 * @author Jecket
 *
 */
public class TargetEntity {
    private String userName;
    private int age;
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "TargetEntity [userName=" + userName + ", age=" + age + "]";
    }

}
測試調用

測試了兩種調用方法,一種是所有同名屬性的值都會賦值給目標實體,一種是排除指定屬性剩餘的同名屬性纔會賦值給目標實體。

import org.junit.Test;
import org.springframework.beans.BeanUtils;

/**
 * 測試 Spring 中 BeanUtils 中
 * 具有相同屬性名稱的實體類間的屬性值賦值 方法
 * 
 * 直白的說,就是免去了手動get,set 方法,
 * 自動將源實體與目標實體同名屬性的值賦值給目標實體的同名屬性
 * @author WuJieJecket
 *
 */
public class SpringBeanUtilsTest {

    @Test
    public void testCopyProperties(){
        //實例化 SourceVO 並賦值
        SourceVO source=new SourceVO();
        source.setUserName("jecket");
        source.setPassWord("******");

        //實例化接受數據的實體
        TargetEntity target1=new TargetEntity();
        TargetEntity target2=new TargetEntity();

        //使用 Spring 中 BeanUtils.CopyProperties 方法將同名屬性值賦值給另一個實體

        //但凡同名的都賦值
        BeanUtils.copyProperties(source, target1);
        System.out.println("方式一:同名屬性全部賦值,source賦值給target1");
        System.out.println("source:"+source.toString());
        System.out.println("target1:"+target1.toString());


        //指定某些屬性不賦值,其餘但凡同名的都賦值
        BeanUtils.copyProperties(source, target2,null,"userName","passWord");
        System.out.println("方式二:排除 userName,passWord 屬性,其餘同名屬性全部賦值,source賦值給target2");
        System.out.println("source:"+source.toString());
        System.out.println("target2:"+target2.toString());

    }
測試方法運行結果
方式一:同名屬性全部賦值,source賦值給target1
source:SourceVO [userName=jecket, passWord=******]
target1:TargetEntity [userName=jecket, age=0]
方式二:排除 userName,passWord 屬性,其餘同名屬性全部賦值,source賦值給target2
source:SourceVO [userName=jecket, passWord=******]
target2:TargetEntity [userName=null, age=0]
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章