Android下Sqlite数据库ORM框架之GreenDao详解

    在大型项目中,android的数据库操作不可能再像第二篇文章那样,用最基础的API去实现各方面的操作,那样效率会十分的底下。那么,在android开发中,提拱了androrm,Ormlite,greenDao三个主流框架,博主三生有幸,再开发第一个项目的时候,就被逼着学习使用greenDao这个ORM框架。现在回过头看,greenDao似乎是三种框架中效率最高的,但是对于初学者来说,使用起来非常的不方面,因为官方是纯英文文档,例子也不够详细。博主那个时候真的是在前进中摸索,各种坎坷,网上的博文介绍的都不够详细,不能满足博主的需求,对于数据库的多表设计,网上的例子也都不够详细,而且大部分都是从官方文档直接copy过来,并不是自己写的,更不会有注释。对于新手不好上手。最近这段时间博主比较有时间,于是整理之前的笔记,在数据库专题来详细讲解一下greendao的使用。博主从零开始,一段一段代码自己敲,并配上注释,保证新手容易上手。熟练掌握greendao的使用。

GreenDao官网:http://greendao-orm.com/

GreenDao github下载地址:https://github.com/greenrobot/greenDAO

GreenDao设计目的:最大性能,最快的Android ORM框架,易于使用的API,高度优化,最小内存的损耗

有兴趣的同学可以将完整的工程下载下来学习,看完后绝对可以掌握GreenDao的使用,可以直接拿去自己的项目工程里使用

示例代码下载地址:http://download.csdn.net/detail/victorfreedom/8353631


好了,废话说完了,接下来一步一步的开发一个使用greenDao的android项目工程。

一、新建一个JAVA工程,用于装载GreenDao类,生成Dao类文件。

在这个工程里面必须导入 greendao-generator.jar和freemarker.jar或者直接在下载下来的例子里面的de.greenrobot.daogenerator包内容导入
博主的项目结构如图:

接下来,我们来写Dao类文件的生成代码,详情请看代码:
  1. package com.batways.apopo.generator;  
  2.   
  3. import de.greenrobot.daogenerator.DaoGenerator;  
  4. import de.greenrobot.daogenerator.Entity;  
  5. import de.greenrobot.daogenerator.Property;  
  6. import de.greenrobot.daogenerator.Schema;  
  7. import de.greenrobot.daogenerator.ToMany;  
  8.   
  9. /** 
  10.  * @ClassName: TestCase 
  11.  * @author victor_freedom (x_freedom_reddevil@126.com) 
  12.  * @createddate 2015-1-12 下午2:17:52 
  13.  * @Description: TODO 
  14.  */  
  15. public class TestCase {  
  16.     // 数据库升级  
  17.     private static int dbVersion = 1;  
  18.     private String modelPackage = "com.example.freedomsql.bean";  
  19.     private Schema schema = new Schema(dbVersion, modelPackage);  
  20.   
  21.     public static void main(String[] args) throws Exception {  
  22.         TestCase testCase = new TestCase();  
  23.         testCase.init();  
  24.         testCase.schema.enableKeepSectionsByDefault();  
  25.         testCase.schema.enableActiveEntitiesByDefault();  
  26.         new DaoGenerator().generateAll(testCase.schema,  
  27.                 "E:\\mayflygeek\\mayflygeekprojects\\FreedomSql\\src");  
  28.     }  
  29.   
  30.     public void init() {  
  31.   
  32.         // 定义一个实体  
  33.         Entity OrderHeader = schema.addEntity("OrderHeader");  
  34.         // 实现序列化接口  
  35.         OrderHeader.implementsSerializable();  
  36.         // 定义ID主键  
  37.         OrderHeader.addIdProperty();  
  38.         // 增加其他字段,这里可以定义很多类型,还可以指定属性  
  39.         OrderHeader.addStringProperty("orderName").notNull();  
  40.           
  41.         //如果不想用上面的定义ID主键,还可以自己这样定义。  
  42. //      OrderHeader.addLongProperty("orderId").primaryKey().autoincrement();  
  43.   
  44.         //后面的实体定义和上面的差不多。就不在详细描述  
  45.         Entity OrderItem = schema.addEntity("OrderItem");  
  46.         OrderItem.implementsSerializable();  
  47.         OrderItem.addIdProperty();  
  48.         OrderItem.addStringProperty("itemName");  
  49.         // 用于做多表设计使用  
  50.         Property orderId = OrderItem.addLongProperty("orderId").getProperty();  
  51.   
  52.         Entity Student = schema.addEntity("Student");  
  53.         Student.implementsSerializable();  
  54.         Student.addIdProperty();  
  55.         Student.addStringProperty("studentName");  
  56.         // 增加一个字段,数据库升级  
  57.         // Student.addDoubleProperty("results");  
  58.   
  59.         Entity Teacher = schema.addEntity("Teacher");  
  60.         Teacher.implementsSerializable();  
  61.         Teacher.addIdProperty();  
  62.         Teacher.addStringProperty("teacherName");  
  63.           
  64.         Entity StudentTeacher = schema.addEntity("StudentTeacher");  
  65.         Property teacherId = StudentTeacher.addLongProperty("teacherId")  
  66.                 .getProperty();  
  67.         Property studentId = StudentTeacher.addLongProperty("studentId")  
  68.                 .getProperty();  
  69.   
  70.         // Entity Grade = schema.addEntity("Grade");  
  71.         // Grade.implementsSerializable();  
  72.         // Grade.addIdProperty();  
  73.         // Grade.addStringProperty("gradeName");  
  74.   
  75.         // 树状结构,自身实现1对多  
  76.         Entity Tree = schema.addEntity("Tree");  
  77.         Tree.addIdProperty();  
  78.         Tree.addStringProperty("treeName");  
  79.         Property parentId = Tree.addLongProperty("parentId").getProperty();  
  80.         Tree.addToOne(Tree, parentId).setName("parent");  
  81.         Tree.addToMany(Tree, parentId).setName("children");  
  82.   
  83.         // 外键添加,1对多  
  84.         OrderItem.addToOne(OrderHeader, orderId);  
  85.         ToMany addToMany = OrderHeader.addToMany(OrderItem, orderId);  
  86.         addToMany.setName("orderItems");  
  87.   
  88.         // greenDao不支持多对多的实现,但是我们可以 自定义实现多对多  
  89.         StudentTeacher.addToOne(Student, studentId);  
  90.         StudentTeacher.addToOne(Teacher, teacherId);  
  91.         Student.addToMany(StudentTeacher, studentId)  
  92.                 .setName("studentsteachers");  
  93.         Teacher.addToMany(StudentTeacher, teacherId)  
  94.                 .setName("studentsteachers");  
  95.   
  96.     }  
  97. }  

