編輯:關於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 界面設計 【實驗目的】 1.熟悉 Android Studio 開發工具操作 2.熟悉 Android 基本 UI
Android開發技巧——大圖裁剪 本篇內容是接上篇《Android開發技巧——定制仿微信圖片裁剪控件》 的,先簡單介紹對上篇所封裝的裁剪控件
手把手帶你畫一個漂亮蜂窩view Android自定義view 這個效果做起來好像沒什麼意義,如果不加監聽回調 圖片就能直接替代。寫這篇博客的目的是鍛煉一下思維能力,以更
基於CoordinatorLayout實現向上滾動導航條ToolBar滾