文档章节

Android ORM框架之LiteOrm的使用心得

SRain215
 SRain215
发布于 2016/12/30 14:25
字数 2144
阅读 201
收藏 0

    之前一直在使用SQLite,无意中发现LiteOrm,看了下基本使用,感觉很方便而且效率也挺高的,特别是级联查询上,很面向对象。

    LiteOrm并不是OrmLite,没有文档仅能查看GitHub上的samples。不过在数据库框架的使用方法上比较相似。 

    两者之间的比较:Android数据库框架:greenDAO vs LiteOrm

    GitHub地址:https://github.com/litesuits/android-lite-orm 
    LiteSuits 官网: http://litesuits.com/?form=gorm

 

一、创建数据库    

/*
1. 创建config信息
*/
DataBaseConfig config = new DataBaseConfig(mContext);
//数据库名,可设置存储路径。默认在内部存储位置databases文件夹下
//"liteorm.db"是数据库名称,名称里包含路径符号"/"则将数据库建立到该路径下,可以使用sd卡路径。 不包含则在系统默认路径下创建DB文件。        
config.dbName = DB_NAME_PATH + File.separator + "liteorm.db";
config.debugged = true; //是否打Log
config.dbVersion = 1; // database Version
config.onUpdateListener = null; //升级

/**
*2. 生成实例对象
*/
//级联操作
liteOrm = LiteOrm.newCascadeInstance(config);
//独立操作
liteOrm = LiteOrm.newSingleInstance(config);

LiteOrm有两种获取实例的方法:

    独立操作:使用 LiteOrm 的 single 实例,可与 cascade 方式平滑切换,性能高,仅处理该对象数据,其关系、和关联对象忽略;
    级联操作:使用 LiteOrm 的 cascade 实例,可与 single 方式平滑切换,全递归,该对象数据,及其关系、和关联对象都被处理;

    这两种获取方式根据项目需求而定,如果级联操作比较多的话,就可以使用cascadeInstance,而其又可以和独立操作任意切换:

LiteOrm db = LiteOrm.newCascadeInstance(this, "cascade.db");
db.cascade().save(user);//级联操作:保存[当前对象],以及该对象所有的[关联对象]以及它们的[映射关系]。
db.single().save(user);//非级联操作:仅保存[当前对象],高效率。

二、注解

    基础注解

  • @Table("test_model") 表名
  • @PrimaryKey(AssignType.AUTO_INCREMENT) 主键自增长
  • @PrimaryKey(AssignType.BY_MYSELF) 自己设置主键
  • @Ignore 忽略该字段,不存入数据库
  • @Column("login") 指定列名
  • @Collate("NOCASE") 大小写无关

    关系映射:

  • @Mapping(Relation.ManyToMany) 多对多
  • @Mapping(Relation.OneToMany) 一对多
  • @Mapping(Relation.OneToOne) 一对一
  • @Mapping(Relation.ManyToOne) 多对一
  • @MapCollection(ConcurrentLinkedQueue.class) 指定约束对象的集合类型

    约束相关:

  • @NotNull 非空约束
  • @Default("true") 默认约束
  • @Check("index > 0 ") check约束
  • @Unique 唯一约束
  • @UniqueCombine() 联合唯一约束

    约束冲突:

    ON CONFLICT 子句不是一个单独的 SQL 命令。 它可以出现在很多其它的 SQL 命令中,是一个非标准的子句。ON CONFLICT 子句指定一个用于解决约束冲突的算法。 有五种选择(具体解释请看文末参考链接,copy过来也没啥意思): 
@Conflict(Strategy.ROLLBACK) 
@Conflict(Strategy.ABORT) 
@Conflict(Strategy.FAIL) 
@Conflict(Strategy.IGNORE) 
@Conflict(Strategy.REPLACE)

从注解也可以看出来该框架确实比较全面,它的查询某些语法完全和SQL语句一样,可以复习一下SQL语句。

