DBFlow(4.2)新版使用

来源:https://www.cnblogs.com/xxdh/archive/2018/07/09/9282504.html
-Advertisement-
Play Games

DBFlow新版使用,該實例涉及功能:1.資料庫增刪改查(操作封裝),2.同/非同步+事物操作,3.資料庫升級(新增表+新增欄位+預設值設置等)+自定義資料庫存儲路徑... ...


DBFlow新版使用

一、DBFlow4.2.4介紹

DBFlow是一個基於AnnotationProcessing(註解處理器)的ORM框架。此框架設計為了速度、性能和可用性。消除了大量死板的資料庫代碼,取而代之的是強大而又簡介的API介面。

 

二、特性:

1、無縫支持多個資料庫;

2、使用annotation processing提高速度;

3、ModelContainer類庫可以直接解析像JSON這樣的數據;

4、增加靈活性的豐富介面。

 

三、該實例涉及功能:

1.資料庫增刪改查(操作封裝)

2.同/非同步+事物操作

3.資料庫升級(新增表+新增欄位+預設值設置等)+自定義資料庫存儲路徑

 

四、配置:

在項目目錄的build.gradle中加入:

allprojects {
    repositories {
        ...
        maven { url "https://jitpack.io" }
    }
}

在工程目錄的build.gradle中加入:

apply plugin: 'com.android.application'

def dbflow_version = "4.2.4"

android {
	...
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:27.1.1'
    testImplementation 'junit:junit:4.12'
    annotationProcessor "com.github.Raizlabs.DBFlow:dbflow-processor:$dbflow_version"
    // gradle 3.0.0 可以使用 implementation,否則用 compile
    implementation "com.github.Raizlabs.DBFlow:dbflow-core:$dbflow_version"
    implementation "com.github.Raizlabs.DBFlow:dbflow:$dbflow_version"
//

}

 

五、使用

1.創建DataBase

@Database(name = AppDatabase.NAME, version = AppDatabase.VERSION)
public class AppDatabase {
    
    //版本號
    public static final int VERSION = 1;
    //資料庫名稱
    public static final String NAME = "App2018DB";
}

2.創建Model

  必須繼承BaseModel,BaseModel包含了基本的資料庫操作(save、delete、update、insert、exists)

//必須是共有的修飾符,如果使用私有屬性則返回(老的版本記得寫get/set方法就可以了):
// Error:Execution failed for task ':xxx:compileDebugJavaWithJavac'.>
//Compilation failed; see the compiler error output for details.

@Table(database =AppDatabase.class)
public class BigSeaInfo0 extends BaseModel{

    @PrimaryKey(autoincrement = true)
    @Column
    public int userId;
   
    @Column
    public String name;


    @Column(defaultValue = "18")//預設值無效
    public int age=20;//有效

    @Column//(name = "desc")
    public String remarks;

    @Column
    public long money=3000;
}
//備註:DBFlow會根據你的類名自動生成一個表明,以此為例:
//這個類對應的表名為:UserData_Table
//常用註解操作符:

// @Table、
// @PrimaryKey、//主鍵
// @Column、//// @Unique、:唯一的
// @ForeignKey:外鍵,一般數據褲不常用
//

3.DbFlow初始化

//初始化方式有三種:
public class App extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        //DBFlow初始配置:3中方式

        //FlowManager.init(this);// 初始化方式1

        //FlowManager.init(new FlowConfig.Builder(this).build());//初始化方式2

        //自定義路徑-初始化方式3-->  api>=23需授權(文件讀寫),再添加此操作,具體見StartActivity
//        FileDatabaseContext mSdDatabaseContext = 
//        new  FileDatabaseContext(getApplicationContext());
//        FlowManager.init(mSdDatabaseContext);

        FlowLog.setMinimumLoggingLevel(FlowLog.Level.V);//添加日誌

    }

4.一般使用操作:

//-------------------------添加操作-----------------------

