HarmonyOS數(shù)據(jù)管理·對象關(guān)系映射數(shù)據(jù)庫的應(yīng)用

      網(wǎng)友投稿 1142 2022-05-29

      HarmonyOS 對象關(guān)系映射(Object Relational Mapping,ORM)數(shù)據(jù)庫是一款基于 SQLite 的數(shù)據(jù)庫框架,屏蔽了底層 SQLite 數(shù)據(jù)庫的 SQL 操作,針對實(shí)體和關(guān)系提供了增刪改查等一系列的面向?qū)ο蠼涌凇?yīng)用開發(fā)者不必再去編寫復(fù)雜的 SQL 語句, 以操作對象的形式來操作數(shù)據(jù)庫,提升效率的同時(shí)也能聚焦于業(yè)務(wù)開發(fā)。

      對象關(guān)系映射數(shù)據(jù)庫的三個(gè)主要組件:

      數(shù)據(jù)庫:被開發(fā)者用 @Database 注解,且繼承了 OrmDatabase 的類,對應(yīng)關(guān)系型數(shù)據(jù)庫。

      實(shí)體對象:被開發(fā)者用 @Entity 注解,且繼承了 OrmObject 的類,對應(yīng)關(guān)系型數(shù)據(jù)庫中的表。

      對象數(shù)據(jù)操作接口:包括數(shù)據(jù)庫操作的入口 OrmContext 類和謂詞接口(OrmPredicate)等。

      謂詞:數(shù)據(jù)庫中是用來代表數(shù)據(jù)實(shí)體的性質(zhì)、特征或者數(shù)據(jù)實(shí)體之間關(guān)系的詞項(xiàng),主要用來定義數(shù)據(jù)庫的操作條件。對象關(guān)系映射數(shù)據(jù)庫將 SQLite 數(shù)據(jù)庫中的謂詞封裝成了接口方法供開發(fā)者調(diào)用。開發(fā)者通過對象數(shù)據(jù)操作接口,可以訪問到應(yīng)用持久化的關(guān)系型數(shù)據(jù)。

      對象關(guān)系映射數(shù)據(jù)庫:通過將實(shí)例對象映射到關(guān)系上,實(shí)現(xiàn)使用操作實(shí)例對象的語法,來操作關(guān)系型數(shù)據(jù)庫。它是在 SQLite 數(shù)據(jù)庫的基礎(chǔ)上提供的一個(gè)抽象層。

      SQLite 數(shù)據(jù)庫:一款輕型的數(shù)據(jù)庫,是遵守 ACID 的關(guān)系型數(shù)據(jù)庫管理系統(tǒng)。

      對象關(guān)系映射數(shù)據(jù)庫操作是基于關(guān)系型數(shù)據(jù)庫操作接口完成的,實(shí)際是在關(guān)系型數(shù)據(jù)庫操作的基礎(chǔ)上又實(shí)現(xiàn)了對象關(guān)系映射等特性。因此對象關(guān)系映射數(shù)據(jù)庫跟關(guān)系型數(shù)據(jù)庫一樣,都使用 SQLite 作為持久化引擎,底層使用的是同一套數(shù)據(jù)庫連接池和數(shù)據(jù)庫連接機(jī)制。

      使用對象關(guān)系映射數(shù)據(jù)庫的開發(fā)者需要先配置實(shí)體模型與關(guān)系映射文件。應(yīng)用數(shù)據(jù)管理框架提供的類生成工具會(huì)解析這些文件,生成數(shù)據(jù)庫幫助類,這樣應(yīng)用數(shù)據(jù)管理框架就能在運(yùn)行時(shí),根據(jù)開發(fā)者的配置創(chuàng)建好數(shù)據(jù)庫,并在存儲(chǔ)過程中自動(dòng)完成對象關(guān)系映射。開發(fā)者再通過對象數(shù)據(jù)操作接口,如 OrmContext 接口和謂詞接口等操作持久化數(shù)據(jù)庫。

      對象數(shù)據(jù)操作接口提供一組基于對象映射的數(shù)據(jù)操作接口,實(shí)現(xiàn)了基于 SQL 的關(guān)系模型數(shù)據(jù)到對象的映射,讓用戶不需要再和復(fù)雜的 SQL 語句打交道,只需簡單地操作實(shí)體對象的屬性和方法。對象數(shù)據(jù)操作接口支持對象的增刪改查操作,同時(shí)支持事務(wù)操作等。

      HarmonyOS之?dāng)?shù)據(jù)管理·對象關(guān)系映射數(shù)據(jù)庫的應(yīng)用

      對象關(guān)系映射數(shù)據(jù)庫運(yùn)作機(jī)制如下圖所示:

      如果不指定數(shù)據(jù)庫的日志模式,那么系統(tǒng)默認(rèn)日志方式是 WAL(Write Ahead Log)模式。

      如果不指定數(shù)據(jù)庫的落盤模式,那么系統(tǒng)默認(rèn)落盤方式是 FULL 模式。

      HarmonyOS 數(shù)據(jù)庫使用的共享內(nèi)存默認(rèn)大小是 2MB。

      HarmonyOS 對象關(guān)系映射數(shù)據(jù)庫是建立在關(guān)系型數(shù)據(jù)庫的基礎(chǔ)之上的,因此與關(guān)系型數(shù)據(jù)庫一致:

      數(shù)據(jù)庫中連接池的最大數(shù)量是 4 個(gè),用以管理用戶的讀寫操作。

      為保證數(shù)據(jù)的準(zhǔn)確性,數(shù)據(jù)庫同一時(shí)間只能支持一個(gè)寫操作。

      實(shí)體對象屬性支持的類型:

      對象關(guān)系映射數(shù)據(jù)庫適用于開發(fā)者使用的數(shù)據(jù)可以分解為一個(gè)或多個(gè)對象,且需要對數(shù)據(jù)進(jìn)行增刪改查等操作,但是不希望編寫過于復(fù)雜的 SQL 語句的場景。

      該對象關(guān)系映射數(shù)據(jù)庫的實(shí)現(xiàn)是基于關(guān)系型數(shù)據(jù)庫,除了數(shù)據(jù)庫版本升降級(jí)等場景外,操作對象關(guān)系映射數(shù)據(jù)庫一般不需要編寫 SQL 語句,但是仍然要求使用者對于關(guān)系型數(shù)據(jù)庫的基本概念有一定的了解。

      創(chuàng)建數(shù)據(jù)庫:需要定義一個(gè)表示數(shù)據(jù)庫的類,繼承 OrmDatabase,再通過 @Database 注解內(nèi)的 entities 屬性指定哪些數(shù)據(jù)模型類屬于該數(shù)據(jù)庫。屬性如下

      version:數(shù)據(jù)庫版本號(hào);

      entities:數(shù)據(jù)庫內(nèi)包含的表。

      創(chuàng)建數(shù)據(jù)表:可通過創(chuàng)建一個(gè)繼承了 OrmObject 并用 @Entity 注解的類,獲取數(shù)據(jù)庫實(shí)體對象,也就是表的對象。屬性如下:

      tableName:表名;

      primaryKeys:主鍵名,一個(gè)表里只能有一個(gè)主鍵,一個(gè)主鍵可以由多個(gè)字段組成;

      foreignKeys:外鍵列表;

      indices:索引列表。

      注解如下表所示:

      對象關(guān)系映射數(shù)據(jù)庫提供數(shù)據(jù)庫加密的能力,創(chuàng)建數(shù)據(jù)庫時(shí)傳入指定密鑰、創(chuàng)建加密數(shù)據(jù)庫,后續(xù)打開加密數(shù)據(jù)庫時(shí),需要傳入正確密鑰。

      數(shù)據(jù)庫傳入密鑰接口:

      通過對象數(shù)據(jù)操作接口,可以對對象數(shù)據(jù)進(jìn)行增刪改查操作。

      對象數(shù)據(jù)操作接口:

      通過使用對象數(shù)據(jù)操作接口,開發(fā)者可以在某些數(shù)據(jù)上設(shè)置觀察者,接收數(shù)據(jù)變化的通知。

      數(shù)據(jù)變化觀察者接口:

      通過調(diào)用數(shù)據(jù)庫升降級(jí)接口,開發(fā)者可以將數(shù)據(jù)庫切換到不同的版本。

      數(shù)據(jù)庫升降級(jí)接口:

      開發(fā)者可以將當(dāng)前數(shù)據(jù)庫的數(shù)據(jù)進(jìn)行備份,在必要的時(shí)候進(jìn)行數(shù)據(jù)恢復(fù)。

      數(shù)據(jù)庫備份與恢復(fù)接口:

      如果使用注解處理器的模塊為“com.huawei.ohos.hap”模塊,則需要在模塊的“build.gradle”文件的“ohos”節(jié)點(diǎn)中添加以下配置:

      compileOptions{ annotationEnabled true }

      1

      2

      3

      如果使用注解處理器的模塊為“com.huawei.ohos.library”模塊,則需要在模塊的“build.gradle”文件的“dependencies”節(jié)點(diǎn)中配置注解處理器。查看“orm_annotations_java.jar”、“orm_annotations_processor_java.jar” 、“javapoet_java.jar”這3個(gè) jar 包在 HUAWEI SDK 中的對應(yīng)目錄,并將目錄的這三個(gè) jar 包導(dǎo)進(jìn)來。

      dependencies { compile files("orm_annotations_java.jar的路徑", "orm_annotations_processor_java.jar的路徑", "javapoet_java.jar的路徑") annotationProcessor files("orm_annotations_java.jar的路徑", "orm_annotations_processor_java.jar的路徑", "javapoet_java.jar的路徑") }

      1

      2

      3

      4

      如果使用注解處理器的模塊為“java-library”模塊,則需要在模塊的“build.gradle”文件的“dependencies”節(jié)點(diǎn)中配置注解處理器,并導(dǎo)入“ohos.jar”:

      dependencies { compile files("ohos.jar的路徑","orm_annotations_java.jar的路徑","orm_annotations_processor_java.jar的路徑","javapoet_java.jar的路徑") annotationProcessor files("orm_annotations_java.jar的路徑","orm_annotations_processor_java.jar的路徑","javapoet_java.jar的路徑") }

      1

      2

      3

      4

      定義一個(gè)數(shù)據(jù)庫類BookStore.java,數(shù)據(jù)庫包含了“User”,“Book”,"AllDataType"三個(gè)表,版本號(hào)為“1”。數(shù)據(jù)庫類的 getVersion 方法和 getHelper 方法不需要實(shí)現(xiàn),直接將數(shù)據(jù)庫類設(shè)為虛類即可:

      @Database(entities = {User.class, Book.class, AllDataType.class}, version = 1) public abstract class BookStore extends OrmDatabase { }

      1

      2

      3

      即創(chuàng)建數(shù)據(jù)庫實(shí)體類并配置對應(yīng)的屬性(如對應(yīng)表的主鍵,外鍵等)。數(shù)據(jù)表必須與其所在的數(shù)據(jù)庫在同一個(gè)模塊中。

      例如,定義了一個(gè)實(shí)體類 User.java,對應(yīng)數(shù)據(jù)庫內(nèi)的表名為“user”;indices 為“firstName”和“l(fā)astName”兩個(gè)字段建立了復(fù)合索引“name_index”,并且索引值是唯一的;“ignoredColumns”表示該字段不需要添加到“user”表的屬性中:

      @Entity(tableName = "user", ignoredColumns = {"ignoredColumn1", "ignoredColumn2"}, indices = {@Index(value = {"firstName", "lastName"}, name = "name_index", unique = true)}) public class User extends OrmObject { // 此處將userId設(shè)為了自增的主鍵。注意只有在數(shù)據(jù)類型為包裝類型時(shí),自增主鍵才能生效。 @PrimaryKey(autoGenerate = true) private Integer userId; private String firstName; private String lastName; private int age; private double balance; private int ignoredColumn1; private int ignoredColumn2; // 開發(fā)者自行添加字段的getter和setter方法。 }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      例如,通過對象數(shù)據(jù)操作接口OrmContext,創(chuàng)建一個(gè)別名為“BookStore”,數(shù)據(jù)庫文件名為“BookStore.db”的數(shù)據(jù)庫。如果數(shù)據(jù)庫已經(jīng)存在,執(zhí)行以下代碼不會(huì)重復(fù)創(chuàng)建。通過context.getDatabaseDir()可以獲取創(chuàng)建的數(shù)據(jù)庫文件所在的目錄。

      DatabaseHelper helper = new DatabaseHelper(context); // context入?yún)㈩愋蜑閛hos.app.Context,注意不要使用slice.getContext()來獲取context,請直接傳入slice,否則會(huì)出現(xiàn)找不到類的報(bào)錯(cuò)。 OrmContext context = helper.getOrmContext("BookStore", "BookStore.db", BookStore.class);

      1

      2

      3

      如果開發(fā)者有多個(gè)版本的數(shù)據(jù)庫,通過設(shè)置數(shù)據(jù)庫版本遷移類可以實(shí)現(xiàn)數(shù)據(jù)庫版本升降級(jí)。數(shù)據(jù)庫版本升降級(jí)的調(diào)用示例如下,其中 BookStoreUpgrade 類也是一個(gè)繼承了 OrmDatabase 的數(shù)據(jù)庫類,與 BookStore 類的區(qū)別在于配置的版本號(hào)不同:

      OrmContext context = helper.getOrmContext("BookStore", "BookStore.db", BookStoreUpgrade.class, new TestOrmMigration32(), new TestOrmMigration23(), new TestOrmMigration12(), new TestOrmMigration21());

      1

      2

      3

      4

      5

      6

      7

      TestOrmMigration12 的實(shí)現(xiàn)示例如下:

      private static class TestOrmMigration12 extends OrmMigration { // 此處用于配置數(shù)據(jù)庫版本遷移的開始版本和結(jié)束版本,super(startVersion, endVersion)即數(shù)據(jù)庫版本號(hào)從1升到2。 public TestOrmMigration12() {super(1, 2); } @Override public void onMigrate(RdbStore store) { store.executeSql("ALTER TABLE `Book` ADD COLUMN `addColumn12` INTEGER"); } }

      1

      2

      3

      4

      5

      6

      7

      8

      增加數(shù)據(jù),例如,在數(shù)據(jù)庫的名為“user”的表中,新建一個(gè) User 對象并設(shè)置對象的屬性。直接傳入 OrmObject 對象的增加接口,只有在 flush() 接口被調(diào)用后才會(huì)持久化到數(shù)據(jù)庫中。

      User user = new User(); user.setFirstName("Zhang"); user.setLastName("San"); user.setAge(29); user.setBalance(100.51); boolean isSuccessed = context.insert(user); isSuccessed = context.flush();

      1

      2

      3

      4

      5

      6

      7

      更新或刪除數(shù)據(jù),分為兩種情況:

      通過直接傳入 OrmObject 對象的接口來更新數(shù)據(jù),需要先從表中查到需要更新的 User 對象列表,然后修改對象的值,再調(diào)用更新接口持久化到數(shù)據(jù)庫中。刪除數(shù)據(jù)與更新數(shù)據(jù)的方法類似,只是不需要更新對象的值。例如,更新“user”表中 age 為“29”的行,需要先查找“user”表中對應(yīng)數(shù)據(jù),得到一個(gè) User 的列表。然后選擇列表中需要更新的 User 對象(如第0個(gè)對象),設(shè)置需要更新的值,并調(diào)用 update 接口傳入被更新的 User 對象,最后調(diào)用 flush 接口持久化到數(shù)據(jù)庫中:

      // 更新數(shù)據(jù) OrmPredicates predicates = context.where(User.class); predicates.equalTo("age", 29); List users = context.query(predicates); User user = users.get(0); user.setFirstName("Li"); context.update(user); context.flush(); // 刪除數(shù)據(jù) OrmPredicates predicates = context.where(User.class); predicates.equalTo("age", 29); List users = context.query(predicates); User user = users.get(0); context.delete(user); context.flush();

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      通過傳入謂詞的接口來更新和刪除數(shù)據(jù),方法與 OrmObject 對象的接口類似,只是無需 flush 就可以持久化到數(shù)據(jù)庫中:

      ValuesBucket valuesBucket = new ValuesBucket(); valuesBucket.putInteger("age", 31); valuesBucket.putString("firstName", "ZhangU"); valuesBucket.putString("lastName", "SanU"); valuesBucket.putDouble("balance", 300.51); OrmPredicates update = context.where(User.class).equalTo("userId", 1); context.update(update, valuesBucket);

      1

      2

      3

      4

      5

      6

      7

      查詢數(shù)據(jù)。在數(shù)據(jù)庫的“user”表中查詢lastName為“San”的User對象列表,示例如下:

      OrmPredicates query = context.where(User.class).equalTo("lastName", "San"); List users = context.query(query);

      1

      2

      注冊觀察者:

      // 定義一個(gè)觀察者類。 private class MyOrmObjectObserver implements OrmObjectObserver { @Override public void onChange(OrmContext changeContext, AllChangeToTarget subAllChange) { // 用戶可以在此處定義觀察者行為 } } // 調(diào)用registerEntityObserver方法注冊一個(gè)觀察者observer。 MyOrmObjectObserver observer = new MyOrmObjectObserver(); context.registerEntityObserver("user", observer); // 當(dāng)以下方法被調(diào)用,并flush成功時(shí),觀察者observer的onChange方法會(huì)被觸發(fā)。其中,方法的入?yún)⒈仨殲閁ser類的對象。 public boolean insert(T object) public boolean update(T object) public boolean delete(T object)

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      備份數(shù)據(jù)庫。其中原數(shù)據(jù)庫名為“OrmBackup.db”,備份數(shù)據(jù)庫名為“OrmBackup001.db”:

      OrmContext context = helper.getObjectContext("OrmBackup", "OrmBackup.db", BookStore.class); context.backup("OrmBackup001.db"); context.close();

      1

      2

      3

      helper.deleteRdbStore("OrmBackup.db");

      1

      HarmonyOS之實(shí)現(xiàn)對象關(guān)系映射數(shù)據(jù)庫的升級(jí)、備份、刪除、恢復(fù)以及表的增刪改查。

      數(shù)據(jù)庫 數(shù)據(jù)管理服務(wù) DAS

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:讓智能成為本能,華為云引領(lǐng)智能計(jì)算新時(shí)代
      下一篇:【Python技能樹共建】文件模塊r3
      相關(guān)文章
      久久综合日韩亚洲精品色| 亚洲中文字幕无码mv| 亚洲综合偷自成人网第页色| 久久亚洲高清观看| 亚洲av区一区二区三| 日产国产精品亚洲系列| 激情婷婷成人亚洲综合| 校园亚洲春色另类小说合集| 日韩亚洲人成在线综合| 亚洲A∨午夜成人片精品网站| 亚洲av色香蕉一区二区三区| 亚洲AV电影天堂男人的天堂| 337p日本欧洲亚洲大胆人人| 国产99久久亚洲综合精品| 亚洲人成未满十八禁网站 | 亚洲高清毛片一区二区| 亚洲国产精品无码观看久久| 亚洲熟女乱色一区二区三区| 亚洲av无码专区亚洲av不卡| 亚洲avav天堂av在线网毛片| 色窝窝亚洲av网| 青草久久精品亚洲综合专区| 亚洲欧洲一区二区三区| 亚洲色无码一区二区三区| 亚洲精品二区国产综合野狼| 亚洲AV综合色区无码一区 | 亚洲日韩精品射精日| 亚洲精品狼友在线播放| 亚洲国产成人久久综合碰碰动漫3d| 久久国产亚洲电影天堂| 亚洲国产高清视频在线观看| 99热亚洲色精品国产88| 午夜亚洲WWW湿好爽| 亚洲综合色视频在线观看| 亚洲精品无码国产| 亚洲高清无在码在线电影不卡| 亚洲成a人不卡在线观看| 99亚偷拍自图区亚洲| 国产精品亚洲一区二区三区在线观看| 一级毛片直播亚洲| 亚洲色偷偷偷鲁综合|