[Huawei Developers] ask011:
Introduction

In this article, we can create an app showing below storage features:

1. Create database and create table

2. Insert data

3. Update data

4. Delete data

5. Fetch data

Requirements

1. Dev Eco IDE

2. Wearable watch (Can use simulator also)

Harmony OS Supports various ways of storage

1. Storage like (Shared preference, key value pairs).

2. File Storage

3. SQLite Db

In this article, we will test SQLite Db

UI Design

ability_main.xml

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:height="match_parent"
ohos:width="match_parent"
ohos:orientation="vertical"
ohos:background_element="#8c7373"
ohos:padding="32">

<Text
ohos:multiple_lines="true"
ohos:id="$+id:text"
ohos:height="match_content"
ohos:width="200"
ohos:layout_alignment="horizontal_center"
ohos:text="Text"
ohos:text_size="10fp"/>

<Button
ohos:id="$+id:button"
ohos:height="match_content"
ohos:width="match_content"
ohos:background_element="$graphic:background_button"
ohos:layout_alignment="horizontal_center"
ohos:text="$string:save"
ohos:text_size="30"
ohos:top_margin="5"/>

<Button
ohos:id="$+id:button_get"
ohos:height="match_content"
ohos:width="match_content"
ohos:background_element="$graphic:background_button"
ohos:layout_alignment="horizontal_center"
ohos:padding="5"
ohos:text="$string:read"
ohos:text_size="30"
ohos:top_margin="5"/>

<Button
ohos:id="$+id:button_update"
ohos:height="match_content"
ohos:width="match_content"
ohos:background_element="$graphic:background_button"
ohos:layout_alignment="horizontal_center"
ohos:padding="5"
ohos:text="$string:update"
ohos:text_size="30"
ohos:top_margin="5"/>

<Button
ohos:id="$+id:button_delete"
ohos:height="match_content"
ohos:width="match_content"
ohos:background_element="$graphic:background_button"
ohos:layout_alignment="horizontal_center"
ohos:padding="5"
ohos:text="$string:delete"
ohos:text_size="30"
ohos:top_margin="5"/>
</DirectionalLayout>

MainAbilitySlice.java

package com.example.testwearableemptyfeaturejava.slice;

import com.example.testwearableemptyfeaturejava.ResourceTable;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.Button;
import ohos.agp.components.Component;
import ohos.agp.components.Text;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.window.dialog.ToastDialog;
import ohos.app.Context;
import ohos.data.DatabaseHelper;
import ohos.data.rdb.*;
import ohos.data.resultset.ResultSet;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;

public class MainAbilitySlice extends AbilitySlice {
static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00201, "MY_TAG");
RdbStore mStore;
Text mText;

@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_main);
initDb(getApplicationContext());

mText = (Text) findComponentById(ResourceTable.Id_text);
Button button = (Button) findComponentById(ResourceTable.Id_button);
if (button != null) {
button.setClickedListener(new Component.ClickedListener() {
@Override
// Register a listener for observing click events of the button.
public void onClick(Component component) {
HiLog.warn(LABEL, "inside %{public}s", "MainAbilitySliceButtonClick");
// Add the operation to perform when the button is clicked.
insertData();
}
});
}

Button buttonGet = (Button) findComponentById(ResourceTable.Id_button_get);
if(buttonGet != null){
buttonGet.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
HiLog.warn(LABEL, "inside %{public}s", "get data");
readData();
}
});
}

Button buttonDelete = (Button) findComponentById(ResourceTable.Id_button_delete);
if(buttonDelete != null){
buttonDelete.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
HiLog.warn(LABEL, "inside %{public}s", "deleteData");
deleteData();
}
});
}

Button buttonUpdate = (Button) findComponentById(ResourceTable.Id_button_update);
if(buttonUpdate != null){
buttonUpdate.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
HiLog.warn(LABEL, "inside %{public}s", "updateData");
updateData();
}
});
}
}

private void initDb(Context context){
StoreConfig config = StoreConfig.newDefaultConfig("RdbStoreTest.db");
final RdbOpenCallback callback = new RdbOpenCallback() {
@Override
public void onCreate(RdbStore store) {
store.executeSql("CREATE TABLE IF NOT EXISTS test (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, age INTEGER, salary REAL, blobType BLOB)");
}
@Override
public void onUpgrade(RdbStore store, int oldVersion, int newVersion) {
}
};
DatabaseHelper helper = new DatabaseHelper(context);
mStore = helper.getRdbStore(config, 1, callback, null);
}

private void insertData(){
ValuesBucket values = new ValuesBucket();
//values.putInteger("id", 2);
values.putString("name", "kamal");
values.putInteger("age", 18);
values.putDouble("salary", 100.5);
values.putByteArray("blobType", new byte[] {1, 2, 3});
long id = mStore.insert("test", values);
HiLog.warn(LABEL, "insert completed %{public}s", "id is"+id);
showToastMessage("data inserted successfully");
}

