Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android greenDAO數據庫配置教程

Android greenDAO數據庫配置教程

編輯:關於Android編程

一、環境配置

1、在Android Studio中,在.src/main目錄下新建一個java-gen文件夾,和java文件夾同級。用於存放greenDAO生成的DaoMaster、DaoSession、Table、TableDaoSession實體類。

  

\

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

  

\
sourceSets {
        main {
            java.srcDirs = ['src/main/java', 'src/main/java-gen']
        }
    }
compile 'de.greenrobot:greendao:1.3.7'

3、新建一個greengenerator模塊,用於代碼自動生成DaoMaster、DaoSession、Table、TableDao實體類

  

\

  

\

  

\

配置新建moudle的build.gradle文件

  

\
compile 'de.greenrobot:greendao-generator:1.3.1'

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

二、利用greedgenerater模塊生成DaoMaster、DaoSession、Table、TableDao實體類的代碼,編寫moudle下的MyClass類

import de.greenrobot.daogenerator.DaoGenerator;
import de.greenrobot.daogenerator.Entity;
import de.greenrobot.daogenerator.Schema;

public class MyClass {
    public static void main(String[] args) throws Exception {
        // 正如你所見的,你創建了一個用於添加實體(Entity)的模式(Schema)對象。
        // 兩個參數分別代表:數據庫版本號與自動生成代碼的包路徑。
        Schema schema = new Schema(1, "test.greendao");
//      當然,如果你願意,你也可以分別指定生成的 Bean 與 DAO 類所在的目錄,只要如下所示:
//      Schema schema = new Schema(1, "test.greendao.bean");
//      schema.setDefaultJavaPackageDao("test.greendao.dao");

        // 模式(Schema)同時也擁有兩個默認的 flags,分別用來標示 entity 是否是 activie 以及是否使用 keep sections。
        // schema2.enableActiveEntitiesByDefault();
        // schema2.enableKeepSectionsByDefault();

        // 一旦你擁有了一個 Schema 對象後,你便可以使用它添加實體(Entities)了。
        addNote(schema);

        // 最後我們將使用 DAOGenerator 類的 generateAll() 方法自動生成代碼,此處你需要根據自己的情況更改輸出目錄(既之前創建的 java-gen)。
        // 其實,輸出目錄的路徑可以在 build.gradle 中設置,有興趣的朋友可以自行搜索,這裡就不再詳解。
        new DaoGenerator().generateAll(schema, "/Users/licheng/Documents/Healthdoctor/app/src/main/java-gen");
    }

    /**
     * @param schema
     */
    private static void addNote(Schema schema) {
        // 一個實體(類)就關聯到數據庫中的一張表,此處表名為「Note」(既類名)
        Entity note = schema.addEntity("TestTable");
        // 你也可以重新給表命名
        // note.setTableName("NODE");

        // greenDAO 會自動根據實體類的屬性值來創建表字段,並賦予默認值
        // 接下來你便可以設置表中的字段:
        note.addIdProperty();
        note.addStringProperty("aa");
        // 與在 Java 中使用駝峰命名法不同,默認數據庫中的命名是使用大寫和下劃線來分割單詞的。
        // For example, a property called “creationDate” will become a database column “CREATION_DATE”.
        note.addIntProperty("bb");
        note.addIntProperty("cc");
        note.addIntProperty("dd");
        note.addIntProperty("ee");
    }
}

  

\
如果運行結果打印如下,說明配置成功並且實體類生成成功

  

\

  

\

三、greenDAO代碼全局配置

1、DaoMaster、DaoSession配置

一個APP項目,一般不只一個數據庫,一個數據庫裡也不只一個表,如果有多個表的情況,按照上面的配置,會發現每生成一個實體類表,除了Table和TableDao類外,都會有一個DaoMaster和DaoSession生成,這時候我們就可以配置DaoMaster和DaoSession類了,一個類管理多張表。

我們可以再生成一個實體類表,表名為TestAnOtherTable,這樣,一個數據庫下就有了2個表。

  

\

配置DaoMaster類

package test.greendao;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import de.greenrobot.dao.AbstractDaoMaster;
import de.greenrobot.dao.identityscope.IdentityScopeType;

import test.greendao.TestAnOtherTableDao;

// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.
/** 
 * Master of DAO (schema version 1): knows all DAOs.
*/
public class DaoMaster extends AbstractDaoMaster {
    public static final int SCHEMA_VERSION = 1;

    /** Creates underlying database table using DAOs. */
    public static void createAllTables(SQLiteDatabase db, boolean ifNotExists) {
        TestAnOtherTableDao.createTable(db, ifNotExists);
        TestTableDao.createTable(db, ifNotExists);
    }
    
    /** Drops underlying database table using DAOs. */
    public static void dropAllTables(SQLiteDatabase db, boolean ifExists) {
        TestAnOtherTableDao.dropTable(db, ifExists);
        TestTableDao.dropTable(db, ifExists);
    }
    
    public static abstract class OpenHelper extends SQLiteOpenHelper {

        public OpenHelper(Context context, String name, CursorFactory factory) {
            super(context, name, factory, SCHEMA_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            Log.i("greenDAO", "Creating tables for schema version " + SCHEMA_VERSION);
            createAllTables(db, false);
        }
    }
    
    /** WARNING: Drops all table on Upgrade! Use only during development. */
    public static class DevOpenHelper extends OpenHelper {
        public DevOpenHelper(Context context, String name, CursorFactory factory) {
            super(context, name, factory);
        }

        @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);
        }
    }

    public DaoMaster(SQLiteDatabase db) {
        super(db, SCHEMA_VERSION);
        registerDaoClass(TestAnOtherTableDao.class);
        registerDaoClass(TestTableDao.class);
    }
    
    public DaoSession newSession() {
        return new DaoSession(db, IdentityScopeType.Session, daoConfigMap);
    }
    
    public DaoSession newSession(IdentityScopeType type) {
        return new DaoSession(db, type, daoConfigMap);
    }
    
}
配置DaoSession類
package test.greendao;

import android.database.sqlite.SQLiteDatabase;

import java.util.Map;

import de.greenrobot.dao.AbstractDao;
import de.greenrobot.dao.AbstractDaoSession;
import de.greenrobot.dao.identityscope.IdentityScopeType;
import de.greenrobot.dao.internal.DaoConfig;

import test.greendao.TestAnOtherTable;

import test.greendao.TestAnOtherTableDao;

// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.

/**
 * {@inheritDoc}
 * 
 * @see de.greenrobot.dao.AbstractDaoSession
 */
public class DaoSession extends AbstractDaoSession {

    private final DaoConfig testAnOtherTableDaoConfig;
    private final DaoConfig testTableDaoConfig;

    private final TestAnOtherTableDao testAnOtherTableDao;
    private final TestTableDao testTableDao;

    public DaoSession(SQLiteDatabase db, IdentityScopeType type, Map<class<? extends="">>, DaoConfig>
            daoConfigMap) {
        super(db);

        testAnOtherTableDaoConfig = daoConfigMap.get(TestAnOtherTableDao.class).clone();
        testAnOtherTableDaoConfig.initIdentityScope(type);
        
        testTableDaoConfig = daoConfigMap.get(TestTable.class).clone();
        testTableDaoConfig.initIdentityScope(type);

        testAnOtherTableDao = new TestAnOtherTableDao(testAnOtherTableDaoConfig, this);
        testTableDao = new TestTableDao(testTableDaoConfig, this);

        registerDao(TestAnOtherTable.class, testAnOtherTableDao);
        registerDao(TestTable.class, testTableDao);
    }
    
    public void clear() {
        testAnOtherTableDaoConfig.getIdentityScope().clear();
        testTableDaoConfig.getIdentityScope().clear();
    }

    public TestAnOtherTableDao getTestAnOtherTableDao() {
        return testAnOtherTableDao;
    }

    public TestTableDao getTestTableDao() {
        return testTableDao;
    }
}

這樣,2個表就可以通過一個DaoMaster和DaoSession管理了。

2、greenDAO Application配置

greedDAO官方建議,DaoSession最好配置在Application裡。

我們新建一個GreenDaoUtils類,用來新建數據庫以及管理所有數據庫表。

