HarmonyOS 鸿蒙Next 使用关系型数据库时想要将重写的数据库操作方法单独写在工具类里

HarmonyOS 鸿蒙Next 使用关系型数据库时想要将重写的数据库操作方法单独写在工具类里 如题,一个 app 由多个 Ability 构成,各个 Ability 还有其 子slice,由该 app 创建一个关系型数据库,它们的数据都是存储在同一个 DB_NAME = database.db 里。

将各个Ability需要用的 重写的 数据库操作方法分别写进了 工具类里,如 MainAbility 有 MainDataManager, A_Ability 有 A_DataManager, B_Ability 有 B_DataManager,问:

  1. 各个 Ability 如何连接该数据库?
  2. 各 Ability 的 子Slice 如何连接该数据库?
  3. 若将数据库操作方法单独写在 各 Ability 的 DataManager 里,在 Slice 中仅调用 DataManager 里的方法, DataManager 应如何连接该数据库?

官方给出的代码里只有单个 MainAbility 的 主Slice 连接数据库的方法……

https://developer.huawei.com/consumer/cn/codelabsPortal/carddetails/HarmonyOS-Relational-Database —— “为了方便操作,直接在MainAbilitySlice中定义DataAbilityHelper变量,并在onStart()方法中创建其实例……

进行了一些尝试和查阅后,参照类似的方法,除MainAbility外无法连接上数据库……

