GreenDao 八大特性
- 1.對(duì)象/關(guān)系映射(ORM---Object relation mapping)
GreenDAO的本質(zhì)是為存儲(chǔ)在關(guān)系數(shù)據(jù)庫SQLite中的數(shù)據(jù)提供面向?qū)ο蟮慕缑妗J褂眠^程中,我們只需定義數(shù)據(jù)模型铛嘱,而GreenDAO將創(chuàng)建Java數(shù)據(jù)對(duì)象(實(shí)體)和DAO(數(shù)據(jù)訪問對(duì)象)
對(duì)象關(guān)系映射圖 - 2.性能
GreenDao
官方說過一句話:GreenDAO does not make any compromises regarding performance.
GreenDAO
對(duì)性能不做任何妥協(xié)!!!
在目前所知道的ORM
中,GreenDao
是最快的帖烘,非常適合存儲(chǔ)大量數(shù)據(jù)。所以這也是為什么我已經(jīng)了解LitePal
了還要再學(xué)習(xí)GreenDao
的原因!!!
舉一個(gè)簡(jiǎn)單的例子乡摹,使用了GreenDao
,大多數(shù)實(shí)體可以以每秒幾千個(gè)實(shí)體的速率進(jìn)行插入,更新和加載板熊。
這是官方測(cè)試圖例:
image.png
性能實(shí)在是太高了!!!!為什么不學(xué)呢!!!!! - 3.加密支持
GreenDao
支持加密數(shù)據(jù)庫來保護(hù)敏感數(shù)據(jù) - 4.微小的依賴庫
GreenDao
關(guān)鍵依賴庫大小不超過100kb因此也不會(huì)出現(xiàn)因?yàn)橐?code>GreenDao而出現(xiàn)65k問題. - 5.活動(dòng)實(shí)體
如果需要,實(shí)體可以被“激活”.而活動(dòng)實(shí)體可以透明地解析關(guān)系(我們要做的只是調(diào)用getter
即可)拆撼,并且有更新鸭蛙、刪除和刷新方法,以便方便地訪問持久性功能. - 6.協(xié)議緩沖區(qū)支持
GreenDAO
允許將協(xié)議緩沖區(qū)(protobuf
)對(duì)象直接保存到數(shù)據(jù)庫中.如果用戶通過protobuf
通話到用戶的服務(wù)器,則不需要另一個(gè)映射肪获。常規(guī)實(shí)體的所有持久性操作都可用于protobuf
對(duì)象。因此,相信這是GreenDAO
的獨(dú)特之處. - 7.自動(dòng)生成代碼
使用GreenDao
,我們無需關(guān)注實(shí)體類以及Dao
.體貼的GreenDao
已為我們自動(dòng)生成. - 8.開源
可以查看源碼青柄,深入了解機(jī)制.
GreenDao 優(yōu)勢(shì)
- 1.目前來說性能最高,內(nèi)存消耗最小,支持?jǐn)?shù)據(jù)庫加密;
- 2.依賴庫小于
100kb
,且使用人數(shù)眾多,維護(hù)者也一直在更新; - 3.完善的
api
,并且對(duì)Android
進(jìn)行了高度優(yōu)化,個(gè)人覺得很不錯(cuò)
GreenDao核心類簡(jiǎn)介
- 1.
DaoMaster
:
使用GreenDao
的切入點(diǎn)(開始)。
DaoMaster
保存數(shù)據(jù)庫對(duì)象(SQLiteDatabase
)并管理特定模式的Dao
類(而不是對(duì)象)。它具有靜態(tài)方法來創(chuàng)建表或?qū)⑺鼈儎h除飒货。其內(nèi)部類OpenHelper
和DevOpenHelper
是在SQLite
數(shù)據(jù)庫中創(chuàng)建模式的SQLiteOpenHelper
實(shí)現(xiàn)。 - 2.
DaoSession
:
管理特定模式的所有可用Dao
對(duì)象莫辨,可以使用其中一個(gè)getter
方法獲取。DaoSession
還為實(shí)體提供了一些通用的持久性方法蟆融,如插入山憨,加載郁竟,更新,刷新和刪除讥蟆。最后,DaoSession
對(duì)象也跟蹤一個(gè)身份范圍质况。有關(guān)更多詳細(xì)信息,請(qǐng)點(diǎn)擊查看會(huì)話文檔潭陪。 - 3.
Dao
層:
全稱Data access Objects
.數(shù)據(jù)訪問對(duì)象(Dao
)持續(xù)存在并查詢實(shí)體。對(duì)于每個(gè)實(shí)體,GreenDao
生成一個(gè)Dao
,它比DaoSession
有更多的持久化方法,例如:count
,loadAll
和insertInTx
黎炉。 - 4.實(shí)體:
持久對(duì)象---通常實(shí)體是使用標(biāo)準(zhǔn)Java
屬性(如POJO
或JavaBean
)來表示數(shù)據(jù)庫行的對(duì)象.
配置GreenDao
工程目錄下build.gradle下配置
apply plugin: 'org.greenrobot.greendao' // apply plugin
.....
dependencies {
compile 'org.greenrobot:greendao:3.2.2' // add library
}
在module的build.gradle文件中配置如下
buildscript {
repositories {
mavenCentral() // add repository
}
dependencies {
classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2' // add plugin
}
在上面兩個(gè)build.gradlel面對(duì)greenDao進(jìn)行配置完之后庆械。配置之后就搭建好了greenDao的環(huán)境缭乘,可以自動(dòng)生成相關(guān)的類策幼。
當(dāng)然你還可以配置greenDao
的數(shù)據(jù)庫版本號(hào)以及自動(dòng)生成的包名的路徑,當(dāng)然路徑可選擇性的配置到逊。
android{
...
}
greendao{
schemaVersion 2 // 數(shù)據(jù)庫版本號(hào)
daoPackage 'com.doris.sample.greendao'//greenDao 自動(dòng)生成的代碼保存的包名
targetGenDir 'src/main/java' //自動(dòng)生成的代碼存儲(chǔ)的路徑件缸,默認(rèn)是 build/generated/source/greendao.
generateTests false //true的時(shí)候自動(dòng)生成測(cè)試單元
}
用戶自定義entity
接下來你定義自己的entity并且make project就可以開始對(duì)數(shù)據(jù)庫進(jìn)行操作了.
greenDAO3
用注釋去schemas
和實(shí)體類entities
@Entity注釋
@Entity
:將一個(gè)Java
類轉(zhuǎn)變成一個(gè)實(shí)體類。greenDao
會(huì)根據(jù)這個(gè)生成對(duì)應(yīng)的代碼痊末。PS: 必須是java
類凿叠,kotlin
不支持。
在Entity
中我們可以配置許多信息炒刁,比如nameInDb
是聲明了該表數(shù)據(jù)庫中的表名翔始。
indexes
用于建立索引,索引的應(yīng)用場(chǎng)景可用于全谤,當(dāng)你的表有多個(gè)主鍵的時(shí)候补憾,來標(biāo)志一條數(shù)據(jù)的唯一性,配合unique
削饵。
當(dāng)然上面兩個(gè)只是我們常用的屬性窿撬,還有幾個(gè)其他屬性,目前我還沒有用到:
schema = "myschema",
當(dāng)你有多個(gè)schema
跛璧,用這個(gè)屬性來告訴數(shù)據(jù)庫當(dāng)前entity
屬于哪個(gè)schema
座柱。
active = true
辆布,用于標(biāo)志某個(gè)entity
是否是active
的,active
的實(shí)體類有刪改的方法。默認(rèn)是false
,為true
的時(shí)候會(huì)自動(dòng)生成下面的代碼在entity
里面:
@Entity(
// 如果你有一個(gè)以上的模式割粮,你可以告訴greendao實(shí)體屬于哪個(gè)模式(選擇任何字符串作為名稱)。
schema = "myschema",
// 標(biāo)志允許實(shí)體類可有更新,刪除,刷新方法
active = true,
// 指定數(shù)據(jù)庫中表的名稱蛇摸。默認(rèn)情況下赶袄,該名稱基于實(shí)體類名。(重要)
nameInDb = "AWESOME_USERS",
// 在這里定義多個(gè)列的索引(重要)
indexes = {
@Index(value = "name DESC", unique = true)
},
// 如果DAO創(chuàng)建數(shù)據(jù)庫表(默認(rèn)為true)唬格,則設(shè)置標(biāo)記去標(biāo)識(shí)门粪。如果有多個(gè)實(shí)體映射到一個(gè)表玄妈,或者在greenDAO之外創(chuàng)建表創(chuàng)建,將此設(shè)置為false酝锅。(重要)
createInDb = false,
// 是否應(yīng)該生成所有的屬性構(gòu)造函數(shù)蟋字。一個(gè)無args構(gòu)造函數(shù)總是需要的
generateConstructors = true,
// 是否生成屬性的getter和setter
generateGettersSetters = true
)
@Id注解
標(biāo)志主鍵
選擇long / Long
(多使用Long
)屬性作為實(shí)體ID
苛聘。在數(shù)據(jù)庫方面,它是主要的關(guān)鍵參數(shù)autoincrement
是使ID
值不斷增加的標(biāo)志(不重復(fù)使用舊值)熬拒,也就是我們經(jīng)常說的自增長蛀序。
@Property
如果定義了這個(gè)屬性啸盏,那么nameInDb
的值就是該列在數(shù)據(jù)表里面回懦,該列的名稱潜圃。
比如下面的代碼中StudentName就是該類stuName(原列)在數(shù)據(jù)表里面,該列的名稱.
@Property(nameInDb = "StudentName")
private String stuName;
允許用戶定義屬性映射到的非默認(rèn)列名稱吧凉。如果缺少胀瞪,greenDAO
將以SQL-ish
方式使用字段名稱(大寫字母,下劃線而不是駝峰命名法傍妒,例如customName
將成為CUSTOM_NAME
)。注意:當(dāng)前只能使用內(nèi)聯(lián)常量來指定列名。
@NotNull
標(biāo)志這個(gè)字段不能是null
該屬性在數(shù)據(jù)庫端成為“NOT NULL”列。通常使用@NotNull標(biāo)記原始類型(long酪术,int,short翠储,byte)是有意義的绘雁,而具有包裝類(Long,Integer援所,Short庐舟,Byte))的可空值。
@Transient
表示不存儲(chǔ)在數(shù)據(jù)庫中
@Index
為相應(yīng)的數(shù)據(jù)庫列創(chuàng)建數(shù)據(jù)庫索引
名稱:如果不喜歡greenDAO
為索引生成的默認(rèn)名稱滔岳,則可以在此處指定。
唯一:向索引添加UNIQUE
約束,強(qiáng)制所有值都是唯一的缚柳。
entity
必須有一個(gè)long
/Long
的屬性作為主鍵,但是有時(shí)候我們的主鍵不一定是long
/Long
型的可能是string
或者其它苦蒿,這個(gè)時(shí)候我們就可以定義索引屬性并且注明其獨(dú)一無二
@Index(name = "keyword", unique = true)
private String key;
@Unique
向數(shù)據(jù)庫列添加了一個(gè)UNIQUE
約束惫撰。請(qǐng)注意苍蔬,SQLite
還會(huì)隱式地為其創(chuàng)建索引
編寫自己的entity---Student類
//告訴GreenDao該對(duì)象為實(shí)體,只有被@Entity注釋的Bean類才能被dao類操作
//在Entity中我們可以配置許多信息,比如nameInDb是聲明了該表數(shù)據(jù)庫中的表名。
//indexes 用于建立索引悄雅,索引的應(yīng)用場(chǎng)景可用于,當(dāng)你的表有多個(gè)主鍵的時(shí)候,來標(biāo)志一條數(shù)據(jù)的唯一性铅匹,配合unique再姑。
@Entity
public class Student {
// id自增長
//(autoincrement = true)表示主鍵會(huì)自增蔽挠,如果false就會(huì)使用舊值
@Id(autoincrement = true)
//學(xué)員id,注意這里的stuId只能是Long類型
private Long stuId;
// 學(xué)員編號(hào)---這里的意思是學(xué)員編號(hào)stuNo具有唯一性即數(shù)據(jù)庫中不能有兩個(gè)一樣的stuNo
//如果數(shù)據(jù)庫中有兩個(gè)相同的stuNo會(huì)報(bào)錯(cuò)違反unique規(guī)則
//注意這里的@Index(unique =true)只是針對(duì)stuNo的,和下面的stuName stuSex stuScore沒有什么關(guān)系
@Index(unique =true)
private String stuNo;
// 學(xué)員姓名
//@Property:在數(shù)據(jù)庫中蚌铜,會(huì)對(duì)應(yīng)生成一個(gè)字段涣觉,nameInDb:StudentName(字段名稱)
//@NotNull 標(biāo)志這個(gè)字段不能是null
//@Property 如果定義了這個(gè)屬性昆汹,那么nameInDb的值就是該列在數(shù)據(jù)表里面步淹,該列的名稱挎塌。
// 下面的例子,stuName的值存儲(chǔ)在數(shù)據(jù)表里面的StudentName那一列莹汤。
//@Transient 表示不存儲(chǔ)在數(shù)據(jù)庫中
@Property(nameInDb = "StudentName") @NotNull
private String stuName;
// 學(xué)員性別
private String stuSex;
// 學(xué)員成績
private String stuScore;
}
// 學(xué)員姓名
//@Property:在數(shù)據(jù)庫中燃乍,會(huì)對(duì)應(yīng)生成一個(gè)字段色建,nameInDb:StudentName(字段名稱)
//@NotNull 標(biāo)志這個(gè)字段不能是null
//@Property 如果定義了這個(gè)屬性,那么nameInDb的值就是該列在數(shù)據(jù)表里面,該列的名稱。
// 下面的例子,stuName的值存儲(chǔ)在數(shù)據(jù)表里面的StudentName那一列。
//@Transient 表示不存儲(chǔ)在數(shù)據(jù)庫中
@Property(nameInDb = "StudentName") @NotNull
private String stuName;
用圖片來說明:
點(diǎn)擊Build-> make project就可以自動(dòng)生成相關(guān)的代碼了。
項(xiàng)目目錄結(jié)構(gòu)中多出了如下文件夾,(因?yàn)槲覀兏牧四J(rèn)的目錄結(jié)構(gòu),詳情見下行代碼我們之前設(shè)置的,所以才會(huì)出現(xiàn)項(xiàng)目目錄中多出了如下文件夾)
greendao{
......
targetGenDir 'src/main/java' //自動(dòng)生成的代碼存儲(chǔ)的路徑旁理,默認(rèn)是 build/generated/source/greendao.
}
然后我們編寫的
student
類中也多出來了如下代碼:
//@Generated:編譯后自動(dòng)生成的構(gòu)造函數(shù)、方法等的注釋,提示構(gòu)造函數(shù)、方法等不能被修改
@Generated(hash = 315497705)
public Student(Long stuId, String stuNo, String stuName, String stuSex,
String stuScore) {
this.stuId = stuId;
this.stuNo = stuNo;
this.stuName = stuName;
this.stuSex = stuSex;
this.stuScore = stuScore;
}
@Generated(hash = 1556870573)
public Student() {
}
public Long getStuId() {
return this.stuId;
}
public void setStuId(Long stuId) {
this.stuId = stuId;
}
public String getStuNo() {
return this.stuNo;
}
public void setStuNo(String stuNo) {
this.stuNo = stuNo;
}
public String getStuName() {
return this.stuName;
}
public void setStuName(String stuName) {
this.stuName = stuName;
}
public String getStuSex() {
return this.stuSex;
}
public void setStuSex(String stuSex) {
this.stuSex = stuSex;
}
public String getStuScore() {
return this.stuScore;
}
public void setStuScore(String stuScore) {
this.stuScore = stuScore;
}
獲取StudentDao
初始化Dao
//創(chuàng)建數(shù)據(jù)庫名字為xdl.db
DaoMaster.DevOpenHelper devOpenHelper=new DaoMaster.DevOpenHelper(this,"xdl.db",null);
SQLiteDatabase db=devOpenHelper.getWritableDatabase();
DaoMaster daoMaster=new DaoMaster(db);
DaoSession daoSession=daoMaster.newSession();
//獲取StudentDao,通過StudentDao來CURD數(shù)據(jù)
StudentDao studentDao=daoSession.getStudentDao();
Dao的CURD方法
1.1新增一條數(shù)據(jù)
/**
* Insert an entity into the table associated with a concrete DAO.
*
* @return row ID of newly inserted entity
*/
/**
*將一個(gè)實(shí)體插入與具體DAO關(guān)聯(lián)的表中。
*
* @新插入的實(shí)體的返回行ID
*/
public long insert(T entity) {
return executeInsert(entity, statements.getInsertStatement(), true);
}
studentDao.insert(new Student(null,"002","張針","男孩","0"));
1.2.新增List集合數(shù)據(jù)
/**
* Inserts the given entities in the database using a transaction.
*
* @param entities The entities to insert.
*/
/**
*使用事務(wù)將給定的實(shí)體插入到數(shù)據(jù)庫中。
*
* @參數(shù)實(shí)體要插入的實(shí)體。
*/
public void insertInTx(Iterable<T> entities) {
insertInTx(entities, isEntityUpdateable());
}
case R.id.id_insert_list:
List<Student> list=new ArrayList<>();
list.add(new Student(null, "006", "賀利權(quán)", "大爺兒們", "35"));
list.add(new Student(null, "007", "賀利權(quán)", "老爺兒們", "99"));
list.add(new Student(null, "008", "賀利權(quán)", "老少爺兒們", "88"));
list.add(new Student(null, "009", "賀利權(quán)", "小爺兒們", "43"));
//新增集合數(shù)據(jù)
studentDao.insertInTx(list);
break;
2.刪除指定信息
case R.id.id_delete:
studentDao.queryBuilder().where(StudentDao.Properties.StuName.eq("申學(xué)超")).buildDelete().executeDeleteWithoutDetachingEntities();
Toast.makeText(this,"刪除成功",Toast.LENGTH_SHORT).show();
break;
3.更新指定信息
case R.id.id_update:
Student student=studentDao.queryBuilder().where(StudentDao.Properties.StuName.eq("張針")).build().unique();
if (student!=null){
student.setStuName("屎殼郎");
studentDao.update(student);
}
Toast.makeText(this,"更新成功",Toast.LENGTH_SHORT).show();
break;
4.1查詢所有
case R.id.id_search_all:
List<Student> stulist= studentDao.queryBuilder().list();
if (stulist!=null){
String searchAllInfo=" ";
for (int i=0;i<stulist.size();i++){
Student student=stulist.get(i);
searchAllInfo+=" id" +student.getStuId()+" 編號(hào):"+student.getStuNo()+" 姓名:"+student.getStuName()+
" 性別:"+student.getStuSex() +" 得分:"+student.getStuScore()+"\n";
mTvSearchAllInfo.setText(searchAllInfo);
}
}
break;
4.2.查詢指定數(shù)據(jù) 查詢姓名為"徐冬磊"的信息
case R.id.id_search_assign:
String searchAssignInfo = "";
List<Student> stuList = studentDao.queryBuilder().where(StudentDao.Properties.StuName.eq("徐冬磊")).list();
for (int i = 0; i < stuList.size(); i++) {
Student student = stuList.get(i);
searchAssignInfo += "id:" + student.getStuId() + "編號(hào):" + student.getStuNo() + "姓名:" + student.getStuName() + "性別:" + student.getStuSex() + "成績:" + student.getStuScore() + "\n";
}
mTvInsertAssing.setText(searchAssignInfo);
break;
4.3.查詢指定數(shù)據(jù) 查詢姓名為"賀利權(quán)"的信息并按照成績排序-降序
case R.id.id_search_assign_order_desc:
String searchAssignorderdesc = "";
List<Student> stuList1 = studentDao.queryBuilder().where(StudentDao.Properties.StuName.eq("賀利權(quán)")).orderDesc(StudentDao.Properties.StuScore).list();
for (int i = 0; i < stuList1.size(); i++) {
Student student = stuList1.get(i);
searchAssignorderdesc += "id:" + student.getStuId() + "編號(hào):" + student.getStuNo() + "姓名:" + student.getStuName() + "性別:" + student.getStuSex() + "成績:" + student.getStuScore() + "\n";
}
mTvsearchdesc.setText(searchAssignorderdesc);
break;
4.4.查詢指定數(shù)據(jù) 查詢姓名為"賀利權(quán)"的信息并按照成績排序-升序
case R.id.id_search_assign_order_asc:
String searchassignorderasc=" ";
List<Student> stuList2=studentDao.queryBuilder().where(StudentDao.Properties.StuName.eq("賀利權(quán)")).orderAsc(StudentDao.Properties.StuScore).list();
for (int i=0;i<stuList2.size();i++){
Student student=stuList2.get(i);
searchassignorderasc += "id:" + student.getStuId() + "編號(hào):" + student.getStuNo() + "姓名:" + student.getStuName() + "性別:" + student.getStuSex() + "成績:" + student.getStuScore() + "\n";
}
mTvsearchasc.setText(searchassignorderasc);
break;
4.5.組合查詢數(shù)據(jù) 查詢姓名為"賀利權(quán)" 并且成績小于等于60
case R.id.id_search_combination:
String search_combination=" ";
List<Student> stuList3=studentDao.queryBuilder().where(StudentDao.Properties.StuName.eq("賀利權(quán)"),StudentDao.Properties.StuScore.le(60)).list();
for (int i=0;i<stuList3.size();i++){
Student student=stuList3.get(i);
search_combination+="id:" + student.getStuId() + "編號(hào):" + student.getStuNo() + "姓名:" + student.getStuName() + "性別:" + student.getStuSex() + "成績:" + student.getStuScore() + "\n";
}
mTvSearchCombine.setText(search_combination);
break;
4.6.查詢所有返回?cái)?shù)據(jù) 但只返回前三條數(shù)據(jù)
case R.id.id_search_limit:
List<Student> stuList4=studentDao.queryBuilder().limit(3).list();
if (stuList4!=null){
String searchlimit=" ";
for (int i=0;i<stuList4.size();i++){
Student student=stuList4.get(i);
searchlimit+="id:" + student.getStuId() + "編號(hào):" + student.getStuNo() + "姓名:" + student.getStuName() + "性別:" + student.getStuSex() + "成績:" + student.getStuScore() + "\n";
mTvSearchLimitInfo.setText(searchlimit);
}
}
break;
4.7.查詢所有返回?cái)?shù)據(jù) 但只返回前三條數(shù)據(jù) 并且跳過第一條數(shù)據(jù)
case R.id.id_search_limit_offset:
List<Student> stuList5=studentDao.queryBuilder().limit(3).offset(1).list();
if (stuList5!=null){
String searchlimit=" ";
for (int i=0;i<stuList5.size();i++){
Student student=stuList5.get(i);
searchlimit+="id:" + student.getStuId() + "編號(hào):" + student.getStuNo() + "姓名:" + student.getStuName() + "性別:" + student.getStuSex() + "成績:" + student.getStuScore() + "\n";
mTvSearchLimitOffsetInfo.setText(searchlimit);
}
}
break;
4.8.查詢所有信息總條數(shù)
case R.id.id_search_count:
int stucount=studentDao.queryBuilder().list().size();
//stucount是一個(gè)整型數(shù)據(jù)而setText需要傳入的是一個(gè)CharSequence型數(shù)據(jù)所以如果只傳入stucount會(huì)報(bào)錯(cuò)
mTvSearchCountInfo.setText(stucount+" ");
break;
程序源碼
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private DaoMaster.DevOpenHelper devOpenHelper;
private SQLiteDatabase db;
private DaoMaster daoMaster;
private DaoSession daoSession;
private StudentDao studentDao;
private Button mBtnInsert;
private Button mBtnInsetList;
private Button mBtnInsertall;
private TextView mTvSearchAllInfo;
private Button mBtnInsertassign;
private TextView mTvInsertAssing;
private Button mBtnSearchdesc;
private TextView mTvsearchdesc;
private Button mBtnSearchasc;
private TextView mTvsearchasc;
private Button mBtnSearchCombine;
private TextView mTvSearchCombine;
private Button mBtnSearchLimit;
private TextView mTvSearchLimitInfo;
private Button mBtnSearchLimitOffset;
private TextView mTvSearchLimitOffsetInfo;
private Button mBtnSearchCount;
private TextView mTvSearchCountInfo;
private Button mBtnDelete;
private Button mBtnUpdate;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
devOpenHelper =new DaoMaster.DevOpenHelper(this,"xdl.db",null);
db=devOpenHelper.getWritableDatabase();
daoMaster=new DaoMaster(db);
daoSession=daoMaster.newSession();
studentDao=daoSession.getStudentDao();
mBtnInsert=findViewById(R.id.id_insert);
mBtnInsert.setOnClickListener(this);
mBtnInsetList=findViewById(R.id.id_insert_list);
mBtnInsetList.setOnClickListener(this);
mBtnInsertall=findViewById(R.id.id_search_all);
mBtnInsertall.setOnClickListener(this);
mTvSearchAllInfo=findViewById(R.id.id_search_all_info);
mBtnInsertassign=findViewById(R.id.id_search_assign);
mBtnInsertassign.setOnClickListener(this);
mTvInsertAssing=findViewById(R.id.id_search_assign_info);
mBtnSearchdesc=findViewById(R.id.id_search_assign_order_desc);
mBtnSearchdesc.setOnClickListener(this);
mTvsearchdesc=findViewById(R.id.id_search_assign_order_desc_info);
mBtnSearchasc=findViewById(R.id.id_search_assign_order_asc);
mTvsearchasc=findViewById(R.id.id_search_assign_order_asc_info);
mBtnSearchasc.setOnClickListener(this);
mBtnSearchCombine=findViewById(R.id.id_search_combination);
mTvSearchCombine=findViewById(R.id.id_search_combination_info);
mBtnSearchCombine.setOnClickListener(this);
mBtnSearchLimit=findViewById(R.id.id_search_limit);
mTvSearchLimitInfo=findViewById(R.id.id_search_limit_info);
mBtnSearchLimit.setOnClickListener(this);
mBtnSearchLimitOffset=findViewById(R.id.id_search_limit_offset);
mBtnSearchLimitOffset.setOnClickListener(this);
mTvSearchLimitOffsetInfo=findViewById(R.id.id_search_limit_offset_info);
mBtnSearchCount=findViewById(R.id.id_search_count);
mBtnSearchCount.setOnClickListener(this);
mTvSearchCountInfo=findViewById(R.id.id_search_count_info);
mBtnDelete=findViewById(R.id.id_delete);
mBtnDelete.setOnClickListener(this);
mBtnUpdate=findViewById(R.id.id_update);
mBtnUpdate.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.id_insert:
Student stu = new Student(null,"001", "徐冬磊", "男孩", "50");
long end=studentDao.insert(stu);
if (end>0){
Toast.makeText(this,"001新增成功",Toast.LENGTH_SHORT).show();
}else
{
Toast.makeText(this,"001新增失敗",Toast.LENGTH_SHORT).show();
}
studentDao.insert(new Student(null,"002","張針","男孩","0"));
studentDao.insert(new Student(null,"003","申學(xué)超","男孩","60"));
studentDao.insert(new Student(null,"004","李東","男孩","40"));
studentDao.insert(new Student(null,"005","黃偉健","男孩","80"));
Toast.makeText(this, "002 003 004新增成功~", Toast.LENGTH_SHORT).show();
break;
case R.id.id_insert_list:
List<Student> list=new ArrayList<>();
list.add(new Student(null, "006", "賀利權(quán)", "大爺兒們", "35"));
list.add(new Student(null, "007", "賀利權(quán)", "老爺兒們", "99"));
list.add(new Student(null, "008", "賀利權(quán)", "老少爺兒們", "88"));
list.add(new Student(null, "009", "賀利權(quán)", "小爺兒們", "43"));
//新增集合數(shù)據(jù)
studentDao.insertInTx(list);
break;
case R.id.id_search_all:
List<Student> stulist= studentDao.queryBuilder().list();
if (stulist!=null){
String searchAllInfo=" ";
for (int i=0;i<stulist.size();i++){
Student student=stulist.get(i);
searchAllInfo+=" id" +student.getStuId()+" 編號(hào):"+student.getStuNo()+" 姓名:"+student.getStuName()+
" 性別:"+student.getStuSex() +" 得分:"+student.getStuScore()+"\n";
mTvSearchAllInfo.setText(searchAllInfo);
}
}
break;
case R.id.id_search_assign:
String searchAssignInfo = "";
List<Student> stuList = studentDao.queryBuilder().where(StudentDao.Properties.StuName.eq("徐冬磊")).list();
for (int i = 0; i < stuList.size(); i++) {
Student student = stuList.get(i);
searchAssignInfo += "id:" + student.getStuId() + "編號(hào):" + student.getStuNo() + "姓名:" + student.getStuName() + "性別:" + student.getStuSex() + "成績:" + student.getStuScore() + "\n";
}
mTvInsertAssing.setText(searchAssignInfo);
break;
case R.id.id_search_assign_order_desc:
String searchAssignorderdesc = "";
List<Student> stuList1 = studentDao.queryBuilder().where(StudentDao.Properties.StuName.eq("賀利權(quán)")).orderDesc(StudentDao.Properties.StuScore).list();
for (int i = 0; i < stuList1.size(); i++) {
Student student = stuList1.get(i);
searchAssignorderdesc += "id:" + student.getStuId() + "編號(hào):" + student.getStuNo() + "姓名:" + student.getStuName() + "性別:" + student.getStuSex() + "成績:" + student.getStuScore() + "\n";
}
mTvsearchdesc.setText(searchAssignorderdesc);
break;
case R.id.id_search_assign_order_asc:
String searchassignorderasc=" ";
List<Student> stuList2=studentDao.queryBuilder().where(StudentDao.Properties.StuName.eq("賀利權(quán)")).orderAsc(StudentDao.Properties.StuScore).list();
for (int i=0;i<stuList2.size();i++){
Student student=stuList2.get(i);
searchassignorderasc += "id:" + student.getStuId() + "編號(hào):" + student.getStuNo() + "姓名:" + student.getStuName() + "性別:" + student.getStuSex() + "成績:" + student.getStuScore() + "\n";
}
mTvsearchasc.setText(searchassignorderasc);
break;
case R.id.id_search_combination:
String search_combination=" ";
List<Student> stuList3=studentDao.queryBuilder().where(StudentDao.Properties.StuName.eq("賀利權(quán)"),StudentDao.Properties.StuScore.le(60)).list();
for (int i=0;i<stuList3.size();i++){
Student student=stuList3.get(i);
search_combination+="id:" + student.getStuId() + "編號(hào):" + student.getStuNo() + "姓名:" + student.getStuName() + "性別:" + student.getStuSex() + "成績:" + student.getStuScore() + "\n";
}
mTvSearchCombine.setText(search_combination);
break;
case R.id.id_search_limit:
List<Student> stuList4=studentDao.queryBuilder().limit(3).list();
if (stuList4!=null){
String searchlimit=" ";
for (int i=0;i<stuList4.size();i++){
Student student=stuList4.get(i);
searchlimit+="id:" + student.getStuId() + "編號(hào):" + student.getStuNo() + "姓名:" + student.getStuName() + "性別:" + student.getStuSex() + "成績:" + student.getStuScore() + "\n";
mTvSearchLimitInfo.setText(searchlimit);
}
}
break;
case R.id.id_search_limit_offset:
List<Student> stuList5=studentDao.queryBuilder().limit(3).offset(1).list();
if (stuList5!=null){
String searchlimit=" ";
for (int i=0;i<stuList5.size();i++){
Student student=stuList5.get(i);
searchlimit+="id:" + student.getStuId() + "編號(hào):" + student.getStuNo() + "姓名:" + student.getStuName() + "性別:" + student.getStuSex() + "成績:" + student.getStuScore() + "\n";
mTvSearchLimitOffsetInfo.setText(searchlimit);
}
}
break;
case R.id.id_search_count:
int stucount=studentDao.queryBuilder().list().size();
//stucount是一個(gè)整型數(shù)據(jù)而setText需要傳入的是一個(gè)CharSequence型數(shù)據(jù)所以如果只傳入stucount會(huì)報(bào)錯(cuò)
mTvSearchCountInfo.setText(stucount+" ");
break;
case R.id.id_delete:
studentDao.queryBuilder().where(StudentDao.Properties.StuName.eq("申學(xué)超")).buildDelete().executeDeleteWithoutDetachingEntities();
Toast.makeText(this,"刪除成功",Toast.LENGTH_SHORT).show();
break;
case R.id.id_update:
Student student=studentDao.queryBuilder().where(StudentDao.Properties.StuName.eq("張針")).build().unique();
if (student!=null){
student.setStuName("屎殼郎");
studentDao.update(student);
}
Toast.makeText(this,"更新成功",Toast.LENGTH_SHORT).show();
break;
}
}
}
/**
* Created by Administrator on 2018/4/21.
*/
//告訴GreenDao該對(duì)象為實(shí)體,只有被@Entity注釋的Bean類才能被dao類操作
//在Entity中我們可以配置許多信息,比如nameInDb是聲明了該表數(shù)據(jù)庫中的表名禾锤。
//indexes 用于建立索引着帽,索引的應(yīng)用場(chǎng)景可用于书闸,當(dāng)你的表有多個(gè)主鍵的時(shí)候,來標(biāo)志一條數(shù)據(jù)的唯一性现柠,配合unique。
@Entity
public class Student {
// id自增長
//(autoincrement = true)表示主鍵會(huì)自增,如果false就會(huì)使用舊值
@Id(autoincrement = true)
//學(xué)員id,注意這里的stuId只能是Long類型
private Long stuId;
// 學(xué)員編號(hào)---這里的意思是學(xué)員編號(hào)stuNo具有唯一性即數(shù)據(jù)庫中不能有兩個(gè)一樣的stuNo
//如果數(shù)據(jù)庫中有兩個(gè)相同的stuNo會(huì)報(bào)錯(cuò)違反unique規(guī)則
//注意這里的@Index(unique =true)只是針對(duì)stuNo的,和下面的stuName stuSex stuScore沒有什么關(guān)系
@Index(unique =true)
private String stuNo;
// 學(xué)員姓名
//@Property:在數(shù)據(jù)庫中路捧,會(huì)對(duì)應(yīng)生成一個(gè)字段窒舟,nameInDb:StudentName(字段名稱)
//@NotNull 標(biāo)志這個(gè)字段不能是null
//@Property 如果定義了這個(gè)屬性系忙,那么nameInDb的值就是該列在數(shù)據(jù)表里面,該列的名稱惠豺。
// 下面的例子,stuName的值存儲(chǔ)在數(shù)據(jù)表里面的StudentName那一列笨觅。
//@Transient 表示不存儲(chǔ)在數(shù)據(jù)庫中
@Property(nameInDb = "StudentName") @NotNull
private String stuName;
// 學(xué)員性別
private String stuSex;
// 學(xué)員成績
private String stuScore;
//@Generated:編譯后自動(dòng)生成的構(gòu)造函數(shù)、方法等的注釋耕腾,提示構(gòu)造函數(shù)、方法等不能被修改
@Generated(hash = 315497705)
public Student(Long stuId, String stuNo, String stuName, String stuSex,
String stuScore) {
this.stuId = stuId;
this.stuNo = stuNo;
this.stuName = stuName;
this.stuSex = stuSex;
this.stuScore = stuScore;
}
@Generated(hash = 1556870573)
public Student() {
}
public Long getStuId() {
return this.stuId;
}
public void setStuId(Long stuId) {
this.stuId = stuId;
}
public String getStuNo() {
return this.stuNo;
}
public void setStuNo(String stuNo) {
this.stuNo = stuNo;
}
public String getStuName() {
return this.stuName;
}
public void setStuName(String stuName) {
this.stuName = stuName;
}
public String getStuSex() {
return this.stuSex;
}
public void setStuSex(String stuSex) {
this.stuSex = stuSex;
}
public String getStuScore() {
return this.stuScore;
}
public void setStuScore(String stuScore) {
this.stuScore = stuScore;
}
}
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:overScrollMode="never"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="15dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="本示例旨在為大家簡(jiǎn)單講解關(guān)于GreenDao使用"/>
<Button
android:id="@+id/id_insert"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="新增一條數(shù)據(jù)"/>
<Button
android:id="@+id/id_insert_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="新增集合數(shù)據(jù)"/>
<Button
android:id="@+id/id_search_all"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="查詢所有數(shù)據(jù)"/>
<TextView
android:id="@+id/id_search_all_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/id_search_assign"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="查詢指定數(shù)據(jù)"/>
<TextView
android:id="@+id/id_search_assign_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/id_search_assign_order_desc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="查詢指定數(shù)據(jù)并根據(jù)成績排序-降序"/>
<TextView
android:id="@+id/id_search_assign_order_desc_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/id_search_assign_order_asc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="查詢指定數(shù)據(jù)并根據(jù)成績排序-升序"/>
<TextView
android:id="@+id/id_search_assign_order_asc_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/id_search_combination"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="組合查詢-降序顯示(默認(rèn))"/>
<TextView
android:id="@+id/id_search_combination_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/id_search_limit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="查詢所有 只返回3條"/>
<TextView
android:id="@+id/id_search_limit_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/id_search_limit_offset"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="查詢所有 只返回3條 跳過第一條"/>
<TextView
android:id="@+id/id_search_limit_offset_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/id_search_count"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="查詢所有信息總條數(shù)"/>
<TextView
android:id="@+id/id_search_count_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/id_delete"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="刪除指定信息"/>
<Button
android:id="@+id/id_update"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="更新指定信息"/>
</LinearLayout>
</ScrollView>
結(jié)束語
當(dāng)然CRUD
方法還不是很全可以再看看官方文檔:
GreenDao 官網(wǎng):http://greenrobot.org/greendao/
GreenDao 特征介紹:http://greenrobot.org/greendao/features/
GreenDao 學(xué)習(xí)文檔:http://greenrobot.org/greendao/documentation/
GreenDao 更新日志:http://greenrobot.org/greendao/changelog/
GreenDao GitHub地址:https://github.com/greenrobot/greenDAO