編輯:關於android開發
Greendao3.0release與7月6日發布,其中最主要的三大改變就是:1.換包名 2.實體注解 3.加密支持的優化
本文裡面會遇到一些代碼示例,就摘了官方文檔和demo裡的例子了,因為他們的例子已經寫的很好了。
3.0相比2.0的配置較為方便,不用新建Module等一系列操作,可以直接在build.gradle裡配置並新建實體用添加注解的方式生成
build.gradle下添加這些配置(v7包下面的3個是greendao的)
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'org.greenrobot:greendao-gradle-plugin:3.0.0'
}
}
apply plugin: 'org.greenrobot.greendao'
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.4.0'
compile 'org.greenrobot:greendao:3.0.1'
compile 'org.greenrobot:greendao-generator:3.0.0'
compile 'net.zetetic:android-database-sqlcipher:3.5.2'
}
greendao {
targetGenDir 'src/main/java'
daoPackage 'com.XXXX.dao.db'
}
2.2版本是在maingen裡使用addEntity,addProperty等方法,3.0只需要手動創建一個實體類加上注解即可(下面會詳細說)
build項目,自動生成DaoMaster,Daosession,UserDao等文件,接下來就可以在代碼中正常使用了。
大部分的注解都能找到之前與2.0對應的語法
@Entity
public class User {
@Id(autoincrement = true)
private Long id;
@Property(nameInDb = "USERNAME")
private String name;
@NotNull
private int repos;
@Transient
private int tempUsageCount;
...
}
其中
@Entity 用於標識這是一個需要Greendao幫我們生成代碼的bean
@Id 標明主鍵,括號裡可以指定是否自增 相當於2.2版本的
Entity entity = schema.addEntity("User");
entity.addLongProperty("id").primaryKey().autoincrement();
@Property 用於設置屬性在數據庫中的列名(默認不寫就是保持一致)
@NotNull 非空
@Transient 標識這個字段是自定義的不會創建到數據庫表裡 相當於2.2版本的
schema.enableKeepSectionsByDefault(); 會生成下列代碼 // KEEP INCLUDES - put your custom includes here // KEEP INCLUDES END // KEEP FIELDS - put your custom fields here // KEEP FIELDS END // KEEP METHODS - put your custom methods here // KEEP METHODS END
之前想自定義的屬性和其getset方法需要寫在注釋中,現在這個注解就能代替作用
@Entity(
schema = "myschema",
active = true,
nameInDb = "AWESOME_USERS",
indexes = {
@Index(value = "name DESC", unique = true)
},
createInDb = false
)
public class User {
...
}
其中
schema是一個項目中有多個schema時 標明要讓這個dao屬於哪個schema
active 是標明是否支持實體類之間update,refresh,delete等操作 相當於2.2版本的
schema.enableActiveEntitiesByDefault();
nameInDb 就是寫個存在數據庫裡的表名(不寫默認是一致)
indexes 定義索引,這裡可跨越多個列
CreateInDb 如果是有多個實體都關聯這個表,可以把多余的實體裡面設置為false避免重復創建(默認是true)
@Entity
public class User {
@Id private Long id;
@Index(unique = true)
private String name;
}
@Entity
public class User {
@Id private Long id;
@Unique private String name;
}
其中
@Index 通過這個字段建立索引
@Unique 添加唯一約束,上面的括號裡unique=true作用相同
@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;
}
@ToOne 是將自己的一個屬性與另一個表建立關聯,相當於2.2版本的
Property property = entity.addLongProperty("customerId").getProperty();
entity.addToOne(Customer, property);
@ToMany 的使用場景有些多,下面的代碼默認折疊起來
@Entity
public class User {
@Id private Long id;
@ToMany(referencedJoinProperty = "ownerId")
private List<Site> ownedSites;
}
@Entity
public class Site {
@Id private Long id;
private long ownerId;
}
// ----------------------------
@Entity
public class User {
@Id private Long id;
@Unique private String authorTag;
@ToMany(joinProperties = {
@JoinProperty(name = "authorTag", referencedName = "ownerTag")
})
private List<Site> ownedSites;
}
@Entity
public class Site {
@Id private Long id;
@NotNull private String ownerTag;
}
// ----------------------------
@Entity
public class Site {
@Id private Long id;
@ToMany
@JoinEntity(
entity = JoinSiteToUser.class,
sourceProperty = "siteId",
targetProperty = "userId"
)
private List<User> authors;
}
@Entity
public class JoinSiteToUser {
@Id private Long id;
private Long siteId;
private Long userId;
}
@Entity
public class User {
@Id private Long id;
}
@ToMany的屬性referencedJoinProperty,類似於外鍵約束。
@JoinProperty 對於更復雜的關系,可以使用這個注解標明目標屬性的源屬性。
@JoinEntity 如果你在做多對多的關系,有其他的表或實體參與,可以給目標屬性添加這個額外的注解(感覺不常用吧)

