以前一直在使用SQLite,无心中发现LiteOrm,看了下基本使用,感受很方便并且效率也挺高的,特别是级联查询上,很面向对象。java
LiteOrm并非OrmLite,没有文档仅能查看GitHub上的samples。不过在数据库框架的使用方法上比较类似。 android
二者之间的比较:Android数据库框架:greenDAO vs LiteOrm。git
GitHub地址:https://github.com/litesuits/android-lite-orm
LiteSuits 官网: http://litesuits.com/?form=gormgithub
/* 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 方式平滑切换,全递归,该对象数据,及其关系、和关联对象都被处理;sql
这两种获取方式根据项目需求而定,若是级联操做比较多的话,就可使用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)
app
从注解也能够看出来该框架确实比较全面,它的查询某些语法彻底和SQL语句同样,能够复习一下SQL语句。框架
仅须要创建实体类添加相应的注解就能够了,是否是很方便。less
// 仅插入数据 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);
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);
在写查询语句时,必定要铭记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);
删除 实体
// 删除 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算法将在没有定义任何算法时缺省使用。