Android ORM——greenDAO 3之Properties、QueryBuilder与数据库的增删改查的基本语法应用(二)

引言

Android ORM——初识greenDAO 3及使用greenDAO 3前应该掌握的一些知识点介绍了greenDAO的配置步骤和一些重要的知识点,以及重要的角色的功能和联系,这一篇就正式开始结合点源码从应用greenDAO方面总结。在使用greenDAO之前,我们得明确一点greenDAO是ORM框架,简单来说就是把数据库实体表映射成为对应的JavaBean,操作JavaBean即是操作数据表,完完全全的面向对象思想。

一、Property和Properties、Query和QueryBuilder

1、Property和Properties

Property源码中是这样子介绍的:映射到数据库列的属性的元数据,用于创建查询构建器使用的WhereCondition 对象(Meta data describing a property mapped to a database column; used to create WhereCondition object used by the query builder),简单理解它就是数据列在以JavaBean的形式展现,除此之外还有一个重要的功能就是构造Where条件子句(封装了很多条件子句),一切皆基于对象嘛,而Properties则可以看成是一个数据表的结构,一个Properties对应数据表的列。

Property的部分方法名说明
WhereCondition eq(Object value)相当于在Where字句后加上 “=” value
WhereCondition notEq(Object value)在Where字句后加上 “!=” value
WhereCondition like(String value)在Where字句后加上 “like” value模糊查询
WhereCondition between(Object a, Object b)在Where字句后加上 “between a and b” value

2、Query<T>和QueryBuilder<T>

总所周知查询是为了得到符合特定条件的实体数据,而在greenDAO中我们有两种查询方式:通过Query使用原始SQL来制定查询不编写原始SQL语句而是调用QueryBuilder封装的对应API优先考虑,原因就是因为QueryBuilder 已经封装了对应的接口方法去生成不同类型的SQL语句,使用的时候可以通过QueryBuilder 创建自定义查询Without SQL。),简单来说greeDAO就是把原始的SQL的分为很多部分,而且分别封装成了对应的API方法,比如:GreenDAOApplication.getDaoSessionins().getUserDao().queryBuilder(),作用就相当于Select * from table,是主句,其他的条件子句、排序、去重等子句的构造(包括执行数据的增删改查),都是封装到了对应的方法,调用了之后自动添加到主句之后,最终形成完整的一条SQL语句完成数据操作

QueryBuilder部分方法名说明
protected QueryBuilder(AbstractDao<T,?> dao)构造方法是保护的,不能通过其构造方法获取对象
QueryBuilder<T> distinct()去重查询,相当于是在SQL语句中加了distinct
QueryBuilder<T> where(WhereCondition cond, WhereCondition… condMore)条件子句,相当于SQL中的Where
QueryBuilder<T> whereOr(WhereCondition cond1, WhereCondition cond2, WhereCondition… condMore)或条件查询
WhereCondition and(WhereCondition cond1, WhereCondition cond2, WhereCondition… condMore)且条件
QueryBuilder<T> orderAsc(Property… properties)Order 子句
QueryBuilder<T> limit(int limit)分页查询
DeleteQuery<T> buildDelete()删除
List<T> list()执行Query并把返回集合,并且entity都会加载到内存中,返回的结果通常就是ArrayList
LazyList listLazy()Entity按需加载到内存中,在第一次访问list中的element时,它就会呗加载并且缓存。
LazyList listLazyUncached()每次访问结果集的时候都是从数据库中加载,而不使用缓存。
LazyList listIterator()通过迭代器访问结果集,并且采用的时lazy-loading,结果不会缓存。
T unique()返回唯一的数据

尽管QueryBuilder已经很强大,但是假如还是不能满足你的需求,greeDAO还支持原始的SQL语句,主要有两种方式:

  • QueryBuilder,WhereConditon,StringCondition结合
