springboot~ObjectMapper~dto到entity的自(zi)動賦值
實體與Dto自動賦值
在開發的(de)(de)過(guo)程中,實體(ti)之間相互賦(fu)值(zhi)是很正常的(de)(de)事(shi),但(dan)是我們(men)一般(ban)的(de)(de)方法都(dou)通過(guo)set和(he)get方法來(lai)進行(xing)的(de)(de),如(ru)果要(yao)賦(fu)值(zhi)的(de)(de)字(zi)段少那(nei)(nei)還行(xing),但(dan)是需要(yao)賦(fu)值(zhi)的(de)(de)字(zi)段超過(guo)10個(ge),那(nei)(nei)就是個(ge)災難,你會(hui)看(kan)到(dao)整屏代(dai)碼(ma)中全是set和(he)get方法。
- 兩個實體屬性字段幾乎完全相同
- 兩個字體有部分字段相同
- 源實體只有部分字段賦值,目標實體有完整的值
第一種情況
對于第1點來說,我們用到最多的就是entity和dto之間的轉換了,這個我們可以使用Spring的工具類BeanUtils來解決,這里要注意的一點是,第一個參數是源,第二個參數是目標。
import org.springframework.beans.BeanUtils;
BeanUtils.copyProperties(origin, target);
第二種情況
但是對于第2點來說,就沒有那么簡單了,再使用BeanUtils已經不能滿足我們的需要了。
我們可(ke)以使用jackson的(de)ObjectMapper
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import com.jd.fastjson.JSON;
ObjectMapper objectMapper = new ObjectMapper();
//配置該objectMapper在反序列化時,忽略目標對象沒有的屬性。凡是使用該objectMapper反序列化時,都會擁有該特性。
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
//讀入需要更新的目標實體
ObjectReader objectReader = objectMapper.readerForUpdating(target);
//將源實體的值賦值到目標實體上
objectReader.readValue(JSON.toJSONString(source));
我們(men)總(zong)結(jie)一下objectMapper的過濾(lv)參數:
/*
通過該方法對mapper對象進行設置,所有序列化的對象都將按改規則進行系列化
Include.Include.ALWAYS 默認
Include.NON_DEFAULT 屬性為默認值不序列化
Include.NON_EMPTY 屬性為 空(“”) 或者為 NULL 都不序列化
Include.NON_NULL 屬性為NULL 不序列化
*/
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_DEFAULT);
String outJson = objectMapper.writeValueAsString(productDetail);
//上面代碼里,outJson的值將會過濾掉只有默認值的屬性
第三種情況
本情況主要對于從dto到entity轉換(huan)過程中出(chu)現 ,比(bi)如一(yi)個put操作,前(qian)端可能只修改(gai)某幾個屬性,而在后端處理時(shi)也只希(xi)望處理這(zhe)(zhe)幾個被賦值(zhi)的屬性,這(zhe)(zhe)時(shi)我們(men)使用(yong)下面的方法:
@RequestMapping(value = "/{id}", method = RequestMethod.PUT)
public HttpEntity update(@PathVariable int id, @RequestBody ProductDetail productDetail)
throws IOException {
ProductDetail existing = repository.findById(id).get();
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_DEFAULT);
String outJson = objectMapper.writeValueAsString(productDetail);
ObjectReader objectReader = objectMapper.readerForUpdating(existing);
objectReader.readValue(outJson);
repository.save(existing);
return new ResponseEntity<>(existing, HttpStatus.ACCEPTED);
}
集合轉集合
String requestData="[]";
List<ProductDetail> list = objectMapper.readValue(requestData,
new TypeReference<List<ProductDetail>>() {
});
repository.saveAll(list);
通過objectMapper的使用,確實讓我們少寫很多重復的代(dai)碼。