//DBFlow 對數據的增刪改查已經做了封裝,使用起來比較簡單
private void insertBaseModle() {
    BigSeaInfo0 product = new BigSeaInfo0();
    product.name = "P000" + index;
    product.age = 18 + index;
    product.remarks = "備註-" + index;
    product.money = 300 * index;
    //        product.insert();
    boolean success = product.save();
    index++;
    // 執行到這裡之後 id 已經被賦值
    App.showToast(this, "添加結果:" + success);
}

//-------------------------修改操作-----------------------
    /*
     * 更新和刪除可以為先查詢後操作,只要查到對應的數據,在 bean 上做修改,
     * 然後調用 update() 方法,資料庫就能修改完成。還有另一中更接近 sql 語法的方式。
     */
private void updateBaseModle0() {
    // 第一種 先查後改
    BigSeaInfo0 product = SQLite.select()
        .from(BigSeaInfo0.class)//查詢第一個
        .where(BigSeaInfo0_Table.name.is("P0000"))
        .querySingle();// 區別與 queryList()
    if (product != null) {
        Log.d("zhh_Bd", "Update: " + product.name + " update to P0000");
        product.name = "P000X";
        boolean success = product.update();
        App.showToast(this, "修改結果:" + success);
    } else {
        App.showToast(this, "name=P0000的條件數據不存在:");
    }
}

// update:第二種 高級用法,刪改查都是同理
private void updateBaseModle1() {
    SQLite.update(BigSeaInfo0.class)
        .set(BigSeaInfo0_Table.name.eq("PXXXX"))
        .where(BigSeaInfo0_Table.name.is("P0001"))
        .execute();

}

//-------------------------刪除操作-----------------------
//刪除1
private void deleteBaseModle() {
    // 第一種 先查後刪
    BigSeaInfo0 product = SQLite.select()
        .from(BigSeaInfo0.class)
        .where(BigSeaInfo0_Table.name.is("P00010"))
        .querySingle();//查詢單個
    if (product != null) {
        product.delete();
        Log.d("zhh_db", "Delete: " + product.name);
    }

    //刪除一張表
    // Delete.table(BigSeaInfo0.class);
    // 刪除多張表
    // Delete.tables(MyTable1.class, MyTable2.class);


}

//刪除2
private void deleteBaseModle1() {
    // 第二種
    SQLite.delete(BigSeaInfo0.class)
        .where(BigSeaInfo0_Table.name.is("PXXXX"))
        .execute();
}

//-------------------------查詢操作-----------------------
 //查詢
private void selectBaseModle() {
    //  List<BigSeaInfo0> list = SQLite.select().from(BigSeaInfo0.class).queryList();
    List<BigSeaInfo0> list = SQLite.select().from(BigSeaInfo0.class).
        where(BigSeaInfo0_Table.name.like("P%")).queryList();
    printData(list);
}

//非同步執行查詢:儘管是非同步的,但是線程安全的
private void selectBaseModleSync() {
    SQLite.select().from(BigSeaInfo0.class)//.where(BigSeaInfo0_Table.name.is(""))
        .async().queryListResultCallback(new QueryTransaction.
                                         QueryResultListCallback<BigSeaInfo0>() {
                                             
        @Override
        public void onListQueryResult(QueryTransaction transaction, 
                                      @NonNull List<BigSeaInfo0> tResult) {
            printData(tResult);//更新UI
        }
    });
}


//指定欄位升降序查詢
private void selectBaseModleOrderBy() {
    //true為'ASC'正序, false為'DESC'反序
    List<BigSeaInfo0> list = SQLite.select()
        .from(BigSeaInfo0.class)
        .where()
        .orderBy(BigSeaInfo0_Table.userId, true)
        .queryList();
    printData(list);
}

//分組查詢--以年齡+名字分組查詢:先排序後分組
private void selectBaseModleGroupBy() {
    List<BigSeaInfo0> list = SQLite.select()
        .from(BigSeaInfo0.class)
        .groupBy(BigSeaInfo0_Table.age, BigSeaInfo0_Table.name)
        .queryList();
    printData(list);

}

