内容导读

1、HarmonyOS NEXT数据库项目初建

2、创建数据库工具类、用户实体类与数据库配置

3、创建用户页面

4、项目优化与部署运行

一、HarmonyOS NEXT数据库项目初建

1、启动开发工具DevEco Studio创建项目DataDemo

项目结构如下:

二、创建用户实体类、数据库工具类与数据库配置

1、创建用户实体类User.ets

在ets文件夹下创建model子文件夹,并创建ArkTS文件,名称为User.ets,内容如下:

export default class User {
  //为空判断
  id: number | null = null;
  username: string | null = null;//联合类型
  password: string | null = null;//联合类型
  mobile:string|null=null;//联合类型
  //构造函数
  constructor(id: number, username: string, password: string,mobile:string) {
    this.id = id;
    this.username = username;
    this.password = password;
    this.mobile=mobile;
  }
}

2、创建数据库工具类DBTools.ets

在ets文件夹下创建utils子文件夹,并创建ArkTS文件,名称为DBTools.ets,内容如下:

import { relationalStore } from '@kit.ArkData';
import { BusinessError } from '@kit.BasicServicesKit';
import User from '../model/User';

/**
 * 数据库管理工具,从缓存中读出store/pstm,完成CURD
 */
export default class DBTools {
  //数据库对象
  private static rdbstore: relationalStore.RdbStore;

  //设置数据库对象
  static setStore(store: relationalStore.RdbStore) {
    DBTools.rdbstore = store;
  }

  //获取数据库对象
  static getStore(): relationalStore.RdbStore {
    return DBTools.rdbstore;
  }

  //执行sql用于建表等
  static executeSql(sql: string): Promise<void> { //返加异步对象
    return DBTools.getStore().executeSql(sql);
  }

  //1.添加记录
  static insert(tableName: string, data: relationalStore.ValuesBucket): Promise<number> { //返回id号
    return DBTools.getStore().insert(tableName, data);
  }

  //2.1查询数据:通过用户名与密码
  static queryByUser(username: string, password: string): Promise<number> {
    let pd = new relationalStore.RdbPredicates('USER');
    pd.equalTo('username', username).and().equalTo('password',password);
    return new Promise<number>((resolve, reject) => {
      let temp = -1;
      DBTools.getStore().query(pd).then((rs) => {
        if (rs.goToNextRow()) {
          temp = rs.getLong(rs.getColumnIndex('id'));
        }
        //解析正确的数据
        resolve(temp);
      }).catch((err: BusinessError) => {
        reject(err);
      });
    })
  }

  //2.2查询所有数据
  static queryAll(): Promise<Array<User>> {
    let pd = new relationalStore.RdbPredicates('USER');
    return new Promise<Array<User>>((resolve, reject) => {
      DBTools.getStore().query(pd).then((rs) => {
        let users = Array<User>();
        while (rs.goToNextRow()) {
          let user = new User(
            rs.getLong(0),
            rs.getString(1),
            rs.getString(2),
            rs.getString(3)
          )
          users.push(user);
        }
        //解析正确的数据
        resolve(users);
      }).catch((err: BusinessError) => {
        reject(err);
      })
    })
  }

  //3.删除记录:通过id
  static deleteById(id: number) { //:Promise<number>
    let pd = new relationalStore.RdbPredicates('USER');
    pd.equalTo('id', id);
    //传入删除条件
    return DBTools.getStore().delete(pd);
  }

  //4.更新数据:通过id
  static updateById(id: number, data: relationalStore.ValuesBucket) {
    let pd = new relationalStore.RdbPredicates('USER');
    pd.equalTo('id', id);
    ////传入数据、条件
    return DBTools.getStore().update(data, pd);
  }
}

3、EntryAbility.ets中进行数据库配置

在entryability文件夹下打开EntryAbility.ets文件并进行数据库配置,内容如下:

import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { window } from '@kit.ArkUI';
import { relationalStore } from '@kit.ArkData';
import DBTools from '../utils/DBTools';

export default class EntryAbility extends UIAbility {
  static pstm: relationalStore.RdbStore | undefined = undefined;

