基于ORMLite封裝的數(shù)據(jù)庫操作工具類碘橘,分頁查詢就是這么簡(jiǎn)單

EasyDB

基于ORMLite封裝的數(shù)據(jù)庫操作工具類——致力于最簡(jiǎn)潔的數(shù)據(jù)庫操作API

功能點(diǎn)

  • 支持自定義數(shù)據(jù)庫路徑:SD卡或系統(tǒng)
  • 支持主鍵、索引
  • 支持增碉钠、刪所禀、改、查
  • 支持多條件查詢放钦、排序、統(tǒng)計(jì)恭金、清空操禀、是否存在
  • 支持批處理、數(shù)據(jù)庫事務(wù)操作
  • 支持模糊查詢like横腿、between颓屑、equal、>耿焊、<揪惦、>=、<=罗侯、<>
  • 支持分頁查詢器腋,分頁查詢只需要定義每頁條數(shù)即可
  • 支持批量處理
  • 支持異步任務(wù)操作
  • 支持?jǐn)?shù)據(jù)庫升級(jí),使數(shù)據(jù)庫升級(jí)更為簡(jiǎn)潔
  • 完整的日志與異常處理
  • 后續(xù)優(yōu)化中...

引用方式

Maven

<dependency>
  <groupId>com.zhousf.lib</groupId>
  <artifactId>easydb</artifactId>
  <version>1.7.0</version>
  <type>pom</type>
</dependency>

Gradle

compile 'com.zhousf.lib:easydb:1.7.0'

提交記錄

  • 2016-12-15 項(xiàng)目提交
  • 2016-12-20 增加批處理、事務(wù)操作功能
  • 2016-12-23 增加異步任務(wù)功能
  • 2016-12-27 擴(kuò)展更新纫塌、刪除操作
  • 2017-05-23 優(yōu)化結(jié)構(gòu)诊县,采用動(dòng)態(tài)代理方式
  • 2017-06-12 增加自定義數(shù)據(jù)庫路徑功能

項(xiàng)目演示DEMO

項(xiàng)目中已包含所有支持業(yè)務(wù)的demo,詳情請(qǐng)下載項(xiàng)目參考源碼措左。

Application中配置

EasyDBConfig.init()
        .showDBLog(true)//顯示數(shù)據(jù)庫操作日志
        .setLogTAG("EASY_DB")//日志顯示標(biāo)識(shí)
        .build();

自定義數(shù)據(jù)庫單例

單例模式防止頻繁打開關(guān)閉數(shù)據(jù)庫依痊,從而導(dǎo)致數(shù)據(jù)操作性能下降,甚至出現(xiàn)一些異常錯(cuò)誤怎披。
自定義數(shù)據(jù)庫單例繼承BaseDBHelper胸嘁,BaseDBHelper進(jìn)行數(shù)據(jù)庫操作的緩存管理

// 數(shù)據(jù)庫輔助類
public class EasyDBHelper extends BaseDBHelper {

    //版本號(hào)
    private static final int DB_VERSION = 2;

    //數(shù)據(jù)庫存放路徑
    private static final String DB_PATH = Environment.getExternalStorageDirectory() + "/easy_db";

    //數(shù)據(jù)庫名稱
    private static final String DB_NAME = "easy_android.db";

    //數(shù)據(jù)表清單-數(shù)據(jù)庫與表的關(guān)系更直觀
    private static final Class<?>[] tables = {
        SimpleData.class
    };

    private static EasyDBHelper helper = null;

    public static EasyDBHelper get(){
        if(null == helper){
            synchronized (EasyDBHelper.class){
                if(null == helper){
                    helper = new EasyDBHelper();
                }
            }
        }
        return helper;
    }

    private EasyDBHelper() {
        //系統(tǒng)數(shù)據(jù)庫
        //super(BaseApplication.getApplication(), null,DB_NAME,DB_VERSION,tables);
        //SD卡數(shù)據(jù)庫
        super(BaseApplication.getApplication(), DB_PATH,DB_NAME,DB_VERSION,tables);
    }

    @Override
    protected BaseDBHelper initHelper() {
        return get();
    }

    @Override
    protected boolean upgrade(int oldVersion, int newVersion) throws SQLException {
        //數(shù)據(jù)庫升級(jí)操作
        if(oldVersion < 2){
            //增加字段ext
            getDao(SimpleData.class).executeRaw("ALTER TABLE'simpledata' ADD COLUMN ext TEXT DEFAULT 'default';");
        }
        return true;
    }

}

數(shù)據(jù)庫操作方法

