Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android ORM 框架之 greenDAO應用基礎

Android ORM 框架之 greenDAO應用基礎

編輯:關於Android編程

greenDAO是時下Android最流行的一款ORM框架,其性能高,可加密,使用簡潔,做android開發,如果會使用它,工作量會大大減小。其性能與其他ORM框架之比較可以查閱其官網。
目前greenDAO版本為3.1.1,greenDAO3相較於greenDAO2發生了較大的改變:可以使用注解聲明schemas和實體。有兩種方式使用greenDAO3,一種是使用java庫的形式(greenDAO2的使用方法),一種是基於注解的形式(greenDAO3新增的)。

方式一,java庫形式

1>在 src/main 目錄下新建一個與 java 同層級的java-gen目錄,用於存放由 greendao生成的 Bean類、DAO類、DaoMaster、DaoSession 等類:
這裡寫圖片描述
2> 在build.gradle(app),添加 sourceSets 與依賴:
<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwcmUgY2xhc3M9"brush:java;"> sourceSets { main { java.srcDirs = ['src/main/java', 'src/main/java-gen'] } } dependencies { compile 'org.greenrobot:greendao:3.1.0' // This is only needed if you want to use encrypted databases compile 'net.zetetic:android-database-sqlcipher:3.5.1' }

3>新建java庫模塊:File -> New -> New Module -> Java Library:
這裡寫圖片描述
這裡寫圖片描述
4>在java庫模塊build.gradle的dependencies中添加依賴:

dependencies {
    compile 'org.greenrobot:greendao-generator:3.1.0'
}

5>編寫java庫模塊生成的類,創建實體(表):

public class Generator {
    public static void  main(String[] args) throws Exception {
        int version = 1;
        String defaultPackage = "com.example.bean";
        //創建模式對象,指定版本號和自動生成的bean對象的包名
        Schema schema = new Schema(version, defaultPackage);
        //指定自動生成的dao對象的包名,不指定則都DAO類生成在"com.example.bean"包中
        schema.setDefaultJavaPackageDao("com.example.dao");

        //添加實體
        addEntity(schema);
        //java-gen絕對路徑
        String outDir = "H:/Persion/app/src/main/java-gen";
        //調用DaoGenerator().generateAll方法自動生成代碼到之前創建的java-gen目錄下
        new DaoGenerator().generateAll(schema, outDir);

    }

    private static void addEntity(Schema schema) {
        //添加一個實體,會自動生成實體類Persion
        Entity persion = schema.addEntity("Persion");
        //指定表名,如不指定,表名則為 Persion(即實體類名)
        persion.setTableName("persion");
        //給實體類中添加成員(即給表中添加列,並設置列的屬性)
        persion.addIdProperty().autoincrement();//添加Id,自增長
        persion.addStringProperty("name").notNull();//添加String類型的name,不能為空
        persion.addIntProperty("age");//添加Int類型的age
        persion.addDoubleProperty("high");//添加Double類型的high
        ...
    }
}

6>運行此java類,會自動在Android項目的java-gen目錄下生成bean類和DAO類:
這裡寫圖片描述
這裡寫圖片描述
7>轉到下方 操作數據庫 部汾喎?/kf/yidong/wp/" target="_blank" class="keylink">WPC9jb2RlPjwvY29kZT48L2NvZGU+PC9jb2RlPjwvY29kZT48L2NvZGU+PC9jb2RlPjwvY29kZT48L3A+DQo8aDEgaWQ9"方式二使用注解">方式二,使用注解

1>在build.gradle(app)中添加插件和依賴:

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'org.greenrobot:greendao-gradle-plugin:3.1.0'
    }
}

apply plugin: 'org.greenrobot.greendao'

dependencies {
    compile 'org.greenrobot:greendao:3.1.0'
     // This is only needed if you want to use encrypted databases
    compile 'net.zetetic:android-database-sqlcipher:3.5.1'
    compile 'org.greenrobot:greendao-generator:3.1.0'
}

2>在build.gradle(app)中插件配置:
如果不對 greenDAO進行屬性配置,在下面當”Build -> Make Project”時, greendao生成的源代碼路徑會是: build/generated/source/greendao。對greenDAO進行相關配置,則可以指定其路徑:

greendao {
    schemaVersion 1 
    daoPackage 'com.example.greendao' 
    targetGenDir 'src/main/java' 
}

這個greendao 可以配置的屬性:

schemaVersion: 數據庫schema版本號,默認為1。
daoPackage: greendao生成文件 DAOs,DaoMaster,DaoSession所在的包名,默認為源碼實體所在的包名。
targetGenDir: 上面包所在的路徑目錄,默認為:build/generated/source/greendao。
generateTests: 設置為true可以自動生成單元測試。
targetGenDirTests:生成單元測試存儲在的目錄, 默認為:src/androidTest/java。

3>使用注解創建Bean類:

