Android greenDAO数据库配置教程

一、环境配置

1、在Android Studio中,在.src/main目录下新建一个Java-gen文件夹,和java文件夹同级。用于存放greenDAO生成的DaoMaster、DaoSession、Table、TableDaoSession实体类。


Android greenDAO数据库配置教程_第1张图片

2、配置项目的app.gradle文件,指定java-gen文件,引入greenDAO第三方jar包

Android greenDAO数据库配置教程_第2张图片

[java]  view plain  copy
 
  1. sourceSets {  
  2.         main {  
  3.             java.srcDirs = ['src/main/java''src/main/java-gen']  
  4.         }  
  5.     }  
[java]  view plain  copy
 
  1. compile 'de.greenrobot:greendao:1.3.7'  

3、新建一个greengenerator模块,用于代码自动生成DaoMaster、DaoSession、Table、TableDao实体类

Android greenDAO数据库配置教程_第3张图片


Android greenDAO数据库配置教程_第4张图片

Android greenDAO数据库配置教程_第5张图片

配置新建moudle的build.gradle文件

Android greenDAO数据库配置教程_第6张图片

[java]  view plain  copy
 
  1. compile 'de.greenrobot:greendao-generator:1.3.1'  


至此,greenDAO的环境配置就完成了。


二、利用greedgenerater模块生成DaoMaster、DaoSession、Table、TableDao实体类的代码,编写moudle下的MyClass类

[java]  view plain  copy
 
  1. import de.greenrobot.daogenerator.DaoGenerator;  
  2. import de.greenrobot.daogenerator.Entity;  
  3. import de.greenrobot.daogenerator.Schema;  
  4.   
  5. public class MyClass {  
  6.     public static void main(String[] args) throws Exception {  
  7.         // 正如你所见的,你创建了一个用于添加实体(Entity)的模式(Schema)对象。  
  8.         // 两个参数分别代表:数据库版本号与自动生成代码的包路径。  
  9.         Schema schema = new Schema(1"test.greendao");  
  10. //      当然,如果你愿意,你也可以分别指定生成的 Bean 与 DAO 类所在的目录,只要如下所示:  
  11. //      Schema schema = new Schema(1, "test.greendao.bean");  
  12. //      schema.setDefaultJavaPackageDao("test.greendao.dao");  
  13.   
  14.         // 模式(Schema)同时也拥有两个默认的 flags,分别用来标示 entity 是否是 activie 以及是否使用 keep sections。  
  15.         // schema2.enableActiveEntitiesByDefault();  
  16.         // schema2.enableKeepSectionsByDefault();  
  17.   
  18.         // 一旦你拥有了一个 Schema 对象后,你便可以使用它添加实体(Entities)了。  
  19.         addNote(schema);  
  20.   
  21.         // 最后我们将使用 DAOGenerator 类的 generateAll() 方法自动生成代码,此处你需要根据自己的情况更改输出目录(既之前创建的 java-gen)。  
  22.         // 其实,输出目录的路径可以在 build.gradle 中设置,有兴趣的朋友可以自行搜索,这里就不再详解。  
  23.         new DaoGenerator().generateAll(schema, "/Users/licheng/Documents/Healthdoctor/app/src/main/java-gen");  
  24.     }  
  25.   
  26.     /** 
  27.      * @param schema 
  28.      */  
  29.     private static void addNote(Schema schema) {  
  30.         // 一个实体(类)就关联到数据库中的一张表,此处表名为「Note」(既类名)  
  31.         Entity note = schema.addEntity("TestTable");  
  32.         // 你也可以重新给表命名  
  33.         // note.setTableName("NODE");  
  34.   
  35.         // greenDAO 会自动根据实体类的属性值来创建表字段,并赋予默认值  
  36.         // 接下来你便可以设置表中的字段:  
  37.         note.addIdProperty();  
  38.         note.addStringProperty("aa");  
  39.         // 与在 Java 中使用驼峰命名法不同,默认数据库中的命名是使用大写和下划线来分割单词的。  
  40.         // For example, a property called “creationDate” will become a database column “CREATION_DATE”.  
  41.         note.addIntProperty("bb");  
  42.         note.addIntProperty("cc");  
  43.         note.addIntProperty("dd");  
  44.         note.addIntProperty("ee");  
  45.     }  
  46. }  

Android greenDAO数据库配置教程_第7张图片

如果运行结果打印如下,说明配置成功并且实体类生成成功

Android greenDAO数据库配置教程_第8张图片

Android greenDAO数据库配置教程_第9张图片

