本篇大部分来自网上,算是个整合。
greenDao的优势就不说了 直接开始吧!
greenDao3在原来的版本做了很大的修改,所以先谈谈搭建!
首先按github官方说明可以知道要在根build.gradle和app下的build.gradle进行设置
首先是根 build.gradle的设置
// In your root build.gradle file:
buildscript {
repositories {
jcenter()
mavenCentral() // add repository
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.1'
classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2' // add plugin
}
}
在之后是app build.gradle的设置
// In your app projects build.gradle file:
apply plugin: 'com.android.application'
apply plugin: 'org.greenrobot.greendao' // apply plugin
dependencies {
compile 'org.greenrobot:greendao:3.2.2' // add library
}
我的设置如下
//schemaVersion: 数据库schema版本,也可以理解为数据库版本号
//daoPackage:设置DaoMaster、DaoSession、Dao包名
//targetGenDir:设置DaoMaster、DaoSession、Dao目录
//targetGenDirTest:设置生成单元测试目录
//generateTests:设置自动生成单元测试用例
greendao {
schemaVersion 1
daoPackage 'com.gjn.msdemo.green'
targetGenDir 'src/main/java'
}
之后再dependencies中加入greenDao3.2.2就好了 中间其他导入的就省略了
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
......
compile 'org.greenrobot:greendao:3.2.2'
}
之后需要设置我们的数据库了
greenDao3之后是以注解式来创建表的,下面先放一些注解说明 来自这边
@Entity 用于标识这是一个需要Greendao帮我们生成代码的bean
@Id 标明主键,括号里可以指定是否自增
@Property 用于设置属性在数据库中的列名(默认不写就是保持一致)
@NotNull 非空
@Transient 标识这个字段是自定义的不会创建到数据库表里
@Entity(
schema = "myschema",
active = true,
nameInDb = "AWESOME_USERS",
indexes = {
@Index(value = "name DESC", unique = true)
},
createInDb = false
)
schema是一个项目中有多个schema时 标明要让这个dao属于哪个schema
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 通过这个字段建立索引
@ToOne 是将自己的一个属性与另一个表建立关联
@ToMany 是将自己的一个属性与多个表建立关联
这两个比较繁琐可以看原文,这边就不详细说明了!
首先我们创建一个类GDUser.class
如下添加注解
@Entity
public class GDUser {
@Id
private Long id;
@NotNull
private String name;
private String sex;
private int age;
}
package com.gjn.msdemo.greendaoModel;
import org.greenrobot.greendao.annotation.Entity;
import org.greenrobot.greendao.annotation.Id;
import org.greenrobot.greendao.annotation.NotNull;
import org.greenrobot.greendao.annotation.Generated;
/**
* GDUser
* Author: gjn.
* Time: 2017/9/7.
*/
@Entity
public class GDUser {
@Id
private Long id;
@NotNull
private String name;
private String sex;
private int age;
@Generated(hash = 1925400777)
public GDUser(Long id, @NotNull String name, String sex, int age) {
this.id = id;
this.name = name;
this.sex = sex;
this.age = age;
}
@Generated(hash = 1014226889)
public GDUser() {
}
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
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;
}
public int getAge() {
return this.age;
}
public void setAge(int age) {
this.age = age;
}
}
然后项目中在green设置的下面也多了一个GDUserDao的类
之后我们需要对这个GDUser表进行操作就需要建一个帮助类
package com.gjn.msdemo.util;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import com.gjn.msdemo.green.DaoMaster;
import com.gjn.msdemo.green.DaoSession;
/**
* GreenDaoHelper
* Author: gjn.
* Time: 2017/9/6.
*/
public class GreenDaoHelper {
private static DaoMaster.DevOpenHelper devOpenHelper;
private static SQLiteDatabase database;
private static DaoMaster daoMaster;
private static DaoSession daoSession;
/**
* 初始化 建议放在Application中
* @param context
*/
public static void initDatabase(Context context){
// 注意:默认的 DaoMaster.DevOpenHelper 会在数据库升级时,删除所有的表,意味着这将导致数据的丢失。
// 所以,在正式的项目中,你还应该做一层封装,来实现数据库的安全升级。
devOpenHelper = new DaoMaster.DevOpenHelper(context,"msdemo_db",null);
database = devOpenHelper.getWritableDatabase();
// 注意:该数据库连接属于 DaoMaster,所以多个 Session 指的是相同的数据库连接。
daoMaster = new DaoMaster(database);
daoSession = daoMaster.newSession();
}
public static SQLiteDatabase getDatabase() {
return database;
}
public static DaoSession getDaoSession() {
return daoSession;
}
}
帮助类写好了之后 我们就可以对数据库进行操作了
首先我做了个简单的界面操作
操作如下
添加数据->查询全部->删除1号数据->查询全部->全部删除->添加数据->修改张三数据->查询全部
代码如下
package com.gjn.msdemo.greendaoModel;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import com.gjn.msdemo.R;
import com.gjn.msdemo.green.GDUserDao;
import com.gjn.msdemo.util.GreenDaoHelper;
import butterknife.ButterKnife;
import butterknife.OnClick;
public class GreenDaoActivity extends AppCompatActivity {
private static final String TAG = "GreenDaoActivity";
private GDUserDao userDao;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_green_dao);
ButterKnife.bind(this);
userDao = GreenDaoHelper.getDaoSession().getGDUserDao();
}
@OnClick(R.id.btn_add_gd)
public void add(){
userDao.insert(new GDUser(null,"张三","男",18));
userDao.insert(new GDUser(null,"李四","女",28));
userDao.insert(new GDUser(null,"王五","男",38));
Log.e(TAG, "添加成功");
}
@OnClick(R.id.btn_delete_gd)
public void delete(){
try{
userDao.deleteByKey((long) 1);
Log.e(TAG, "删除成功");
}catch (Exception e){
Log.e(TAG, "删除失败");
}
}
@OnClick(R.id.btn_change_gd)
public void change(){
GDUser user = userDao.queryBuilder()
.where(GDUserDao.Properties.Name.eq("张三"))
.build()
.unique();
if (user != null){
user.setName("马六");
userDao.update(user);
Log.e(TAG, "修改成功");
}else{
Log.e(TAG, "修改失败");
}
}
@OnClick(R.id.btn_query_gd)
public void query(){
for (GDUser gdUser : userDao.loadAll()) {
Log.e(TAG, "==>\n"+gdUser.getId()+","+gdUser.getName()
+","+gdUser.getSex() +","+gdUser.getAge());
}
}
@OnClick(R.id.btn_deleteall_gd)
public void deleteAll(){
userDao.deleteAll();
Log.e(TAG, "全部删除");
}
}
可以看到这些都是基本的操作
下面我将把这块分开来讲解下
首先我们先通过帮助类获取写操作
userDao = GreenDaoHelper.getDaoSession().getGDUserDao();
增加是最简单的直接加入对象即可
userDao.insert(new GDUser(null,"张三","男",18));
userDao.insert(new GDUser(null,"李四","女",28));
userDao.insert(new GDUser(null,"王五","男",38));
首先我上面设置的实体类是Long,当@Id设置的是Long的时候 传入null id就会自增
删除的方法有几个
包括删除全部
userDao.deleteAll();
删除key为多少的对象
userDao.deleteByKey((long) 1); //这边是删除id=1的对象
比如我想删掉张三
GDUser user = userDao.queryBuilder()
.where(GDUserDao.Properties.Name.eq("张三"))
.build()
.unique();
userDao.delete(user);
改的话方法是update
userDao.update(user);
就只能依靠查询的对象来进行修改
查询是数据库中最重要的一环 所以会比较多
查询的方法主要依靠下面2个
userDao.queryRaw();
userDao.queryBuilder();
这就很像我们直接对Sqlite数据库操作的的查询了并且返回的值是一个List 代表多个
现在我们要从上面的默认三个数据中查找男性user
for (GDUser gdUser : userDao.queryRaw("where T.SEX=?", "男")) {
Log.e(TAG, "==>\n"+gdUser.getId()+","+gdUser.getName()
+","+gdUser.getSex() +","+gdUser.getAge());
}
这边开始写的是直接
userDao.queryRaw("SEX=?", "男")
发现报错,然后看了下源码发现
/** A raw-style query where you can pass any WHERE clause and arguments. */
public List queryRaw(String where, String... selectionArg) {
Cursor cursor = db.rawQuery(statements.getSelectAll() + where, selectionArg);
return loadAllAndCloseCursor(cursor);
}
然后依据报错 加入了 where和 T. 然后就可以成功查询了
结果如下
下面在说个查询是通过构建查询对象进行查询
这边我想查询年龄小于等于30岁的user 代码如下
for (GDUser gdUser : userDao.queryBuilder()
.where(GDUserDao.Properties.Age.le(30))
.build()
.list()) {
Log.e(TAG, "==>\n"+gdUser.getId()+","+gdUser.getName()
+","+gdUser.getSex() +","+gdUser.getAge());
}
上面我们在修改中也查询过,但是那个是查询单个人 最后build的是unique 而这边是集合 所以使用了list
其中后面的eq le 可以直接点入源码查看
下面罗列下吧
eq | ('=') |
notEq | ('<>') |
like | LIKE |
between | BETWEEN ... AND ... |
in | IN (..., ..., ...) |
notIn | NOT IN (..., ..., ...) |
gt | ('>') |
lt | ('<') |
ge | ('>=') |
le | ('<=') |
isNull | IS NULL |
isNotNull | IS NOT NULL |
其他还有更多的应用我下面添加下
作者:离羊
链接:http://www.jianshu.com/p/4e6d72e7f57a
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
long insert(T entity) // 插入指定实体
void insertInTx(T... entities)
void insertInTx(java.lang.Iterable entities)
void insertInTx(java.lang.Iterable entities, boolean setPrimaryKey)
long insertWithoutSettingPk(T entity) // 插入指定实体,无主键
long insertOrReplace(T entity) // 插入或替换指定实体
void insertOrReplaceInTx(T... entities)
void insertOrReplaceInTx(java.lang.Iterable entities)
void insertOrReplaceInTx(java.lang.Iterable entities, boolean setPrimaryKey)
void save(T entity) // 依赖指定的主键插入或修改实体
void saveInTx(T... entities)
void saveInTx(java.lang.Iterable entities)
void deleteAll() // 删除所有
void delete(T entity) // 删除指定的实体
void deleteInTx(T... entities)
void deleteInTx(java.lang.Iterable entities)
void deleteByKey(K key) // 删除指定主键对应的实体
void deleteByKeyInTx(K... keys)
void deleteByKeyInTx(java.lang.Iterable keys)
void update(T entity)
void updateInTx(T... entities)
void updateInTx(java.lang.Iterable entities)
void refresh(T entity) // 从数据库获取值刷新本地实体
long count() // 数量
boolean detach(T entity) // 从域中分离实体
void detachAll() // 从域中分离所有实体
AbstractDaoSession getSession()
Database getDatabase()
java.lang.String getTablename()
java.lang.String[] getAllColumns()
java.lang.String[] getPkColumns()
java.lang.String[] getNonPkColumns()
Property getPkProperty()
Property[] getProperties()
java.util.List loadAll()
T load(K key)
T loadByRowId(long rowId)
List joes = userDao.queryBuilder() // 查询 User
.where(Properties.FirstName.eq("Joe")) // 首名为 Joe
.orderAsc(Properties.LastName) // 末名升序排列
.list(); // 返回集合
// Joe,>= 1970.10
QueryBuilder qb = userDao.queryBuilder();
qb.where(Properties.FirstName.eq("Joe"),
qb.or(Properties.YearOfBirth.gt(1970),
qb.and(Properties.YearOfBirth.eq(1970), Properties.MonthOfBirth.ge(10))));
List youngJoes = qb.list();
QueryBuilder queryBuilder() // Dao
// QueryBuilder
QueryBuilder where(WhereCondition cond, WhereCondition... condMore) // 条件,AND 连接
QueryBuilder whereOr(WhereCondition cond1, WhereCondition cond2, WhereCondition... condMore) // 条件,OR 连接
QueryBuilder distinct() // 去重,例如使用联合查询时
QueryBuilder limit(int limit) // 限制返回数
QueryBuilder offset(int offset) // 偏移结果起始位,配合limit(int)使用
QueryBuilder orderAsc(Property... properties) // 排序,升序
QueryBuilder orderDesc(Property... properties) // 排序,降序
QueryBuilder orderCustom(Property property, java.lang.String customOrderForProperty) // 排序,自定义
QueryBuilder orderRaw(java.lang.String rawOrder) // 排序,SQL 语句
QueryBuilder preferLocalizedStringOrder() // 本地化字符串排序,用于加密数据库无效
QueryBuilder stringOrderCollation(java.lang.String stringOrderCollation) // 自定义字符串排序,默认不区分大小写
WhereCondition and(WhereCondition cond1, WhereCondition cond2, WhereCondition... condMore) // 条件,AND 连接
WhereCondition or(WhereCondition cond1, WhereCondition cond2, WhereCondition... condMore) // 条件,OR 连接
// Joe,1970
Query query = userDao.queryBuilder().where(
Properties.FirstName.eq("Joe"), Properties.YearOfBirth.eq(1970)
).build();
List joesOf1970 = query.list();
// Maria,1977
query.setParameter(0, "Maria");
query.setParameter(1, 1977);
List mariasOf1977 = query.list();
// QueryBuilder
Query build()
CursorQuery buildCursor()
CountQuery buildCount()
DeleteQuery buildDelete()
// Query
// 设置查询参数,从 0 开始
Query setParameter(int index, java.lang.Object parameter)
Query setParameter(int index, java.lang.Boolean parameter)
Query setParameter(int index, java.util.Date parameter)
void setLimit(int limit) // 限制返回数
void setOffset(int offset) // 偏移结果起始位,配合limit(int)使用
// Query 绑定线程,执行非本线程的 Query 抛异常,调用获取本线程 Query
Query forCurrentThread() // 获取本线程 Query
// QueryBuilder、Query
T unique() // 返回唯一结果或者 null
T uniqueOrThrow() // 返回唯一非空结果,如果 null 则抛异常
java.util.List list() // 返回结果集进内存
// 懒加载,须在 try/finally 代码中关闭。
LazyList listLazy() // 第一次使用返回结果集,所有数据使用后会自动关闭
LazyList listLazyUncached() // 返回虚拟结果集,数据库读取不缓存
CloseableListIterator listIterator() // 懒加载数据迭代器,不缓存,所有数据使用后会自动关闭
// QueryBuilder、CountQuery
long count() // 获取结果数量
// QueryBuilder.where() 配合 WhereCondition.StringCondition() 实现SQL查询
Query query = userDao.queryBuilder()
.where(new WhereCondition.StringCondition("_ID IN (SELECT USER_ID FROM USER_MESSAGE WHERE READ_FLAG = 0)"))
.build();
// Dao.queryRawCreate() 实现SQL查询
Query query = userDao.queryRawCreate( ", GROUP G WHERE G.NAME=? AND T.GROUP_ID=G._ID", "admin");
// Dao
java.util.List queryRaw(java.lang.String where, java.lang.String... selectionArg)
Query queryRawCreate(java.lang.String where, java.lang.Object... selectionArg)
Query queryRawCreateListArgs(java.lang.String where, java.util.Collection selectionArg)
// WhereCondition.PropertyCondition
PropertyCondition(Property property, java.lang.String op)
PropertyCondition(Property property, java.lang.String op, java.lang.Object value)
PropertyCondition(Property property, java.lang.String op, java.lang.Object[] values)
// WhereCondition.StringCondition
StringCondition(java.lang.String string)
StringCondition(java.lang.String string, java.lang.Object value)
StringCondition(java.lang.String string, java.lang.Object... values)
DeleteQuery buildDelete() // QueryBuilder
QueryBuilder.LOG_SQL = true;
QueryBuilder.LOG_VALUES = true;
// DaoSession 的方法转换成 Dao 的对应方法执行
long insert(T entity)
long insertOrReplace(T entity)
void delete(T entity)
void deleteAll(java.lang.Class entityClass)
void update(T entity)
T load(java.lang.Class entityClass, K key)
java.util.List loadAll(java.lang.Class entityClass)
QueryBuilder queryBuilder(java.lang.Class entityClass)
java.util.List queryRaw(java.lang.Class entityClass, java.lang.String where, java.lang.String... selectionArgs)
void refresh(T entity)
// 芝麻街住户
QueryBuilder queryBuilder = userDao.queryBuilder();
queryBuilder.join(Address.class, AddressDao.Properties.userId)
.where(AddressDao.Properties.Street.eq("Sesame Street"));
List users = queryBuilder.list();
// 欧洲超过百万人口的城市
QueryBuilder qb = cityDao.queryBuilder().where(Properties.Population.ge(1000000));
Join country = qb.join(Properties.CountryId, Country.class);
Join continent = qb.join(country, CountryDao.Properties.ContinentId,
Continent.class, ContinentDao.Properties.Id);
continent.where(ContinentDao.Properties.Name.eq("Europe"));
List bigEuropeanCities = qb.list();
// 爷爷叫林肯的人
QueryBuilder qb = personDao.queryBuilder();
Join father = qb.join(Person.class, Properties.FatherId);
Join grandfather = qb.join(father, Properties.FatherId, Person.class, Properties.Id);
grandfather.where(Properties.Name.eq("Lincoln"));
List lincolnDescendants = qb.list();
// QueryBuilder,联合查询
Join join(java.lang.Class destinationEntityClass, Property destinationProperty)
Join join(Property sourceProperty, java.lang.Class destinationEntityClass)
Join join(Property sourceProperty, java.lang.Class destinationEntityClass, Property destinationProperty)
Join join(Join,T> sourceJoin, Property sourceProperty, java.lang.Class destina
//schemaVersion: 数据库schema版本,也可以理解为数据库版本号
//daoPackage:设置DaoMaster、DaoSession、Dao包名
//targetGenDir:设置DaoMaster、DaoSession、Dao目录
//targetGenDirTest:设置生成单元测试目录
//generateTests:设置自动生成单元测试用例
greendao {
schemaVersion 2
daoPackage 'com.gjn.msdemo.green'
targetGenDir 'src/main/java'
}
这边升级为2了
private String remarks;
package com.gjn.msdemo.util;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import com.github.yuweiguocn.library.greendao.MigrationHelper;
import com.gjn.msdemo.green.DaoMaster;
import com.gjn.msdemo.green.GDUserDao;
import com.gjn.msdemo.green.TUserDao;
import org.greenrobot.greendao.database.Database;
/**
* UpgradeHelper
* Author: gjn.
* Time: 2017/9/7.
*/
public class UpgradeHelper extends DaoMaster.OpenHelper {
public UpgradeHelper(Context context, String name, SQLiteDatabase.CursorFactory factory) {
super(context, name, factory);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
MigrationHelper.migrate(db, new MigrationHelper.ReCreateAllTableListener() {
@Override
public void onCreateAllTables(Database db, boolean ifNotExists) {
DaoMaster.createAllTables(db,ifNotExists);
}
@Override
public void onDropAllTables(Database db, boolean ifExists) {
DaoMaster.dropAllTables(db,ifExists);
}
}, GDUserDao.class, TUserDao.class);
}
}
继承DaoMaster.OpenHelper 重写 onUpgrade方法
package com.gjn.msdemo.util;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import com.gjn.msdemo.green.DaoMaster;
import com.gjn.msdemo.green.DaoSession;
/**
* GreenDaoHelper
* Author: gjn.
* Time: 2017/9/6.
*/
public class GreenDaoHelper {
private static DaoMaster.DevOpenHelper devOpenHelper;
private static SQLiteDatabase database;
private static DaoMaster daoMaster;
private static DaoSession daoSession;
/**
* 初始化 建议放在Application中
* @param context
*/
public static void initDatabase(Context context){
// 注意:默认的 DaoMaster.DevOpenHelper 会在数据库升级时,删除所有的表,意味着这将导致数据的丢失。
// 所以,在正式的项目中,你还应该做一层封装,来实现数据库的安全升级。
// devOpenHelper = new DaoMaster.DevOpenHelper(context,"msdemo_db",null);
// database = devOpenHelper.getWritableDatabase();
//引用升级帮助类
UpgradeHelper helper = new UpgradeHelper(context,"msdemo_db",null);
database = helper.getWritableDatabase();
// 注意:该数据库连接属于 DaoMaster,所以多个 Session 指的是相同的数据库连接。
daoMaster = new DaoMaster(database);
daoSession = daoMaster.newSession();
}
public static SQLiteDatabase getDatabase() {
return database;
}
public static DaoSession getDaoSession() {
return daoSession;
}
}
//引用升级帮助类
UpgradeHelper helper = new UpgradeHelper(context,"msdemo_db",null);
database = helper.getWritableDatabase();