public class GreenDaoUtils {
    /**
     * 創建數據庫連接
     *
     * @param context
     * @return
     */
    public static DaoSession createDB(Context context) {
        DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(context,
                TableNameEntity.DB_NAME, null);
        return new DaoMaster(helper.getWritableDatabase()).newSession();
    }

  
    /**
     * 給TestTable表插入數據
     * @param testTable
     * @param daoSession
     */
    public static void addTestTableInfo(TestTable testTable, DaoSession daoSession){
        daoSession.getTestTableDao().insert(testTable);
    }

    /**
     * 獲取TestTable表所有數據
     * @param daoSession
     * @return
     */
    public static List<!--{cke_protected}{C}%3C!%2D%2D%3F%2D%2D%3E--> getTestTableInfoList(DaoSession daoSession){
        QueryBuilder<testtable> queryBuilder = daoSession.getTestTableDao()
                .queryBuilder().orderAsc(TestTableDao.Properties.Id);
        if(!ListUtils.isEmpty(queryBuilder.list())){
            return queryBuilder.list();
        }
        return null;
    }

}

public class HealthApplication extends Application {

    private GreenDaoUtils mGreenDaoUtils;
    private DaoSession mDaoSession;



    private static HealthApplication instance;

    public static HealthApplication getInstance(){
        return instance;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        instance = this;

       
        //greenDao數據庫
        initGreenDao();

    }


    /** greenDao數據庫框架初始化 **/
    private void initGreenDao() {
        mGreenDaoUtils = new GreenDaoUtils();
        mDaoSession = mGreenDaoUtils.createDB(this);
    }

    public DaoSession getmDaoSession() {
        return mDaoSession;
    }

   
}

在代碼中調用
DaoSession mDaoSession = HealthApplication.getInstance().getmDaoSession();
        TestTable testTable = new TestTable();
        testTable.setAa("aa");
        testTable.setBb(11);
        testTable.setCc(22);
        testTable.setFf(44);
        GreenDaoUtils.addTestTableInfo(testTable, mDaoSession);

這樣,我們就通過上面代碼向TestTable數據庫表中插入了一條數據。關於greenDAO的sql語句語法,可以自行查找資料,這裡就不再多述。

三、greedDAO數據庫的升級

新建一個MigrationHelper類

import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.text.TextUtils;
import android.util.Log;



import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import de.greenrobot.dao.AbstractDao;
import de.greenrobot.dao.internal.DaoConfig;

public class MigrationHelper {

    private static final String CONVERSION_CLASS_NOT_FOUND_EXCEPTION =
            "MIGRATION HELPER - CLASS DOESN'T MATCH WITH THE CURRENT PARAMETERS";
    private static MigrationHelper instance;

    public static MigrationHelper getInstance() {
        if (instance == null) {
            instance = new MigrationHelper();
        }
        return instance;
    }

    public void migrate(SQLiteDatabase db, Class<!--{cke_protected}{C}%3C!%2D%2D%3F%20extends%20AbstractDao%3C%3F%2C%20%3F%2D%2D%3E-->>... daoClasses) {
        generateTempTables(db, daoClasses);
        DaoMaster.dropAllTables(db, true);
        DaoMaster.createAllTables(db, false);
        restoreData(db, daoClasses);
    }

    private void generateTempTables(SQLiteDatabase db, Class<!--{cke_protected}{C}%3C!%2D%2D%3F%20extends%20AbstractDao%3C%3F%2C%20%3F%2D%2D%3E-->>... daoClasses) {
        for (int i = 0; i < daoClasses.length; i++) {
            DaoConfig daoConfig = new DaoConfig(db, daoClasses[i]);

            String divider = "";
            String tableName = daoConfig.tablename;
            String tempTableName = daoConfig.tablename.concat("_TEMP");
            ArrayList<string> properties = new ArrayList<>();

            StringBuilder createTableStringBuilder = new StringBuilder();

            createTableStringBuilder.append("CREATE TABLE ").append(tempTableName).append(" (");

            for (int j = 0; j < daoConfig.properties.length; j++) {
                String columnName = daoConfig.properties[j].columnName;

                if (getColumns(db, tableName).contains(columnName)) {
                    properties.add(columnName);

                    String type = null;

                    try {
                        type = getTypeByClass(daoConfig.properties[j].type);
                    } catch (Exception exception) {
                    }

                    createTableStringBuilder.append(divider).append(columnName).append(" ").append(type);

                    if (daoConfig.properties[j].primaryKey) {
                        createTableStringBuilder.append(" PRIMARY KEY");
                    }

                    divider = ",";
                }
            }
            createTableStringBuilder.append(");");

            db.execSQL(createTableStringBuilder.toString());

            StringBuilder insertTableStringBuilder = new StringBuilder();

            insertTableStringBuilder.append("INSERT INTO ").append(tempTableName).append(" (");
            insertTableStringBuilder.append(TextUtils.join(",", properties));
            insertTableStringBuilder.append(") SELECT ");
            insertTableStringBuilder.append(TextUtils.join(",", properties));
            insertTableStringBuilder.append(" FROM ").append(tableName).append(";");

            db.execSQL(insertTableStringBuilder.toString());
        }
    }

