在spring項(xiàng)目中,有多種不同的O,DTO 、DO、VO等等,不同層使用不同的O。在不同層之間傳輸時(shí)可能會(huì)進(jìn)行不同O之間的轉(zhuǎn)化。所以寫對(duì)象之間的轉(zhuǎn)化的代碼是有必要,但又無(wú)聊的,特別是當(dāng)對(duì)象涉及到特別多的屬性。所以牛人們開發(fā)出自動(dòng)生成set和get的插件:generateAllSetter。使用起來(lái)也是比較簡(jiǎn)單的,例如:現(xiàn)在有兩個(gè)Bean,BeanVO和BeanDTO屬性是一致的,都有三個(gè)String類型的屬性,變量名相同。
(以將DTO轉(zhuǎn)VO為例)自動(dòng)生成代碼步驟就是:首先構(gòu)建一個(gè)如下的函數(shù):
private BeanVO toBeanVo(BeanDTO beanDTO) {
}
函數(shù)返回類型是BeanVO,函數(shù)入?yún)⑹荁eanDTO,接著使用組合按鍵: Alt + Enter ,會(huì)彈出來(lái)下面的選項(xiàng):

接著選中就會(huì)自動(dòng)生成代碼:

當(dāng)對(duì)象屬性特別多的時(shí)候且公司要求手寫不能使用對(duì)象拷貝工具類的時(shí)候,這個(gè)插件的價(jià)值就體現(xiàn)出來(lái)了~
當(dāng)公司允許使用對(duì)象拷貝工具類時(shí),為了代碼的簡(jiǎn)潔美化,工具類也是不錯(cuò)的。以spring的BeanUtils為例:
上述方式可以直接改為:
BeanUtils.copyProperties(beanVO, beanDTO);
確實(shí)挺方便的,但這里有一個(gè)坑,當(dāng)beanDTO拷貝到beanVO時(shí),如果beanDTO的某個(gè)屬性是null,且beanVO中也有這個(gè)屬性時(shí),無(wú)論beanVO這個(gè)屬性是否有值,都會(huì)被設(shè)置為null。
以下舉例:

a對(duì)象的address一開始拷貝到c對(duì)象的,第一次輸出也是正常有值的。b對(duì)象的address是null,在將b凱貝到c對(duì)象時(shí),將原來(lái)的值給設(shè)置為b中address了,所以第二次輸出是null。
來(lái)打斷點(diǎn)看一下:斷點(diǎn)處:BeanUtils.copyProperties(b, c);

可以看到整個(gè)拷貝的步驟是,首先獲取C所有的屬性,對(duì)于每一個(gè)屬性都去B中檢索,如果存在則將b對(duì)象中這個(gè)屬性的值,通過(guò)c的set方法寫入到c對(duì)象中。
解決上述問(wèn)題,可以通過(guò)先將a拷貝給b,接著再將b拷貝給c,就不會(huì)出現(xiàn)null覆蓋原有的不為null的屬性了。見圖

當(dāng)然也可以改寫這個(gè)方法,判斷b中的屬性不為null時(shí)再執(zhí)行invoke方法,寫入到c對(duì)象。