三、greenDAO代码全局配置

1、DaoMaster、DaoSession配置

一个APP项目,一般不只一个数据库,一个数据库里也不只一个表,如果有多个表的情况,按照上面的配置,会发现每生成一个实体类表,除了Table和TableDao类外,都会有一个DaoMaster和DaoSession生成,这时候我们就可以配置DaoMaster和DaoSession类了,一个类管理多张表。

我们可以再生成一个实体类表,表名为TestAnOtherTable,这样,一个数据库下就有了2个表。

Android greenDAO数据库配置教程_第10张图片

配置DaoMaster类

[java]  view plain  copy
 
  1. package test.greendao;  
  2.   
  3. import android.content.Context;  
  4. import android.database.sqlite.SQLiteDatabase;  
  5. import android.database.sqlite.SQLiteDatabase.CursorFactory;  
  6. import android.database.sqlite.SQLiteOpenHelper;  
  7. import android.util.Log;  
  8. import de.greenrobot.dao.AbstractDaoMaster;  
  9. import de.greenrobot.dao.identityscope.IdentityScopeType;  
  10.   
  11. import test.greendao.TestAnOtherTableDao;  
  12.   
  13. // THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.  
  14. /**  
  15.  * Master of DAO (schema version 1): knows all DAOs. 
  16. */  
  17. public class DaoMaster extends AbstractDaoMaster {  
  18.     public static final int SCHEMA_VERSION = 1;  
  19.   
  20.     /** Creates underlying database table using DAOs. */  
  21.     public static void createAllTables(SQLiteDatabase db, boolean ifNotExists) {  
  22.         TestAnOtherTableDao.createTable(db, ifNotExists);  
  23.         TestTableDao.createTable(db, ifNotExists);  
  24.     }  
  25.       
  26.     /** Drops underlying database table using DAOs. */  
  27.     public static void dropAllTables(SQLiteDatabase db, boolean ifExists) {  
  28.         TestAnOtherTableDao.dropTable(db, ifExists);  
  29.         TestTableDao.dropTable(db, ifExists);  
  30.     }  
  31.       
  32.     public static abstract class OpenHelper extends SQLiteOpenHelper {  
  33.   
  34.         public OpenHelper(Context context, String name, CursorFactory factory) {  
  35.             super(context, name, factory, SCHEMA_VERSION);  
  36.         }  
  37.   
  38.         @Override  
  39.         public void onCreate(SQLiteDatabase db) {  
  40.             Log.i("greenDAO""Creating tables for schema version " + SCHEMA_VERSION);  
  41.             createAllTables(db, false);  
  42.         }  
  43.     }  
  44.       
  45.     /** WARNING: Drops all table on Upgrade! Use only during development. */  
  46.     public static class DevOpenHelper extends OpenHelper {  
  47.         public DevOpenHelper(Context context, String name, CursorFactory factory) {  
  48.             super(context, name, factory);  
  49.         }  
  50.   
  51.         @Override  
  52.         public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {  
  53.             Log.i("greenDAO""Upgrading schema from version " + oldVersion + " to " + newVersion + " by dropping all tables");  
  54.             dropAllTables(db, true);  
  55.             onCreate(db);  
  56.         }  
  57.     }  
  58.   
  59.     public DaoMaster(SQLiteDatabase db) {  
  60.         super(db, SCHEMA_VERSION);  
  61.         registerDaoClass(TestAnOtherTableDao.class);  
  62.         registerDaoClass(TestTableDao.class);  
  63.     }  
  64.       
  65.     public DaoSession newSession() {  
  66.         return new DaoSession(db, IdentityScopeType.Session, daoConfigMap);  
  67.     }  
  68.       
  69.     public DaoSession newSession(IdentityScopeType type) {  
  70.         return new DaoSession(db, type, daoConfigMap);  
  71.     }  
  72.       
  73. }  
配置DaoSession类