@Entity
public class Persion {
    @Id
    private Long id;
    @NotNul
    private String name;
    private int age;
}

4>Build -> Make Project:
Make Project後,greenDAO自動為Bean類生成構造方法和每個成員的get set方法,以及前面設置的com.example.greendao包及其中的文件:
這裡寫圖片描述
5>轉到下方 操作數據庫 部分

類注解

@Entity:注解實體類,標識一個表,添加的屬性可以查閱依賴庫中Entity注解類:

public @interface Entity {

    /**
     * 指定數據庫中表明,默認為注解的實體類的類名
     */
    String nameInDb() default "";

    /**
     * 對實體的索引
     * 

* 注意: 如果創建單列索引使用 {@link Index} */ Index[] indexes() default {}; /** * 如果設置為false,表示這個實體類不在數據庫中創建表。 僅僅是一個實體類。 * 注意,greendao不會在緩存中同步多個實體。 */ boolean createInDb() default true; /** * 指定schema名字。 */ String schema() default "default"; /** * 是否可以生成update/delete/refresh方法。 *如果實體被定義成{@link ToMany} 或者 {@link ToOne} 關系,這個屬性是active */ boolean active() default false; /** * 構造器是否可以生成. */ boolean generateConstructors() default true; }

用法為:

@Entity(nameInDb="persion ",active=false)

注意:注解方式不支持多schema,但java庫形式支持。

基礎屬性注解

@Id:對象id,通過設置@Id(autoincrement = true)表示自增,只有當Long/long時才有效

@Property:設置成員屬性名(表的列名),如果不設置此屬性表示默認是類成員名

@NotNull :表示此成員屬性非空

@Transient:標識這個字段是自定義的,不會創建到數據庫表中

自定義類型

@Convert:如果有自定義的成員類型,使用此注解。如果自定義類型或轉換器是在此實體類外,需要設置她們為靜態的。
使用實例:

@Entity
public class User {
    @Id
    private Long id;
    //注解中converter指向類型類,columnType指向在此表中顯示的字段類型 
    @Convert(converter = RoleConverter.class, columnType = String.class)
    private Role role;

    enum Role {
        DEFAULT, AUTHOR, ADMIN
    }

    static class RoleConverter implements PropertyConverter {
        @Override
        public Role convertToEntityProperty(String databaseValue) {
            return Role.valueOf(databaseValue);
        }

        @Override
        public String convertToDatabaseValue(Role entityProperty) {
            return entityProperty.name();
        }
    }
}

索引注解

@Index:為數據庫中此列設置為索引列,通過其name參數指定此列的索引名,通過unique參數給索引添加約束 。
@Unique:給索引添加約束。

關系注解

@ToOne:聲明與另一個實體的關系:一對一。參數joinProperty 指向另一個實體的 ID列,如果不設置,則默認為id主鍵:

@Entity
public class Order {
    @Id private Long id;

    private long customerId;

    @ToOne(joinProperty = "customerId")
    private Customer customer;
}

@Entity
public class Customer {
    @Id private Long id;
}

@ToMany:聲明與另外多個實體的關系:一對多。這種關系映射有三種情況:
referencedJoinProperty 參數:外鍵屬性,指向另一實體的ID列:

@Entity
public class User {
    @Id private Long id;

    @ToMany(referencedJoinProperty = "ownerId")
    private List ownedSites;
}

@Entity
public class Site {
    @Id private Long id;
    private long ownerId;
}

joinProperties 參數:對於更復雜的關系,可以使用多個@JoinProperty:

@Entity
public class User {
    @Id private Long id;
    @Unique private String authorTag;

    @ToMany(joinProperties = {
            @JoinProperty(name = "authorTag", referencedName = "ownerTag")
    })
    private List ownedSites;
}

@Entity
public class Site {
    @Id private Long id;
    @NotNull private String ownerTag;
}

@JoinEntity:多對多的關系:

@Entity
public class Site {
    @Id private Long id;

    @ToMany
    @JoinEntity(
            entity = JoinSiteToUser.class,
            sourceProperty = "siteId",
            targetProperty = "userId"
    )
    private List authors;
}

@Entity
public class JoinSiteToUser {
    @Id private Long id;
    private Long siteId;
    private Long userId;
}

@Entity
public class User {
    @Id private Long id;
}

@Generated代碼

@Generated 這個是build後greendao自動生成的,這個注解理解為防止重復,每一塊代碼生成後會加個hash作為標記。 官方不建議你去碰這些代碼,改動會導致裡面代碼與hash值不符。如果手動改變引發錯誤:

Error:Execution failed for task ':app:greendao'.
> Constructor (see ExampleEntity:21) has been changed after generation.
Please either mark it with @Keep annotation instead of @Generated to keep it untouched,
or use @Generated (without hash) to allow to replace it.

當這個錯誤出現時,通常有兩種方法解決:
1>恢復@Generated注解的代碼,可以刪除此段代碼,下次build時,會再重新生成。
2>使用@Keep注解代替@Generated注解,它會告訴greenDAO不去觸碰@Keep注解的代碼。

