首先快速解釋一下。假設我們有一個方法,它接受一個 Student 物件和一個 Id 作為屬性,并用給定的 Id 更新 student 和包含在傳遞物件中的資訊。到目前為止,我找到的最簡單的解決方案如下:
- 我們搜索我們的存盤庫,尋找我們想要更新的學生。
- 如果我們找到它,我們就會使用 setter 來設定新值。
public void updateStudent(Long id, Student newStudent) {
Student studentToBeUpdated = studentRepo
.findStudentById(id)
.orElseThrow(() ->
new UserNotFoundException("Student with id " id " was not found"));
studentToBeUpdated.setFirstName(newStudent.getFirstName());
studentToBeUpdated.setLastName(newStudent.getLastName());
studentToBeUpdated.setEmail(newStudent.getEmail());
}
那么,干得好,我們可以回家了,對嗎?好吧,現在假設我們的專案增長了很多,我們必須向我們的 Student 類添加 20 個以上的屬性。突然間,我們必須手動更新此方法以及執行類似操作的任何其他方法。不好。此外,我們剛剛創建了一些不好的樣板代碼。
我真正在尋找的是一種無需考慮我們的 Student 類具有多少屬性或這些屬性是什么的方法,即使它們本身是列舉、陣列甚至其他物件。我想要的是這樣的:
studentToBeUpdated.replace(newStudent);
這是可能的還是只是我的一廂情愿?下一個最好的事情可能是創建一個可以自己完成所有這些事情的方法,但這仍然不是一個完美的解決方案,因為每次類屬性更改時都必須對其進行編輯。
uj5u.com熱心網友回復:
對于兩個 Java 物件之間的映射,您可以使用MapStruct 之類的東西,也可以撰寫自己的映射器,本質上是將樣板代碼提取到單獨的類/服務中。
如果您決定創建自己的映射器,您可以使用反射,也可以使用setter方法或構建器模式(Lombok@Builder也可以幫助避免為構建器模式撰寫樣板)。
...現在假設我們的專案增長了很多,我們必須向我們的 Student 類添加 20 多個屬性。突然間,我們必須手動更新此方法以及執行類似操作的任何其他方法。
當然,您的物體以及您的資料庫的欄位/列數量可能會增加,但是如果您提取不同類中的所有映射和轉換,這通常不會有什么大不了的。在大多數情況下,您無論如何都必須更新欄位的子集。
uj5u.com熱心網友回復:
使用傳統方式,它很羅嗦,但我們可以對復制屬性充滿信心。
public Student copyFrom(Student student)
public void copyFrom(Student student)
其他方式,使用反射來復制值......但我們有時會遇到一些奇怪的問題......對于復雜的物件,例如 Map/List 和其他結構。使用時請小心......這是我在我的專案中使用的當前簽名。
public void copyFrom(Object src, List<String> excludes) {
final List<String> excFields = excludes;
ReflectionUtils.doWithFields(src.getClass(), fieldCallback-> {});
....
}
這里有一些與反射有關的基本方法。我使用了 spring 內置的 ReflectionUtils,你可以自己寫一個或使用其他庫...
Field field= ReflectionUtils.findField(cls, fieldName);
Method m = ReflectionUtils.findMethod(cls, fieldName);
field.set(this,value)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/315800.html