//獲取數(shù)據(jù)庫操作接口
BaseDao<SimpleData> dao = EasyDBHelper.get().dao(SimpleData.class);

//增加
int line = dao.add(new SimpleData(1,"信息1"));

//查詢所有
List<SimpleData> list = dao.queryAll();

//多條件查詢并排序
List<SimpleData> list = dao.query(WhereInfo.get().between("index",1,18).equal("group1",true).order("id", false));
 
//分頁查詢-每頁5條
WhereInfo info = WhereInfo.get().limit(5);
List<SimpleData> list = dao.queryLimit(info);//第一頁查詢
list = dao.queryLimit(info);//第二頁查詢

//更新
dao.update(data)

//刪除
dao.delete(data)

//條目統(tǒng)計(jì)
long num = dao.countOf(WhereInfo.get().equal("group1", true));

//是否存在
boolean isExist = dao.isExist(WhereInfo.get().equal("description","信息2"));

//清空表
int line = dao.clearTable();

//批處理-批量操作消耗性能最低
dao.callBatchTasks(new Callable<SimpleData>() {
    @Override
    public SimpleData call() throws Exception {
        List<SimpleData> list = dao.queryAll();
        for(SimpleData data : list){
            data.description += "_批處理";
            dao.update(data);
        }
        return null;
    }
});

//更新-采用事務(wù)方式,自動(dòng)回滾
dao.callInTransaction(new Callable<SimpleData>() {
    @Override
    public SimpleData call() throws Exception {
        List<SimpleData> list = dao.queryAll();
        if(!list.isEmpty()){
            SimpleData data = list.get(0);
            data.description = "更新內(nèi)容";
            dao.update(data);
        }
        return null;
    }
});

//刪除表
int clear = dao.dropTable();

/**
 * 異步任務(wù)方式一:在Activity/Fragment中盡量采用異步任務(wù)操作數(shù)據(jù)庫
 * 異步任務(wù)可以重寫run方法和onMainThread方法凉逛,可根據(jù)業(yè)務(wù)自定義重寫方式
 **/
dao.asyncTask(new EasyRun<List<SimpleData>>(){
    //該方法在異步線程中執(zhí)行
    @Override
    public List<SimpleData> run() throws Exception {
        return dao.queryAll();
    }
    //該方法在UI線程中執(zhí)行
    @Override
    public void onMainThread(List<SimpleData> data) throws Exception {
        printList(data);
    }
});
//異步任務(wù)方式二
dao.asyncTask(new EasyRun<Object>(){
    @Override
    public Object run() throws Exception {
        return dao.queryAll();
    }

    @Override
    public void onMainThread(Object data) throws Exception {
        printList((List<SimpleData>)data);
    }
});
//異步任務(wù)方式三
dao.asyncTask(new EasyRun<SimpleData>(){
    @Override
    public SimpleData run() throws Exception {
        return dao.queryAll().get(0);
    }

    @Override
    public void onMainThread(SimpleData data) throws Exception {
        tvResult.setText(data.toString());
    }
});


數(shù)據(jù)庫操作方法

public class SimpleData extends BaseModel {

    @DatabaseField(generatedId = true)
    public int id;
    @DatabaseField(index = true)
    public int index;
    @DatabaseField
    public String description;
    @DatabaseField
    public Date date;
    @DatabaseField
    public boolean group1;
    @DatabaseField
    public boolean group2;
    @DatabaseField
    public String ext;

    //必須有無參構(gòu)造方法
    public SimpleData() {
    }

    public SimpleData(int index,String description) {
        this.date = new Date(System.currentTimeMillis());
        this.index = index;
        this.description = description;
        this.group1 = ((index % 2) == 0);
        this.group2 = ((index % 4) == 0);
        super.father = "基類"+index;
    }

}

數(shù)據(jù)庫操作接口

package com.easydblib.dao;
import com.easydblib.callback.EasyRun;
import com.easydblib.info.WhereInfo;
import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.stmt.QueryBuilder;
import java.util.List;
import java.util.concurrent.Callable;

/**
 * 數(shù)據(jù)庫操作接口
 * @author : zhousf
 */
public interface BaseDao<T> {

    /**
     * 增加
     * @param model 映射類
     * @return 影響行數(shù)
     */
    int add(T model);

    /**
     * 增加集合
     * @param list 映射類集合
     * @return 影響行數(shù)
     */
    int add(List<T> list);

    /**
     * 增加或更新
     * @param model 映射類
     * @return 影響行數(shù)
     */
    int addOrUpdate(T model);

    /**
     * 不存在時(shí)增加
     * @param model 映射類
     * @return 增加的對(duì)象
     */
    T addIfNotExists(T model);

