原標題:Spring認證中國教育管理中心-Spring Data Couchbase教程二(Spring中國教育管理中心) 2.1.3一般建議
覆蓋屬性Java 允許靈活設計域類,其中子類可以定義一個已在其超類中以相同名稱聲明的屬性。考慮以下示例: public class SuperType { private CharSequence field; public SuperType(CharSequence field) { this.field = field; } public CharSequence getField() { return this.field; } public void setField(CharSequence field) { this.field = field; } }public class SubType extends SuperType { private String field; public SubType(String field) { super(field); this.field = field; } @Override public String getField() { return this.field; } public void setField(String field) { this.field = field; // optional super.setField(field); } } 這兩個類都定義了一個fieldusing 可分配類型。SubType然而陰影SuperType.field。根據類設計,使用構造函數可能是設置的唯一默認方法SuperType.field?;蛘?,調用super.setField(…)setter 可以設置fieldin SuperType。所有這些機制都會在某種程度上產生沖突,因為屬性共享相同的名稱但可能代表兩個不同的值。如果類型不可分配,Spring Data 會跳過超類型屬性。也就是說,被覆蓋的屬性的類型必須可以分配給它的超類型屬性類型才能注冊為覆蓋,否則超類型屬性被認為是瞬態(tài)的。我們通常建議使用不同的屬性名稱。 Spring Data 模塊通常支持覆蓋不同值的屬性。從編程模型的角度來看,有幾點需要考慮:
2.1.4。Kotlin 支持Spring Data 調整了 Kotlin 的細節(jié)以允許對象創(chuàng)建和變異。 Kotlin 對象創(chuàng)建Kotlin 類支持實例化,默認情況下所有類都是不可變的,需要明確的屬性聲明來定義可變屬性??紤]以下data類Person: data class Person(val id: String, val name: String) 上面的類編譯成一個帶有顯式構造函數的典型類。我們可以通過添加另一個構造函數來自定義這個類,并用注釋@PersistenceConstructor來指示構造函數的偏好: data class Person(var id: String, val name: String) { @PersistenceConstructor constructor(id: String) : this(id, "unknown") } Kotlin 通過在未提供參數時允許使用默認值來支持參數可選性。當 Spring Data 檢測到具有參數默認值的構造函數時,如果數據存儲不提供值(或簡單地返回null),它將使這些參數不存在,因此 Kotlin 可以應用參數默認值??紤]以下應用參數默認值的類name data class Person(var id: String, val name: String = "unknown") 每次name參數不是結果的一部分或其值為 時null,name默認為unknown。 Kotlin 數據類的屬性總體在 Kotlin 中,默認情況下所有類都是不可變的,并且需要顯式的屬性聲明來定義可變屬性??紤]以下data類Person: data class Person(val id: String, val name: String) 這個類實際上是不可變的。它允許創(chuàng)建新實例,因為 Kotlin 生成一個copy(…)創(chuàng)建新對象實例的方法,該方法從現有對象復制所有屬性值并將作為參數提供的屬性值應用到該方法。 Kotlin 覆蓋屬性Kotlin 允許聲明屬性覆蓋以更改子類中的屬性。 open class SuperType(open var field: Int)class SubType(override var field: Int = 1) : SuperType(field) { } 這樣的安排呈現了兩個名為 的屬性field。Kotlin 為每個類中的每個屬性生成屬性訪問器(getter 和 setter)。實際上,代碼如下所示: public class SuperType { private int field; public SuperType(int field) { this.field = field; } public int getField() { return this.field; } public void setField(int field) { this.field = field; } }public final class SubType extends SuperType { private int field; public SubType(int field) { super(field); this.field = field; } public int getField() { return this.field; } public void setField(int field) { this.field = field; } } getter 和 setterSubType僅在set 上SubType.field,而不在SuperType.field. 在這種安排中,使用構造函數是 set 的唯一默認方法SuperType.field。添加一個方法來SubType設置 Spring Data 模塊通常支持覆蓋不同值的屬性。從編程模型的角度來看,有幾點需要考慮:
2.2.文檔和字段所有實體都應使用注釋進行@Document注釋,但這不是必需的。 此外,實體中的每個字段都應使用注釋進行@Field注釋。雖然這是 - 嚴格來說 - 可選的,但它有助于減少邊緣情況并清楚地顯示實體的意圖和設計。它還可以用于以不同的名稱存儲字段。 還有一個特殊的@Id注釋需要始終到位。最佳做法是同時命名屬性 id。 這是一個非常簡單的User實體: 示例 6. 帶有字段的簡單文檔 import org.springframework.data.annotation.Id;import org.springframework.data.couchbase.core.mapping.Field;import org.springframework.data.couchbase.core.mapping.Document;@Documentpublic class User { @Id private String id; @Field private String firstname; @Field private String lastname; public User(String id, String firstname, String lastname) { this.id = id; this.firstname = firstname; this.lastname = lastname; } public String getId() { return id; } public String getFirstname() { return firstname; } public String getLastname() { return lastname; } } Couchbase Server 支持文檔自動過期。該庫通過@Document注釋實現對它的支持。您可以設置一個expiry值,該值轉換為文檔被自動刪除之前的秒數。如果你想讓它在突變后 10 秒內過期,請將其設置為@Document(expiry = 10). 或者,您可以使用 Spring 的屬性支持和expiryExpression參數配置到期,以允許動態(tài)更改到期值。例如:@Document(expiryExpression = "${valid.document.expiry}")。該屬性必須可解析為 int 值,并且不能混合使用這兩種方法。 如果您想要文檔中的字段名稱與實體中使用的字段名稱不同的表示形式,您可以在@Field注釋上設置不同的名稱。例如,如果您想保持文檔較小,您可以將 firstname 字段設置為@Field("fname")。在JSON文件,你會看到{"fname": ".."},而不是{"firstname": ".."}。 在@Id注釋中需要存在,因為Couchbase每個文件需要一個唯一的密鑰。該鍵必須是長度不超過 250 個字符的任意字符串。隨意使用適合您用例的任何內容,無論是 UUID、電子郵件地址還是其他任何內容。 2.3.數據類型和轉換器選擇的存儲格式是 JSON。這很棒,但與許多數據表示一樣,它允許的數據類型比您直接用 Java 表達的要少。因此,對于所有非原始類型,需要進行某種形式的與支持類型之間的轉換。 對于以下實體字段類型,無需添加特殊處理: 由于JSON支持對象(“映射”)和列表,Map和List類型可以自然被轉換。如果它們只包含最后一段中的原始字段類型,則您也不需要添加特殊處理。這是一個例子: 示例 7. 帶有地圖和列表的文檔 @Documentpublic class User { @Id private String id; @Field private List<String> firstnames; @Field private Map<String, Integer> childrenAges; public User(String id, List<String> firstnames, Map<String, Integer> childrenAges) { this.id = id; this.firstnames = firstnames; this.childrenAges = childrenAges; } } 用一些示例數據存儲用戶可能看起來像這樣的 JSON 表示: 示例 8. 帶有地圖和列表的文檔 - JSON { "_class": "foo.User", "childrenAges": { "Alice": 10, "Bob": 5 }, "firstnames": [ "Foo", "Bar", "Baz" ] } 您不需要一直將所有內容分解為原始類型和列表/映射。當然,您也可以用這些原始值組合其他對象。讓我們修改最后一個示例,以便我們要存儲 a Listof Children: 示例 9. 包含組合對象的文檔 @Documentpublic class User { @Id private String id; @Field private List<String> firstnames; @Field private List<Child> children; public User(String id, List<String> firstnames, List<Child> children) { this.id = id; this.firstnames = firstnames; this.children = children; } static class Child { private String name; private int age; Child(String name, int age) { this.name = name; this.age = age; } } } 填充的對象可能如下所示: 示例 10. 包含組合對象的文檔 - JSON { "_class": "foo.User", "children": [ { "age": 4, "name": "Alice" }, { "age": 3, "name": "Bob" } ], "firstnames": [ "Foo", "Bar", "Baz" ] } 大多數情況下,您還需要存儲一個時間值,例如 a Date。由于它不能直接存儲在 JSON 中,因此需要進行轉換。該庫實現默認的轉換器Date,Calendar以及JodaTime類型(如果在classpath)。所有這些在文檔中默認表示為一個 unix 時間戳(數字)。您始終可以使用自定義轉換器覆蓋默認行為,如下所示。這是一個例子: 示例 11. 帶有日期和日歷的文檔 @Documentpublic class BlogPost { @Id private String id; @Field private Date created; @Field private Calendar updated; @Field private String title; public BlogPost(String id, Date created, Calendar updated, String title) { this.id = id; this.created = created; this.updated = updated; this.title = title; } } 填充的對象可能如下所示: 示例 12. 帶有日期和日歷的文檔 - JSON { "title": "a blog post title", "_class": "foo.BlogPost", "updated": 1394610843, "created": 1394610843897} 可選地,可以通過將系統(tǒng)屬性設置 示例 13. 自定義轉換器 @Overridepublic CustomConversions customConversions() { return new CustomConversions(Arrays.asList(FooToBarConverter.INSTANCE, BarToFooConverter.INSTANCE)); }@WritingConverterpublic static enum FooToBarConverter implements Converter<Foo, Bar> { INSTANCE; @Override public Bar convert(Foo source) { return /* do your conversion here */; } }@ReadingConverterpublic static enum BarToFooConverter implements Converter<Bar, Foo> { INSTANCE; @Override public Foo convert(Bar source) { return /* do your conversion here */; } } 自定義轉換需要注意以下幾點:
|
|
來自: 王先生的內容 > 《Spring國際認證》