//分頁查詢--每頁查詢3條--》limit後面跟的是3條數據,offset:是從第(page*3)條開始讀取
private void selectPageBaseModle(int page) {
    List<BigSeaInfo0> list = SQLite.select()
        .from(BigSeaInfo0.class)
        .limit(3)//條數-》3
        .offset(page * 3)//當前頁數
        .queryList();
    printData(list);
}

5.事物回滾+非同步操作

//-------------------------添加操作-----------------------
private void insertBaseModle0() {
    BigSeaInfo0 product = new BigSeaInfo0();
    product.name = "P000" + index;
    product.age = 18 + index;
    product.remarks = "備註-" + index;
    product.money = 300 * index;
    //boolean success = product.save();
    boolean success = product.async().save();//非同步
    //添加成功,但是返回為false,因為是非同步,還未執行完成非同步就返回值了,所以需要配置事物操作(個人理解)
    index++;
    // 執行到這裡之後 id 已經被賦值
    App.showToast(this, "添加結果:" + success);
}

//非同步執行查詢:儘管是非同步的,但是線程安全的
private void insertBaseModle1() {
    //自己去實現事務批量保存
    Transaction transaction = FlowManager.getDatabase(AppDatabase.class).
        beginTransactionAsync(new ITransaction() {
        @Override
        public void execute(DatabaseWrapper databaseWrapper) {
            // todo 處理list保存:批量添加
            int i = 0;
            Iterator<BigSeaInfo0> iterator = resultList().iterator();
            while (iterator.hasNext()) {
                BigSeaInfo0 info = iterator.next();
                boolean success = info.save();
                i = success ? ++i : i;
            }
            Log.i("zhh_db_sync", "成功添加了數據條數:" + i);


        }
    }).build();
    transaction.execute();
    //transaction.executeSync();//非同步執行
}

private void insertBaseModle2() {
    FlowManager.getDatabase(AppDatabase.class)
        .beginTransactionAsync(new ProcessModelTransaction.Builder<>(
            new ProcessModelTransaction.ProcessModel<BigSeaInfo0>() {
                @Override
                public void processModel(BigSeaInfo0 bigSeaInfo0,
                                         DatabaseWrapper wrapper) {
                    // do work here -- i.e. user.delete() or user.update()
                    //增刪改操作等,這裡添加集合對象
                    boolean success = bigSeaInfo0.save();
                    Log.i("zhh_db_sync", "添加結果" + success);
                }

            }).addAll(resultList()).build())  
        .error(new Transaction.Error() {
            @Override
            public void onError(Transaction transaction, Throwable error) {
                App.showToast(DbFlowTransactionActivity.this, 
                              "error結果:" + error.getMessage());
                Log.i("zhh_db_sync", "error結果" + error.getMessage());
            }
        })
        .success(new Transaction.Success() {
            @Override
            public void onSuccess(Transaction transaction) {
                App.showToast(DbFlowTransactionActivity.this, 
                              "success結果:" + transaction.name());
                Log.i("zhh_db_sync", "添加success");
            }
        }).build()
        // .execute();//同步
        .executeSync();//非同步
}

//-------------------------修改||刪除操作-----------------------
private void updateBaseModle0() {
    //不存在的條件數據做更改,也走成功的方法
    SQLite.update(BigSeaInfo0.class)
        .set(BigSeaInfo0_Table.name.eq("PXXXX"))
        .where(BigSeaInfo0_Table.name.is("P0001"))
        .async()
        .error(new Transaction.Error() {
            @Override
            public void onError(@NonNull Transaction transaction, @NonNull Throwable error) {
                Log.i("zhh_db_sync", "非同步修改error---" + error.getMessage());
            }
        }).success(new Transaction.Success() {
        @Override
        public void onSuccess(@NonNull Transaction transaction) {
            Log.i("zhh_db_sync", "非同步修改success");
        }
    }).execute();
}