[java]  view plain  copy
 
  1. package test.greendao;  
  2.   
  3. import android.database.sqlite.SQLiteDatabase;  
  4.   
  5. import java.util.Map;  
  6.   
  7. import de.greenrobot.dao.AbstractDao;  
  8. import de.greenrobot.dao.AbstractDaoSession;  
  9. import de.greenrobot.dao.identityscope.IdentityScopeType;  
  10. import de.greenrobot.dao.internal.DaoConfig;  
  11.   
  12. import test.greendao.TestAnOtherTable;  
  13.   
  14. import test.greendao.TestAnOtherTableDao;  
  15.   
  16. // THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.  
  17.   
  18. /** 
  19.  * {@inheritDoc} 
  20.  *  
  21.  * @see de.greenrobot.dao.AbstractDaoSession 
  22.  */  
  23. public class DaoSession extends AbstractDaoSession {  
  24.   
  25.     private final DaoConfig testAnOtherTableDaoConfig;  
  26.     private final DaoConfig testTableDaoConfig;  
  27.   
  28.     private final TestAnOtherTableDao testAnOtherTableDao;  
  29.     private final TestTableDao testTableDao;  
  30.   
  31.     public DaoSession(SQLiteDatabase db, IdentityScopeType type, Mapextends AbstractDao>, DaoConfig>  
  32.             daoConfigMap) {  
  33.         super(db);  
  34.   
  35.         testAnOtherTableDaoConfig = daoConfigMap.get(TestAnOtherTableDao.class).clone();  
  36.         testAnOtherTableDaoConfig.initIdentityScope(type);  
  37.           
  38.         testTableDaoConfig = daoConfigMap.get(TestTable.class).clone();  
  39.         testTableDaoConfig.initIdentityScope(type);  
  40.   
  41.         testAnOtherTableDao = new TestAnOtherTableDao(testAnOtherTableDaoConfig, this);  
  42.         testTableDao = new TestTableDao(testTableDaoConfig, this);  
  43.   
  44.         registerDao(TestAnOtherTable.class, testAnOtherTableDao);  
  45.         registerDao(TestTable.class, testTableDao);  
  46.     }  
  47.       
  48.     public void clear() {  
  49.         testAnOtherTableDaoConfig.getIdentityScope().clear();  
  50.         testTableDaoConfig.getIdentityScope().clear();  
  51.     }  
  52.   
  53.     public TestAnOtherTableDao getTestAnOtherTableDao() {  
  54.         return testAnOtherTableDao;  
  55.     }  
  56.   
  57.     public TestTableDao getTestTableDao() {  
  58.         return testTableDao;  
  59.     }  
  60. }  

这样,2个表就可以通过一个DaoMaster和DaoSession管理了。


2、greenDAO Application配置

greedDAO官方建议,DaoSession最好配置在Application里。

我们新建一个GreenDaoUtils类,用来新建数据库以及管理所有数据库表。

[java]  view plain  copy
 
  1. public class GreenDaoUtils {  
  2.     /** 
  3.      * 创建数据库连接 
  4.      * 
  5.      * @param context 
  6.      * @return 
  7.      */  
  8.     public static DaoSession createDB(Context context) {  
  9.         DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(context,  
  10.                 TableNameEntity.DB_NAME, null);  
  11.         return new DaoMaster(helper.getWritableDatabase()).newSession();  
  12.     }  
  13.   
  14.     
  15.     /** 
  16.      * 给TestTable表插入数据 
  17.      * @param testTable 
  18.      * @param daoSession 
  19.      */  
  20.     public static void addTestTableInfo(TestTable testTable, DaoSession daoSession){  
  21.         daoSession.getTestTableDao().insert(testTable);  
  22.     }  
  23.   
  24.     /** 
  25.      * 获取TestTable表所有数据 
  26.      * @param daoSession 
  27.      * @return 
  28.      */  
  29.     public static List getTestTableInfoList(DaoSession daoSession){  
  30.         QueryBuilder queryBuilder = daoSession.getTestTableDao()  
  31.                 .queryBuilder().orderAsc(TestTableDao.Properties.Id);  
  32.         if(!ListUtils.isEmpty(queryBuilder.list())){  
  33.             return queryBuilder.list();  
  34.         }  
  35.         return null;  
  36.     }  
  37.   
  38. }  

[java]  view plain  copy
 
  1. public class HealthApplication extends Application {  
  2.   
  3.     private GreenDaoUtils mGreenDaoUtils;  
  4.     private DaoSession mDaoSession;  
  5.   
  6.   
  7.   
  8.     private static HealthApplication instance;  
  9.   
  10.     public static HealthApplication getInstance(){  
  11.         return instance;  
  12.     }  
  13.   
  14.     @Override  
  15.     public void onCreate() {  
  16.         super.onCreate();  
  17.         instance = this;  
  18.   
  19.          
  20.         //greenDao数据库  
  21.         initGreenDao();  
  22.   
  23.     }  
  24.   
  25.   
  26.     /** greenDao数据库框架初始化 **/  
  27.     private void initGreenDao() {  
  28.         mGreenDaoUtils = new GreenDaoUtils();  
  29.         mDaoSession = mGreenDaoUtils.createDB(this);  
  30.     }  
  31.   
  32.     public DaoSession getmDaoSession() {  
  33.         return mDaoSession;  
  34.     }  
  35.   
  36.      
  37. }  

