成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

HarmonyOS Sample之DataAbility RDB數據庫操作

數據庫 其他數據庫 OpenHarmony
使用Data模板的Ability(以下簡稱“Data”)有助于應用管理其自身和其他應用存儲數據的訪問,并提供與其他應用共享數據的方法。

[[414085]]

想了解更多內容,請訪問:

51CTO和華為官方合作共建的鴻蒙技術社區

https://harmonyos.51cto.com

DataAbility RDB數據庫操作

介紹

使用Data模板的Ability(以下簡稱“Data”)有助于應用管理其自身和其他應用存儲數據的訪問,并提供與其他應用共享數據的方法。Data既可用于同設備不同應用的數據共享,也支持跨設備不同應用的數據共享。

數據的存放形式多樣,可以是數據庫,也可以是磁盤上的文件。Data對外提供對數據的增、刪、改、查,以及打開文件等接口,這些接口的具體實現由開發者提供。

本示例演示了如何使用Data Ability對RDB數據庫進行增、刪、改、查,以及讀取文本文件。

模仿手機的備忘錄,實現了簡單的操作。

搭建環境

安裝DevEco Studio,詳情請參考DevEco Studio下載

設置DevEco Studio開發環境,DevEco Studio開發環境需要依賴于網絡環境,需要連接上網絡才能確保工具的正常使用,可以根據如下兩種情況來配置開發環境:

如果可以直接訪問Internet,只需進行下載HarmonyOS SDK操作

如果網絡不能直接訪問Internet,需要通過代理服務器才可以訪問,請參考配置開發環境

步驟

1.創建一個DataAbility和數據庫常量類

a.創建一個Empty DataAbility

entity右鍵,New- Ability-Empty Data Ability,然后輸入名稱 NoteDataAbility

HarmonyOS Sample 之 DataAbility RDB數據庫操作-鴻蒙HarmonyOS技術社區

b.創建一個數據庫常量類 Const.java

存放數據庫名稱、表名稱、字段列名稱、存儲路徑等

需要注意的是,