@Generated 這個是build後greendao自動生成的,這個注解理解為防止重復,每一塊代碼生成後會加個hash作為標記。 官方不建議你去碰這些代碼,改動會導致裡面代碼與hash值不符。
在Greendao的迭代流程中可以看到這麼一個庫
compile 'org.greenrobot:greendao-generator-encryption:3.0.0beta3'
Greendao3 與下面這個加密庫合作,encryption:3.0.0beta-3相當於一個適配層,之後迭代中並入greendao主庫的3.0.1版本,對database相關的api進行了統一。
compile 'net.zetetic:android-database-sqlcipher:3.5.2'
之前的版本也是支持加密的,但是可以理解為在相互api傳遞數據的時候面臨各種類型轉換,3.0將其統一,使用更加流暢。
可以直接看寫代碼使用
User man1 = new User();
man1.setId(10001);
man1.setName("kobe");
DaoMaster.DevOpenHelper a = new DaoMaster.DevOpenHelper(this,"database_name",null);
try {
daoSession = new DaoMaster(a.getEncryptedWritableDb(MY_PWD)).newSession();
daoSession.getUserDao().insert(man1);
}catch (Exception e){
Log.d("e", String.valueOf(e));
}
// 若干代碼邏輯後。。。
DaoSession normalSession = new DaoMaster(a.getWritableDb()).newSession();
Log.d("無法取數據",normalSession.getUserDao().loadAll().toString());
DaoSession encryptedSession = new DaoMaster(a.getEncryptedWritableDb(MY_PWD)).newSession();//董鉑然 博客園
Log.d("可以取數據",encryptedSession.getUserDao().loadAll().toString());
如上方代碼所示,相比於之前的方法getWriteableDb,加密的方法是用了getEncryptedWritableDb。 並在得到DB並getSession時需要輸入密鑰。 其他的步驟和之前類似。
在取數據時使用的session必須也是使用相同的密鑰new出來的,否則只能看到空數據。
07-27 /com.XXX.dsx.testgreendao3 D/無法取數據: [] 07-27 /com.XXX.dsx.testgreendao3 D/可以取數據: [com.XXX.dsx.testgreendao3.User@2ae5190]
上面的那個MY_PWD是一個靜態變量,建議使用本設備的唯一標識類似於UUID的字段做個加密獲得,這樣每個機器的密鑰是不同的,並且不會發生改變。
如果把加密後的數據庫的本地文件扒出來,也是查不到內容的, 使用dump僅僅可以看到表結構和列名。
如果覺得還不滿意,可以對列名再進行加密。在建表時就對列名加密,後續使用可能會比較麻煩,建議加密一些關鍵表如USER,ACCOUNT。
跨平台開發的兩種方法及其對比,兩種方法
跨平台開發的兩種方法及其對比,兩種方法為什麼移動應用開發對很多開發人員來說,都是一件令人頭痛的事?這是因為,每種流行的移動平台都具有自身的開發語言、開發工具及其特征。 這
實驗一 基本 UI 界面設計
實驗一 基本 UI 界面設計 實驗一 基本 UI 界面設計 【實驗目的】 1.熟悉 Android Studio 開發工具操作 2.熟悉 Android 基本 UI
Android開發技巧——大圖裁剪
Android開發技巧——大圖裁剪 本篇內容是接上篇《Android開發技巧——定制仿微信圖片裁剪控件》 的,先簡單介紹對上篇所封裝的裁剪控件
手把手帶你畫一個漂亮蜂窩view Android自定義view
手把手帶你畫一個漂亮蜂窩view Android自定義view 這個效果做起來好像沒什麼意義,如果不加監聽回調 圖片就能直接替代。寫這篇博客的目的是鍛煉一下思維能力,以更
基於CoordinatorLayout實現向上滾動導航條ToolBar滾出、向下滾動導航條滾出,coordinatorlayout
基於CoordinatorLayout實現向上滾動導航條ToolBar滾