private void readData(){
try {
String[] columns = new String[] {"id", "name", "age", "salary"};
RdbPredicates rdbPredicates = new RdbPredicates("test").orderByAsc("salary");
ResultSet resultSet = mStore.query(rdbPredicates, columns);
if(resultSet == null || resultSet.getRowCount() <=0){
showToastMessage("no data in table");
return;
}

String data = "";
while(resultSet.goToNextRow()){
String name = resultSet.getString(resultSet.getColumnIndexForName("name"));
String age = resultSet.getString(resultSet.getColumnIndexForName("age"));
String salary = resultSet.getString(resultSet.getColumnIndexForName("salary"));
HiLog.warn(LABEL, "inside %{public}s", "read data"+name);
data = data + "[" + name + "][" + age + "][" + salary + "]\n";
}

mText.setText(data);
HiLog.warn(LABEL, "read completedqq %{public}s", "");
showToastMessage("data read successfully");
}catch (Exception e){
e.printStackTrace();
}

}

private void updateData(){
try {
ValuesBucket values = new ValuesBucket();
values.putString("name", "updated kamal");
values.putInteger("age", 28);
values.putDouble("salary", 200.5);
values.putByteArray("blobType", new byte[] {1, 2, 3});

AbsRdbPredicates rdbPredicates = new RdbPredicates("test").equalTo("age", 18);
int index = mStore.update(values, rdbPredicates);
HiLog.warn(LABEL, "update completed %{public}s", ""+index);
showToastMessage("data updated successfully");
}catch (Exception e){
e.printStackTrace();
}
}

private void deleteData(){
try {
String[] columns = new String[] {"id", "name", "age", "salary"};
RdbPredicates rdbPredicates = new RdbPredicates("test").equalTo("age", 18);
int index = mStore.delete(rdbPredicates);
HiLog.warn(LABEL, "delete completed %{public}s", ""+index);
showToastMessage("data deleted successfully");
}catch (Exception e){
e.printStackTrace();
}
}

private void showToastMessage(String string){
new ToastDialog(getApplicationContext()).setText(string).setAlignment(1).setSize(300,50).show();
}

@Override
public void onActive() {
super.onActive();
}

@Override
public void onForeground(Intent intent) {
super.onForeground(intent);
}
}

MainAbility.java

package com.example.testwearableemptyfeaturejava;

import com.example.testwearableemptyfeaturejava.slice.MainAbilitySlice;
import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;

public class MainAbility extends Ability {
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setMainRoute(MainAbilitySlice.class.getName());
}
}

Code Explanation

Create database under “MainAbility.java” or any separate class.

private void initDb(Context context){
StoreConfig config = StoreConfig.newDefaultConfig("RdbStoreTest.db");
final RdbOpenCallback callback = new RdbOpenCallback() {
@Override
public void onCreate(RdbStore store) {
store.executeSql("CREATE TABLE IF NOT EXISTS test (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, age INTEGER, salary REAL, blobType BLOB)");
}
@Override
public void onUpgrade(RdbStore store, int oldVersion, int newVersion) {
}
};
DatabaseHelper helper = new DatabaseHelper(context);
mStore = helper.getRdbStore(config, 1, callback, null);
}

If database is not there, it will be created. onCreate method will create table test.

Insert data under “MainAbility.java” or any new class.

private void insertData(){
ValuesBucket values = new ValuesBucket();
values.putString("name", "kamal");
values.putInteger("age", 18);
values.putDouble("salary", 100.5);
values.putByteArray("blobType", new byte[] {1, 2, 3});
long id = mStore.insert("test", values);
HiLog.warn(LABEL, "insert completed %{public}s", "id is"+id);
}

Data is retrieved and UI is updated.

Update row under “MainAbility.java” or any class.

private void updateData(){
try {
ValuesBucket values = new ValuesBucket();
values.putString("name", "updated kamal");
values.putInteger("age", 28);
values.putDouble("salary", 200.5);
values.putByteArray("blobType", new byte[] {1, 2, 3});

AbsRdbPredicates rdbPredicates = new RdbPredicates("test").equalTo("age", 18);
int index = mStore.update(values, rdbPredicates);
HiLog.warn(LABEL, "update completed %{public}s", ""+index);
showToastMessage("data updated successfully");
}catch (Exception e){
e.printStackTrace();
}
}

Delete data under “MainAbility.java” or any class.

private void deleteData(){
try {
String[] columns = new String[] {"id", "name", "age", "salary"};
RdbPredicates rdbPredicates = new RdbPredicates("test").equalTo("age", 18);
int index = mStore.delete(rdbPredicates);
HiLog.warn(LABEL, "delete completed %{public}s", ""+index);
showToastMessage("data deleted successfully");
}catch (Exception e){
e.printStackTrace();
}
}

Tips and Tricks

1. All the file operations are Asynchronous.

2. Relational mapping is possible.

3. RDB can use a maximum of four connection pools to manage read and write operations.

4. To ensure data accuracy, the RDB supports only one write operation at a time.

5. RdbPredicates: You do not need to write complex SQL statements. Instead, you can combine SQL statements simply by calling methods in this class, such as equalTo, notEqualTo, groupBy, orderByAsc, and beginsWith.

6. RawRdbPredicates: You can set whereClause and whereArgs, but cannot call methods such as equalTo.

Conclusion

we have learned to save, update, delete and retrieve the data using SQLite database in Harmony OS along with the UI components.

Reference

Harmony Official document

DevEco Studio User guide

JS API Reference

Read In Forum