  // 1.创建UI
  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
    this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET);
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
  }

  // 2.窗口初建
  onWindowStageCreate(windowStage: window.WindowStage) {
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
    //配置信息
    const STORE_CONFIG: relationalStore.StoreConfig = {
      name: 'demodb.db', // 数据库文件名
      securityLevel: relationalStore.SecurityLevel.S3, // 数据库安全级别
      encrypt: false, // 可选参数,指定数据库是否加密,默认不加密
      customDir: 'customDir/subCustomDir', // 可选参数,数据库自定义路径。数据库将在如下的目录结构中被创建:context.databaseDir + '/rdb/' + customDir,其中context.databaseDir是应用沙箱对应的路径,'/rdb/'表示创建的是关系型数据库,customDir表示自定义的路径。当此参数不填时,默认在本应用沙箱目录下创建RdbStore实例。
      isReadOnly: false // 可选参数,指定数据库是否以只读方式打开。该参数默认为false,表示数据库可读可写。该参数为true时,只允许从数据库读取数据,不允许对数据库进行写操作,否则会返回错误码801。
    };
    // 判断数据库版本,如果不匹配则需进行升降级操作,假设当前数据库版本为3,表结构:EMPLOYEE (NAME, AGE, SALARY, CODES, IDENTITY)
    // 建表Sql语句, IDENTITY为bigint类型,sql中指定类型为UNLIMITED INT,可以在此处创建好所有表
    const SQL_CREATE_TABLE =
      'CREATE TABLE IF NOT EXISTS USER(ID INTEGER PRIMARY KEY AUTOINCREMENT, USERNAME TEXT NOT NULL, PASSWORD TEXT NOT NULL,MOBILE TEXT NOT NULL)';
    relationalStore.getRdbStore(this.context, STORE_CONFIG, (err, store) => {
      if (err) {
        console.error(`Failed to get RdbStore. Code:${err.code}, message:${err.message}`);
        return;
      }
      store.executeSql(SQL_CREATE_TABLE); // 创建数据表
      //正常则建表
      DBTools.setStore(store);
      console.info('-------------建库建表成功------------');
      //初始化两条记录
      let user1:relationalStore.ValuesBucket={
        'id':1000,
        'username':'bean',
        'password':'1234',
        'mobile':'13601234567'
      }
      let user2:relationalStore.ValuesBucket={
        'id':1001,
        'username':'tom',
        'password':'1234',
        'mobile':'13901234567'
      }
      let us:relationalStore.ValuesBucket[]=[user1,user2];
      store.batchInsert('USER',us,(err,rowId)=>{
        if(err){
          return;
        }
        console.log("=======初始化记录:"+rowId)
      });
    }); //////relationalStore.getRdbStore
    //加载主页
    windowStage.loadContent('pages/Index', (err) => {
      if (err.code) {
        hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
        return;
      }
      hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.');
    });
  }

  // 窗口初建结束

  // 3.窗口销毁
  onWindowStageDestroy(): void {
    // Main window is destroyed, release UI related resources
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
  }

  // 4.前置
  onForeground(): void {
    // Ability has brought to foreground
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');
  }

  // 5.后置
  onBackground(): void {
    // Ability has back to background
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');
  }

  // 6.销毁
  onDestroy(): void {
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');
  }
}

三、创建用户页面

在pages文件夹下创建用户页面

1、创建用户注册页Register.ets,代码如下

import { router, promptAction } from '@kit.ArkUI';
import DBTools from '../utils/DBTools';
import { relationalStore } from '@kit.ArkData';
import { BusinessError } from '@kit.BasicServicesKit';

@Entry
@Component
struct Register {
  @State message: string = '用户注册';
  @State username: string = '';
  @State password: string = '';

  //构建UI
  build() {
    Column() {
      Text(this.message).fontSize(26).fontWeight(FontWeight.Bold).height(80)
      Row() {
        Text('用户名:').fontSize(20).fontColor(Color.Blue)
        TextInput({ text: this.username }).fontSize(20).width(200)
          .onChange((value) => { //赋新值
            this.username = value;
          })
      }.width('80%').height(60)

      Row() {
        Text('密').fontSize(20).fontColor(Color.Blue).margin({ right: 20 })
        Text('码:').fontSize(20).fontColor(Color.Blue)
        //密码框
        TextInput({ text: this.password }).fontSize(20).width(200).type(InputType.Password)
          .onChange((value) => { //赋新值
            this.password = value;
          })
      }.width('80%').height(60)

      ////去登录
      Row() {
        Text('去登录').margin({ right: 50 }).fontColor(Color.Brown)
          .onClick(() => { //回主页去登录
            router.pushUrl({ url: 'pages/Index' })
          })
      }.width('100%')
      .justifyContent(FlexAlign.End)

      ///////用户注册 ////////
      Row() {
        Button('注 册').onClick(() => {
          let data: relationalStore.ValuesBucket = {
            'username': this.username,
            'password': this.password,
            'mobile': '12901234567'
          }
          if (this.username != '' && this.password != '') {
            DBTools.insert('USER', data).then((data) => {
              promptAction.showToast({ message: '用户注册成功' })
            }).catch((err: BusinessError) => {
              console.log(err.message);
            })
          } else {
            promptAction.showToast({ message: '用户名或密码不能为空' })
          }

        });
      }.width('100%').justifyContent(FlexAlign.Center)

    }
  }
}

2、创建登录成功后的页面Success.ets

此页面显示用户信息,验证数据库管理是否正常。

import { router } from '@kit.ArkUI';
import User from '../model/User';
import DBTools from '../utils/DBTools';
import { BusinessError } from '@kit.BasicServicesKit';

@Entry
@Component
struct Success {
  @State message: string = '数据库管理系统';
  //要使用状态数组
  @State  users: Array<User> = [];

  aboutToAppear(): void {
    DBTools.queryAll().then((us: Array<User>) => {
      //重新初始化数组
      this.users = us;
    }).catch((err: BusinessError) => {
      console.log(err.message);
    })
  }

