Android ORM 框架:GreenDao 使用詳解(進階篇)

本文做者:speedy
CSDN 專欄:blog.csdn.net/speedystone…
掘金專欄:juejin.im/post/595a12…java

前言

Android ORM 框架:GreenDao 使用詳解(基礎篇 中,咱們瞭解了 GreenDao 的基本使用,本文咱們將深刻講解 GreenDao 的使用 。react

1、複雜表結構

a, 使用 @ToOne 創建一對一 ( 1 : 1) 關係

@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;
}複製代碼

b,使用 @ToMany 創建一對多 (1:N ) 關係

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

    @ToMany(referencedJoinProperty = "customerId")
    @OrderBy("date ASC")
    private List
  
  
  

 
  
  orders; } @Entity public class Order { @Id private Long id; private Date date; private long customerId; } 

 複製代碼

c, 使用@JoinEntity 創建多對多(N : M)關係

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

    @ToMany
    @JoinEntity(
            entity = JoinProductsWithOrders.class,
            sourceProperty = "productId",
            targetProperty = "orderId"
    )
    private List
  
  
  

 
  
  ordersWithThisProduct; } @Entity public class JoinProductsWithOrders { @Id private Long id; private Long productId; private Long orderId; } @Entity public class Order { @Id private Long id; } 

 複製代碼

2、自定義類型

1,GreenDao 默認支持的類型有

boolean, Boolean
int, Integer
short, Short
long, Long
float, Float
double, Double
byte, Byte
byte[]
String
Date複製代碼

2,經過 @Convert 註解轉換數據類型

例如:將枚舉類型轉換成整形android

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

    @Convert(converter = RoleConverter.class, columnType = Integer.class)
    private Role role;

    public enum Role {
        DEFAULT(0), AUTHOR(1), ADMIN(2);

        final int id;

        Role(int id) {
            this.id = id;
        }
    }

    public static class RoleConverter implements PropertyConverter
  
  
  

 
  
  { @Override public Role convertToEntityProperty(Integer databaseValue) { if (databaseValue == null) { return null; } for (Role role : Role.values()) { if (role.id == databaseValue) { return role; } } return Role.DEFAULT; } @Override public Integer convertToDatabaseValue(Role entityProperty) { return entityProperty == null ? null : entityProperty.id; } } 

 複製代碼

3、複雜查詢

a, 條件查詢

方法一:git

List
  
  
  

 
  
  joes = userDao.queryRaw("where AGE>?","10");//查詢年齡大於10的用戶 

 複製代碼

方法二:github

List
  
  
  

 
  
  joes = userDao.queryBuilder().where(UserDao.Properties.Age.gt("10")).list(); 

 複製代碼

b, 排序

// order by last name
queryBuilder.orderAsc(Properties.LastName);

// in reverse
queryBuilder.orderDesc(Properties.LastName);

// order by last name and year of birth
queryBuilder.orderAsc(Properties.LastName).orderDesc(Properties.YearOfBirth);複製代碼

c, 分頁

limit(int) : 限制查詢返回的結果的數量。
offset(int): 設置起始位置sql

// 從第二條記錄開始查詢5條記錄
List
  
  
  

 
  
  list = userDao.queryBuilder() .offset(2) .limit(5) .list(); 

 複製代碼

d, 懶加載

LazyList
  
  
  

 
  
  lazyList = userDao.queryBuilder().listLazy(); for (User u:lazyList) { Log.i(TAG, "用戶名:"+u.getName()); } lazyList.close(); //再也不使用時必須關閉,不然會致使數據庫遊標未關閉,從而致使內存泄漏 

 複製代碼

LazyList 是 GreenDao 實現的集合類,實現了 List 接口,因此,直接把 LazyList 當作List 來使用便可,數據庫

public class LazyList
  
  
  

 
  
  implements List 
 
  
    , Closeable { //省略了具體實現 } 
   

 複製代碼

注意: LazyList 再也不使用時必須調用用 close() 方法關閉,不然會致使內存泄漏 。框架

lazyList.close();複製代碼

e, 故障查詢

不少時候咱們在查詢的時候不能查詢到咱們指望的結果,這個時候咱們能夠經過修改 QueryBuilder 的兩個靜態成員變量來打印 SQL 日誌,便於排查問題。ide

QueryBuilder.LOG_SQL = true;
QueryBuilder.LOG_VALUES = true;複製代碼

f, 多表聯合查詢

QueryBuilder
  
  
  

 
  
  queryBuilder = userDao.queryBuilder(); queryBuilder.join(Address.class, AddressDao.Properties.userId) .where(AddressDao.Properties.Street.eq("Sesame Street")); List 
 
  
    users = queryBuilder.list(); 
   

 複製代碼

4、混淆配置

### greenDAO 3
-keepclassmembers class * extends org.greenrobot.greendao.AbstractDao {
public static java.lang.String TABLENAME;
}
-keep class **$Properties

# If you do not use SQLCipher:
-dontwarn org.greenrobot.greendao.database.**
# If you do not use RxJava:
-dontwarn rx.**

### greenDAO 2
-keepclassmembers class * extends de.greenrobot.dao.AbstractDao {
public static java.lang.String TABLENAME;
}
-keep class **$Properties複製代碼

5、數據庫加密

greenDAO 支持 SQLCipher 直接綁定。post

a, 引入依賴:

compile 'net.zetetic:android-database-sqlcipher:3.5.7@aar'複製代碼

b, 初始化加密數據庫

DevOpenHelper helper = new DevOpenHelper(this, "notes-db-encrypted.db");
Database db = helper.getEncryptedWritableDb("
  
  
  

 
  
  "); daoSession = new DaoMaster(db).newSession(); 

 複製代碼

c、其餘操做和未加密同樣(是否是特別簡單)

固然,若是你不是使用 GreenDao 數據庫,一樣可使用 SQLCipher 加密保護咱們的數據,詳細請參考 SQLCipher for Android

六,整合 RxJava

Rxjava 的火爆程度已是如日中天了,GreenDao 對固然也是對提供對 Rxjava 的支持。(比較失望的是目前 GreedDao 僅支持 Rxjava 1,不支持 Rxjava 2)

1,引入 Rxjava 依賴

compile 'io.reactivex:rxandroid:1.2.1'
compile 'io.reactivex:rxjava:1.2.9'複製代碼

3,初始化 GreedDao 配置

public class App extends Application {
    /**
     * 加密標識符
     */
    public static final boolean ENCRYPTED = true;

    private DaoSession daoSession;

    @Override
    public void onCreate() {
        super.onCreate();

        DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(this,ENCRYPTED ? "notes-db-encrypted" : "notes-db");
        Database db = ENCRYPTED ? helper.getEncryptedWritableDb("super-secret") : helper.getWritableDb();
        daoSession = new DaoMaster(db).newSession();
    }

    public DaoSession getDaoSession() {
        return daoSession;
    }
}複製代碼

3, 獲取 RxDao

User user = new User();
 user.setUserId(10);
 user.setName("小紅");
 user.setAge(18);

 DaoSession daoSession = ((MyApp) getApplication()).getDaoSession();
 RxDao
  
  
  

 
  
  userDao = daoSession.getUserDao().rx(); userDao.insert(user) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1 
 
  
    () { @Override public void call(User user) { Log.i(TAG, "保存成功 "); } }); 
   

 複製代碼

相關文章
相關標籤/搜索