BASE_URI 3個杠后面的部分要和config.json Data Ability 聲明的uri完全一致,否則應用無法啟動

  1. /** 
  2.  * Const 
  3.  */ 
  4. public class Const { 
  5.     /** 
  6.      * DataAbility base uri 
  7.      * scheme:協議方案名,固定為“dataability”,代表Data Ability所使用的協議類型。 
  8.      * authority:設備ID。如果為跨設備場景,則為目標設備的ID;如果為本地設備場景,則不需要填寫。 
  9.      * path:資源的路徑信息,代表特定資源的位置信息。 
  10.      * query:查詢參數。 
  11.      * fragment:可以用于指示要訪問的子資源。 
  12.      * 本地設備的“device_id”字段為空,因此在“dataability:”后面有三個“/” 
  13.      * 
  14.      * BASE_URI 3個杠后面的部分要和config.json  Data Ability 聲明的uri完全一致,否則應用無法啟動 
  15.      * 
  16.      */ 
  17.     public static final String BASE_URI = "dataability:///ohos.samples.dataability.NoteDataAbility"
  18.  
  19.     /** 
  20.      * Database name 
  21.      */ 
  22.     public static final String DB_NAME = "note.db"
  23.  
  24.     /** 
  25.      * Database table name 
  26.      */ 
  27.     public static final String DB_TAB_NAME = "note"
  28.  
  29.     /** 
  30.      * Database column name:Id 
  31.      */ 
  32.     public static final String DB_COLUMN_ID = "Id"
  33.     /** 
  34.      * Database column name:noteTitle 
  35.      */ 
  36.     public static final String DB_COLUMN_TITLE = "noteTitle"
  37.  
  38.     /** 
  39.      * Database column name:writeTime 
  40.      */ 
  41.     public static final String DB_COLUMN_TIME = "writeTime"
  42.  
  43.     /** 
  44.      * Database column name:noteCategory 
  45.      */ 
  46.     public static final String DB_COLUMN_CATEGORY = "noteCategory"
  47.     /** 
  48.      * Database column name:noteContent 
  49.      */ 
  50.     public static final String DB_COLUMN_CONTENT = "noteContent"
  51.  
  52.     /** 
  53.      * Database data path 
  54.      */ 
  55.     public static final String DATA_PATH = "/note"
  56.  
  57.  
  58.     /** 
  59.      * 文件名稱 
  60.      */ 
  61.     public static final String FILE_NAME = "userdataability.txt"
  62.  

c.config.json相關配置

config.json涉及NoteDataAbility.java 的地方有3處,

第1處在module對象下,

HarmonyOS Sample 之 DataAbility RDB數據庫操作-鴻蒙HarmonyOS技術社區

第2處是abilities對象下,

permissions表示其他應用的能力調用當前能力所需的權限。

默認情況下隱藏"visible"字段(值為false),表示僅本應用可訪問該Data,開發人員可根據需求修改permissions、visible值、uri等內容。當外部應用需要訪問/控制此數據庫字段時,在該Data Ability配置中增加"visible": true,并在外面應用的配置文件config.json中申請permissions權限。

HarmonyOS Sample 之 DataAbility RDB數據庫操作-鴻蒙HarmonyOS技術社區

第3處是reqPermissions對象下,

說明:如果待訪問的Data Ability是由本應用創建,則可以不聲明該權限。

HarmonyOS Sample 之 DataAbility RDB數據庫操作-鴻蒙HarmonyOS技術社區

2.聲明數據庫存儲對象和數據庫配置

在NoteDataAbility.java 添加如下代碼

  1. //聲明數據庫存儲對象 
  2. private RdbStore rdbStore; 
  3. //數據庫配置,指定數據庫名稱 
  4. private StoreConfig storeConfig = StoreConfig.newDefaultConfig(Const.DB_NAME); 

3.實現打開RDB數據庫回調函數

在NoteDataAbility.java 添加如下代碼

  1. // 管理數據庫創建、升級和降級。 
  2. // 您可以創建一個子類來實現 #onCreate、#onUpgrade 或 #onOpen 方法。  
  3. // 如果一個數據庫已經存在,它將被打開; 如果不存在數據庫,則將創建一個數據庫。  
  4. // 在數據庫升級過程中,也會調用該類的方法。 
  5. private RdbOpenCallback rdbOpenCallback = new RdbOpenCallback() { 
  6.     @Override 
  7.     public void onCreate(RdbStore rdbStore) { 
  8.         //創建表 
  9.         rdbStore.executeSql( 
  10.                 "create table if not exists " + Const.DB_TAB_NAME + "2 (" + 
  11.                         Const.DB_COLUMN_ID + " integer primary key autoincrement ," + 
  12.                         Const.DB_COLUMN_TITLE + " text not null," + 
  13.                         Const.DB_COLUMN_CONTENT + " text not null," + 
  14.                         Const.DB_COLUMN_TIME + " text not null," + 
  15.                         Const.DB_COLUMN_CATEGORY + " text not null" + 
  16.  
  17.                         ")" 
  18.         ); 
  19.     } 
  20.  
  21.     @Override 
  22.     public void onUpgrade(RdbStore rdbStore, int i, int i1) { 
  23.         //數據庫升級 
  24.     } 
  25. }; 

4.初始化RDB數據庫存儲對象

在NoteDataAbility.java 添加如下代碼

  1. @Override 
  2. public void onStart(Intent intent) { 
  3.     super.onStart(intent); 
  4.     HiLog.info(LABEL_LOG, "NoteDataAbility onStart"); 
  5.     //數據庫幫助類 
  6.     DatabaseHelper databaseHelper = new DatabaseHelper(this); 
  7.     //初始化RDB數據庫存儲對象 
  8.     rdbStore = databaseHelper.getRdbStore(storeConfig, 1, rdbOpenCallback); 
  9.  

5.實現對數據庫的基本操作函數

NoteDataAbility.java操作數據庫的方法都需要自己實現,包括:添加、修改、查詢、刪除,還有打開文件,主要使用rdbStore對象。

  1. @Override 
  2. public ResultSet query(Uri uri, String[] columns, DataAbilityPredicates predicates) { 
  3.     HiLog.info(LABEL_LOG, "NoteDataAbility query"); 
  4.     RdbPredicates rdbPredicates = DataAbilityUtils.createRdbPredicates(predicates, Const.DB_TAB_NAME); 
  5.     return rdbStore.query(rdbPredicates, columns); 
  6.  
  7. @Override 
  8. public int insert(Uri uri, ValuesBucket value) { 
  9.     HiLog.info(LABEL_LOG, "NoteDataAbility insert"); 
  10.     //long to int 
  11.     int rowId = (int) rdbStore.insert(Const.DB_TAB_NAME, value); 
  12.     //通知觀察者數據發生變化 
  13.     DataAbilityHelper.creator(this).notifyChange(uri); 
  14.     return rowId; 
  15.  
  16. @Override 
  17. public int delete(Uri uri, DataAbilityPredicates predicates) { 
  18.     //rdb 條件,通過DataAbilityUtils將DataAbilityPredicates轉成 RdbPredicates 
  19.     RdbPredicates rdbPredicates = DataAbilityUtils.createRdbPredicates(predicates, Const.DB_TAB_NAME); 
  20.     //執行刪除 
  21.     int rowId = rdbStore.delete(rdbPredicates); 
  22.     HiLog.info(LABEL_LOG, "%{public}s""delete"); 
  23.     //通知觀察者數據發生變化 
  24.     DataAbilityHelper.creator(this).notifyChange(uri); 
  25.     return rowId; 
  26.  
  27. @Override 
  28. public int update(Uri uri, ValuesBucket value, DataAbilityPredicates predicates) { 
  29.     //rdb 條件,通過DataAbilityUtils將DataAbilityPredicates轉成 RdbPredicates 
  30.     RdbPredicates rdbPredicates = DataAbilityUtils.createRdbPredicates(predicates, Const.DB_TAB_NAME); 
  31.     int rowId =rdbStore.update(value, rdbPredicates); 
  32.     //通知觀察者數據發生變化 
  33.     DataAbilityHelper.creator(this).notifyChange(uri); 
  34.     return rowId; 
  35.  
  36. @Override 
  37. public FileDescriptor openFile(Uri uri, String mode) { 
  38.  
  39.     //獲取應用程序在設備內部存儲器上存放文件的目錄 
  40.     File file = new File(getFilesDir(), uri.getDecodedQuery()); 
  41.  
  42.     FileDescriptor fileDescriptor = null
  43.     try { 
  44.         FileInputStream fis = new FileInputStream(file); 
  45.         //獲取FD 
  46.         fileDescriptor = fis.getFD(); 
  47.         //獲取一個新的文件描述符,它是現有文件描述符的副本 
  48.         return MessageParcel.dupFileDescriptor(fileDescriptor); 
  49.     } catch (IOException e) { 
  50.         e.printStackTrace(); 
  51.     } 
  52.     return fileDescriptor; 

6.數據的訂閱和通知

在NoteDataAbility.java 中, 我們看到insert/update/delete方法都有一行。

  1. DataAbilityHelper.creator(this).notifyChange(uri); 

目的是在數據庫數據發生變化時,通知數據的訂閱者。

而在MainAbilitySlice.java 類中有如下方法,在OnStart()中被調用,實現了數據變化的訂閱。

  1. private void initDatabaseHelper() { 
  2.     //創建實例 
  3.     dataAbilityHelper = DataAbilityHelper.creator(this); 
  4.     //注冊一個觀察者來觀察給定 Uri 指定的數據,dataObserver表示 IDataAbilityObserver 對象 
  5.     dataAbilityHelper.registerObserver(Uri.parse(Const.BASE_URI), dataAbilityObserver); 

同時,數據變化訂閱方還需要實現IDataAbilityObserver接口,在數據變化時會自動回調,完成對應的邏輯處理。

  1. //觀察者模式,數據變化時回調 
  2. private final IDataAbilityObserver dataAbilityObserver=() -> { 
  3.     HiLog.info(LABEL, "%{public}s""database changed"); 
  4.     //篩選數據 
  5.     initLists(this); 
  6. }; 

當數據訂閱者不再需要訂閱Data變化時,則調用unregisterObserver​(Uri uri, IDataAbilityObserver dataObserver)方法取消。

  1. @Override 
  2. protected void onStop() { 
  3.     super.onStop(); 
  4.     dataAbilityHelper.unregisterObserver(Uri.parse(Const.BASE_URI), dataAbilityObserver); 

觀察者模式的作用在于當數據庫表格的內容產生變化時,可以主動通知與該表格數據相關聯的進程或者應用,從而使得相關進程或者應用接收到數據變化后完成相應的處理。

7.訪問Data Ability,新建AddNoteAbility,在AddNoteAbilitySlice實現數據的添加和修改

開發者可以通過DataAbilityHelper類來訪問當前應用或其他應用提供的共享數據。

DataAbilityHelper作為客戶端,與提供方的Data進行通信。DataAbilityHelper提供了一系列與Data Ability通信的方法。

a.數據的添加

  1. /** 
  2.  * 保存數據 
  3.  * 
  4.  * @param component component 
  5.  */ 
  6. private void saveNote(Component component) { 
  7.     ValuesBucket valuesBucket = new ValuesBucket(); 
  8.     TextField noteTitle = (TextField) findComponentById(ResourceTable.Id_add_note_title); 
  9.     if (noteTitle.getText().isEmpty()) { 
  10.         DialLogUtils dialog = new DialLogUtils(this, "標題不能為空!"); 
  11.         dialog.showDialog(); 
  12.         return
  13.     } 
  14.     TextField noteContent = (TextField) findComponentById(ResourceTable.Id_add_note_content); 
  15.     if (noteContent.getText().isEmpty()) { 
  16.         DialLogUtils dialog = new DialLogUtils(this, "內容不能為空!"); 
  17.         dialog.showDialog(); 
  18.         return
  19.     } 
  20.     Text noteCategory = (Text) findComponentById(ResourceTable.Id_add_note_category); 
  21.     Text noteTime = (Text) findComponentById(ResourceTable.Id_add_note_time); 
  22.  
  23.     HiLog.debug(LABEL, "%{public}s""saveNote, noteId:[" + noteId + "],noteCategory:" + noteCategory.getText()); 
  24.     int rowId; 
  25.     //放入鍵值 
  26.     valuesBucket.putString(Const.DB_COLUMN_TITLE, noteTitle.getText()); 
  27.     valuesBucket.putString(Const.DB_COLUMN_CATEGORY, noteCategory.getText()); 
  28.     valuesBucket.putString(Const.DB_COLUMN_CONTENT, noteContent.getText()); 
  29.     valuesBucket.putString(Const.DB_COLUMN_TIME, noteTime.getText()); 
  30.     try { 
  31.         if (noteId.isEmpty()) { 
  32.             HiLog.debug(LABEL, "%{public}s""saveNote, insert"); 
  33.             //插入數據 
  34.             rowId = dataAbilityHelper.insert(Uri.parse(Const.BASE_URI + Const.DATA_PATH), valuesBucket); 
  35.             HiLog.debug(LABEL, "%{public}s""insert,rowId:" + rowId); 
  36.  
  37.         } else { 
  38.             HiLog.debug(LABEL, "%{public}s""saveNote, update"); 
  39.             //指定修改謂語 
  40.             DataAbilityPredicates predicates = new DataAbilityPredicates(); 
  41.             predicates.equalTo(Const.DB_COLUMN_ID, noteId); 
  42.             //修改數據 
  43.             rowId = dataAbilityHelper.update(Uri.parse(Const.BASE_URI + Const.DATA_PATH), valuesBucket, predicates); 
  44.             HiLog.debug(LABEL, "%{public}s""update,rowId:" + rowId); 
  45.         } 
  46.  
  47.         //返回列表頁 
  48.         backListPage(); 
  49.     } catch (DataAbilityRemoteException | IllegalStateException exception) { 
  50.         HiLog.error(LABEL, "%{public}s""insert: dataRemote exception|illegalStateException"); 
  51.     } 

b.修改和刪除數據

  1. @Override 
  2. public void onStart(Intent intent) { 
  3.     super.onStart(intent); 
  4.     //設置UI布局資源 
  5.     super.setUIContent(ResourceTable.Layout_ability_add_note); 
  6.     // 
  7.     initDatabaseHelper(); 
  8.     //返回按鈕 
  9.     Component backButton = findComponentById(ResourceTable.Id_back_image); 
  10.     backButton.setClickedListener(component -> terminateAbility()); 
  11.     TextField noteContent = (TextField) findComponentById(ResourceTable.Id_add_note_content); 
  12.  
  13.  
  14.     //修改筆記 
  15.     if (intent.hasParameter("Id")) { 
  16.         HiLog.info(LABEL, "%{public}s""change data coming"); 
  17.         noteId = intent.getStringParam("Id"); 
  18.         HiLog.info(LABEL, "%{public}s""noteId:" + noteId); 
  19.         if (noteId != null) { 
  20.             DataAbilityPredicates predicates = new DataAbilityPredicates(); 
  21.             predicates.equalTo(Const.DB_COLUMN_ID, noteId); 
  22.             //查詢數據 
  23.             NoteListItemInfo itemInfo = queryOne(predicates); 
  24.             HiLog.info(LABEL, "%{public}s""noteTitle:" + itemInfo.getNoteTitle() + ",category:" + itemInfo.getNoteCategory()); 
  25.             //設置顯示 
  26.             TextField noteTitle = (TextField) findComponentById(ResourceTable.Id_add_note_title); 
  27.             noteTitle.setText(itemInfo.getNoteTitle()); 
  28.  
  29.             noteContent.setText(itemInfo.getNoteContent()); 
  30.  
  31.             Text category = (Text) findComponentById(ResourceTable.Id_add_note_category); 
  32.             category.setText(itemInfo.getNoteCategory()); 
  33.  
  34.             Text noteTime = (Text) findComponentById(ResourceTable.Id_add_note_time); 
  35.             noteTime.setText(itemInfo.getNoteTime()); 
  36.  
  37.  
  38.             Component deleteButton = findComponentById(ResourceTable.Id_delete_image); 
  39.             //設置刪除按鈕可用,只有修改筆記才能刪除 
  40.             deleteButton.setClickable(true); 
  41.             //添加事件 
  42.             deleteButton.setClickedListener(component -> { 
  43.                 try { 
  44.                     int rowId = dataAbilityHelper.delete(Uri.parse(Const.BASE_URI + Const.DATA_PATH), predicates); 
  45.                     HiLog.info(LABEL, "%{public}s""deleteNote,rowId:" + rowId); 
  46.  
  47.                     //返回列表頁 
  48.                     backListPage(); 
  49.                 } catch (DataAbilityRemoteException e) { 
  50.                     HiLog.error(LABEL, "%{public}s""delete: exception|DataAbilityRemoteException"); 
  51.                 } 
  52.             }); 
  53.         } 
  54.     } else { 
  55.         Text timeText = (Text) findComponentById(ResourceTable.Id_add_note_time); 
  56.         String time24 = sdf.format(new Date()); 
  57.         timeText.setText(time24); 
  58.     } 
  59.  
  60.     //保存筆記 
  61.     Component insertButton = findComponentById(ResourceTable.Id_finish_image); 
  62.     insertButton.setClickedListener(this::saveNote); 
  63.  

c.查詢數據

  1. private NoteListItemInfo queryOne(DataAbilityPredicates predicates) { 
  2.     HiLog.info(LABEL, "%{public}s""database query"); 
  3.     String[] columns = new String[]{ 
  4.             Const.DB_COLUMN_ID, 
  5.             Const.DB_COLUMN_TITLE, Const.DB_COLUMN_TIME, 
  6.             Const.DB_COLUMN_CATEGORY, Const.DB_COLUMN_CONTENT}; 
  7.     try { 
  8.         ResultSet resultSet = dataAbilityHelper.query( 
  9.                 Uri.parse(Const.BASE_URI + Const.DATA_PATH), columns, predicates); 
  10.  
  11.         //無數據 
  12.         if (resultSet.getRowCount() == 0) { 
  13.             HiLog.info(LABEL, "%{public}s""query:No result found"); 
  14.             return null
  15.         } 
  16.         // 
  17.         resultSet.goToFirstRow(); 
  18.         //根據列索引獲取列值 
  19.         String noteId = resultSet.getString(resultSet.getColumnIndexForName(Const.DB_COLUMN_ID)); 
  20.         String noteTitle = resultSet.getString(resultSet.getColumnIndexForName(Const.DB_COLUMN_TITLE)); 
  21.         String noteTime = resultSet.getString(resultSet.getColumnIndexForName(Const.DB_COLUMN_TIME)); 
  22.         String noteCategory = resultSet.getString(resultSet.getColumnIndexForName(Const.DB_COLUMN_CATEGORY)); 
  23.         String noteContent = resultSet.getString(resultSet.getColumnIndexForName(Const.DB_COLUMN_CONTENT)); 
  24.         Element image = ElementScatter.getInstance(getContext()).parse(ResourceTable.Graphic_icon_nodata); 
  25.         HiLog.info(LABEL, "%{public}s""set  show:" + noteCategory); 
  26.         // 
  27.         return new NoteListItemInfo(noteId, noteTitle, noteContent, noteTime, noteCategory, image); 
  28.  
  29.     } catch (DataAbilityRemoteException | IllegalStateException exception) { 
  30.         HiLog.error(LABEL, "%{public}s""query: dataRemote exception|illegalStateException"); 
  31.     } 
  32.     return null

實踐中遇到的小知識點記錄一下

1. 如何監聽 TextField 文本變更事件

  1. /** 
  2.  * 監聽TextFiled 文本變化 
  3.  */ 
  4. private void initSearchBtnEvent(AbilitySlice slice) { 
  5.     TextField searchTF = (TextField) findComponentById(ResourceTable.Id_tf_note_search); 
  6.     //添加文本觀察器 TextObserver 以檢測文本是否發生更改。 
  7.     searchTF.addTextObserver(new Text.TextObserver() { 
  8.         @Override 
  9.         public void onTextUpdated(String s, int i, int i1, int i2) { 
  10.             HiLog.info(LABEL, "addTextObserver 按鍵事件觸發....."); 
  11.             //篩選數據 
  12.             initLists(slice); 
  13.         } 
  14.     }); 

2. ListContainer 組件添加點擊事件

在 Provider 中 getComponent添加,在初始化Provider時傳遞AbilitySlice對象過來

  1. public ListItemProvider(List<ItemInfo> itemList, AbilityContext context,AbilitySlice slice) { 
  2.     this.itemList = itemList; 
  3.     this.context = context; 
  4.     this.typeFactory = new ListTypeFactory(); 
  5.     this.slice=slice; 
  6. @Override 
  7. public Component getComponent(int index, Component component, ComponentContainer componentContainer) { 
  8.     Component itemComponent = component; 
  9.     ViewHolder viewHolder; 
  10.     if (itemComponent == null) { 
  11.         itemComponent = LayoutScatter.getInstance(componentContainer.getContext()) 
  12.                 .parse(getItemComponentType(index), componentContainer, false); 
  13.  
  14.     } 
  15.     viewHolder = typeFactory.getViewHolder(getItemComponentType(index), itemComponent); 
  16.     viewHolder.setUpComponent(getItem(index), context); 
  17.  
  18.  
  19.     //設置點擊事件 
  20.     itemComponent.setClickedListener(component1 -> { 
  21.         //獲取noteId 
  22.         String noteId=""
  23.         if(getItem(index) instanceof NoteListItemInfo){ 
  24.             //HiLog.debug(LABEL, "%{public}s""ItemInfo instanceof SingleButtonDoubleLineListItemInfo"); 
  25.             noteId=((NoteListItemInfo)getItem(index)).getNoteId(); 
  26.         } 
  27.         HiLog.debug(LABEL, "%{public}s""noteId:" + noteId); 
  28.         //1.攜帶筆記ID參數,跳轉到AddNoteAbilitySlice 
  29.         Intent intent = new Intent(); 
  30.         if(noteId!=null){ 
  31.             //保存要傳遞的參數 
  32.             intent.setParam("Id", noteId); 
  33.             Operation operation = new Intent.OperationBuilder() 
  34.                     .withDeviceId(""
  35.                     .withBundleName("com.buty.samples"
  36.                     .withAbilityName(AddNoteAbility.class).build(); 
  37.             intent.setOperation(operation); 
  38.  
  39.             slice.startAbility(intent); 
  40.         }else { 
  41.             HiLog.error(LABEL, "%{public}s""noteId is null"); 
  42.         } 
  43.     }); 
  44.  
  45.     return itemComponent; 

效果展示

文章相關附件可以點擊下面的原文鏈接前往下載。

原文鏈接:https://harmonyos.51cto.com/posts/7386

想了解更多內容,請訪問:

51CTO和華為官方合作共建的鴻蒙技術社區

https://harmonyos.51cto.com

 

責任編輯:jianghua 來源: 鴻蒙社區
相關推薦

2022-04-08 11:25:58

數據庫操作AbilityData

2009-08-19 16:40:26

C#操作Access數

2021-09-06 10:24:12

鴻蒙HarmonyOS應用

2011-07-12 15:22:04

SQLite數據庫

2010-08-18 13:49:01

DB2數據庫

2021-09-03 15:41:00

鴻蒙HarmonyOS應用

2011-08-02 16:43:26

iPhone開發 Ssqlite3 數據庫

2021-09-15 14:55:49

鴻蒙HarmonyOS應用

2021-08-17 10:20:14

鴻蒙HarmonyOS應用

2022-08-01 13:59:04

數據庫通信ArkUI

2010-09-30 09:11:01

2010-09-30 08:27:48

2010-09-27 14:54:38

SQL數據庫

2010-08-31 16:53:54

DHCP數據庫

2021-07-28 14:40:57

鴻蒙HarmonyOS應用

2021-09-17 14:43:54

鴻蒙HarmonyOS應用

2021-09-24 09:25:01

鴻蒙HarmonyOS應用

2021-11-23 09:58:35

鴻蒙HarmonyOS應用

2022-05-24 15:06:57

AbilityeTS FA鴻蒙

2021-05-24 09:08:50

數據庫工具技術
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲性视频网站 | 欧美久久天堂 | 久久久久久亚洲精品 | 成人免费xxxxx在线视频 | 亚洲精品免费在线观看 | 精品视频免费 | 中文在线一区 | 欧美一区二区三区在线 | 欧美日韩精品一区 | 91一区二区三区在线观看 | 911网站大全在线观看 | 欧美日韩在线观看一区 | 久久久www成人免费无遮挡大片 | 伊人在线 | 欧美片网站免费 | 国产精品久久久久久二区 | 日韩成人中文字幕 | 精国产品一区二区三区四季综 | 午夜tv免费观看 | 91国内在线观看 | 久久久久久999 | 日韩成人免费视频 | 亚洲精品一| 亚洲高清在线观看 | 性一爱一乱一交一视频 | 成人免费小视频 | 精品久久中文字幕 | 亚洲欧美日韩电影 | 欧美成人一区二区三区 | 久久精品天堂 | 夜夜骑首页 | 秋霞a级毛片在线看 | 国产一级在线 | 在线视频99 | 一区二区在线 | 99久久精品免费看国产免费软件 | 精品视频一区在线 | 黄色一级大片在线免费看产 | 成人福利视频网站 | 一区二区三区日 | 精品国产视频 |