二、Android工程中GreenDao的使用

首先需要导入对应的jar包。这个无需在详细说明。下载下来的例子里面有。

1、Android工程中代码生成的结构

1、DaoMaster,DaoSession的生成

  这两个文件是最关键的两个文件,数据库的生成和表的操作都在这两个类里面。如果没有指定生成目录,会和实体文件一起生成在同一目录里面

2、实体类和对应Dao类的生成

这里以OrderHeader实体来说明,详情看代码:
  1. package com.example.freedomsql.bean;  
  2.   
  3. import java.util.List;  
  4. import com.example.freedomsql.bean.DaoSession;  
  5. import de.greenrobot.dao.DaoException;  
  6.   
  7. // THIS CODE IS GENERATED BY greenDAO, EDIT ONLY INSIDE THE "KEEP"-SECTIONS  
  8.   
  9. // KEEP INCLUDES - put your custom includes here  
  10. // KEEP INCLUDES END  
  11. /** 
  12.  * Entity mapped to table ORDER_HEADER. 
  13.  */  
  14. public class OrderHeader implements java.io.Serializable {  
  15.   
  16.     private Long id;  
  17.     private String orderName;  
  18.   
  19.     /** Used to resolve relations */  
  20.     private transient DaoSession daoSession;  
  21.   
  22.     /** Used for active entity operations. */  
  23.     private transient OrderHeaderDao myDao;  
  24.   
  25.     private List<OrderItem> orderItems;  
  26.   
  27.     // 如果设置了enableKeepSectionsByDefault();enableActiveEntitiesByDefault();这两个属性,那么我们可以再指定的区域内写入自定义代码,方便下次升级的时候不会被覆盖掉  
  28.     // KEEP FIELDS - put your custom fields here  
  29.     // KEEP FIELDS END  
  30.   
  31.     public OrderHeader() {  
  32.     }  
  33.   
  34.     public OrderHeader(Long id) {  
  35.         this.id = id;  
  36.     }  
  37.   
  38.     public OrderHeader(Long id, String orderName) {  
  39.         this.id = id;  
  40.         this.orderName = orderName;  
  41.     }  
  42.   
  43.     /** called by internal mechanisms, do not call yourself. */  
  44.     public void __setDaoSession(DaoSession daoSession) {  
  45.         this.daoSession = daoSession;  
  46.         myDao = daoSession != null ? daoSession.getOrderHeaderDao() : null;  
  47.     }  
  48.   
  49.     public Long getId() {  
  50.         return id;  
  51.     }  
  52.   
  53.     public void setId(Long id) {  
  54.         this.id = id;  
  55.     }  
  56.   
  57.     public String getOrderName() {  
  58.         return orderName;  
  59.     }  
  60.   
  61.     public void setOrderName(String orderName) {  
  62.         this.orderName = orderName;  
  63.     }  
  64.   
  65.     /** 
  66.      * To-many relationship, resolved on first access (and after reset). Changes 
  67.      * to to-many relations are not persisted, make changes to the target 
  68.      * entity. 
  69.      */  
  70.     public List<OrderItem> getOrderItems() {  
  71.         if (orderItems == null) {  
  72.             if (daoSession == null) {  
  73.                 throw new DaoException("Entity is detached from DAO context");  
  74.             }  
  75.             OrderItemDao targetDao = daoSession.getOrderItemDao();  
  76.             List<OrderItem> orderItemsNew = targetDao  
  77.                     ._queryOrderHeader_OrderItems(id);  
  78.             synchronized (this) {  
  79.                 if (orderItems == null) {  
  80.                     orderItems = orderItemsNew;  
  81.                 }  
  82.             }  
  83.         }  
  84.         return orderItems;  
  85.     }  
  86.   
  87.     /** 
  88.      * Resets a to-many relationship, making the next get call to query for a 
  89.      * fresh result. 
  90.      */  
  91.     public synchronized void resetOrderItems() {  
  92.         orderItems = null;  
  93.     }  
  94.   
  95.     /** 
  96.      * Convenient call for {@link AbstractDao#delete(Object)}. Entity must 
  97.      * attached to an entity context. 
  98.      */  
  99.     public void delete() {  
  100.         if (myDao == null) {  
  101.             throw new DaoException("Entity is detached from DAO context");  
  102.         }  
  103.         myDao.delete(this);  
  104.     }  
  105.   
  106.     /** 
  107.      * Convenient call for {@link AbstractDao#update(Object)}. Entity must 
  108.      * attached to an entity context. 
  109.      */  
  110.     public void update() {  
  111.         if (myDao == null) {  
  112.             throw new DaoException("Entity is detached from DAO context");  
  113.         }  
  114.         myDao.update(this);  
  115.     }  
  116.   
  117.     /** 
  118.      * Convenient call for {@link AbstractDao#refresh(Object)}. Entity must 
  119.      * attached to an entity context. 
  120.      */  
  121.     public void refresh() {  
  122.         if (myDao == null) {  
  123.             throw new DaoException("Entity is detached from DAO context");  
  124.         }  
  125.         myDao.refresh(this);  
  126.     }  
  127.   
  128.     // KEEP METHODS - put your custom methods here  
  129.     // KEEP METHODS END  
  130.   
  131. }  