三、建表

    仅需要建立实体类添加相应的注解就可以了,是不是很方便。

四、CRUD操作

1.保存    

// 仅插入数据
Person man= new Person("name",23);
liteOrm.insert(man);
// 保存单个实例
Person person = new Person("name",23);
liteOrm.save(person); 
// 保存一个List
List<Person> list = new ArrayList<>();
liteOrm.save(list);

2.修改

book.setIndex(1988);
book.setAuthor("hehe");
liteOrm.update(book);

     更新指定列

// 把所有书的author强制批量改为liter
HashMap<String, Object> bookIdMap = new HashMap<String, Object>();
bookIdMap.put(Book.COL_AUTHOR, "liter");
liteOrm.update(bookList, new ColumnsValue(bookIdMap), ConflictAlgorithm.Fail);
// 仅 author 这一列更新为该对象的最新值。
//liteOrm.update(bookList, new ColumnsValue(new String[]{Book.COL_AUTHOR}, null), ConflictAlgorithm.Fail);

3.查询

    在写查询语句时,一定要铭记sql语句:

SELECT 列
FROM 表
WHERE 条件
GROUP BY 分组条件
HAVING 分组后条件
ORDER BY 排序
LIMIT (x,y)

     读取全部数据

// 读取全部数据
List<Person> list = liteOrm.query(Person.class);

    查询操作里面这个 ? 必不可少,是不是和写sql很像,? 是个占位符。同时SQL并不区分大小写,但关键字建议大写。

    聚合函数count查询

//聚合函数count查询,好像只有这一个
long nums = liteOrm.queryCount(Address.class); //查询有多少行

    查询  根据ID

Student student = liteOrm.queryById(student1.getId(), Student.class);
OrmLog.i(TAG, student);

    查询  模糊

//模糊查询
QueryBuilder<Address> qb = new QueryBuilder<Address>(Address.class).where("address LIKE ?", new String[]{"%山%"});
liteOrm.query(qb);

    查询  与或非等

qb = new QueryBuilder<Address>(Address.class)        
.whereEquals("city", "南京")
.whereAppendAnd() 
.whereEquals("address", "香港路");
liteOrm.query(qb);

    查询 任意

List<Book> books = liteOrm.query(new QueryBuilder<Book>(Book.class)
        .columns(new String[]{"id", "author", Book.COL_INDEX})
        .distinct(true)
        .whereGreaterThan("id", 0)
        .whereAppendAnd()
        .whereLessThan("id", 10000)
        .limit(6, 9)
        .appendOrderAscBy(Book.COL_INDEX));
OrmLog.i(TAG, books);

    查询  自己拼SQL语句

QueryBuilder<Address> qb = new QueryBuilder<Address>(Address.class)        
.columns(new String[]{Address.COL_ADDRESS})    //查询列
.appendOrderAscBy(Address.COL_ADDRESS)        //升序
.appendOrderDescBy(Address.COL_ID)       //当第一列相同时使用该列降序排序
.distinct(true)        //去重
.where(Address.COL_ADDRESS + "=?", new String[]{"香港路"}); //where条件
liteOrm.query(qb);

4.删除

    删除 实体

// 删除 student-0
liteOrm.delete(student0);

    删除 指定数量

// 按id升序,删除[2, size-1],结果:仅保留第一个和最后一个
// 最后一个参数可为null,默认按 id 升序排列
liteOrm.delete(Book.class, 2, bookList.size() - 1, "id");

    删除 使用WhereBuilder

// 删除 student-1
liteOrm.delete(new WhereBuilder(Student.class)
        .where(Person.COL_NAME + " LIKE ?", new String[]{"%1%"})
        .and()
        .greaterThan("id", 0)
        .and()
        .lessThan("id", 10000));

    删除全部

// 连同其关联的Person,Person关联的其他对象一带删除
liteOrm.deleteAll(Person.class);

    删除数据库文件

liteOrm.deleteDatabase();
// 顺带测试:然后重建一个新库
liteOrm.openOrCreateDatabase();

五、级联操作

    为什么说面向对象呢。就是仅仅需要在JavaBean里声明对象间关系,并用注解标识就OK了。举个例子:

@Table("school")
public class School{
  @Mapping(Relation.OneToMany)
  public ArrayList<Classes> classesList; //一个学校有多个教室
}

@Table("class")
public class Classes  {        
  @Mapping(Relation.OneToOne)   
  public Teacher teacher; //一个教室有一个老师,假设
}

@Table("teacher")
public class Teacher {   
  @Mapping(Relation.ManyToMany)    
  @MapCollection(ConcurrentLinkedQueue.class)   
  private Queue<Student> studentLinkedQueue; //一个老师多个学生,一个学生多个老师,多对多关系
}

@Table("student")
public class Student  {    
  @Mapping(Relation.ManyToMany)    
  private Teacher[] teachersArray;//一个老师多个学生,一个学生多个老师,多对多关系
}

就这样声明,你在Java里创建完对象后使用save()方法保存后,数据库中各种关联表就建好了,完全不用自己设置主键、外键什么的。是不是很方便?不过前提是你要使用LiteOrm.newCascadeInstance(config)这个实例。

六、封装

public enum UOrm implements SQLiteHelper.OnUpdateListener {
  INSTANCE;
  private LiteOrm mLiteOrm;
  UOrm() {
    DataBaseConfig config = new DataBaseConfig(MyApplcation.mContext);
    config.dbName = DB_NAME_PATH + File.separator + DB_NAME;
    config.dbVersion = 1;
    config.onUpdateListener = this;
    config.debugged = BuildConfig.DEBUG;
    //可替换为 newCascadeInstance支持级联操作
    mLiteOrm = LiteOrm.newSingleInstance(config);
  }

  @Override public void onUpdate(SQLiteDatabase sqLiteDatabase, int i, int i1) {
  }

  public void save(Object o) {
    if (o == null) {
      return;
    }
    mLiteOrm.save(o);
  }

  public <T> void save(List<T> collection) {
    if (CommonUtil.isEmpty(collection)) {
      return;
    }
    mLiteOrm.save(collection);
  }

  public <T> void delete(Class<T> tClass) {
    if (tClass == null) {
      return;
    }
    mLiteOrm.delete(tClass);
  }

  public <T> List<T> queryAll(Class<T> tClass) {
    if (tClass == null) {
      return null;
    }
    return mLiteOrm.query(tClass);
  }
}

使用时只用这样调用:

UOrm.INSTANCE.save(modelA);

七、约束冲突

    什么是sql约束?比如@NotNull,@Unique,@Check等。不满足这些约束就会产生冲突,解决约束冲突的算法。有五个选择:ROLLBACK、ABORT、FAIL、IGNORE和REPLACE,缺省方案是ABORT,它并不是标准的SQL语言

ROLLBACK
    当发生约束冲突,立即ROLLBACK,即结束当前事务处理,命令中止并返回SQLITE_CONSTRAINT代码。若当前无活动事务(除了每一条命令创建的默认事务以外),则该算法与ABORT相同。

ABORT
    当发生约束冲突,命令收回已经引起的改变并中止返回SQLITE_CONSTRAINT。但由于不执行ROLLBACK,所以前面的命令产生的改变将予以保留。缺省采用这一行为。

FAIL
    当发生约束冲突,命令中止返回SQLITE_CONSTRAINT。但遇到冲突之前的所有改变将被保留。例如,若一条UPDATE语句在100行遇到冲突100th,前99行的改变将被保留,而对100行或以后的改变将不会发生。

IGNORE
    当发生约束冲突,发生冲突的行将不会被插入或改变。但命令将照常执行。在冲突行之前或之后的行将被正常的插入和改变,且不返回错误信息。

REPLACE
    当发生UNIQUE约束冲突,先存在的,导致冲突的行在更改或插入发生冲突的行之前被删除。这样,更改和插入总是被执行。命令照常执行且不返回错误信息。当发生NOT NULL约束冲突,导致冲突的NULL值会被字段缺省值取代。若字段无缺省值,执行ABORT算法。当冲突应对策略为满足约束而删除行时,它不会调用删除触发器。但在新版中这一特性可能被改变。INSERT或UPDATE的OR子句定义的算法会覆盖CREATE TABLE所定义的。ABORT算法将在没有定义任何算法时缺省使用。

© 著作权归作者所有

上一篇: Android HTTP
下一篇: Android DataBase
SRain215
粉丝 18
博文 144
码字总数 89414
作品 0
扬州
Android工程师
私信 提问
Android数据库框架-Archiver(LiteOrm)的使用

在Android开发中,大家开发不同项目,不同的项目就不有不同需求。但是不管是什么项目都会涉及到数据存储。比如SharePreferences,SQLite,File等方式。但是我最近开发的项目是一个有IM的项目...

问问问问问问N
2015/08/13
9.6K
1
Lite-Orm数据库的学习

前言 Android自带的sqlite存储已经很好了,但是涉及太多sql语句,为了方便操作,今天讲一个比较不错的数据库框架Lite_orm 此数据库具备至少以下两个特点: 效率比Android原始数据库sqlite更高...

奔跑的佩恩
2017/11/23
0
0
Android 中的ORM框架

在android 中,内置了sqlite数据库,java web 中,用惯了Hibernate ,想找找android中是否也有类似的orm框架,后来在开源中国看到了orman,这是一个很不错的框架。 这个可以帮我们快捷方便的...

超级大富
2013/02/09
0
3
移动开发者必须知道的Android框架推荐

一些总结出来的Android快速开发框架,全部都是开源框架,附带项目地址,是开发学习的绝佳资料。 thinkAndroid项目 github地址:https://github.com/white-cat/ThinkAndroid 功 能:ThinkAndr...

程序袁_绪龙
2014/09/02
0
0
Android的快速开发框架,Afinal 0.2.1 发布

Afinal 是一个android的 orm 和 ioc 框架。而且封装了android中的httpClient,使其更加简单易用。使用finalBitmap,无需考虑bitmap在android中加载的时候oom的问题和快速滑动的时候图片加载位...

xiahuawuyu
2012/11/08
0
0

没有更多内容

加载失败,请刷新页面

加载更多

《Kubernetes弹性伸缩全场景解读(五) - 定时伸缩组件发布与开源》

前言 容器技术的发展让软件交付和运维变得更加标准化、轻量化、自动化。这使得动态调整负载的容量变成一件非常简单的事情。在kubernetes中,通常只需要修改对应的replicas数目即可完成。当负...

阿里云官方博客
42分钟前
3
0
一个http请求发送到后端的详细过程

我们来看当我们在浏览器输入http://www.mycompany.com:8080/mydir/index.html,幕后所发生的一切。 首先http是一个应用层的协议,在这个层的协议,只是一种通讯规范,也就是因为双方要进行通讯...

群星纪元
42分钟前
1
0
使用Redis SETNX 命令实现分布式锁

SETNX命令简介 SETNX 是SET if Not eXists的简写。 一、https://blog.csdn.net/lihao21/article/details/49104695 把分布式锁的几个关键点和隐含的坑(解决死锁),说的比较清楚。 二、https...

彬彬公子
43分钟前
3
0
python项目实战:系统复制和剪切板

前言 wx采用的是事件驱动型的编程机制。所谓事件,就是我们的程序在运行中发生的事儿。事件可以是低级的用户动作,如鼠标移动或按键按下,也可以是高级的用户动作(定义在wxPython的窗口部件...

A_裙232550246
56分钟前
2
0
Spring 定时任务之 @Scheduled cron表达式

一个基于Spring boot的一个demo: Java配置中开户对Scheduled的支持 import org.springframework.context.annotation.Configuration;import org.springframework.scheduling.annotation.Ena......

花漾年华
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部