//嵌套子查询,userDao.queryBuilder() 这句执行了之后就相当于是Select * from User
Query query = userDao.queryBuilder().where(
new StringCondition("_ID IN " +
"(SELECT USER_ID FROM USER_MESSAGE WHERE READ_FLAG = 0)").build();
  • 采用queryRaw或者queryRawCreate方法传入一个原始的SQL,它将被追加到SELECT和columns之后。这样,就可以使用Where和Order by来选择entities,此外表还可以使用别名“T”。
Query<User> query = userDao.queryRawCreate(
  ", GROUP G WHERE G.NAME=? AND T.GROUP_ID=G._ID", "admin"
);
Query方法名说明
Query setParameter(int index, Object parameter)设置参数
List<T> list()执行Query并把返回集合,并且entity都会加载到内存中,返回的结果通常就是ArrayList
LazyList listLazy()Entity按需加载到内存中,在第一次访问list中的element时,它就会呗加载并且缓存。
LazyList listLazyUncached()每次访问结果集的时候都是从数据库中加载,而不使用缓存。
LazyList listIterator()通过迭代器访问结果集,并且采用的时lazy-loading,结果不会缓存。
T unique()greenDao支持唯一结果(0 or 1个结果)和结果集。会返回唯一结果或者null
T uniqueOrThrow()会返回唯一结果,不会返回null

另外listLazy,listLazyUncached,listIterator都采用greenDao的LazyList类,在真正使用数据的时候才加载(on-demand),还持有一个database cursor引用。(这就是为什么需要调用close方法关闭lazy lists和iterators(通常在try/finally块里面))。当所有的element被访问了之后,listLazy()和listIterator()自动关闭cursor,但如果list提前处理完成,就必须去调用close()。
Query<T>和QueryBuilder<T>都是可以用于构造SQL并且执行SQL,不同的是QueryBuilder还支持条件、排序子句的构造,而Query既可以完全不依赖QueryBuilder,全部用原始SQL来代替,也可以主句(即Select * from table 这段用QueryBuilder)后面的子句用原始的SQL来执行,两者都支持查询并返回集合。

二、在Application中初始化greenDAO并完成数据库的建立

public class GreenDAOApplication extends Application {
    private final static String DBNAME="REBOT_DB" ;
    public static DaoSession daoSession=null;

    @Override
    public void onCreate() {
        super.onCreate();
        initGreenDAO(this);
    }

    /**
     * 初始化并创建数据库及其结构
     */
    private void initGreenDAO(Context context){
        DaoMaster.DevOpenHelper openHelper=new DaoMaster.DevOpenHelper(context,DBNAME);
        Database database=openHelper.getWritableDb();
        DaoMaster daoMaster=new DaoMaster(database);
        daoSession=daoMaster.newSession();
    }

    public static DaoSession getDaoSessionins(){
        return daoSession;
    }
}

三、增insert(T t)

前面所讲一个Entity实例对应数据表的一行数据,所以插入新增的数据的时候,我们只需要把实例化后的Entity对象传递insert系方法,再通过AbstractDao的子类对象调用即可,其中insert是插入一个,insertInTx是插入多个(“Tx”表示用一个事务去控制整个过程(提高效率))。
insertOrReplace是插入或替换。

/*插入一条记录*/
User user=new User(1,name,"/sdcard/avtar/"+(name+1)+".png");//greenDAO的主键是Long型,如果传入null,则GreenDao会默认设置自增长的值
try{
    GreenDAOApplication.getDaoSessionins().getUserDao().insert(user);
}catch(Exception e){}

四、删

1、deleteBykey(Long id):根据主键删除对应的一条记录

try{
    GreenDAOApplication.getDaoSessionins().getUserDao().deleteByKey(id);
}catch(Exception e){}

2、 根据实体类删除一条记录

根据实体类删除一条记录这个有多种方式:直接调用delete(Entity entity)先查询再通过QueryBuilder

User user = new User((long)1, "crazymo","",false);
try{
    GreenDAOApplication.getDaoSessionins().getUserDao().delete(user);
}catch(Exception e){}
 List<User> list = getUserList();
 GreenDAOApplication.getDaoSessionins().getUserDao().deleteInTx(list);

3、批量删除,需要创建一个QueryBuilder然后调用他的buildDelete方法,然后执行DeleteQuery。开发中采用一般结合查询方法,先查询出一条记录之后再删除对应的一行数据

public void deleteUserInfo(int userId){
     QueryBuilder<User> qb = GreenDAOApplication.getDaoSessionins().getUserDao().queryBuilder();
     DeleteQuery<User> bd = qb.where(Properties._id.eq(userId)).buildDelete();
     bd.executeDeleteWithoutDetachingEntities();
}

3、deleteAll(): 清空

try{
    GreenDAOApplication.getDaoSessionins().getUserDao().deleteAll();
}catch(Exception e){}

五、改update(T t)

例如update USER SET age =20 WHERE name = “CrazyMo_” 这样一个语句在greenDao中怎么执行的,始终记住一句话,greenDao 对对象的增,删,改,查 就是对数据库的增,删,改,查,被查询出的对象被修改后,在替换原来自己的对象就可以了

User user=new User(1,name,"/sdcard/avtar/"+(name+1)+".png");
try{
    GreenDAOApplication.getDaoSessionins().getUserDao().update(user);
}catch(Exception e){}
String updateName = content.getText().toString().trim();
QueryBuilder qb2 = userDao.queryBuilder();
qb2.where(Properties.Name.eq("CrazyMo_"));
List<User> update = qb2.list();
String newName = content.getText().toString().trim();
for (User user : update) {
     user.setAge(20);
     userDao.insertOrReplaceInTx(user);
}

五、查

在数据库的四个基本操作中查询是比较复杂的,优先使用QueryBuilder API,使用更为简单方面而且支持惰性加载(当处理一个较大的结果集时,lazy-loading(懒加载模式)可以节省内存提高性能),在更为复杂的查询的情况下还支持原始SQL查询。

1、QueryBuilder最基本的使用语法

  • 通过DAO的queryBuilder方法获取QueryBuilder 实例,得到查询主句(即Select 子句部分)

  • 调用QueryBuilder 的成员方法根据需求分别构造Where条件子句、Join子句、Order子句等等

  • 调用QueryBuilder 的获取数据集合方法 list系 得到返回数据集,相当于是执行了完整SQL语句。

//查询用户中FirstName为CrazyMo_的所有用户的信息,等价于Select * from User where FirstName=“Mo” order by LastName asc
QueryBuilder qb = userDao.queryBuilder(); //构造QueryBuilder对象
qb.where(Properties.FirstName.eq("Mo"))  //添加Where查询条件子句
.orderAsc(Properties.LastName)            //添加排序子句
.list();            //返回查询结果
Query query = userDao.queryBuilder()
                .where(new WhereCondition.StringCondition("_ID IN (SELECT USER_ID FROM USER_MESSAGE WHERE READ_FLAG = 0)"))
                .build();
query.list();

1、查询表是否包含指定Id

public boolean isSaved(int _id){
    QueryBuilder<User> qb = GreenDAOApplication.getDaoSessionins().getUserDao().queryBuilder();
    qb.where(Properties.Id.eq(_id));
    qb.buildCount().count();
    return qb.buildCount().count() > 0 ? true : false;
}

2、获取整个表的数据集并转为集合

public List<User> getAllUser(){
     return QueryBuilder<User> qb = GreenDAOApplication.getDaoSessionins().getUserDao().queryBuilder().list();
     /* try {
            GreenDAOApplication.getDaoSession().getUserDao().queryBuilder().listLazy();
        }catch (Exception e){
            。。。
        }*/
 }

3、多次调用Query实例重复查询

返回的Query对象是可以多次重复查询的,如果查询条件没有改变直接再调用一次就好,而条件更新了可以通过调用setParameter()方法来更新参数完成再次筛选,避免了多次构建Query对象。

/*等价于Select * from User where FirstName=“Mo” and YearOfBirth=1999*/

Query query = GreenDAOApplication.getDaoSessionins().getUserDao().queryBuilder().where(
Properties.FirstName.eq("Mo"), Properties.YearOfBirth.eq(1999))
.build();
List list= query.list();

查询FirstName为Crazy,YearOfBirth为199的人

query.setParameter(0, "Crazy");//前面0代表条件的序号,通过条件的序号更改查询条件。
query.setParameter(1, 2000);
List list= query.list();
  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CrazyMo_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值