这里需要特别注意的是,在使用getOrderItems()拿到自己1对多的实体内容的时候,一定要记得resetOrderItems一下,不然由于缓存机制,会拿不到最新的实体内容。我们可以看到刚刚在test类中设置的内容都出现了,而且和Orderitem的1对多关系也得到了体现。在数据库操作的时候会变得非常的便捷
在看看Dao类
  1. package com.example.freedomsql.bean;  
  2.   
  3. import android.database.Cursor;  
  4. import android.database.sqlite.SQLiteDatabase;  
  5. import android.database.sqlite.SQLiteStatement;  
  6.   
  7. import de.greenrobot.dao.AbstractDao;  
  8. import de.greenrobot.dao.Property;  
  9. import de.greenrobot.dao.internal.DaoConfig;  
  10.   
  11. import com.example.freedomsql.bean.OrderHeader;  
  12.   
  13. // THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.  
  14. /**  
  15.  * DAO for table ORDER_HEADER. 
  16. */  
  17. public class OrderHeaderDao extends AbstractDao<OrderHeader, Long> {  
  18.   
  19.     public static final String TABLENAME = "ORDER_HEADER";  
  20.   
  21.     /** 
  22.      * Properties of entity OrderHeader.<br/> 
  23.      * Can be used for QueryBuilder and for referencing column names. 
  24.     */  
  25.     public static class Properties {  
  26.         public final static Property Id = new Property(0, Long.class"id"true"_id");  
  27.         public final static Property OrderName = new Property(1, String.class"orderName"false"ORDER_NAME");  
  28.     };  
  29.   
  30.     private DaoSession daoSession;  
  31.   
  32.   
  33.     public OrderHeaderDao(DaoConfig config) {  
  34.         super(config);  
  35.     }  
  36.       
  37.     public OrderHeaderDao(DaoConfig config, DaoSession daoSession) {  
  38.         super(config, daoSession);  
  39.         this.daoSession = daoSession;  
  40.     }  
  41.   
  42.     /** Creates the underlying database table. */  
  43.     public static void createTable(SQLiteDatabase db, boolean ifNotExists) {  
  44.         String constraint = ifNotExists? "IF NOT EXISTS """;  
  45.         db.execSQL("CREATE TABLE " + constraint + "'ORDER_HEADER' (" + //  
  46.                 "'_id' INTEGER PRIMARY KEY ," + // 0: id  
  47.                 "'ORDER_NAME' TEXT);"); // 1: orderName  
  48.     }  
  49.   
  50.     /** Drops the underlying database table. */  
  51.     public static void dropTable(SQLiteDatabase db, boolean ifExists) {  
  52.         String sql = "DROP TABLE " + (ifExists ? "IF EXISTS " : "") + "'ORDER_HEADER'";  
  53.         db.execSQL(sql);  
  54.     }  
  55.   
  56.     /** @inheritdoc */  
  57.     @Override  
  58.     protected void bindValues(SQLiteStatement stmt, OrderHeader entity) {  
  59.         stmt.clearBindings();  
  60.    
  61.         Long id = entity.getId();  
  62.         if (id != null) {  
  63.             stmt.bindLong(1, id);  
  64.         }  
  65.    
  66.         String orderName = entity.getOrderName();  
  67.         if (orderName != null) {  
  68.             stmt.bindString(2, orderName);  
  69.         }  
  70.     }  
  71.   
  72.     @Override  
  73.     protected void attachEntity(OrderHeader entity) {  
  74.         super.attachEntity(entity);  
  75.         entity.__setDaoSession(daoSession);  
  76.     }  
  77.   
  78.     /** @inheritdoc */  
  79.     @Override  
  80.     public Long readKey(Cursor cursor, int offset) {  
  81.         return cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0);  
  82.     }      
  83.   
  84.     /** @inheritdoc */  
  85.     @Override  
  86.     public OrderHeader readEntity(Cursor cursor, int offset) {  
  87.         OrderHeader entity = new OrderHeader( //  
  88.             cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0), // id  
  89.             cursor.isNull(offset + 1) ? null : cursor.getString(offset + 1// orderName  
  90.         );  
  91.         return entity;  
  92.     }  
  93.        
  94.     /** @inheritdoc */  
  95.     @Override  
  96.     public void readEntity(Cursor cursor, OrderHeader entity, int offset) {  
  97.         entity.setId(cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0));  
  98.         entity.setOrderName(cursor.isNull(offset + 1) ? null : cursor.getString(offset + 1));  
  99.      }  
  100.       
  101.     /** @inheritdoc */  
  102.     @Override  
  103.     protected Long updateKeyAfterInsert(OrderHeader entity, long rowId) {  
  104.         entity.setId(rowId);  
  105.         return rowId;  
  106.     }  
  107.       
  108.     /** @inheritdoc */  
  109.     @Override  
  110.     public Long getKey(OrderHeader entity) {  
  111.         if(entity != null) {  
  112.             return entity.getId();  
  113.         } else {  
  114.             return null;  
  115.         }  
  116.     }  
  117.   
  118.     /** @inheritdoc */  
  119.     @Override      
  120.     protected boolean isEntityUpdateable() {  
  121.         return true;  
  122.     }  
  123.       
  124. }  
