在Android開發(fā)過程中,有時候我們需要使用SQLite數(shù)據(jù)庫去本地存儲一些臨時文件蒲祈,之前,我們的做法是通過SQLiteOpenHelper實現(xiàn)創(chuàng)建數(shù)據(jù)庫,以及迭代開發(fā)中的數(shù)據(jù)庫數(shù)據(jù) 內(nèi)容 字段 變更時處理兔朦。
優(yōu)點
1.通常我們在使用GreenDao的時候,我們只需定義數(shù)據(jù)模型磨确,GreenDao框架將創(chuàng)建數(shù)據(jù)對象(實體)和DAO(數(shù)據(jù)訪問對象)沽甥,能夠節(jié)省部分代碼。
2.不向性能妥協(xié)乏奥,使用了GreenDao摆舟,大多數(shù)實體可以以每秒幾千個實體的速率進行插入,更新和加載邓了。
3.GreenDao支持加密數(shù)據(jù)庫來保護敏感數(shù)據(jù)恨诱。
4.微小的依賴庫,GreenDao的關(guān)鍵依賴庫大小不超過100kb.
5.如果需要骗炉,實體是可以被激活的照宝。而活動實體可以透明的解析關(guān)系(我們要做的只是調(diào)用getter即可),并且有更新句葵、刪除和刷新方法厕鹃,以便訪問持久性功能。
6.GreenDao允許您將協(xié)議緩沖區(qū)(protobuf)對象直接保存到數(shù)據(jù)庫中乍丈。如果您通過protobuf通話到您的服務器剂碴,則不需要另一個映射。常規(guī)實體的所有持久性操作都可以用于protobuf對象轻专。所以忆矛,相信這是GreenDao的獨特之處。
7.自動生成代碼请垛,我們無需關(guān)注實體類以及Dao,因為GreenDao已經(jīng)幫我們生成了催训。
8.開源 有興趣的同學可以查看源碼洽议,深入去了解機制。
GreenDao對外提供的核心類簡介
1.DaoMaster
DaoMaster保存數(shù)據(jù)庫對象(SQLiteDatabase)并管理特定模式的Dao類漫拭。它具有靜態(tài)方法來創(chuàng)建表或?qū)⑺麄儎h除绞铃。其內(nèi)部類OpenHelper和DevOpenHelper是在SQLite數(shù)據(jù)庫中創(chuàng)建模式的SQLiteOpenHelper實現(xiàn)。
2.DaoSession
管理特定模式的所有可用Dao對象嫂侍,您可以使用其中一個getter方法獲取儿捧。DaoSession還為實體提供了一些通用的持久性方法,如插入挑宠,加載菲盾,更新,刷新和刪除各淀。最后懒鉴,DaoSession對象也跟蹤一個身份范圍。
3.Dao層
數(shù)據(jù)訪問對象(Dao)持續(xù)存在并查詢實體碎浇。對于每個實體临谱,GreenDao生成一個Dao,它比DaoSession有更多的持久化方法,例如:count,loadAll和insertInTx奴璃。
4.實體
持久對象悉默,通常實體是使用標準Java屬性(如POJO或JavaBean)來表示數(shù)據(jù)庫的對象。
GreenDao使用
1.在工程目錄下build.gradle下添加插件
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.1.2'
classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2' // 添加插件 更好支持GreenDao
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
然后Sync Now即可苟穆。
2.在項目目錄下的build.gradle下添加插件依賴
apply plugin: 'com.android.application'
apply plugin: 'org.greenrobot.greendao'
接下來繼續(xù)添加依賴庫
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0-rc01'
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation 'org.greenrobot:greendao:3.2.2' // 添加庫
}
再接下來就是初始化GreenDao配置抄课,在app下的build.gradle目錄下。
greendao {
schemaVersion 1 //當前數(shù)據(jù)庫版本
}
然后Sync Now即可雳旅。
到這里為止跟磨,GreenDao的基本配置就大差不差了。
使用Demo
1.定義一個實體類
@Id(autoincrement = true)//設(shè)置自增長
private Long id;
@Index(unique = true)//設(shè)置唯一性
private String perNo;//人員編號
private String name;//人員姓名
private String sex;//人員姓名
在我們Make Project后攒盈,實體內(nèi)的變化如下所示:
@Entity
public class PersonInfor {
@Id(autoincrement = true)//設(shè)置自增長
private Long id;
@Index(unique = true)//設(shè)置唯一性
private String perNo;//人員編號
private String name;//人員姓名
private String sex;//人員姓名
@Generated(hash = 1311768890)
public PersonInfor(Long id, String perNo, String name, String sex) {
this.id = id;
this.perNo = perNo;
this.name = name;
this.sex = sex;
}
@Generated(hash = 1362534400)
public PersonInfor() {
}
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public String getPerNo() {
return this.perNo;
}
public void setPerNo(String perNo) {
this.perNo = perNo;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return this.sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
我們可以看到編譯后1.自動生成無參抵拘,有參構(gòu)造。2.自動生成getter,setter方法型豁。
2.封裝數(shù)據(jù)庫操作類
因為我們對數(shù)據(jù)庫的操作無非就是增刪改查四個操作僵蛛,所以我們將他們簡單封裝一下。
public class DbController {
/**
* Helper
*/
private DaoMaster.DevOpenHelper mHelper;//獲取Helper對象
/**
* 數(shù)據(jù)庫
*/
private SQLiteDatabase db;
/**
* DaoMaster
*/
private DaoMaster mDaoMaster;
/**
* DaoSession
*/
private DaoSession mDaoSession;
/**
* 上下文
*/
private Context context;
/**
* dao
*/
private PersonInforDao personInforDao;
private static DbController mDbController;
/**
* 獲取單例
*/
public static DbController getInstance(Context context){
if(mDbController == null){
synchronized (DbController.class){
if(mDbController == null){
mDbController = new DbController(context);
}
}
}
return mDbController;
}
/**
* 初始化
* @param context
*/
public DbController(Context context) {
this.context = context;
mHelper = new DaoMaster.DevOpenHelper(context,"person.db", null);
mDaoMaster =new DaoMaster(getWritableDatabase());
mDaoSession = mDaoMaster.newSession();
personInforDao = mDaoSession.getPersonInforDao();
}
/**
* 獲取可讀數(shù)據(jù)庫
*/
private SQLiteDatabase getReadableDatabase(){
if(mHelper == null){
mHelper = new DaoMaster.DevOpenHelper(context,"person.db",null);
}
SQLiteDatabase db =mHelper.getReadableDatabase();
return db;
}
/**
* 獲取可寫數(shù)據(jù)庫
* @return
*/
private SQLiteDatabase getWritableDatabase(){
if(mHelper == null){
mHelper =new DaoMaster.DevOpenHelper(context,"person.db",null);
}
SQLiteDatabase db = mHelper.getWritableDatabase();
return db;
}
/**
* 會自動判定是插入還是替換
* @param personInfor
*/
public void insertOrReplace(PersonInfor personInfor){
personInforDao.insertOrReplace(personInfor);
}
/**插入一條記錄偷遗,表里面要沒有與之相同的記錄
*
* @param personInfor
*/
public long insert(PersonInfor personInfor){
return personInforDao.insert(personInfor);
}
/**
* 更新數(shù)據(jù)
* @param personInfor
*/
public void update(PersonInfor personInfor){
PersonInfor mOldPersonInfor = personInforDao.queryBuilder().where(PersonInforDao.Properties.Id.eq(personInfor.getId())).build().unique();//拿到之前的記錄
if(mOldPersonInfor !=null){
mOldPersonInfor.setName("張三");
personInforDao.update(mOldPersonInfor);
}
}
/**
* 按條件查詢數(shù)據(jù)
*/
public List<PersonInfor> searchByWhere(String wherecluse){
List<PersonInfor>personInfors = (List<PersonInfor>) personInforDao.queryBuilder().where(PersonInforDao.Properties.Name.eq(wherecluse)).build().unique();
return personInfors;
}
/**
* 查詢所有數(shù)據(jù)
*/
public List<PersonInfor> searchAll(){
List<PersonInfor>personInfors=personInforDao.queryBuilder().list();
return personInfors;
}
/**
* 刪除數(shù)據(jù)
*/
public void delete(String wherecluse){
personInforDao.queryBuilder().where(PersonInforDao.Properties.Name.eq(wherecluse)).buildDelete().executeDeleteWithoutDetachingEntities();
}
}
看看我們的MainActivity
public class MainActivity extends AppCompatActivity {
private Button Add,Delete,Update,Search;
private DbController mDbController;
private PersonInfor personInfor1,personInfor2,personInfor3,personInfor4;
private long insertTipId;
private TextView dataArea;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDbController = DbController.getInstance(MainActivity.this);
initView();
Envent();
similateData();
}
private void similateData() {
personInfor1 = new PersonInfor(null,"001","王大寶","男");
personInfor2 = new PersonInfor(null,"002","李曉麗","女");
personInfor3 = new PersonInfor(null,"003","王麻麻","男");
personInfor4 = new PersonInfor(null,"004","王大錘","女");
}
private void Envent() {
Add.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//Add
mDbController.insertOrReplace(personInfor1);
mDbController.insertOrReplace(personInfor2);
mDbController.insertOrReplace(personInfor3);
mDbController.insertOrReplace(personInfor4);
showDataList();
}
});
Delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//Delete
mDbController.delete("王麻麻");
showDataList();
}
});
Update.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//Update
mDbController.update(personInfor1);
showDataList();
}
});
Search.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//Search
showDataList();
}
});
}
private void showDataList() {
StringBuilder sb = new StringBuilder();
List<PersonInfor>personInfors = mDbController.searchAll();
for(PersonInfor personInfor:personInfors){
// dataArea.setText("id:"+p);
sb.append("id:").append(personInfor.getId())
.append("perNo:").append(personInfor.getPerNo())
.append("name:").append(personInfor.getName())
.append("sex:").append(personInfor.getSex())
.append("\n");
}
dataArea.setText(sb.toString());
}
private void initView() {
Add = findViewById(R.id.Add);
Delete = findViewById(R.id.Delete);
Update = findViewById(R.id.Update);
Search = findViewById(R.id.Search);
dataArea= findViewById(R.id.tips);
}
}
代碼說明:
細心的同學可以看到我們已經(jīng)不用再使用創(chuàng)建數(shù)據(jù)庫的sql語言了墩瞳,因為GreenDao框架已經(jīng)幫我們做了驼壶,通過之前的方式創(chuàng)建數(shù)據(jù)庫過程當中還有可能出現(xiàn)一些莫名其妙的錯誤氏豌。我們只要定義出實體就可以了,從代碼中可以看到我們創(chuàng)建了一個person.db的數(shù)據(jù)庫热凹。其實與我們平常操作就是這個Dao,這個框架會根據(jù)不同的數(shù)據(jù)實體對應生成不同的Dao,通過這個Dao我們就可以調(diào)用相應的接口去完成增刪改查泵喘。
Demo簡單展示
插入數(shù)據(jù)
更新數(shù)據(jù)
刪除數(shù)據(jù)
刪除了王麻麻泪电。
查詢數(shù)據(jù)
GreenDao的介紹和使用就到此為止了,這個框架很方便纪铺,值得一用相速。