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();