我们可以看到对应的表生成语句和字段绑定等都在这个类里面。其实这个类和之前哪篇文件说的Dao类一样,是操作数据库用的。增删改查全部靠这个类来实行。

2、使用greenDao在项目中操作数据库。

1、操作DaoMaster,DaoSession类编写

    之前说过,DaoMaster和DaoSession是非常关键的两个类,所以我们需要单独将他们两个类独立出来处理,新建一个GreenDao类来实现,详情看代码:
  1. package com.example.freedomsql.bean;  
  2.   
  3. import android.content.Context;  
  4.   
  5. import com.example.freedomsql.utils.Config;  
  6.   
  7. /** 
  8.  * @ClassName: GreenDao 
  9.  * @author victor_freedom (x_freedom_reddevil@126.com) 
  10.  * @createddate 2015-1-12 下午3:21:02 
  11.  * @Description: TODO 
  12.  */  
  13. public class GreenDao {  
  14.     private static DaoMaster daoMaster;  
  15.     private static DaoSession daoSession;  
  16.   
  17.     /** 
  18.      * 获取DaoMaster实例 
  19.      *  
  20.      * @param context 
  21.      * @return 
  22.      */  
  23.     public static DaoMaster getDaoMaster(Context context) {  
  24.         if (daoMaster == null) {  
  25.             DaoMaster.OpenHelper helper = new DaoMaster.DevOpenHelper(context,  
  26.                     Config.DB_NAME, null);  
  27.             daoMaster = new DaoMaster(helper.getWritableDatabase());  
  28.         }  
  29.         return daoMaster;  
  30.     }  
  31.   
  32.     /** 
  33.      * 获取DaoSession实例 
  34.      *  
  35.      * @param context 
  36.      * @return 
  37.      */  
  38.     public static DaoSession getDaoSession(Context context) {  
  39.         if (daoSession == null) {  
  40.             if (daoMaster == null) {  
  41.                 daoMaster = getDaoMaster(context);  
  42.             }  
  43.             daoSession = daoMaster.newSession();  
  44.         }  
  45.         return daoSession;  
  46.     }  
  47. }  