    private void restoreData(SQLiteDatabase db, Class<!--{cke_protected}{C}%3C!%2D%2D%3F%20extends%20AbstractDao%3C%3F%2C%20%3F%2D%2D%3E-->>... daoClasses) {
        for (int i = 0; i < daoClasses.length; i++) {
            DaoConfig daoConfig = new DaoConfig(db, daoClasses[i]);

            String tableName = daoConfig.tablename;
            String tempTableName = daoConfig.tablename.concat("_TEMP");
            ArrayList<string> properties = new ArrayList();

            for (int j = 0; j < daoConfig.properties.length; j++) {
                String columnName = daoConfig.properties[j].columnName;

                if (getColumns(db, tempTableName).contains(columnName)) {
                    properties.add(columnName);
                }
            }

            StringBuilder insertTableStringBuilder = new StringBuilder();

            insertTableStringBuilder.append("INSERT INTO ").append(tableName).append(" (");
            insertTableStringBuilder.append(TextUtils.join(",", properties));
            insertTableStringBuilder.append(") SELECT ");
            insertTableStringBuilder.append(TextUtils.join(",", properties));
            insertTableStringBuilder.append(" FROM ").append(tempTableName).append(";");

            StringBuilder dropTableStringBuilder = new StringBuilder();

            dropTableStringBuilder.append("DROP TABLE ").append(tempTableName);

            db.execSQL(insertTableStringBuilder.toString());
            db.execSQL(dropTableStringBuilder.toString());
        }
    }

    private String getTypeByClass(Class<!--{cke_protected}{C}%3C!%2D%2D%3F%2D%2D%3E--> type) throws Exception {
        if (type.equals(String.class)) {
            return "TEXT";
        }
        if (type.equals(Long.class) || type.equals(Integer.class) || type.equals(long.class)) {
            return "INTEGER";
        }
        if (type.equals(Boolean.class)) {
            return "BOOLEAN";
        }

        Exception exception =
                new Exception(CONVERSION_CLASS_NOT_FOUND_EXCEPTION.concat(" - Class: ").concat(type.toString()));
        throw exception;
    }

    private static List<string> getColumns(SQLiteDatabase db, String tableName) {
        List<string> columns = new ArrayList<>();
        Cursor cursor = null;
        try {
            cursor = db.rawQuery("SELECT * FROM " + tableName + " limit 1", null);
            if (cursor != null) {
                columns = new ArrayList<>(Arrays.asList(cursor.getColumnNames()));
            }
        } catch (Exception e) {
            Log.v(tableName, e.getMessage(), e);
            e.printStackTrace();
        } finally {
            if (cursor != null) cursor.close();
        }
        return columns;
    }
}
配置DaoMaster中的DevOpenHelper
/** WARNING: Drops all table on Upgrade! Use only during development. */
    public static class DevOpenHelper extends OpenHelper {
        public DevOpenHelper(Context context, String name, CursorFactory factory) {
            super(context, name, factory);
        }

        @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);
            MigrationHelper.getInstance().migrate(db, TestTable.class);
            MigrationHelper.getInstance().migrate(db, TestAnOtherTable.class);
        }
    }

注意,onUpgrade方法,只有在數據庫版本號更改後才會執行,數據庫版本號在正式包環境中只能向上兼容,也就是版本號的值不能小於上個數據庫的版本號。
public static final int SCHEMA_VERSION = 1;

每次改動數據庫,該值需要更改。

如果數據庫表字段有更新、或添加刪除字段,或數據庫有增刪表,利用generater模塊類重新生成實體類表,然後更改數據庫版本號,就可以實現數據庫的更新。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved