Android 快速开发系列之数据库篇(LiteOrm)

LiteOrm是一个小巧、强大、比系统自带数据库操作性能快1倍的 android ORM 框架类库,开发者一行代码实现数据库的增删改查操作,以及实体关系的持久化和自动映射。


LiteOrm对数据库的操作有两种方式

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

如何使用:
1 . 首先导入需要的 lite-orm-1.9.1.jar,下载地址在文章结尾。一个数据库对应一个LiteOrm的实例,如果一个App只有一个数据库,那么LiteOrm应该是全局单例的。 如果多次新建LiteOrm实例,系统会提示你应该关闭之前的数据库,也可能会引起其他未知错误。可以在自定义的Application类中这样写:

static LiteOrm liteOrm;
if (liteOrm == null) { 
      DataBaseConfig config = new DataBaseConfig(this, "liteorm.db");
      //"liteorm.db"是数据库名称,名称里包含路径符号"/"则将数据库建立到该路径下,可以使用sd卡路径。 不包含则在系统默认路径下创建DB文件。
      //例如 public static final String DB_NAME = SD_CARD + "/lite/orm/liteorm.db";     DataBaseConfig config = new DataBaseConfig(this, DB_NAME);
      config.dbVersion = 1; // set database version
      config.onUpdateListener = null; // set database update listener
      //独立操作,适用于没有级联关系的单表操作,
      liteOrm = LiteOrm.newSingleInstance(config);
      //级联操作,适用于多表级联操作
      // liteOrm=LiteOrm.newCascadeInstance(config); 
}
liteOrm.setDebugged(true); // open the log

2 .单表,新建类TestMode

@Table("test_model")
public class TestModel {

  // 指定自增,每个对象需要有一个主键
  @PrimaryKey(AssignType.AUTO_INCREMENT)
  private int id;

  // 非空字段
  @NotNull
  private String name;

  //忽略字段,将不存储到数据库
  @Ignore
  private String password;

  // 默认为true,指定列名
  @Default("true")
  @Column("login")
  private Boolean isLogin;

  //什么都不做,也会存储到数据库,列名就是"token"
  private String token;
}

3 .多表 Man(男人),Boss(女优。。。),Address(地址),Wife(妻子),Company(公司),关系如下:

  • Man-Boss:多对多关系

  • Man-Address:一对多关系

  • Man-Wife:一对一关系

  • Man-Company:多对一关系

       /**
       * ********** 四种映射关系示例 **************
       */
      @Mapping(Relation.ManyToMany)
      public ArrayList bosses;
    
      //使用任何其他容器
      @Mapping(Relation.OneToMany)
      public ConcurrentLinkedQueue
    addrList; @Mapping(Relation.OneToOne) public Wife wife; @Mapping(Relation.ManyToOne) public Company company;

4 . 常用操作:

- 保存(插入or更新)
School school = new School("hello");
liteOrm.save(school);
- 插入
Book book = new Book("good");
liteOrm.insert(book, ConflictAlgorithm.Abort);
- 更新
book.setIndex(1988);
book.setAuthor("hehe");
liteOrm.update(book);
- 更新指定列
// 把所有书的author强制批量改为liter
HashMap bookIdMap = new HashMap();
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);
- 查询
List list = liteOrm.query(Book.class);
OrmLog.i(TAG, list);
- 查找 使用QueryBuilder
List list = liteOrm.query(new QueryBuilder(Student.class)
      .where(Person.COL_NAME + " LIKE ?", new String[]{"%0"})
      .whereAppendAnd()
      .whereAppend(Person.COL_NAME + " LIKE ?", new String[]{"%s%"}));
OrmLog.i(TAG, list);
- 查询 根据ID
Student student = liteOrm.queryById(student1.getId(), Student.class);
OrmLog.i(TAG, student);
- 查询 任意
List books = liteOrm.query(new QueryBuilder(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);
- 删除 实体
// 删除 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));
- 删除全部
// 连同其关联的classes,classes关联的其他对象一带删除
liteOrm.deleteAll(School.class);
liteOrm.deleteAll(Book.class);

// 顺带测试:连库文件一起删掉
liteOrm.deleteDatabase();
// 顺带测试:然后重建一个新库
liteOrm.openOrCreateDatabase();
// 满血复活

5 . 常用注解:

@Table("class")指定表名是class

@Ignore 忽略字段不被保存到数据库中

@Column("_id") 标明字段在数据中的列名是_id

@Mapping(Relation.XX)用于多表映射

@Check("check > 99")//大于99才存储
private int check = 100;

@Collate("NOCASE") 排序规则,nocase就是大小写无关
private String _collate;

@Default("SQL默认值") 指定字段缺省值

@NotNull 字段不能为空

@PrimaryKey(AssignType.AUTO_INCREMENT) 主键自增长

@Conflict(Strategy.FAIL) 冲突的时候不存储

@Unique 唯一,确保某列中的所有值是不同的。

@UniqueCombine(1) UniqueCombine 值为1,和 UniqueCombine同值 的属性联合唯一
private int mIndex;
@UniqueCombine(1) UniqueCombine值为1,和 mIndex联合唯一
private String author;

@Mapping(Relation.ManyToMany)
@MapCollection(ConcurrentLinkedQueue.class) 表示Queue的具体容器是ConcurrentLinkedQueue
private Queue studentLinkedQueue;

6 .最后讲一下约束冲突这个知识点
什么是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算法将在没有定义任何算法时缺省使用。

官方github: https://github.com/litesuits/android-lite-orm

作者:西瓜太郎123
链接:https://www.jianshu.com/p/0d72226ef434
來源:
著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

你可能感兴趣的:(Android 快速开发系列之数据库篇(LiteOrm))