2、数据库增删改查接口类编写

   在拿到两个非常重要的类之后,接下来就是对数据库操作的接口类的编写。我们以OrderHeader和OrderItem类来举例说明我们写先接口
  1. package com.example.freedomsql.service;  
  2.   
  3. import com.example.freedomsql.bean.OrderHeader;  
  4. import com.example.freedomsql.bean.OrderItem;  
  5. import com.example.freedomsql.bean.Student;  
  6. import com.example.freedomsql.bean.Teacher;  
  7.   
  8. public interface IOrderHeaderService {  
  9.   
  10.     /** 
  11.      * @Title: createOrder 
  12.      * @Description: 创建一个订单 
  13.      * @param order 
  14.      * @return 
  15.      * @throws 
  16.      */  
  17.     public OrderHeader createOrder(OrderHeader order);  
  18.   
  19.     /** 
  20.      * @Title: updateOrder 
  21.      * @Description: 更新一个订单 
  22.      * @param orderHeader 
  23.      * @return 
  24.      * @throws 
  25.      */  
  26.     public OrderHeader updateOrder(OrderHeader orderHeader);  
  27.   
  28.     /** 
  29.      * @Title: findOrderByName 
  30.      * @Description: 根据名称查找订单 
  31.      * @param orderName 
  32.      * @return 
  33.      * @throws 
  34.      */  
  35.     public OrderHeader findOrderByName(String orderName);  
  36.   
  37.     /** 
  38.      * @Title: findOrderById 
  39.      * @Description: 根据主键ID查找订单 
  40.      * @param orderId 
  41.      * @return 
  42.      * @throws 
  43.      */  
  44.     public OrderHeader findOrderById(long orderId);  
  45.   
  46.     /** 
  47.      * @Title: findOrderItemById 
  48.      * @Description:根据主键ID查找订单明细 
  49.      * @param orderItemId 
  50.      * @return 
  51.      * @throws 
  52.      */  
  53.     public OrderItem findOrderItemById(long orderItemId);  
  54.   
  55.     /** 
  56.      * @Title: findOrderItemByName 
  57.      * @Description: 根据名称查找订单明细 
  58.      * @param orderItemName 
  59.      * @return 
  60.      * @throws 
  61.      */  
  62.     public OrderItem findOrderItemByName(String orderItemName);  
  63.   
  64.     /** 
  65.      * @Title: createOrderItem 
  66.      * @Description: 创建订单明细 
  67.      * @param orderHeader 
  68.      * @param name 
  69.      * @return 
  70.      * @throws 
  71.      */  
  72.     public OrderItem createOrderItem(OrderHeader orderHeader, String name);  
  73. }  
