以前一直在使用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算法將在沒有定義任何算法時缺省使用。