俺,弱,救救孩子(泪目


更多关于HarmonyOS 鸿蒙Next 使用关系型数据库时想要将重写的数据库操作方法单独写在工具类里的实战教程也可以访问 https://www.itying.com/category-93-b0.html

6 回复
楼主你好,以下代码本地测试OK:

```java
public class DatabaseHelper {

    /**
     * DataAbility base uri
     */
    public static final String BASE_URI = "dataability:///com.huawei.coookboook.UserDataAbility";

    /**
     * Database name
     */
    public static final String DB_NAME = "dataability.db";

    /**
     * Database table name
     */
    public static final String DB_TAB_NAME = "person";

    /**
     * Database column name:name
     */
    public static final String DB_COLUMN_NAME = "name";

    /**
     * Database column name:age
     */
    public static final String DB_COLUMN_AGE = "age";

    private DataAbilityHelper databaseHelper;
    private IDataAbilityObserver dataAbilityObserver = () -> {
        // 订阅者接收目标数据表格产生变化的通知,通过查询获取最新的数据
    };

    public DatabaseHelper(Context context) {
        initDatabaseHelper(context);
    }

    private void initDatabaseHelper(Context context) {
        Context ctx = context.getApplicationContext();
        databaseHelper = DataAbilityHelper.creator(ctx);
        databaseHelper.registerObserver(Uri.parse(BASE_URI), dataAbilityObserver);
    }

    public void insert(String name, int age) {
        ValuesBucket valuesBucket = new ValuesBucket();
        valuesBucket.putString(DB_COLUMN_NAME, name);
        valuesBucket.putInteger(DB_COLUMN_AGE, age);
        try {
            if (databaseHelper.insert(Uri.parse(BASE_URI + "/" + DB_TAB_NAME), valuesBucket) != -1) {
                LogUtil.info("111", "insert successful");
            }
        } catch (DataAbilityRemoteException | IllegalStateException exception) {
            LogUtil.error("111", "insert: dataRemote exception|illegalStateException");
        }
    }

    public void query() {
        String[] columns = new String[]{
            DB_COLUMN_NAME, DB_COLUMN_AGE};

        // 构造查询条件
        DataAbilityPredicates predicates = new DataAbilityPredicates();
        predicates.between(DB_COLUMN_AGE, 15, 40);
        try {
            ResultSet resultSet = databaseHelper.query(Uri.parse(BASE_URI + "/" + DB_TAB_NAME),
                columns, predicates);
            if (resultSet == null || resultSet.getRowCount() == 0) {
                LogUtil.info("111", "query: resultSet is null or no result found");
                return;
            }
            resultSet.goToFirstRow();
            do {
                String name = resultSet.getString(resultSet.getColumnIndexForName(DB_COLUMN_NAME));
                int age = resultSet.getInt(resultSet.getColumnIndexForName(DB_COLUMN_AGE));
                LogUtil.info("111", "query:  Name :" + name + ",Age :" + age);
            } while (resultSet.goToNextRow());
        } catch (DataAbilityRemoteException | IllegalStateException exception) {
            LogUtil.error("111", "query: dataRemote exception | illegalStateException");
        }
    }
}

更多关于HarmonyOS 鸿蒙Next 使用关系型数据库时想要将重写的数据库操作方法单独写在工具类里的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在 AbilitySlice 里调用不是用 DatabaseHelper dbh = new DatabaseHelper(this); dbh.itemInsert("aaa"); 吗?

楼主你好,具体是什么错误,可以把整个工程放在gitee上,方便我们定位。

补一个在调用 MainDataManager 的 setMainM_DBM() 时报空指针错误的写法……

Log的报错:

05-06 01:25:25.637 28067-28067/? E 02D10/FaultLogger:  Uncaught exception, com.example.databasetest main Attempt to invoke virtual method 'void com.example.databasetest.db.MainDataManager.setMainM_DBH(ohos.aafwk.ability.DataAbilityHelper)' on a null object reference java.lang.NullPointerException: Attempt to invoke virtual method 'void com.example.databasetest.db.MainDataManager.setMainM_DBH(ohos.aafwk.ability.DataAbilityHelper)' on a null object reference
05-06 01:25:25.636 28067-28067/? E AndroidRuntime:  java.lang.NullPointerException: Attempt to invoke virtual method 'void com.example.databasetest.db.MainDataManager.setMainM_DBH(ohos.aafwk.ability.DataAbilityHelper)' on a null object reference

想要这么使用关系型数据库应该如何写呢?(诚恳求教 qwq

DataAbility.java 内:

可以正常启动 DataAbility

MainAbilitySlice.java 内:

private DataAbilityHelper databaseHelper;    
@Override
public void onStart(Intent intent) {
    super.onStart(intent);
    super.setUIContent(ResourceTable.Layout_ability_main);
    databaseHelper = DataAbilityHelper.create(this);
    initData();
}
public void initData(){
    dm.setMainM_DBH(databaseHelper);
    dm.tobigInsert("name1");
    dm.tobigInsert("name2");
    dm.tobigInsert("nameTop");
}

MainDataManager.java 内:

DataAbilityHelper dbh;    

public void setMainM_DBH(DataAbilityHelper dbh){
    this.dbh = dbh;
    HiLog.info(LABEL_LOG, "in Main Manager " + this.dbh);
}

private static final String BASE_URI = "dataability:///com.example.databasetest.DataAbility";
//定义一个 tobig 的表
private static final String DB_TAB_NAME = "tobig";//表名
private static final String DB_COLUMN_ID = "tobig_id";//唯一 id
private static final String DB_COLUMN_NAME = "tobig_name";//名字     
int tobig_id;
String name;
//query():查询方法    
……      
//insert():新增方法
public void tobigInsert(String name) {
    HiLog.info(LABEL_LOG, "in Main Slice " + dbh);
    HiLog.info(LABEL_LOG, "go tobigInsert(...)");
    ValuesBucket valuesBucket = new ValuesBucket();
    valuesBucket.putString(DB_COLUMN_NAME, name);
    try {
        if (dbh.insert(Uri.parse(BASE_URI + DB_TAB_NAME), valuesBucket) != -1) {
            HiLog.info(LABEL_LOG, "tobig insert successful");
            HiLog.info(LABEL_LOG, "Insert   :  todo name :" + name);
        }
    } catch (DataAbilityRemoteException | IllegalStateException exception) {
        HiLog.error(LABEL_LOG, "tobig insert: dataRemote exception|illegalStateException");
    }
}
//update():更新方法    
……      
//delete():删除方法    
……

TobigItem.java 内:

public class TobigItem {
    private int id;
    private String name;
    public TobigItem(int id, String name) {
        this.id = id;
        this.name = name;
    }
    public int getId() { return id; }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
}

欢迎开发小伙伴们进来帮帮楼主

在HarmonyOS鸿蒙Next系统中,若你希望将重写的关系型数据库操作方法单独写在工具类里,可以通过创建一个工具类,并在其中定义静态方法来实现这些数据库操作。以下是实现步骤的简要说明:

  1. 创建工具类: 创建一个新的Java类(注意,这里虽提及Java类,但操作逻辑适用于鸿蒙的ArkTS或相应语言框架下的类定义),例如DatabaseUtils

  2. 定义静态方法: 在DatabaseUtils类中,定义静态方法来实现具体的数据库操作,如插入、查询、更新和删除等。这些方法应接收必要的参数,如数据库连接对象、SQL语句、参数集等。

  3. 实现数据库操作: 在静态方法内部,使用HarmonyOS提供的数据库API执行具体的SQL操作。确保在操作完成后关闭数据库连接或释放相关资源。

  4. 调用工具类方法: 在你的业务逻辑代码中,通过DatabaseUtils类的静态方法调用数据库操作,而无需直接重写数据库操作方法。

这样,你就可以将数据库操作逻辑集中管理,便于维护和复用。

如果问题依旧没法解决请联系官网客服,官网地址是 https://www.itying.com/category-93-b0.html

回到顶部