接下来写实现类:
  1. package com.example.freedomsql.service.impl;  
  2.   
  3. import android.content.Context;  
  4.   
  5. import com.example.freedomsql.bean.DaoSession;  
  6. import com.example.freedomsql.bean.GreenDao;  
  7. import com.example.freedomsql.bean.OrderHeader;  
  8. import com.example.freedomsql.bean.OrderHeaderDao;  
  9. import com.example.freedomsql.bean.OrderItem;  
  10. import com.example.freedomsql.bean.OrderItemDao;  
  11. import com.example.freedomsql.service.IOrderHeaderService;  
  12.   
  13. /** 
  14.  * @ClassName: OrderHeaderService 
  15.  * @author victor_freedom (x_freedom_reddevil@126.com) 
  16.  * @createddate 2015-1-12 下午3:26:41 
  17.  * @Description: TODO 
  18.  */  
  19. public class OrderHeaderService implements IOrderHeaderService {  
  20.   
  21.     private static DaoSession daoSession;  
  22.     private static OrderHeaderService service;  
  23.     private OrderHeaderDao orderHeaderDao;  
  24.     private OrderItemDao orderItemDao;  
  25.   
  26.     private OrderHeaderService(OrderHeaderDao orderHeaderDao,  
  27.             OrderItemDao orderItemDao) {  
  28.         this.orderHeaderDao = orderHeaderDao;  
  29.         this.orderItemDao = orderItemDao;  
  30.     }  
  31.   
  32.     /** 
  33.      * @param context 
  34.      * @return 
  35.      */  
  36.     public static OrderHeaderService getService(Context context) {  
  37.         if (service == null) {  
  38.             daoSession = GreenDao.getDaoSession(context);  
  39.             service = new OrderHeaderService(daoSession.getOrderHeaderDao(),  
  40.                     daoSession.getOrderItemDao());  
  41.         }  
  42.         return service;  
  43.     }  
  44.   
  45.     @Override  
  46.     public OrderHeader createOrder(OrderHeader order) {  
  47.         return orderHeaderDao.loadByRowId(orderHeaderDao.insert(order));  
  48.     }  
  49.   
  50.     @Override  
  51.     public OrderHeader updateOrder(OrderHeader orderHeader) {  
  52.         orderHeaderDao.update(orderHeader);  
  53.         return orderHeader;  
  54.     }  
  55.   
  56.     @Override  
  57.     public OrderHeader findOrderByName(String orderName) {  
  58.         OrderHeader orderHeader = orderHeaderDao.queryBuilder()  
  59.                 .where(OrderHeaderDao.Properties.OrderName.eq(orderName))  
  60.                 .unique();  
  61.         return orderHeader;  
  62.     }  
  63.   
  64.     @Override  
  65.     public OrderHeader findOrderById(long orderId) {  
  66.         return orderHeaderDao.load(orderId);  
  67.     }  
  68.   
  69.     @Override  
  70.     public OrderItem findOrderItemById(long orderItemId) {  
  71.         return orderItemDao.load(orderItemId);  
  72.     }  
  73.   
  74.     @Override  
  75.     public OrderItem findOrderItemByName(String orderItemName) {  
  76.         return orderItemDao.queryBuilder()  
  77.                 .where(OrderItemDao.Properties.ItemName.eq(orderItemName))  
  78.                 .unique();  
  79.     }  
  80.   
  81.     @Override  
  82.     public OrderItem createOrderItem(OrderHeader orderHeader, String name) {  
  83.         OrderItem orderItem = new OrderItem();  
  84.         orderItem.setItemName(name);  
  85.         orderItem.setOrderHeader(orderHeader);  
  86.         return orderItemDao.load(orderItemDao.insert(orderItem));  
  87.     }  
  88.   
  89. }  

我们可以看到,查询条件非常容易写,这里博主只写了些简单的查询条件,在where方法中是可以支持多条件限制查询的,查询方法非常的强大。还支持延迟lazy查询。但是使用延迟查询的话要记得close()掉。我们可以将相关系的表文件的Dao文件写到一起,便于查询方法的编写。这里博主没有演示删除操作,其实也非常简单,API在Dao类里面,一看就懂的。

3、在主项目中的编写

1、接口位置的放置
这些接口,我们肯定是要做成全局变量的,那么,之前说过,全局变量的最好放置地方就是在Application中,参考代码如下
  1. package com.example.freedomsql;  
  2.   
  3. import android.app.Application;  
  4.   
  5. import com.example.freedomsql.service.IClassService;  
  6. import com.example.freedomsql.service.IOrderHeaderService;  
  7. import com.example.freedomsql.service.impl.ClassService;  
  8. import com.example.freedomsql.service.impl.OrderHeaderService;  
  9.   
  10. /** 
  11.  * @ClassName: FreedomApplication 
  12.  * @author victor_freedom (x_freedom_reddevil@126.com) 
  13.  * @createddate 2015-1-12 下午3:39:56 
  14.  * @Description: TODO 
  15.  */  
  16. public class FreedomApplication extends Application {  
  17.   
  18.     public IClassService classService;  
  19.     public IOrderHeaderService orderHeaderService;  
  20.   
  21.     @Override  
  22.     public void onCreate() {  
  23.         super.onCreate();  
  24.         classService = ClassService.getService(getApplicationContext());  
  25.         orderHeaderService = OrderHeaderService  
  26.                 .getService(getApplicationContext());  
  27.     }  
  28. }  