    /**
     * 刪除
     * @param model 映射類
     * @return 影響行數(shù)
     */
    int delete(T model);

    /**
     * 刪除集合
     * @param list 映射類集合
     * @return 影響行數(shù)
     */
    int delete(List<T> list);

    /**
     * 根據(jù)條件刪除
     * @param whereInfo 查詢信息體
     * @return 影響行數(shù)
     */
    int delete(WhereInfo whereInfo);

    /**
     * 更新
     * @param model 映射類
     * @return 影響行數(shù)
     */
    int update(T model);

    /**
     * 更新-根據(jù)查詢條件進(jìn)行更新性宏,只更新第一條數(shù)據(jù),若無則添加
     * @param model 映射類
     * @param whereInfo 查詢信息體
     * @return 影響行數(shù)
     */
    int update(T model,WhereInfo whereInfo);

    /**
     * 查詢所有
     * @return 映射類集合
     */
    List<T> queryAll();

    /**
     * 查詢所有并排序
     * @param whereInfo 查詢信息體
     * @return 映射類集合
     */
    List<T> queryAll(WhereInfo whereInfo);

    /**
     * 多條件查詢并排序
     * @param whereInfo 查詢信息體
     * @return 映射類集合
     */
    List<T> query(WhereInfo whereInfo);


    /**
     * 分頁查詢
     * @param whereInfo 查詢信息體
     * @return 映射類集合
     */
    List<T> queryLimit(WhereInfo whereInfo);

    /**
     * 自定義查詢
     * @param queryBuilder 查詢構(gòu)建
     * @return 映射類集合
     */
    List<T> query(QueryBuilder<T, Integer> queryBuilder);

    /**
     * 統(tǒng)計(jì)條目數(shù)
     * @return 條目數(shù)
     */
    long countOf();

    /**
     * 統(tǒng)計(jì)條目數(shù)
     * @param whereInfo 查詢信息體
     * @return 條目數(shù)
     */
    long countOf(WhereInfo whereInfo);

    /**
     * 是否存在
     * @param whereInfo  查詢信息體
     * @return true 存在  false 不存在
     */
    boolean isExist(WhereInfo whereInfo);

    /**
     * 執(zhí)行原生的SQL語句
     * @param statement SQL語句
     * @param arguments 參數(shù)值-占位符?的值
     * @return 影響行數(shù)
     */
    int executeRaw(String statement, String... arguments);

    /**
     * 清空表
     * @return 條目數(shù)
     */
    int clearTable();

    /**
     * 刪除表
     * @return 條目數(shù)
     */
    int dropTable();

    /**
     * 獲取數(shù)據(jù)表DAO
     * @return dao
     */
    Dao<T, Integer> fetchDao();

    /**
     * 獲取表名
     * @return 表名
     */
    String getTableName();

    /**
     * 執(zhí)行事務(wù)
     * @param callable 事務(wù)回調(diào)
     */
    void callInTransaction(Callable<T> callable);

    /**
     * 批處理-大量數(shù)據(jù)庫操作時(shí)請(qǐng)采用該方法(性能最優(yōu))
     * @param callable 回調(diào)
     */
    <CT> CT callBatchTasks(Callable<CT> callable);

    /**
     * 異步執(zhí)行
     * @param easyRun 異步run
     */
    <T> void asyncTask(EasyRun<T> easyRun);

}

數(shù)據(jù)庫操作代理類

package com.easydblib.handler;
import android.util.Log;
import com.easydblib.EasyDBConfig;
import com.easydblib.dao.RealBaseDao;
import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.table.TableUtils;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;

/**
 * @author : zhousf
 * @description : 數(shù)據(jù)庫操作代理類:主要進(jìn)行預(yù)處理鱼炒、日志打印
 * @date : 2017/5/23.
 */
public class EasyDBProxyHandler<T> implements InvocationHandler {

    private Object obj;
    private Dao<T, Integer> dao;
    private Class<T> mClass;
    private String databaseName;

    public EasyDBProxyHandler(Dao<T, Integer> dao, Class<T> mClass, String databaseName) {
        this.dao = dao;
        this.mClass = mClass;
        this.databaseName = databaseName;
    }