//刪除同上,SQLite.update--》改為SQLite.delete

//-------------------------查詢操作-----------------------
//提供了三種方式

//方式1:QueryResultSingleCallback:單個查詢
SQLite.select().from(BigSeaInfo0.class).where(BigSeaInfo0_Table.name.is("P0000"))
    .async()//非同步查詢
    .querySingleResultCallback(new QueryTransaction.
                               QueryResultSingleCallback<BigSeaInfo0>() {
        @Override
        public void onSingleQueryResult(QueryTransaction transaction, 
                                        @Nullable BigSeaInfo0 bigSeaInfo0) {
            if(null!=bigSeaInfo0){
                Log.i("zhh_db_sync", "對象查詢-----非同步2--id---" 
                      + bigSeaInfo0.userId + ",name->" + bigSeaInfo0.name +
                      ",age---" + bigSeaInfo0.age + ",note--" + bigSeaInfo0.remarks + 
                      ",money-->" + bigSeaInfo0.money);
            }else{
                App.showToast(DbFlowTransactionActivity.this,"數據為空");
            }
        }

    })
    .error(new Transaction.Error() {
        @Override
        public void onError(@NonNull Transaction transaction, 
                            @NonNull Throwable error) {
            Log.i("zhh_db_sync", "Sync-----error--" + error.getMessage());
        }
    }).success(new Transaction.Success() {
    @Override
    public void onSuccess(@NonNull Transaction transaction) {
        Log.i("zhh_db_sync", "Sync-----success--" + transaction.name());
        //更新Ui操作
    }
}).execute();

//方式2:QueryResultListCallback:集合查詢
SQLite.select().from(BigSeaInfo0.class)//.where(BigSeaInfo0_Table.name.is(""))
    .async()//非同步查詢
    .queryListResultCallback(new QueryTransaction.
                             QueryResultListCallback<BigSeaInfo0>() {
        @Override
        public void onListQueryResult(QueryTransaction transaction, 
                                      @NonNull List<BigSeaInfo0> tResult) {
            printData(tResult);//更新UI
        }
    }).error(new Transaction.Error() {
    @Override
    public void onError(@NonNull Transaction transaction, 
                        @NonNull Throwable error) {
        Log.i("zhh_db_sync", "SyncList--error---" + error.getMessage());
    }
}).success(new Transaction.Success() {
    @Override
    public void onSuccess(@NonNull Transaction transaction) {
        Log.i("zhh_db_sync", "SyncList---success--" );
    }
}).execute();

//方式3:QueryResultCallback:方式1+2的統一
SQLite.select().from(BigSeaInfo0.class).async().queryResultCallback(
    new QueryTransaction.QueryResultCallback<BigSeaInfo0>() {
        @Override
        public void onQueryResult(@NonNull QueryTransaction<BigSeaInfo0> transaction, 
                                  @NonNull CursorResult<BigSeaInfo0> tResult) {
            BigSeaInfo0 bigSeaInfo0 = tResult.toModel();
            //這裡可以是返回集合:tResult.toList()
            Log.i("zhh_db_sync", "對象查詢-----非同步1-->id---" + 
                  bigSeaInfo0.userId + ",name->" + bigSeaInfo0.name +
                  ",age---" + bigSeaInfo0.age + ",note--" + bigSeaInfo0.remarks 
                  + ",money-->" + bigSeaInfo0.money);
            
            tResult.close();//關閉資源
        }
    }).execute();

 

六、資料庫升級

 

當你升級資料庫@Database版本,只需要添加一個Migration來配置升級操作,DBFlow 已經有它的幾個現成的實現提供給我們進行使用:

  1.AlterTableMigration 用於重命名錶,增加列

  2.IndexMigration/IndexPropertyMigration 用於索引創建和刪除

  3.UpdateTableMigration 升級資料庫的時候更新數據

資料庫升級--添加列(設置預設值)&新增表----版本改為2,之前是1(個人建議version=10---》參照build.gradle中的versionName:1.0)如下:

//----------------升級-新增表:改版本好即可
//----------------升級-新增列:新增下麵代碼
@Migration(version = VERSION, database = AppDatabase.class)//=2的升級
public static class Migration1 extends AlterTableMigration<BigSeaInfo0> {
    // Migration可設置優先順序,高優先順序的將先被執行。
    //Migration有3個方法:
    //onPreMigrate() 首先被調用,在這兒設置和構造
    //migrate() 具體的遷移在這兒執行
    //onPostMigrate() 執行一些清理工作,或者執行完成的通知
    public Migration1(Class<BigSeaInfo0> table) {
        super(table);
    }

    @Override
    public void onPreMigrate() {
        //所有Java標準的數據類型(boolean、byte、short、int、long、float、double等)及相應的包裝類,
        // 以及String,當然我們還預設提供了對java.util.Date、java.sql.Date與Calendar的支持。
        
        // 使用如下:這裡值添加remarks2
        //addColumn(SQLiteType.get(long.class.getName()), "money");//基本數據類型
        //addColumn(SQLiteType.get(int.class.getName()), "money");//基本數據類型
        //addColumn(SQLiteType.get(double.class.getName()), "money");//基本數據類型:浮點數
        //addColumn(SQLiteType.get(String.class.getName()), "money");//基本數據類型:浮點數
        addColumn(SQLiteType.TEXT, "remarks2");

    }
}

具體使用,請下載源碼:

源碼下載

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • "使用AppleDoc快速生成iOS開發文檔 _ 皮卡丘♪~(´ε` )" "用 appledoc 生成文檔 _ Garan no dou" "xcode select_ error_ tool 'xcodebuild' requires Xcode, but active developer di ...
  • 為什麼不使用xml繪製Andoird的UI? 類型不安全 非空不安全 xml迫使你在很多佈局中寫很多相同的代碼 設備在解析xml時會耗費更多的cpu運行時間和電池 最重要的時,它允許任何代碼重用 簡單案例 findViewById() LayoutParams 使用 描述佈局參數,其中寬高都是 設置 ...
  • 添加依賴 Color 不透明的紅色 Dimensions 使用 和`sp dip(dipValue) sp(spValue)` applyRecursively() applyRecursively()應用於lambda表達式的本身,然後遞歸地運用在他的子view 以上表示,該 中的 的`textS ...
  • Alamofire框架的使用一 —— 基本用法 對於使用Objective-C的開發者,一定非常熟悉AFNetworking這個網路框架。在蘋果推出的Swift之後,AFNetworking的作者專門用Swift來編寫一個類似AFNetworking的網路框架,稱為Alamofire。Alamofi ...
  • Live Photo開發,瞭解之後可以將其應用於開發過程中。 ...
  • 1.什麼是ANR 在Android上,如果你的應用程式有一段時間響應不夠靈敏,系統會向用戶顯示一個對話框,這個對話框稱作應用程式無響應(ANR:Application Not Responding)對話框。用戶可以選擇讓程式繼續運行,但是,他們在使用你的應用程式時,並不希望每次都要處理這個對話框。因 ...
  • 1為什麼要做性能優化? 手機性能越來越好,不用糾結這些細微的性能? Android每一個應用都是運行的獨立的Dalivk虛擬機,根據不同的手機分配的可用記憶體可能只有(32M、64M等),所謂的4GB、6GB運行記憶體其實對於我們的應用不是可以任意索取 詳情:http://10.158.0.33/bbs ...
  • App效果: 功能和交互簡單描述: 針對微信使用用戶每天的零碎時間來進行天氣,新聞要點等查看,免去了打開其他App來查看; 針對每一天可以設置一項重要任務計劃,可開啟通知提醒,讓每一天任務簡化,免去太多任務計劃導致不能按時執行; 很多人在每一天玩手機時間過長,耽誤了工作生活,專註時間功能開啟,即統計 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...