2、主Activity的编写
我们需要在这里生成一些数据来观察数据库:(那些 注释掉的东西是博主后面用来升级数据库使用的)
  1. package com.example.freedomsql;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5.   
  6. import com.example.freedomsql.bean.OrderHeader;  
  7. import com.example.freedomsql.bean.Student;  
  8. import com.example.freedomsql.bean.StudentTeacher;  
  9. import com.example.freedomsql.bean.Teacher;  
  10. import com.example.freedomsql.service.IClassService;  
  11. import com.example.freedomsql.service.IOrderHeaderService;  
  12.   
  13. public class MainActivity extends Activity {  
  14.     private IClassService classService;  
  15.     private IOrderHeaderService orderHeaderService;  
  16.   
  17.     @Override  
  18.     protected void onCreate(Bundle savedInstanceState) {  
  19.         super.onCreate(savedInstanceState);  
  20.         setContentView(R.layout.activity_main);  
  21.         classService = ((FreedomApplication) getApplication()).classService;  
  22.         orderHeaderService = ((FreedomApplication) getApplication()).orderHeaderService;  
  23.         initGreenDaoDB();  
  24.     }  
  25.   
  26.     private void initGreenDaoDB() {  
  27.         Teacher t1 = new Teacher();  
  28.         t1.setTeacherName("freedom");  
  29.         // t1.setTeacherName("freedom2");  
  30.         classService.createTeacher(t1);  
  31.         Teacher t2 = new Teacher();  
  32.         t2.setTeacherName("freedom1");  
  33.         // t2.setTeacherName("freedom3");  
  34.         Student t3 = new Student();  
  35.         t3.setStudentName("victor");  
  36.         // t3.setStudentName("victor2");  
  37.         Student t4 = new Student();  
  38.          t4.setStudentName("victor1");  
  39.         // t4.setStudentName("victor3");  
  40.         classService.createTeacher(t1);  
  41.         classService.createTeacher(t2);  
  42.         classService.createStudent(t3);  
  43.         classService.createStudent(t4);  
  44.         StudentTeacher st1 = new StudentTeacher(t1.getId(), t3.getId());  
  45.         StudentTeacher st2 = new StudentTeacher(t1.getId(), t4.getId());  
  46.         StudentTeacher st3 = new StudentTeacher(t2.getId(), t3.getId());  
  47.         StudentTeacher st4 = new StudentTeacher(t2.getId(), t4.getId());  
  48.         classService.createStudentTeacher(st1);  
  49.         classService.createStudentTeacher(st2);  
  50.         classService.createStudentTeacher(st3);  
  51.         classService.createStudentTeacher(st4);  
  52.         OrderHeader order = new OrderHeader();  
  53.         order.setOrderName("订单1");  
  54.         // order.setOrderName("订单3");  
  55.         OrderHeader order1 = new OrderHeader();  
  56.         order1.setOrderName("订单2");  
  57.         // order1.setOrderName("订单4");  
  58.         orderHeaderService.createOrder(order);  
  59.         orderHeaderService.createOrder(order1);  
  60.         orderHeaderService.createOrderItem(order1, "明细1");  
  61.         orderHeaderService.createOrderItem(order1, "明细2");  
  62.         // orderHeaderService.createOrderItem(order1, "明细3");  
  63.         // orderHeaderService.createOrderItem(order1, "明细4");  
  64.   
  65.     }  
  66. }  

生成数据后如图所示:这里就只上传OrderHeader和OrderItem的图


好了,greenDao的操作基本讲解完毕,相信看了代码的同学基本上学会了如何使用GreenDao,以及多表结构的设计。博主这里就不演示那些查询方法了,都很简单,通俗易懂。接下来博主再讲讲再数据库升级中,如何保存原有数据。


3、使用GreenDao升级数据库

1、TestCase类文件修改

    数据库的升级,一般是在于字段的增加或者表的增加,这里,博主再一个实体中增加一个字段,又增加一个实体来演示
    首先,增加数据库版本号:
  1. private static int dbVersion = 2;  

    再在Student类中增加一个字段
  1. // 增加一个字段,数据库升级  
  2.          Student.addDoubleProperty("results");  

    增加一个实体Grade
  1. Entity Grade = schema.addEntity("Grade");  
  2.         Grade.implementsSerializable();  
  3.         Grade.addIdProperty();  
  4.         Grade.addStringProperty("gradeName");  