操作數據庫

在Android項目中自定義一個Application:

public class App extends Application {
    /** 數據庫是否加密的標識 */
    public static final boolean ENCRYPTED = true;

    private DaoSession daoSession;

    @Override
    public void onCreate() {
        super.onCreate();
        //創建數據庫
        DevOpenHelper helper = new DevOpenHelper(this, ENCRYPTED ? "notes-db-encrypted" : "notes-db");
        //獲取數據庫讀寫的權限,如果進行加密調用helper.getEncryptedWritableDb("super-secret"),參數為設置的密碼
        Database db = ENCRYPTED ? helper.getEncryptedWritableDb("super-secret") : helper.getWritableDb();
        daoSession = new DaoMaster(db).newSession();
    }

    public DaoSession getDaoSession() {
        return daoSession;
    }
}

在Manifest文件中指向自定義的Application:

    

對數據庫加密

在build.gradle中添加依賴:

dependencies {
    compile 'net.zetetic:android-database-sqlcipher:3.5.1'
}

如上App類,對數據庫進行加密讀寫:

//創建數據庫(上下文,數據庫名)
DevOpenHelper helper = new DevOpenHelper(this,"notes-db-encrypted");
//獲取讀寫(密碼)
Database db = helper.getEncryptedWritableDb("super-secret")

如果只要求對加密的數據庫進行讀的操作:

//獲取讀(密碼)
Database db = helper.getEncryptedReadableDb("super-secret")

DaoMaster和DaoSession

DaoMaster:是使用greenDAO的入口點,DaoMaster為指定的schema保存數據庫對象(SQLiteDatabase)並且管理DAO類(不是對象類)。它內部的靜態方法可以用來創建表或刪除表,它的內部類OpenHelper 和 DevOpenHelper 是 SQLiteOpenHelper在數據庫中創建schema的實現。
DaoSession:也是使用greenDAO的重要類,為指定的schema管理所有可用的DAO對象,可以使用getter方法獲得DAO對象。DaoSession還提供了一些通用的持久性的方法,如插入,裝載,更新,刷新和刪除實體。
如果要對數據庫進行操作,需要先獲取相關實體類Dao對象:

daoMaster = new DaoMaster(db);
daoSession = daoMaster.newSession();
persionDao = daoSession.getPersionDao();

請注意,該數據庫連接屬於DaoMaster,所以多個Session指向的是同一個數據庫。新的Session可以相當迅速的創建。每個Session都分配內存,通常為實體的一個Session“緩存”。
如果有對同一個數據庫對象的多個請求,會有幾個java對象來處理?這取決於作用域,默認(如果不對他進行配置)是這多個請求會返回同一個java對象,比如,查詢USER 表的 ID 42 獲取User對象,會為每一個請求返回相同的結果。並且會將其緩存在內存中。如果一個實體仍然存在內存中(greenDAO對它有弱引用),該實體將不會是從數據庫值再次獲得,例如,如果通過其ID加載實體,但是之前已經加載過這個實體,greenDAO就不會再次詢問數據庫了,它會從session緩存“馬上”返回此對象,這樣更快一個或兩個數量級。

操作

1>獲取DAO

        // get the note DAO
        DaoSession daoSession = ((App) getApplication()).getDaoSession();
        persionDao = daoSession.getPersionDao();

2>插入數據:id設為null,數據庫會自動為其分配自增的id:

        Persion persion = new Persion(null, "liHua", 5);
        persionDao.insert(persion);

3>保存數據:如果key屬性不為null,會更新這個對象;如果為null,會插入這個對象:

        Persion persion = new Persion(2, "liHua", 5);
        persionDao.save(persion);

4>查詢數據:

Persion persion = persionDao.queryBuilder().where(PersionDao.Properties.Name.eq("LiHua")).build().unique();

unique()表示查詢結果為一條數據,若數據不存在,persion為null。如果多個獲取多個查詢結果:

List persionList = persionDao.queryBuilder()  
       .where(PersionDao.Properties.Id.notEq(10)) //查詢條件 
       .orderAsc(PersionDao.Properties.Id) //按首字母排列 
       .limit(10)  //限制查詢結果個數
       .build().list(); //結果放進list中

5>刪除數據:

persionDao.delete(persion);
//或
persionDao.deleteByKey(persion.getId()); 

6>事務:當執行的數據較多時,可以使用事務處理,事務的方法有insertInTx(~),saveInTx(~)等後綴為-InTx的方法,其參數為多個對象:

        Persion persion = new Persion(2, "liHua", 5);
        Persion persion1 = new Persion(2, "liHua", 5);
        Persion persion2 = new Persion(2, "liHua", 5);
        persionDao.saveInTx(persion,persion1,persion2);

7>更多使用方法參考greendao庫中AbstractDao類。

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