GreenDAO 注解
實體@Entity注解
@Entity 實體注解,為greendao指明這是一個需要映射到數據庫的實體類
@Entity(
// 告知GreenDao當前實體屬於哪個schema (pick any string as a name).
schema = "myschema",
// 標記一個實體處於活動狀態,活動實體有更新、刪除和刷新方法
active = true,
// 指定該表在數據庫中的名稱,默認是基於實體類名
nameInDb = "AWESOME_USERS",
// 定義跨多個列的索引
indexes = {
@Index(value = "name DESC", unique = true)
},
// 標識DAO類是否應該創建該數據庫表(默認為true)
// 如果有多個實體映射一個表,或者該表已在greenDAO外部創建,則置為false
createInDb = false,
// 是否生成all-properties的構造器
// 無參構造器總是會生成
generateConstructors = true,
// 如果丟失,是否應該生成屬性的getter和setter
generateGettersSetters = true
)
基礎屬性注解
@Id
主鍵,選擇使用long或Long,可以通過@Id(autoincrement = true)設置自增長,引用一下官方文檔的說明
Currently, entities must have a long or Long property as their primary key. This is recommended practice for Android and SQLite.
To work around this, define your key property as an additional property, but create a unique index for it:
@Id
private Long id;@Index(unique = true)
private String key;
@Property
為該屬性映射的列設置一個非默認的名稱,默認是將單詞大寫,用下划線分割單詞,如屬性名customName對應列名CUSTOM_NAME
@Property(nameInDb = "USERNAME")
private String name;
@NotNull
表明這個列非空,通常使用@NotNull標記基本類型(long,int,short,byte),然而可使用包裝類型(Long, Integer, Short, Byte)使其可空
@NotNull
private int repos;
@Transient
表明此字段不存儲到數據庫中,用於不需要持久化的字段,比如臨時狀態
@Transient
private int tempUsageCount;
索引注解
@Index
為相應的列創建索引
name 如果不想使用greenDAO為該屬性生成的默認索引名稱,可通過name設置
unique 給索引添加唯一性約束
@Index(unique = true)
private String name;
@Unique
為相應列添加唯一約束,注意,SQLite會隱式地為該列創建索引
@Unique private String name;
關系注解
在greenDAO,實體使用@to-one 或 @to-many 關聯起來
@ToOne 一對一
@Entity
public class Order {
@Id private Long id;
private long customerId; //定義外鍵
@ToOne(joinProperty = "customerId") //一個Order對一個Customer,joinProperty指定外鍵
private Customer customer; //持有目標實體對象的字段
}
@Entity
public class Customer {
@Id private Long id;
}
外鍵約束語句:
constraint FK_name foreign key(customerId) references Customer(id);
@ToOne 定義到另一個實體對象的關系,應在持有目標實體對象的字段上使用該注解。
如一個Order對一個Customer,應在實體Order的customer字段使用@ToOne
在實體內部,需要定義一個屬性來指向目標實體的ID,也就是定義外鍵(如Order實體的customerId),
使用@ToOne的joinProperty參數來指明外鍵
如果改變了外鍵屬性(customerId),下次調用getter(getCustomer())時會更新實體;如果設置了新的實體(setCustomer()),外鍵也會更新
第一次調用to-one關系的getter方法(getCustomer())時會延遲加載,在隨后的調用會立即返回之前加載的對象。
@ToMany 一對多
@ToMany定義一對多關系(一對一個其他實體的集合),使用@ToMany的屬性代表目標實體的List,集合里的對象都必須至少有一個屬性指向擁有@ToMany的實體
referencedJoinProperty指定目標實體的外鍵
@Entity
public class Customer {
@Id private Long id;
@ToMany(referencedJoinProperty = "customerId") //指定目標實體的外鍵
@OrderBy("date ASC")
private List<Order> orders; //目標實體的List
}
@Entity
public class Order {
@Id private Long id;
private Date date;
private long customerId;
}
joinProperties parameter
對於更復雜的關系,可以指定一個@joinproperty注釋列表,每個@joinproperty需要原始實體中的源屬性和目標實體中的引用屬性。
@Entity
public class Customer {
@Id private Long id;
@Unique private String tag;
@ToMany(joinProperties = {
@JoinProperty(name = "tag", referencedName = "customerTag")
})
@OrderBy("date ASC")
private List<Site> orders;
}
@Entity
public class Order {
@Id private Long id;
private Date date;
@NotNull private String customerTag;
}
@JoinEntity 多對多
如果兩個實體是多對多的關系,那么需要第三張表(表示兩個實體關系的表)
例如學生與課程是多對多關系,需要一個選課表來轉成兩個一對多的關系(學生與選課是一對多,課程與選課是一對多)
@Entity
public class Product {
@Id private Long id;
@ToMany
@JoinEntity(
entity = JoinProductsWithOrders.class,
sourceProperty = "productId",
targetProperty = "orderId"
)
private List<Order> ordersWithThisProduct;
}
@Entity
public class JoinProductsWithOrders {
@Id private Long id;
private Long productId;
private Long orderId;
}
@Entity
public class Order {
@Id private Long id;
}
獲取和更新To-many關系
To-many在首次請求時會延遲加載,之后,相關的實體緩存到源實體的內部List對象中。隨后的訪問不再查詢數據庫,而是直接從緩存中獲取。所以當數據庫更新to-many關系后,需要手動更新to-many的list緩存。
// 插入新的實體之前獲取to-many list,否則新實體可能在list中出現兩次
List<Order> orders = customer.getOrders();
// 創建新實體
Order newOrder = ...
// 設置外鍵
newOrder.setCustomerId(customer.getId());
// 插入新實體
daoSession.insert(newOrder);
// 添加新實體到to-many list
orders.add(newOrder);
同樣,可以刪掉關聯的實體
List<Order> orders = customer.getOrders();
// 從數據庫中刪掉其中一個關聯的實體
daoSession.delete(someOrder);
// 手動從to-many list中刪除
orders.remove(someOrder);
當添加、更新或刪除很多關聯實體時可以使用reset方法來清掉緩存,然后調用getter方法時會重新查詢
// clear any cached list of related orders
customer.resetOrders();
List<Order> orders = customer.getOrders();