2、DaoMaster类的修改,这里我们只需要重写一下onUpgrade方法

  1. @Override  
  2. public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {  
  3.     Log.i("greenDAO""Upgrading schema from version " + oldVersion  
  4.             + " to " + newVersion + " by dropping all tables");  
  5.     //正常情况下,GreenDao默认升级的时候,将所有的表删除后再建,所以我们需要在这里处理  
  6.     // dropAllTables(db, true);  
  7.     // onCreate(db);  
  8.     if (oldVersion == 1 && newVersion == 2) {  
  9.         // 增加一个实体表  
  10.         GradeDao.createTable(db, false);  
  11.         // 修改Student表  
  12.         db.execSQL("ALTER TABLE 'STUDENT' ADD 'RESULTS' REAL");  
  13.     }  
  14.   
  15. }  

3、主Activity的修改,其他地方都不用修改了

对于主Activity,我们需要重新生成一些数据对比之前的数据即可
  1. package com.example.freedomsql;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5.   
  6. import com.example.freedomsql.bean.OrderHeader;  
  7. import com.example.freedomsql.bean.Student;  
  8. import com.example.freedomsql.bean.StudentTeacher;  
  9. import com.example.freedomsql.bean.Teacher;  
  10. import com.example.freedomsql.service.IClassService;  
  11. import com.example.freedomsql.service.IOrderHeaderService;  
  12.   
  13. public class MainActivity extends Activity {  
  14.     private IClassService classService;  
  15.     private IOrderHeaderService orderHeaderService;  
  16.   
  17.     @Override  
  18.     protected void onCreate(Bundle savedInstanceState) {  
  19.         super.onCreate(savedInstanceState);  
  20.         setContentView(R.layout.activity_main);  
  21.         classService = ((FreedomApplication) getApplication()).classService;  
  22.         orderHeaderService = ((FreedomApplication) getApplication()).orderHeaderService;  
  23.         initGreenDaoDB();  
  24.     }  
  25.   
  26.     private void initGreenDaoDB() {  
  27.         Teacher t1 = new Teacher();  
  28.         // t1.setTeacherName("freedom");  
  29.         t1.setTeacherName("freedom2");  
  30.         classService.createTeacher(t1);  
  31.         Teacher t2 = new Teacher();  
  32.         // t2.setTeacherName("freedom1");  
  33.         t2.setTeacherName("freedom3");  
  34.         Student t3 = new Student();  
  35.         // t3.setStudentName("victor");  
  36.         t3.setStudentName("victor2");  
  37.         Student t4 = new Student();  
  38.         // t4.setStudentName("victor1");  
  39.         t4.setStudentName("victor3");  
  40.         classService.createTeacher(t1);  
  41.         classService.createTeacher(t2);  
  42.         classService.createStudent(t3);  
  43.         classService.createStudent(t4);  
  44.         StudentTeacher st1 = new StudentTeacher(t1.getId(), t3.getId());  
  45.         StudentTeacher st2 = new StudentTeacher(t1.getId(), t4.getId());  
  46.         StudentTeacher st3 = new StudentTeacher(t2.getId(), t3.getId());  
  47.         StudentTeacher st4 = new StudentTeacher(t2.getId(), t4.getId());  
  48.         classService.createStudentTeacher(st1);  
  49.         classService.createStudentTeacher(st2);  
  50.         classService.createStudentTeacher(st3);  
  51.         classService.createStudentTeacher(st4);  
  52.         OrderHeader order = new OrderHeader();  
  53.         // order.setOrderName("订单1");  
  54.         order.setOrderName("订单3");  
  55.         OrderHeader order1 = new OrderHeader();  
  56.         // order1.setOrderName("订单2");  
  57.         order1.setOrderName("订单4");  
  58.         orderHeaderService.createOrder(order);  
  59.         orderHeaderService.createOrder(order1);  
  60.         // orderHeaderService.createOrderItem(order1, "明细1");  
  61.         // orderHeaderService.createOrderItem(order1, "明细2");  
  62.         orderHeaderService.createOrderItem(order1, "明细3");  
  63.         orderHeaderService.createOrderItem(order1, "明细4");  
  64.   
  65.     }  
  66. }  

我们来看看运行前后的数据库Student表效果图对比


我们可以看到新生的字段也在,之前的数据也在

在看看新生成的Grade表



我们可以看到GRADE表也成功的生成了。整个数据库的数据都还保留着。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值