在代码中调用

[java]  view plain  copy
 
  1. DaoSession mDaoSession = HealthApplication.getInstance().getmDaoSession();  
  2.         TestTable testTable = new TestTable();  
  3.         testTable.setAa("aa");  
  4.         testTable.setBb(11);  
  5.         testTable.setCc(22);  
  6.         testTable.setFf(44);  
  7.         GreenDaoUtils.addTestTableInfo(testTable, mDaoSession);  

这样,我们就通过上面代码向TestTable数据库表中插入了一条数据。关于greenDAO的sql语句语法,可以自行查找资料,这里就不再多述。


三、greedDAO数据库的升级

新建一个MigrationHelper类

[java]  view plain  copy
 
  1. import android.database.Cursor;  
  2. import android.database.sqlite.SQLiteDatabase;  
  3. import android.text.TextUtils;  
  4. import android.util.Log;  
  5.   
  6.   
  7.   
  8. import java.util.ArrayList;  
  9. import java.util.Arrays;  
  10. import java.util.List;  
  11.   
  12. import de.greenrobot.dao.AbstractDao;  
  13. import de.greenrobot.dao.internal.DaoConfig;  
  14.   
  15. public class MigrationHelper {  
  16.   
  17.     private static final String CONVERSION_CLASS_NOT_FOUND_EXCEPTION =  
  18.             "MIGRATION HELPER - CLASS DOESN'T MATCH WITH THE CURRENT PARAMETERS";  
  19.     private static MigrationHelper instance;  
  20.   
  21.     public static MigrationHelper getInstance() {  
  22.         if (instance == null) {  
  23.             instance = new MigrationHelper();  
  24.         }  
  25.         return instance;  
  26.     }  
  27.   
  28.     public void migrate(SQLiteDatabase db, Classextends AbstractDao>... daoClasses) {  
  29.         generateTempTables(db, daoClasses);  
  30.         DaoMaster.dropAllTables(db, true);  
  31.         DaoMaster.createAllTables(db, false);  
  32.         restoreData(db, daoClasses);  
  33.     }  
  34.   
  35.     private void generateTempTables(SQLiteDatabase db, Classextends AbstractDao>... daoClasses) {  
  36.         for (int i = 0; i < daoClasses.length; i++) {  
  37.             DaoConfig daoConfig = new DaoConfig(db, daoClasses[i]);  
  38.   
  39.             String divider = "";  
  40.             String tableName = daoConfig.tablename;  
  41.             String tempTableName = daoConfig.tablename.concat("_TEMP");  
  42.             ArrayList properties = new ArrayList<>();  
  43.   
  44.             StringBuilder createTableStringBuilder = new StringBuilder();  
  45.   
  46.             createTableStringBuilder.append("CREATE TABLE ").append(tempTableName).append(" (");  
  47.   
  48.             for (int j = 0; j < daoConfig.properties.length; j++) {  
  49.                 String columnName = daoConfig.properties[j].columnName;  
  50.   
  51.                 if (getColumns(db, tableName).contains(columnName)) {  
  52.                     properties.add(columnName);  
  53.   
  54.                     String type = null;  
  55.   
  56.                     try {  
  57.                         type = getTypeByClass(daoConfig.properties[j].type);  
  58.                     } catch (Exception exception) {  
  59.                     }  
  60.   
  61.                     createTableStringBuilder.append(divider).append(columnName).append(" ").append(type);  
  62.   
  63.                     if (daoConfig.properties[j].primaryKey) {  
  64.                         createTableStringBuilder.append(" PRIMARY KEY");  
  65.                     }  
  66.   
  67.                     divider = ",";  
  68.                 }  
  69.             }  
  70.             createTableStringBuilder.append(");");  
  71.   
  72.             db.execSQL(createTableStringBuilder.toString());  
  73.   
  74.             StringBuilder insertTableStringBuilder = new StringBuilder();  
  75.   
  76.             insertTableStringBuilder.append("INSERT INTO ").append(tempTableName).append(" (");  
  77.             insertTableStringBuilder.append(TextUtils.join(",", properties));  
  78.             insertTableStringBuilder.append(") SELECT ");  
  79.             insertTableStringBuilder.append(TextUtils.join(",", properties));  
  80.             insertTableStringBuilder.append(" FROM ").append(tableName).append(";");  
  81.   
  82.             db.execSQL(insertTableStringBuilder.toString());  
  83.         }  
  84.     }  
  85.   
  86.     private void restoreData(SQLiteDatabase db, Classextends AbstractDao>... daoClasses) {  
  87.         for (int i = 0; i < daoClasses.length; i++) {  
  88.             DaoConfig daoConfig = new DaoConfig(db, daoClasses[i]);  
  89.   
  90.             String tableName = daoConfig.tablename;  
  91.             String tempTableName = daoConfig.tablename.concat("_TEMP");  
  92.             ArrayList properties = new ArrayList();  
  93.   
  94.             for (int j = 0; j < daoConfig.properties.length; j++) {  
  95.                 String columnName = daoConfig.properties[j].columnName;  
  96.   
  97.                 if (getColumns(db, tempTableName).contains(columnName)) {  
  98.                     properties.add(columnName);  
  99.                 }  
  100.             }  
  101.   
  102.             StringBuilder insertTableStringBuilder = new StringBuilder();  
  103.   
  104.             insertTableStringBuilder.append("INSERT INTO ").append(tableName).append(" (");  
  105.             insertTableStringBuilder.append(TextUtils.join(",", properties));  
  106.             insertTableStringBuilder.append(") SELECT ");  
  107.             insertTableStringBuilder.append(TextUtils.join(",", properties));  
  108.             insertTableStringBuilder.append(" FROM ").append(tempTableName).append(";");  
  109.   
  110.             StringBuilder dropTableStringBuilder = new StringBuilder();  
  111.   
  112.             dropTableStringBuilder.append("DROP TABLE ").append(tempTableName);  
  113.   
  114.             db.execSQL(insertTableStringBuilder.toString());  
  115.             db.execSQL(dropTableStringBuilder.toString());  
  116.         }  
  117.     }  
  118.   
  119.     private String getTypeByClass(Class type) throws Exception {  
  120.         if (type.equals(String.class)) {  
  121.             return "TEXT";  
  122.         }  
  123.         if (type.equals(Long.class) || type.equals(Integer.class) || type.equals(long.class)) {  
  124.             return "INTEGER";  
  125.         }  
  126.         if (type.equals(Boolean.class)) {  
  127.             return "BOOLEAN";  
  128.         }  
  129.   
  130.         Exception exception =  
  131.                 new Exception(CONVERSION_CLASS_NOT_FOUND_EXCEPTION.concat(" - Class: ").concat(type.toString()));  
  132.         throw exception;  
  133.     }  
  134.   
  135.     private static List getColumns(SQLiteDatabase db, String tableName) {  
  136.         List columns = new ArrayList<>();  
  137.         Cursor cursor = null;  
  138.         try {  
  139.             cursor = db.rawQuery("SELECT * FROM " + tableName + " limit 1"null);  
  140.             if (cursor != null) {  
  141.                 columns = new ArrayList<>(Arrays.asList(cursor.getColumnNames()));  
  142.             }  
  143.         } catch (Exception e) {  
  144.             Log.v(tableName, e.getMessage(), e);  
  145.             e.printStackTrace();  
  146.         } finally {  
  147.             if (cursor != null) cursor.close();  
  148.         }  
  149.         return columns;  
  150.     }  
  151. }  


