GitHub地址:GreenDao
介绍
GreenDao是一款适用于Android的轻量快速ORM,可将对象映射到SQLite数据库。 针对Android进行了高度优化,GreenDao提供了出色的性能并消耗最少的内存。
使用
1.配置/添加依赖
image.png2.初始化数据库
//android 中
greendao{
schemaVersion 1//版本
daoPackage 'com.ffcs.z.greendaodemo.dao'//dao生成的位置
targetGenDir 'src/main/java'//目标位置}
3.创建数据库
//创建一个数据库,名字为"wesker"
DaoMaster.DevOpenHelper devOpenHelper = new DaoMaster.DevOpenHelper(this, "wesker", null);
//一个DaoMaster就代表着一个数据库的连接;
DaoMaster mDaoMaster = new DaoMaster(devOpenHelper.getWritableDatabase());
daoSession = mDaoMaster.newSession();
4.创建实体类User.class
@Entity
public class User {
@Id(autoincrement = true)
private Long id;
@Unique
private String userName;
@Transient
private String temp;
}
然后Build->Make Projec一下,即可生成get、set方法以及User的Dao包
@Entity 创建与实体相关联的表
(1)schema = “myschema”, 当程序中有多个secema(数据库)时,可以选择我们想要的一个。
(2)active = true, 设置Entity是否是活动的。如果是活动的,那么他将有更新,删除,刷新的方法。
(3)nameInDb = “AWESOME_USERS”, 数据库中的表名,默认是实体类名。
(4)indexes = { @Index(value = “name DESC”, unique = trut) }, 索引
(5) createInDb = false, 是否会创建数据库表,默认是true 当多个实体映射一个表,或者表不在greenDao之内创建时为false。
(6)generateConstructors = true, 不管有没有有参函数,一个无参函数总是会创建
(7)generateGettersSetters = true 产生get,set方法
成员变量前的注解
(1)@Id(autoincrement = true) 主键自增长 .必须是Long类型
(2)@NotNull 不为空
(3)@OrderBy(date desc) 降序
(4)@Transient 短暂的,不会持久化,因此不会生成数据库中的列
(5)@Property 参数,在数据库表中默认为如下格式customName—–CUSTOM_NAME
@Property(nameInDb = “USERNAME”) 固定格式如下
(6)@Unique 唯一约束
(7)Sqlite中主键必须是Long类型,因此尽量添加一个附加属性
@Index(unique = true) Private String key;
(8)@ToOne:定义与另一个实体(一个实体对象)的关系(下面6.@ToOne详解)
@ToMany:定义与多个实体对象的关系(底下会有详解)
5.增、删、改、查操作
public class GreenDaoUtils {
private DaoSession daoSession;
private UserDao mUserDao;
public GreenDaoUtils() {
daoSession = App.getDaoSession();
mUserDao = daoSession.getUserDao();
}
//添加
public boolean insert(String username) {
User mUser = new User(null, username);
try {
mUserDao.insert(mUser);
return true;
} catch (Exception e) {
return false;
}
}
//查找
public List<User> query() {
List<User> userList = mUserDao.queryBuilder()
.orderDesc(UserDao.Properties.Id)//倒叙
.limit(10)
.build().list();
return userList;
}
//改
public void update(String username, String updateName) {
User findUser = mUserDao.queryBuilder().where(UserDao.Properties.UserName.eq(username)).build().unique();
if (findUser != null) {
findUser.setUserName(updateName);
mUserDao.update(findUser);
}
}
//删除
public void delete(String username) {
User findUser = mUserDao.queryBuilder().where(UserDao.Properties.UserName.eq(username)).build().unique();
if (findUser != null) {
mUserDao.deleteByKey(findUser.getId());
}
}}
查询
(1)orderAsc:升序排序
(2)orderDesc: 降序排序
(3)eq():==
(4)noteq():!=
(5)gt(): >
(6)t():<
(7)ge:>=
(8)le:<=
(9)like():包含
(10)between:俩者之间
(11)in:在某个值内
(12)notIn:不在某个值内
6.@ToOne详解:通过外键来关联另一个实体
@Entity
public class User {
@Id
private Long UserId;
private long pictureId;
@Property(nameInDb = "NAME")
private String name;
@Property(nameInDb = "AGE")
private String age;
@Property(nameInDb = "SEX")
private String sex;
@ToOne(joinProperty = "pictureId")//pictureId是我们需要关联的外键
private Picture picture;}
@Entity
public class Picture implements Serializable {
private static final long serialVersionUID = 11;
@Id
private Long pictureId;
private long userId;
@Property
private String pictureName;
@Property(nameInDb = "width")
private String width;
@Property(nameInDb = "height")
private String height;
@ToOne(joinProperty = "userId")
private User user;}
需要注意的是:Intent传递对象需要用到:Serializable
必须把serialVersionUID 给带上,不然会报错
1:n
@ToMany(referencedJoinProperty = "customerId")
joinProperties这个参数是referencedJoinProperty 参数的升级版
@ToMany(joinProperties = {
@JoinProperty(name = "id", referencedName = "customerId")
})
需要用到的两个实体类为:Customer .java 以及 Order.java
@Entity
public class Customer {
@Id
private Long id;
@Property
private String name;
//@ToMany(referencedJoinProperty = "customerId")
@ToMany(joinProperties = {@JoinProperty(name = "id", referencedName = "customerId")})
@OrderBy("date ASC")
private List<Order> orders;}
@Entity
public class Order {
@Id
private Long id;
@Property
private Date date;
private long customerId;}
@ToMany(referencedJoinProperty = “customerId”),注解写在对应关系的一里边。
它这个注解默认的是customer的主键对应order的外键。
当我们不需要用一的主键对应N的外键时,我们可以自己定制
即:@ToMany(joinProperties = {@JoinProperty(name = "id", referencedName = "customerId")})
即本类中的id对应其他类中的customerId
PS:
问题一:当我们获取到Customer值的时候,通过调试,我们可以发现,orders=null?
这是因为获取Customer的时候提并没有马上去数据库查找关联的order值,只有调用getOrders的时候才会去从数据库查询。
问题二:获取Customer中的Orders,在修改Customer中的Orders值,再去获取Customer中的Orders值,为啥并没有改变值?
当我第一次获取Orders值的时候,DaoSession已经帮我们生成缓存了,当我们第二次获去获取Orders值的时候,并没有重新去已经更新的Orders表中获取数据,是从缓存中直接获取的,导致第一次和第二次获取数据相同,那我们应该怎么做呢?那我们可以发现Customer中只有getOrders和resetOrders方法,getOrders我们知道是获取Customer下的Orders数据,那resetOrder是啥?看一下GreenDao的注解: /** Resets a to-many relationship, making the next get call to query for a fresh result. */=>/ *重置多对多关系,进行下一次调用以查询新结果。/,既然是刷新关系结果,那我们可以,在调用getOrders之前就执行resetOrder就可以获取到最新的关联数据。
M:n
@JoinEntity 定义了N:M的映射关系。 创建三个实体类,其中一个为关联类。 需
要的三个实体类分别为:Order.java、product.java、JoinProductsWithOrders.java
@Entity
public class Order {
@Id
private Long id;
@Property
private Date date;
private long customerId;}
@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;}
在类里边写toMany表示的是将此类当成唯一,他需要一个中间类生成的表来连接另外一个表(实体),
关键代码如下:
@ToMany
@JoinEntity(
entity = JoinProductsWithOrders.class,
sourceProperty = "productId",
targetProperty = "orderId"
)
private List<Order> ordersWithThisProduct;
个人见解比较有限,欢迎提问,以及补充,不胜感激....
网友评论