greenDao 在众多数据库中应该算是比较突出的,已经到升级到3了。注解的方式还是很便利的。简略记一下。
基本配置:
1501634855(1).jpgclasspath 'com.android.tools.build:gradle:2.3.1' 版本至少要2.3.x以上。不然编译不通过。
一些其他的配置:
android{
...
}
greendao{
schemaVersion 1
daoPackage "com.yang.gd"//
targetGenDir "src/main/java" //
generateTests true
}
schemaVersion :数据库版本
daoPackage DAOs, DaoMaster, and DaoSession存放三个类的package name。
targetGenDir 上面三个类的生成位置(默认"build/generated/source/greendao")。
generateTests 是否生成单元测试。
targetGenDirTests 单元测试生成的位置(默认"src/androidTest/java")
Create:
@Entry 实体类打上@Entry,该类的数据就会持久化,即字段类名对应表名,字段对应列名。
注解后也是可以配置一些其他的东西,列几个比较常用的
@Entry(
nameInDb = "TABLE_NAME",
indexes = {
@Index(value = "字段名 DESC/ARC", unique = true)
},//为某些列指定升降序,和是否唯一
)
@Id @Transient @Index
public class User{
@Id(autoincrement = true)
public int id;
@Transient
public int sex;
@Index(unique = true,name="User_Name")
public String name;
public String age;
}
@Id 用于long/Long类型的,可以设置是否自增长,充当主键。
@Transient 该字段将被greenDAO忽略不会,生成列。
@Index 用于属性的时候,没有value参数,只有unique 和name。如果只是想唯一,也可以直接@Unique。
多种关系:
@To-One注解:
一对一的关系,就好比一个人一个手机..:
People的Id和Phone 的phoneId 建立起来对应关系:
@Entity
public class Phone{
@Id private Long id;
private long phoneId;
@ToOne(joinProperty = "phoneId")
private People people;
}
@Entity
public class People{
@Id private Long id;
}
@To-Many注解:
一对多,就好比土豪一个人有好多手机。
多个Phone 的phoneId对应一个People的Id
No .1
@Entity
public class People{
@Id private Long id;
@ToMany(referencedJoinProperty = "phoneId")
@OrderBy("date ASC")
private List<Phone > phones;
}
@Entity
public class Phone {
@Id private Long id;
private Date date;
private long phoneId;
@ToOne(joinProperty = "phoneId")
private People people;
}
Make 的时候会生成getter 、set方法.
持有people对象就可以轻松获取该对象的所有手机。
List<Phone> phones=people.getPhones();
持有Phone 对象就可获取该手机对应的boss:
People people =phone.getPeople();
No.2
No1.只是默认对应主键Id,不想对应主键Id的写法:
指定tag 和phoneTag对应。
@Entity
public class People{
@Id private Long id;
@Unique private String tag;
@ToMany(joinProperties = {
@JoinProperty(name = "tag", referencedName = "phoneTag")
})
@OrderBy("date ASC")
private List<Phone> phones;
}
@Entity
public class Phone {
@Id private Long id;
private Date date;
@NotNull private String phoneTag;
}
@Many-To-Many注解:
数据库中的多对多关联关系一般需采用中间表的方式处理,将多对多转化为两个一对多,三张表,其中Relations 充当关系表(中间表,两个外键,分别关联两张表。)
@Entity
public class Student{
@Id private Long id;
@ToMany
@JoinEntity(
entity = Relations .class,
sourceProperty = "stutId",
targetProperty = "curseId"
)
private List<Curse> curses;
}
@Entity
public class Relations {
@Id private Long id;
private Long stutId;
private Long curseId;
}
@Entity
public class Curse{
@Id private Long id;
@ToMany
@JoinEntity(
entity = Relations .class,
sourceProperty = "curseId",
targetProperty = "stutId"
)
private List<Student> stu;
}
一样的:
持有学生的对象的时候就可可以知道该学生所选的所有课程:
List<Curse> curses =stu.getCurses();
持有Curse的对象的时候就可以知道该所有选择该课程的学生了:
List<Student> stus=curse.getStu();
实现原理什么的基本就是下面query 种的join的应用了。
基本获取:
这边就是一个基本获取,正式应该是单例获取DaoSession ,然后通过DaoSession 去取得对应表的DAO .
DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(context, DB_NAME);
DaoMaster daoMaster = new DaoMaster(helper.getWritableDatabase());
DaoSession daoSession = new DaoMaster(db).newSession();
Query、Save
save
save 就是获取对应的Dao,进行sava(Entry)。
单表查询(基本操作)
1.执行build的qb 可以多次使用。而没有build的,只能单次使用
2.由于查询条件可能变化,又要build的话,可以使用setParams。
QueryBuilder qb=userDao.queryBuilder();
Query<User> query=qb.where(Properties.name.eq("名字"),Properties.age.ge(12))
.orderAsc(Properties.age)
.build();
query.list();
//对where 条件的变量进行替代
query.setParameter(0, "名字1");
query.setParameter(1, 13);
query.list();
3.多线程查询的话,需要调用 forCurrentThread()。 forCurrentThread()方法会为当前线程返回一个Query对象。如果其他的线程对这个Query对象进行setParameter,或者绑定该对象到另一个线程,就会抛出异常。我们不需要在进行同步操作。
qb.build(). forCurrentThread();
4 .query 的方法还是很多的:gt 、lt、ge...等等。不懂什么意思还得看看源码注释。
1501468230(1).jpg5.通过queryRaw 支持原生查询。
多表查询(这才是常用的吧!)
关于Join api(三个重载):
/**
* 传入被关联的表(就是类),以及该表中和初始表相关连的字段(这里是Property)
* 这个方法默认是原的类中的主键和这里传入的Property 是相关联的
*/
public <J> Join<T, J> join(Class<J> destinationEntityClass, Property destinationProperty)
/**
* 传入原表关联字段,以及被关联的表
* 这个方法默认是原的表中关联字段和这里传入的关联表的主键是相关联的
*/
public <J> Join<T, J> join(Property sourceProperty, Class<J> destinationEntityClass)
/**
*这个就比较全了,原表中的关联字段、关联表、以及关联表中的关联字段
*/
public <J> Join<T, J> join(Property sourceProperty, Class<J> destinationEntityClass,
Property destinationProperty)
/**
*这个就是多表关联的api了。sourceJoin 为第一张表和中间表的连接,
* sourceProperty 中间表的字段和 destinationProperty 关联。
*/
public <J> Join<T, J> join(Join<?, T> sourceJoin, Property sourceProperty,
Class<J> destinationEntityClass, Property destinationProperty)
1.两张表。User表,Address表。 两张表User表主键关联 Address表的UserId。查某一个人的地址(官网例子):
QueryBuilder<User> queryBuilder = userDao.queryBuilder();
queryBuilder.join(Address.class, AddressDao.Properties.userId)
.where(AddressDao.Properties.Street.eq("Sesame Street"));
List<User> users = queryBuilder.list();
2.三张表. city表、country表、Continent表。查询洲际是欧洲的,并且城市人口超过100000的的所有城市:
QueryBuilder<City> qb = cityDao.queryBuilder().where(Properties.Population.ge(10000000));
//city 表的CountryId 关联Country表的主键
Join country = qb.join(Properties.CountryId, Country.class);
//Country 表的ContinentId 关联Continent 的Id
Join continent = qb.join(country, CountryDao.Properties.ContinentId,
Continent.class, ContinentDao.Properties.Id);
continent.where(ContinentDao.Properties.Name.eq("Europe"));
List<City> bigEuropeanCities = qb.list();
官方的doucument
http://greenrobot.org/greendao/documentation/
网友评论