配置DaoMaster中的DevOpenHelper

[java]  view plain  copy
 
  1. /** WARNING: Drops all table on Upgrade! Use only during development. */  
  2.     public static class DevOpenHelper extends OpenHelper {  
  3.         public DevOpenHelper(Context context, String name, CursorFactory factory) {  
  4.             super(context, name, factory);  
  5.         }  
  6.   
  7.         @Override  
  8.         public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {  
  9.             Log.i("greenDAO""Upgrading schema from version " + oldVersion + " to " + newVersion + " by dropping all tables");  
  10. //            dropAllTables(db, true);  
  11. //            onCreate(db);  
  12.             MigrationHelper.getInstance().migrate(db, TestTable.class);  
  13.             MigrationHelper.getInstance().migrate(db, TestAnOtherTable.class);  
  14.         }  
  15.     }  

注意,onUpgrade方法,只有在数据库版本号更改后才会执行,数据库版本号在正式包环境中只能向上兼容,也就是版本号的值不能小于上个数据库的版本号。

[java]  view plain  copy
 
  1. public static final int SCHEMA_VERSION = 1;  

每次改动数据库,该值需要更改。

如果数据库表字段有更新、或添加删除字段,或数据库有增删表,利用generater模块类重新生成实体类表,然后更改数据库版本号,就可以实现数据库的更新。

你可能感兴趣的:(Android)