    public RealBaseDao<T> getProxy(Object targetObject) {
        this.obj = targetObject;
        Object proxy = Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
                targetObject.getClass().getInterfaces(), this);
        return (RealBaseDao<T>)proxy;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        long startTime = getTime();
        doBefore();
        Object result = method.invoke(obj, args);
        doAfter(method,result,startTime);
        return result;
    }

    /**
     * 執(zhí)行前操作
     */
    private void doBefore(){
        prepareDeal();
    }

    /**
     * 執(zhí)行后操作
     */
    private void doAfter(Method method, Object result, long startTime){
        if(result != null){
            String methodName = method.getName();
            if(result instanceof Integer || result instanceof Long){
                String line = String.valueOf(result);
                doLog(methodName+"["+(getTime()-startTime)+"ms] 影響行數(shù):"+line);
            }else if(result instanceof List){
                int line = ((List) result).size();
                doLog(methodName+"["+(getTime()-startTime)+"ms] 影響行數(shù):"+line);
            }else if(result instanceof Boolean){
                String res = String.valueOf(result);
                doLog(methodName+"["+(getTime()-startTime)+"ms] :"+res);
            }else {
                doLog(methodName+"["+(getTime()-startTime)+"ms] ");
            }
        }
    }

    /**
     * 預(yù)處理
     */
    private void prepareDeal(){
        checkTable();
    }

    /**
     * 檢查數(shù)據(jù)表
     */
    private void checkTable(){
        try {
            TableUtils.createTableIfNotExists(dao.getConnectionSource(),mClass);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private long getTime(){
        return System.currentTimeMillis();
    }

    /**
     * 打印日志
     */
    private void doLog(String msg){
        if(EasyDBConfig.showDBLog)
            Log.d(EasyDBConfig.logTAG,msg+" | "+mClass.getSimpleName()+" | "+databaseName);
    }
}

相關(guān)截圖

基本操作界面

有問題反饋

在使用中有任何問題衔沼,歡迎反饋給我,可以用以下聯(lián)系方式跟我交流

  • QQ: 424427633
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末昔瞧,一起剝皮案震驚了整個(gè)濱河市指蚁,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌自晰,老刑警劉巖凝化,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異酬荞,居然都是意外死亡搓劫,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門混巧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來枪向,“玉大人,你說我怎么就攤上這事咧党∶鼗祝” “怎么了?”我有些...
    開封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵傍衡,是天一觀的道長(zhǎng)深员。 經(jīng)常有香客問我,道長(zhǎng)蛙埂,這世上最難降的妖魔是什么倦畅? 我笑而不...
    開封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮绣的,結(jié)果婚禮上叠赐,老公的妹妹穿的比我還像新娘欲账。我一直安慰自己,他們只是感情好燎悍,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開白布敬惦。 她就那樣靜靜地躺著,像睡著了一般谈山。 火紅的嫁衣襯著肌膚如雪俄删。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天奏路,我揣著相機(jī)與錄音畴椰,去河邊找鬼。 笑死鸽粉,一個(gè)胖子當(dāng)著我的面吹牛斜脂,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播触机,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼帚戳,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了儡首?” 一聲冷哼從身側(cè)響起片任,我...
    開封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蔬胯,沒想到半個(gè)月后对供,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡氛濒,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年产场,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片舞竿。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡京景,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出骗奖,到底是詐尸還是另有隱情醋粟,我是刑警寧澤,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布重归,位于F島的核電站,受9級(jí)特大地震影響厦凤,放射性物質(zhì)發(fā)生泄漏鼻吮。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一较鼓、第九天 我趴在偏房一處隱蔽的房頂上張望椎木。 院中可真熱鬧违柏,春花似錦、人聲如沸香椎。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽畜伐。三九已至馍惹,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間玛界,已是汗流浹背万矾。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留慎框,地道東北人良狈。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像笨枯,于是被迫代替她去往敵國(guó)和親薪丁。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,072評(píng)論 25 707
  • 需要原文的可以留下郵箱我給你發(fā)馅精,這里的文章少了很多圖严嗜,懶得網(wǎng)上粘啦 1數(shù)據(jù)庫基礎(chǔ) 1.1數(shù)據(jù)庫定義 1)數(shù)據(jù)庫(D...
    極簡(jiǎn)純粹_閱讀 7,421評(píng)論 0 46
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)硫嘶,斷路器阻问,智...
    卡卡羅2017閱讀 134,651評(píng)論 18 139
  • 古代神話故事中,經(jīng)常出現(xiàn)修煉成精的狐貍沦疾,它們可以變成人形称近,通常都化作絕色美女。 最為出名的便是《封神榜》中的蘇妲己...
    石之畫趣閱讀 1,379評(píng)論 14 18
  • 你們是否也有那麼一個(gè)人 儘管你們很久都不聯(lián)繫 平常很少聊天 在每年的每個(gè)節(jié)日你都會(huì)收到他的紅包 時(shí)間要麼在凌晨 要...
    慕幸晨曦閱讀 238評(píng)論 0 1