how to use greendao in android studio
http://www.arjunsk.com/android/use-greendao-android-studio/
1、新建一个java文件MainGenerator.java:
import de.greenrobot.daogenerator.DaoGenerator; import de.greenrobot.daogenerator.Entity; import de.greenrobot.daogenerator.Schema; public class MainGenerator { public static void main(String[] args) throws Exception { //place where db folder will be created inside the project folder Schema schema = new Schema(1,"com.codekrypt.greendao.db"); //Entity i.e. Class to be stored in the database // ie table LOG Entity word_entity= schema.addEntity("LOG"); // 最好将 LOG 改成 Log,但不要用 log,因为它会自动生成类名,所以不要首字母小写,如果你不希望你的class名字是小写字母开头的话。 word_entity.addIdProperty(); //It is the primary key for uniquely identifying a row word_entity.addStringProperty("text").notNull(); //Not null is SQL constrain // ./app/src/main/java/ ---- com/codekrypt/greendao/db is the full path new DaoGenerator().generateAll(schema, "./app/src/main/java"); } }
2、完成第一步之后,会生成一个叫db的文件夹,里面包含文件:
DaoMaster.java, DaoSession.java, LOG.java, LOGDAO.java
这些文件是你在android里要用的entity及一些help文件。
3、在android里面使用这些文件:
package com.codekrypt.greendao; import android.database.sqlite.SQLiteDatabase; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; import android.widget.TextView; import com.codekrypt.greendao.db.DaoMaster; import com.codekrypt.greendao.db.DaoSession; import com.codekrypt.greendao.db.LOG; import com.codekrypt.greendao.db.LOGDao; import java.util.List; public class MainActivity extends AppCompatActivity { //Dao --> Data Access Object private LOGDao log_dao; // Sql access object private LOG temp_log_object; // Used for creating a LOG Object String log_text=""; //Entered text data is save in this variable private final String DB_NAME ="logs-db" ; //Name of Db file in the Device @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //Initialise DAO log_dao=setupDb(); //Setting up form elements Button textSave= (Button) findViewById(R.id.textSave); Button textTop= (Button) findViewById(R.id.textTop); final TextView textData=(TextView) findViewById(R.id.textData); assert textSave != null; textSave.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { log_text=textData.getText().toString(); temp_log_object=new LOG(null,log_text);// Class Object, Id is auto increment SaveToSQL(temp_log_object); } }); assert textTop != null; textTop.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { textData.setText( getFromSQL() ); } }); } //---------------------------------SQL QUERY Functions-----------------------------------------// public String getFromSQL(){ List<LOG> log_list = log_dao.queryBuilder().orderDesc(LOGDao.Properties.Id).build().list(); //Get the list of all LOGS in Database in descending order if(log_list.size()>0) { //if list is not null return log_list.get(0).getText(); //get(0)--> 1st object // getText() is the function in LOG class } return ""; } public void SaveToSQL(LOG log_object) { log_dao.insert(log_object); } //----------------------------***END SQL QUERY***---------------------------------------------// //-------------------------------DB Setup Functions---------------------------------------------// //Return the Configured LogDao Object public LOGDao setupDb(){ DaoMaster.DevOpenHelper masterHelper = new DaoMaster.DevOpenHelper(this, DB_NAME, null); //create database db file if not exist SQLiteDatabase db = masterHelper.getWritableDatabase(); //get the created database db file DaoMaster master = new DaoMaster(db);//create masterDao DaoSession masterSession=master.newSession(); //Creates Session session return masterSession.getLOGDao(); } //-------------------------***END DB setup Functions***---------------------------------------// }
下面这两个文件演示了如何添加 byte array 作为表的字段:
https://github.com/greenrobot/greenDAO/blob/2e86e8678f95f15b129bdd53a74d932d9cfa7224/tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/SimpleEntity.java
https://github.com/greenrobot/greenDAO/blob/ac748fd1462ef59e378d296137271ff63328c07d/tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/SimpleEntityDao.java
如何在 greendao 里添加 byte array字段:
https://stackoverflow.com/questions/18942188/greendao-how-insert-blob
Yes you can use addByteArrayProperty to store the raw bytes of your file. The file format doesn't matter, you only have to know how to deal with the raw data.
If you have files you could also store the path to the files on your device in your database.
relationship:
GreenDAO does not create foreign key nor cascade rules when you define relations. The relation exist just in the greenDaoModel。也就是说似乎sqlite里没有实现relations,是GreenDao模拟了这种relations?
多表关系映射
To-One
相当于外键关系:
// The variables "user" and "picture" are just regular entities Property pictureIdProperty = user.addLongProperty("pictureId").getProperty(); user.addToOne(picture, pictureIdProperty);
这将导致产生的User实体类中有一个Picture属性(getPicture/setPicture);
Relation Names and multiple Relations
每一个关联都有一个名称。默认情况下关联的名称就是目标实体的名称。所以一般情况下建议主动设置该关联的名称以免重名。可以通过setName()来设置。
Property pictureIdProperty = user.addLongProperty("pictureId").getProperty(); Property thumbnailIdProperty = user.addLongProperty("thumbnailId").getProperty(); user.addToOne(picture, pictureIdProperty);//使用默认的关系名 user.addToOne(picture, thumbnailIdProperty, "thumbnail");//为了防止重名,设置关系名为thumbnail Property customerId = order.addLongProperty("customerId").notNull().getProperty(); ToMany customerToOrders = customer.addToMany(order, customerId); customerToOrders.setName("orders"); // Optional customerToOrders.orderAsc(orderDate); // Optional 产生的代码中Customer类将多出一个getOrders() List orders = customer.getOrders();
Resolving and Updating To-Many Relations
To-Many解析第一次使用懒加载,即是一旦加载之后to-many list就会被缓存到一个List当中,后续的请求不会再通过数据库,而是直接从缓存中返回,所以一旦修改之后,需要对缓存中的数据进行更新。
由于缓存的作用下面的代码会产生令人困惑的结果:
List orders1 = customer.getOrders(); int size1 = orders1.size(); Order order = new Order(); order.setCustomerId(customer.getId()); daoSession.insert(order); Listorders2 = customer.getOrders(); // size1 == orders2.size(); // NOT updated // orders1 == orders2; // SAME list object
所以我们需要对缓存进行Updating
改正后的代码如下:
List orders = customer.getOrders(); newOrder.setCustomerId(customer.getId()); daoSession.insert(newOrder); orders.add(newOrder);//更新缓存 对于删除操作也是一样的。: List orders = customer.getOrders(); daoSession.delete(newOrder); orders.remove(newOrder);//更新缓存
但是如果有个时候这些没法达到你预期的要求或者是更新缓存比较困难的情况下,没关系greendao还提供如下方法resetXxx()重置缓存:
customer.resetOrders();
List orders2 = customer.getOrders();
双向关联To-One与To-many结合使用
Entity customer = schema.addEntity("Customer"); customer.addIdProperty(); customer.addStringProperty("name").notNull(); Entity order = schema.addEntity("Order"); order.setTableName("ORDERS"); // "ORDER" is a reserved keyword order.addIdProperty(); Property orderDate = order.addDateProperty("date").getProperty(); Property customerId = order.addLongProperty("customerId").notNull().getProperty(); order.addToOne(customer, customerId); ToMany customerToOrders = customer.addToMany(order, customerId); customerToOrders.setName("orders"); customerToOrders.orderAsc(orderDate); 这样便产生了双向关联了。 List allOrdersOfCustomer = order.getCustomer().getOrders();
Many-to-Many Relations (n:m)
目前greendao还没有实现。 但可以使用双向关联的 OneToMany 来实现。使用时注意如何更新缓存。
Modelling Tree Relations
You can model a tree relation by modelling an entity having a to-one and a to-many relation pointing to itself:
Entity treeEntity = schema.addEntity("TreeEntity"); treeEntity.addIdProperty(); Property parentIdProperty = treeEntity.addLongProperty("parentId").getProperty(); treeEntity.addToOne(treeEntity, parentIdProperty).setName("parent"); treeEntity.addToMany(treeEntity, parentIdProperty).setName("children"); 然后再生成的代码中我们就可以进行导航了: [java] view plaincopy TreeEntity parent = child.getParent(); List grandChildren = child.getChildren();
package com.welhzh.tcp; import org.greenrobot.greendao.generator.DaoGenerator; import org.greenrobot.greendao.generator.Entity; import org.greenrobot.greendao.generator.Property; import org.greenrobot.greendao.generator.Schema; public class GreenDaoMainGenerator { public static void main(String[] args) throws Exception { //place where db folder will be created inside the project folder Schema schema = new Schema(1, "org.linphone.contact"); // 参数最好首字母大写,因为它最终会自动生成类名,当然也是数据库表名 Entity word_entity= schema.addEntity("SipAddr"); word_entity.addIdProperty(); //It is the primary key for uniquely identifying a row word_entity.addStringProperty("name").notNull(); //Not null is SQL constrain word_entity.addStringProperty("sipAddr"); word_entity.addByteArrayProperty("pic"); Property gidProperty = word_entity.addLongProperty("gid").getProperty(); Entity group= schema.addEntity("Group"); group.addIdProperty(); group.addStringProperty("gtitle"); word_entity.addToOne(group, gidProperty, "group"); // name参数最好使用小写的数据库表名命名,最终会编程一个变量 group.addToMany(word_entity, gidProperty, "users"); // ./app/src/main/java/ ---- com/codekrypt/greendao/db is the full path new DaoGenerator().generateAll(schema, "."); } }
在android中这样使用:
package com.welhzh.android.mystockcapital; import java.util.List; import android.app.Activity; import android.database.sqlite.SQLiteDatabase; import android.os.Bundle; import android.util.Log; public class MainActivity extends Activity { private DaoSession sipAddrSession = null; private static final String CONTACTS_DB ="contact" ; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); goTest(); } private void goTest() { SipAddrDao sipAddrDao = setupSipAddrDao(); GrouppDao groupDao = setupGroupDao(); Groupp group1 = new Groupp(null, "g1"); groupDao.insert(group1); Groupp group2 = new Groupp(null, "g2"); groupDao.insert(group2); SipAddr sipAddr1 = new SipAddr(null, "hzh1", "2001", null, group1.getId()); sipAddrDao.insert(sipAddr1); SipAddr sipAddr2 = new SipAddr(null, "hzh2", "2002", null, null); sipAddrDao.insert(sipAddr2); SipAddr sipAddr3 = new SipAddr(null, "hzh3", "2003", null, group1.getId()); sipAddrDao.insert(sipAddr3); SipAddr sipAddr4 = new SipAddr(null, "hzh4", "2004", null, group2.getId()); sipAddrDao.insert(sipAddr4); SipAddr sipAddr5 = new SipAddr(null, "hzh5", "2005", null, null); sipAddrDao.insert(sipAddr5); group1.resetUsers(); List<SipAddr> usersGroup1 = group1.getUsers(); group2.resetUsers(); List<SipAddr> usersGroup2 = group2.getUsers(); Groupp myGroup1 = sipAddr1.getGroup(); // 这样取不合理,在外键的表被修改的情况下,没有实时更新,见后面的代码 Groupp myGroup2 = sipAddr2.getGroup(); // 这样取不合理,在外键的表被修改的情况下,没有实时更新,见后面的代码 String p = ""; int size = usersGroup1.size(); for (int i = 0; i < size; i++) { p += usersGroup1.get(i).getSipAddr() + "@" + usersGroup1.get(i).getName() + "; "; } Log.i("welhzh_g", p); p = ""; size = usersGroup2.size(); for (int i = 0; i < size; i++) { p += usersGroup2.get(i).getSipAddr() + "@" + usersGroup2.get(i).getName() + "; "; } Log.i("welhzh_g", p); Log.i("welhzh_g", "" + (null == myGroup1 ? myGroup1 : myGroup1.getGtitle())); Log.i("welhzh_g", "" + (null == myGroup2 ? myGroup2 : myGroup2.getGtitle())); // 获取 oneToMany 中的 many: /* 下面这种方法行不通 ************** p = ""; Group groupNull = new Group(null, "ggggg"); List<SipAddr> usersGroupNull = groupNull.getUsers(); size = usersGroupNull.size(); for (int i = 0; i < size; i++) { p += usersGroupNull.get(i).getSipAddr() + "@" + usersGroupNull.get(i).getName() + "; "; } Log.i("welhzh_g", p); **********************************/ /* 下面这种方法行不通 ************** p = ""; myGroup1.setId(null); List<SipAddr> usersGroupNull = myGroup1.getUsers(); size = usersGroupNull.size(); for (int i = 0; i < size; i++) { p += usersGroupNull.get(i).getSipAddr() + "@" + usersGroupNull.get(i).getName() + "; "; } Log.i("welhzh_g", p); **********************************/ /** * 综合上面两种方法,oneToMany 和 ManyToOne 中,要获取 oneToMany 中的 many, * 必须many数据库的每个实体的外键都弄成真实的reference key, 没有外键的字段用一个默认的真实的键值代替。 * 如果relationship的外键键值为 null, 则one无法使用 get 获取到 many。 * 因此,那些没有群组的联系人,用一个真实的群组代替,群组名字叫 "无群组" */ Log.i("welhzh_g", "" + groupDao.loadAll().size()); group1.delete(); Log.i("welhzh_g", "" + groupDao.loadAll().size()); sipAddr1.refresh(); // reload from db,但是没有更新它自己的 group (relation 没更新) sipAddr1.update(); // save(modify) into db sipAddrDao.refresh(sipAddr1); // 也没有更新 relation sipAddrSession.refresh(sipAddr1); // 也没有更新 relation sipAddrSession.clear(); // 也没有更新 relation myGroup1 = sipAddr1.getGroup(); // 这样取不合理,没有被更新 Log.i("welhzh_g", "" + (null == myGroup1 ? myGroup1 : myGroup1.getGtitle())); myGroup1 = groupDao.load(sipAddr1.getGid()); // 这样最合理,直接从数据库获取的 Log.i("welhzh_g", "" + (null == myGroup1 ? myGroup1 : myGroup1.getGtitle())); } private SipAddrDao setupSipAddrDao() { //create database file if not exist DaoMaster.DevOpenHelper masterHelper = new DaoMaster.DevOpenHelper(this, CONTACTS_DB, null); SQLiteDatabase db = masterHelper.getWritableDatabase(); //get the created database db file DaoMaster master = new DaoMaster(db); //create masterDao DaoSession masterSession = master.newSession(); //Creates Session session sipAddrSession = masterSession; return masterSession.getSipAddrDao(); } private GrouppDao setupGroupDao() { //create database file if not exist DaoMaster.DevOpenHelper masterHelper = new DaoMaster.DevOpenHelper(this, CONTACTS_DB, null); SQLiteDatabase db = masterHelper.getWritableDatabase(); //get the created database db file DaoMaster master = new DaoMaster(db); //create masterDao DaoSession masterSession = master.newSession(); //Creates Session session return masterSession.getGrouppDao(); } }
greedDao 生成 Content Provider :
Each entity has its own ContentProvider for now, just call addContentProvider of your entities.
for example:
Entity clientServer = schema.addEntity("ClientServer"); clientServer.addIdProperty(); clientServer.addIntProperty("tedadMorajeat"); clientServer.addLongProperty("clientId"); clientServer.addLongProperty("serverId"); clientServer.addContentProvider();
但是,在 greendao 1.3.1 及以前的版本里 addContentProvider() 是没实现完的,不知道最新的版本(3.4版)实现完了没有,如果3.4版也不行,可以采用如下解决方案:
As mentionned by SMHJamali, adding the following line will generate ContentProvider classes for each entity : clientServer.addContentProvider();
But as pointed out by greenrobot the feature is not fully implemented yet. If you want to see by yourself but don't see the addContentProvider
function, you need to upgrade to version 1.3.1 de.greenrobot:DaoGenerator:1.3.1
.
I suggest implementing a Contract class and using ProviGen (url: https://github.com/TimotheeJeannin/ProviGen)to generate the ContentProviders.
greendao 在自己指定的路径生成数据库:
For quite some time (Android 2.2 I believe) it is possible use SQLiteOpenHelper
with an absolute path. So for the greendao sample app (only tested with Android 4.4 and 5.0)
File path = new File(Environment.getExternalStorageDirectory(), "my_sdcard_dir/deeper_dir/notes-db"); path.getParentFile().mkdirs(); DevOpenHelper helper = new DaoMaster.DevOpenHelper(this, path.getAbsolutePath(), null); db = helper.getWritableDatabase(); daoMaster = new DaoMaster(db); ...
Alternatively, as the DaoMaster
only needs the database itself, you can ether do this:
File path = new File(Environment.getExternalStorageDirectory(), "my_sdcard_dir/deeper_dir/notes-db"); path.getParentFile().mkdirs(); db = SQLiteDatabase.openOrCreateDatabase(path, null); DaoMaster.createAllTables(db, true); daoMaster = new DaoMaster(db); ...
下面这篇文章更详细的讲解了 greendao 的 relationship 的使用:
http://souly.cn/%E6%8A%80%E6%9C%AF%E5%8D%9A%E6%96%87/2015/05/21/greenDAO%E5%BC%80%E6%BA%90%E6%A1%86%E6%9E%B6%E6%9B%B4%E6%96%B0%E5%92%8C%E5%A4%9A%E8%A1%A8%E5%85%B3%E8%81%94/
更新操作
使用greenDao当android应用升级数据库新增表或者修改表,如何只是修改版本号数据会被清空。 需要自己修改SQLiteOpenHelper:
1.找到greenDao生成的DaoMaster.java文件,里面有SQLiteOpenHelper实现
2.修改DevOpenHelper类里的 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 方法
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.i("greenDAO", "Upgrading schema from version " + oldVersion + " to " + newVersion + " by dropping all tables");
dropAllTables(db, true);
onCreate(db);
}
通过oldVersion newVersion 来判断需要创建表或alter表
http://blog.csdn.net/h3c4lenovo/article/details/43566169
多表关联操作
数据库的表可能涉及到一对一和一对多关系,在greenDAO中涉及到to-one和to-many关系。例如,你想在greenDAO中建立一个对多关系模型,你就 需要使用to-one和to-many关系。但是,请注意,to-one和to-many关系是不相关的,所以你必须同时更新。
关系名称和多种关系
每一个关系都有一个名字,名字用在维持关系的实体类的相应的属性上,默认名称是目标实体的名称。这个名字可以用setName方法重写。 请记住,如果一个实体与同一个目标实体有多个关系,默认名称不能唯一。
To-One关系模型
在greenDAO generator中建模时,必须使一个属性作为外键,使用这个属性,你可以用Entity.addToOne方法增加to-one关系。 addToOne方法的参数是另一个实体,和本实体的外键属性。
/**
* Adds a to-one relationship to the given target entity using the given given foreign key property (which belongs
* to this entity).
*/
public ToOne addToOne(Entity target, Property fkProperty) {
if(protobuf) {
throw new IllegalStateException("Protobuf entities do not support realtions, currently");
}
Property[] fkProperties = { fkProperty };
ToOne toOne = new ToOne(schema, this, target, fkProperties, true);
toOneRelations.add(toOne);
return toOne;
}
/** Convenience for {@link #addToOne(Entity, Property)} with a subsequent call to {@link ToOne#setName(String)}. */
public ToOne addToOne(Entity target, Property fkProperty, String name) {
ToOne toOne = addToOne(target, fkProperty);
toOne.setName(name);
return toOne;
}
例如:user有一个picture属性,user和picture都是普通实体
// The variables "user" and "picture" are just regular entities
Property pictureIdProperty = user.addLongProperty("pictureId").getProperty();
user.addToOne(picture, pictureIdProperty);
这样就使user有一个Picture属性,并且可以直接操作Picture对象,user类具有Picture属性的getPicture/setPicture方法。 to-one关系中的getter方法在第一次加载目标实体的时候是懒汉式加载,之后的访问将返回先前已解析的对象。
注意外键属性(“pictureid”)和实体对象的属性(“picture”)绑在一起。如果你改变了pictureid,下一次调用getPicture()的时候就 会用更新之后的id重新解析Picture实体。同样,如果设置了一个新的picture实体,pictureId属性也会被更新。
greenDAO同样支持在to-one中的饿汉式加载,这会在一次数据库查询中解析一个类的所有to-one关系,这会在你关联实体类时有不错的表现, 目前你可以使用loadDeep和queryDeep方法,以后可能会改变。
关系名称和多种关系
每一关系都有一个名字,它被用于实体的相应的属性中。默认名称是目标实体的名称。这个名字可以用setName方法重写。 如果一个实体与同一个目标实体有多个关系,默认名称不是唯一的。在这种情况下,必须显式地指定关系名。
让我们扩展前面的例子,让user还拥有一个缩略图(thumbnail picture)。因为图片和缩略图都是指同一个实体(picture),所以会有一个名称冲突。 因此,我们将第二个关系重新命名为“缩略图”:
Property pictureIdProperty = user.addLongProperty("pictureId").getProperty();
Property thumbnailIdProperty = user.addLongProperty("thumbnailId").getProperty();
user.addToOne(picture, pictureIdProperty);
user.addToOne(picture, thumbnailIdProperty, "thumbnail");
To-Many关系模型
To-many关系和To-One关系类似,除了外键是放置在目标表中。让我们看看客户/订单的例子,客户可以有多个订单,所以我们用To-Many关系模型, 在数据库中,在订单表中创建customer ID列,来创建1:N关系。这样的话,就可以使用客户的id查询客户的所有的订单。
在greenDAO中建立to-many模型的方法和数据库中的操作类似,首先需要在目标实体中增加一个属性,用于关联To-many关系中的资源实体,然后使用 这个属性,添加到资源实体的To-many关系。
假设我们有一个客户和一个订单实体,我们想把订单连接到一个客户。以下代码将添加到客户实体的To-Many关系:
Property customerId = order.addLongProperty("customerId").notNull().getProperty();
ToMany customerToOrders = customer.addToMany(order, customerId);
customerToOrders.setName("orders"); // Optional
customerToOrders.orderAsc(orderDate); // Optional
这样,我们可以在客户类中简单的调用生成的getOrders()方法获取订单。
To-Many关系的解析和更新
To-Many关系在第一次请求时懒汉式解析,之后,关联的实体被缓存在资源实体的List中。以后再调用get方法不查询数据库。
注意更新To-Many关系模型需要一些额外的工作。因为To-Many的列表已经被缓存,当将关联实体添加到数据库中时,它们不被更新。 下面的代码说明了这种行为:
List orders1 = customer.getOrders();
int size1 = orders1.size();
Order order = new Order();
order.setCustomerId(customer.getId());
daoSession.insert(order);
Listorders2 = customer.getOrders();
// size1 == orders2.size(); // NOT updated
// orders1 == orders2; // SAME list object
因为缓存,您应该手动添加新的关系实体到To-Many关系资源实体的list。这就涉及到如何插入新的关系实体。
1.取得to-many list集合(必须在新实体建立前执行,因为我们不知道我们是否从最新的结果中取得缓存,这样执行后我们就知道了已经缓存了) 2.创造一个实体对象(作为many) 3.在新的实体中设置外键 4.使用insert插入新对象 5.添加新的对象到list
代码如下:
List orders = customer.getOrders();
newOrder.setCustomerId(customer.getId());
daoSession.insert(newOrder);
orders.add(newOrder);
注意,getOrders在insert之前调用,确保list被缓存。如果getOrders在insert之后,如果万一list没有在之前被缓存,那么新的对象 会在list中出现两次。
同样,您可以删除关联实体:
List orders = customer.getOrders();
daoSession.delete(newOrder);
orders.remove(newOrder);
有时,在关联实体添加或删除后手动更新所有To-Many关系可能是繁琐的,甚至是不可能的。为了补救,greendao有reset方法来清除缓存列表。 如果to-many关系可能发生潜在变化,你可以重载关联实体的list:
customer.resetOrders();
List orders2 = customer.getOrders();
双向1:N关系
有时你想实现双向1:n关系,在greendao中,你要添加to-one和to-many关系来实现这个。下面的例子使用我们之前例子的客户和订单, 显示了完整的建模实体的过程。这次我们使用customerId属性创建两种关系。
Entity customer = schema.addEntity("Customer");
customer.addIdProperty();
customer.addStringProperty("name").notNull();
Entity order = schema.addEntity("Order");
order.setTableName("ORDERS"); // "ORDER" is a reserved keyword
order.addIdProperty();
Property orderDate = order.addDateProperty("date").getProperty();
Property customerId = order.addLongProperty("customerId").notNull().getProperty();
order.addToOne(customer, customerId);
ToMany customerToOrders = customer.addToMany(order, customerId);
customerToOrders.setName("orders");
customerToOrders.orderAsc(orderDate);
让我们假设有一个订单的实体。利用这两个关系,我们可以得到客户的信息和客户的所有订单。
List allOrdersOfCustomer = order.getCustomer().getOrders();
Many-to-Many关系(n:m)
在数据库关系模型中M,N是利用连接表。该表的实体具有一系列外键,这些外键关联到每一个关联表。目前greendao不直接支持Many-to-Many关系, 你可以用单独的实体来建模连接表。在实践中,你通常有一个具有额外属性的关系实体,你可能想这样做。在未来的版本, greendao可能会支持N:M关系。
树形关系
你可以通过建立一个具有指向自己的to-one和to-many关系的实体来建立一个树形关系模型:
Entity treeEntity = schema.addEntity("TreeEntity");
treeEntity.addIdProperty();
Property parentIdProperty = treeEntity.addLongProperty("parentId").getProperty();
treeEntity.addToOne(treeEntity, parentIdProperty).setName("parent");
treeEntity.addToMany(treeEntity, parentIdProperty).setName("children");
生成的实体允许你访问它的父节点和子节点:
TreeEntity parent = child.getParent(); List grandChildren = child.getChildren();
greendao 的批量操作,也即transaction:
List<UserInfo> userList = ...;
final UserInfo[] userArray = userList.toArray(new UserInfo[userList.size()]); final UserInfoDao userInfoDao = Db.getDaoSession().getUserInfoDao(); // userInfoDao.deleteAll(); userInfoDao.getSession().runInTx(new Runnable() { @Override public void run() { userInfoDao.saveInTx(userArray);
println("1"); } });
println("2");
注意 runInTx 是同步运行的,只是打了个包,不是异步运行的,别看它是run函数。
也就是说打印的 1 永远在 2 的前面,不管 userInfoDao.saveInTx(userInfos); 这一句操作了多少个对象。
支付宝扫一扫捐赠
![支付宝扫一扫捐赠](https://images.cnblogs.com/cnblogs_com/welhzh/2159800/o_220512091701_hzh_alipay.jpg)
微信公众号: 共鸣圈
欢迎讨论,邮件: 924948$qq.com 请把$改成@
QQ群:263132197
QQ: 924948