  build() {
    Column() {
      Row() {
        Text(this.message).fontSize(30).fontColor(Color.Blue)
      }.justifyContent(FlexAlign.Center)
      .width('100%')
      .height(80)

      Row() {
        Text('用户信息管理').fontSize(20).fontColor(Color.Green).height(80)
      }
      Row(){
        Text('序号').fontSize(18).fontWeight(FontWeight.Bold).width(40).textAlign(TextAlign.Center)
        Text('编码').fontSize(18).fontWeight(FontWeight.Bold).width(50).textAlign(TextAlign.Center)
        Text('用户名').fontSize(18).fontWeight(FontWeight.Bold).width(80).textAlign(TextAlign.Center)
        Text('手机').fontSize(18).fontWeight(FontWeight.Bold).width(120).textAlign(TextAlign.Center)
      }.height(100).justifyContent(FlexAlign.Center).width('100%')
      Column() {
        Grid() { //网格组件
          ForEach(this.users, (item: User, index: number) => {
            GridItem() { //只能套一个子组件
              Row() { //嵌入行组件
                Text((index + 1) + '').fontSize(18).width(40)
                Text(item.id + '').fontSize(18).width(50)
                Text(item.username).fontSize(18).width(80)
                Text(item.mobile).width(120)
              }
            }
          });
        }
      }.width('80%').alignItems(HorizontalAlign.Center);

      Row() { //默认上下居中
        Button('返 回').width(120).fontSize(20).onClick(() => {
          router.back();
        })
      }.width('100%').height('30%').backgroundColor(Color.Transparent)
      .justifyContent(FlexAlign.Center)
    }.width('100%')
    .height('100%')

  }
}

3、优化主页Index.ets

在主页中实现用户登录,代码如下:

import { router } from '@kit.ArkUI';
import DBTools from '../utils/DBTools';
import { BusinessError } from '@kit.BasicServicesKit';

@Entry
@Component
struct Index {
  @State message: string = '用户登录';
  @State username: string = 'bean';
  @State password: string = '1234';

  // 首先加载,在EntryAbility中oncreate之前
  aboutToAppear(): void {
    console.log('---------主页---------');
  }

  build() {
    Column() { //自动为Flex
      Text(this.message).fontSize(26).fontWeight(FontWeight.Bold)
      Row() {
        Text('用户名:').fontSize(20).fontColor(Color.Blue)
        TextInput({ text: this.username }).fontSize(20).width(200)
          .onChange((value)=>{//赋新值
            this.username=value;
          })
      }.width('80%').height(60)

      Row() {
        Text('密').fontSize(20).fontColor(Color.Blue).margin({ right: 20 })
        Text('码:').fontSize(20).fontColor(Color.Blue)
        //密码框
        TextInput({ text: this.password }).fontSize(20).width(200).type(InputType.Password)
          .onChange((value)=>{//赋新值
            this.password=value;
          })
      }.width('80%').height(60)

      Row() {
        Text('去注册').margin({ right: 50 }).fontColor(Color.Brown)
          .onClick(()=>{
            router.pushUrl({url:'pages/Register'})
          })
      }.width('100%')
      .justifyContent(FlexAlign.End)

      // 用户登录
      Row() {
        Button('登 录').onClick(() => {
          DBTools.queryByUser(this.username,this.password).then((data)=>{
            if(data>0){
              //AlertDialog.show({message:'正常登录:'+data})
              router.pushUrl({url:'pages/Success'})
            }else{
              AlertDialog.show({message:'用户名或密码有误'})
            }
          }).catch((err:BusinessError)=>{
             console.log(err.message);
          })
        });
      }

    }.width('100%')
    .height('100%')
    .backgroundColor('#eee')
    .justifyContent(FlexAlign.Center)
  }
}

四、项目优化与部署运行

1、resources/profile文件夹下的main_pages.json配置文件

{
  "src": [
    "pages/Index",
    "pages/Success",
    "pages/Register"
  ]
}

2、项目根路径下的构建配置文件build-profile.json5

{
  "app": {
    "signingConfigs": [],
    "products": [
      {
        "name": "default",
        "signingConfig": "default",
        "compatibleSdkVersion": "5.0.1(13)",
        "runtimeOS": "HarmonyOS",
        "buildOption": {
          "strictMode": {
            "caseSensitiveCheck": true,
            "useNormalizedOHMUrl": true
          }
        }
      }
    ],
    "buildModeSet": [
      {
        "name": "debug",
      },
      {
        "name": "release"
      }
    ]
  },
  "modules": [
    {
      "name": "entry",
      "srcPath": "./entry",
      "targets": [
        {
          "name": "default",
          "applyToProducts": [
            "default"
          ]
        }
      ]
    }
  ]
}

3、安装并配置手机模拟器

说明:数据库的应用需要使用手机模器或真机,不能在开发工具的预览器中使用。

(1)创建模拟器

(2)启动已创建好的模拟器

手机模拟器效果如下:

(3)安装应用到模拟器

效果如下图:

4、数据库操作

(1)用户注册

说明:可以注册多个用户,便于信息显示

(2)用户登录与信息显示

最后不使用了,别忘了关闭模拟器。

OK,HarmonyOS系统中数据库的操作非常顺利,大家试试吧!

更多精彩内容还请持续关注本站...

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