ArkTS鸿蒙--关系型数据库的级联

一、关系型数据库介绍

关系型数据库基于SQLite组件,适用于存储包含复杂关系数据的场景,例如对于一个班级的学生信息,需要包括学生的姓名、学号、各科成绩等;对于公司的员工信息,需要包括姓名、工号、职位等,由于数据之间有较强的对应关系,复杂程度比键值型数据更高,此时需要使用关系型数据库来持久化保存数据。

二、场景介绍

下面将实现一个案例,来实现关系型数据库的级联操作。在一个公司的场景中,将会创建两张表:部门表、员工表。部门表里面存储的信息有部门编号(did)、部门名称(dname)、部门人数(count),员工表里面存储的信息有员工编号(eid)、员工姓名(ename)、员工所在的部门编号(did),这两张表会通过部门编号相关联,可以通过查询部门的编号,来找到里面所属的员工信息以及该部门所包含的员工数。

三、工程目录

四、工程代码

1、Index页面视图代码
复制代码
// 创建新实例并使用给定对象初始化
let para: Record<string, string> = { 'tableName': 't_dept' };
let storage: LocalStorage = new LocalStorage(para);


@Entry(storage)
@Component
struct Index {
  //部门表的表名
  @LocalStorageLink('tableName') tableName: string = 't_dept';
  //页面标题
  @State titleText: string = '关系型数据库的级联'
  //控制半模态窗口是否打开的状态变量
  @Provide('isBindSheetShow') isBindSheetShow: boolean = false
  //半模态窗口的显示内容
  @Provide('contentId') contentId: number = 1
  //查询信息的分类
  @State departmentList: Array<DepartmentModel> = [
    { depId: 0, depName: '总计', count: 0 }
  ]
  //部门选中时的状态数组
  @State isSelectList: Array<boolean> = []
  //数组:存储员工的信息
  @State employeeList: Array<EmployeeListModel> = []
  //人数数组
  @State personList: Array<number> = [0]

  aboutToAppear(): void {
    //读取用户首选项中的table字段
    this.tableName = PreferenceUtils.getData(getContext(), 'table') as string
    console.log('aboutToAppear中读取到的tableName的值为:' + this.tableName)
  }

  build() {
    Column() {
      //======顶部标题======//
      Text(this.titleText)
        .width('100%')
        .height('8%')
        .fontSize(28)
        .fontWeight(FontWeight.Medium)
        .backgroundColor('#AFE1AF')
        .fontColor('#FFFFFF')
        .textAlign(TextAlign.Start)
        .padding(8)

      //======按钮布局:新建表、查询表、删除表======//
      Scroll() {
        Row() {
          //===>点击按钮:利用半模态窗口:收集新建表的相关信息
          Text('新建表')
            .padding({
              left: 12,
              right: 12,
              top: 8,
              bottom: 8
            })
            .fontSize(18)
            .borderRadius(14)
            .backgroundColor('#ECFFDC')
            .margin({ right: 12 })
            .onClick(() => {
              //创建部门表和员工表的选择
              this.contentId = 1
              this.isBindSheetShow = true
            })
          //===>点击按钮:利用半模态窗口:收集需要查询表的相关信息
          Text('查询表')
            .padding({
              left: 12,
              right: 12,
              top: 8,
              bottom: 8
            })
            .fontSize(18)
            .borderRadius(14)
            .backgroundColor('#ECFFDC')
            .margin({ right: 12 })
            .onClick(async () => {
              //===>直接查询部门表和员工表
              console.log('查询的部门表的表名为:' + this.tableName)
              let selectDepTable: string = `select * from ${this.tableName}`
              let selectEmpTable: string = "select * from t_emp"
              console.log('selectDepTable:' + selectDepTable)
              //将departmentList数组恢复至默认状态
              this.departmentList = [{ depId: 0, depName: '总计', count: 0 }]
              //各个分类的人数数组
              this.personList = [0]
              //将employeeList数组恢复至默认状态
              this.employeeList = []
              //执行sql语句==>查询部门表
              let resultSet = await RdbUtils.executeQuerySql(selectDepTable)
              if (resultSet.goToFirstRow()) {
                do {
                  const departmentData: DepartmentModel = {
                    depId: resultSet.getLong(resultSet.getColumnIndex('did')), //获取部门编号
                    depName: resultSet.getString(resultSet.getColumnIndex('dname')), //获取部门名称
                    count: resultSet.getLong(resultSet.getColumnIndex('count')), //获取部门人数
                  }
                  this.departmentList.push(departmentData)
                  this.personList.push(0)
                } while (resultSet.goToNextRow())
              }
              resultSet.close()
              //将选中状态恢复至默认状态
              this.isSelectList = []
              //将isSelectList数组重新赋值
              for (let index = 0; index < this.departmentList.length; index++) {
                this.isSelectList.push(false)
              }
              //将isSelectList的第一个元素(总计)的选中状态改为true
              this.isSelectList[0] = true
              console.log('department is select:' + this.isSelectList)
              //执行sql语句==>查询员工表
              let resultSetEmp = await RdbUtils.executeQuerySql(selectEmpTable)
              if (resultSetEmp.goToFirstRow()) {
                do {
                  const employee: EmployeeModel = {
                    empId: resultSetEmp.getLong(resultSetEmp.getColumnIndex('eid')), //获取员工编号
                    empName: resultSetEmp.getString(resultSetEmp.getColumnIndex('ename')), //获取员工姓名
                    depId: resultSetEmp.getLong(resultSetEmp.getColumnIndex('did')), //获取部门编号
                  }
                  //查询员工编号所对应的部门名称
                  let selectDepInfo: string = `select * from ${this.tableName} where did = ${employee.depId}`
                  //根据部门ID值添加人数
                  this.personList[employee.depId]++
                  let result = await RdbUtils.executeQuerySql(selectDepInfo)
                  if (result.goToFirstRow()) {
                    do {
                      const dName: string = result.getString(result.getColumnIndex('dname')) //获取对应部门名称
                      const employeeListModel: EmployeeListModel = {
                        employee: employee,
                        dname: dName
                      }
                      //将数据放进employeeList数组中
                      this.employeeList.push(employeeListModel)
                      //查询到一个员工,那么数组departmentList第0项的count值++,总人数的值
                      this.departmentList[0].count++
                    } while (result.goToNextRow())
                  }
                } while (resultSetEmp.goToNextRow())

                this.personList[0] = this.departmentList[0].count
              }

              //显示提示框--表格查询成功
              promptAction.showToast({ message: "表格查询成功" })
            })
          //===>点击按钮:利用半模态窗口:收集需要添加数据的相关信息
          Text('添加数据')
            .padding({
              left: 12,
              right: 12,
              top: 8,
              bottom: 8
            })
            .fontSize(18)
            .borderRadius(14)
            .backgroundColor('#ECFFDC')
            .margin({ right: 12 })
            .onClick(() => {
              //选择添加的数据是在部门表还是员工表中
              this.contentId = 2
              this.isBindSheetShow = true
            })
          //===>点击按钮:利用半模态窗口:收集需要更新数据的相关信息
          Text('更新数据')
            .padding({
              left: 12,
              right: 12,
              top: 8,
              bottom: 8
            })
            .fontSize(18)
            .borderRadius(14)
            .backgroundColor('#ECFFDC')
            .margin({ right: 12 })
            .onClick(() => {
              //选择更新的数据是在部门表还是员工表中
              this.contentId = 3
              this.isBindSheetShow = true
            })
          //===>点击按钮:利用半模态窗口:收集需要删除表的相关信息
          Text('删除表')
            .padding({
              left: 12,
              right: 12,
              top: 8,
              bottom: 8
            })
            .fontSize(18)
            .borderRadius(14)
            .backgroundColor('#ECFFDC')
            .onClick(() => {
              //选择删除的是哪张表
              this.contentId = 4
              this.isBindSheetShow = true
            })
        }
        .height('100%')
        .padding(8)
        .justifyContent(FlexAlign.SpaceBetween)
      }
      .width('100%')
      .height('8%')
      .scrollBar(BarState.Off)
      .scrollable(ScrollDirection.Horizontal)

      //======显示表格的查询内容======//
      Column() {
        //查询部门表,获取部门信息
        Scroll() {
          Row({ space: 14 }) {
            ForEach(this.departmentList, (item: DepartmentModel, index: number) => {
              Column({ space: 4 }) {
                //显示部门名称
                Text(item.depId + '-' + item.depName).fontSize(18)
                //显示部门人数
                Text(`(${this.personList[index]} 人)`).fontSize(14)
              }
              .padding(12)
              .borderRadius(10)
              .backgroundColor(this.isSelectList[index] ? '#AFE1AF' : '#E6E6E6')
              .onClick(async () => {
                //重置isSelectList里面的值
                for (let index = 0; index < this.isSelectList.length; index++) {
                  this.isSelectList[index] = false
                }
                this.isSelectList[index] = true

                //分类查询每个部门的员工信息
                this.employeeList = await querySpecificalInfo(index, this.tableName)

              })

            })
          }
          .height('100%')

        }
        .width('100%')
        .height('12%')
        .scrollable(ScrollDirection.Horizontal)
        .scrollBar(BarState.Off)
        .align(Alignment.Start)

        Scroll() {
          Column({ space: 8 }) {
            if (this.employeeList.length == 0) {
              Text('暂无员工').fontSize(20).fontWeight(FontWeight.Bold)
            } else {
              ForEach(this.employeeList, (item: EmployeeListModel, index: number) => {
                EmployeeCard(item.employee, item.dname)
              })
            }
          }
          .width('100%')
        }
        .border({ width: { top: 1 }, color: { top: '#333333' } })
        .width('100%')
        .height('88%')
        .padding({ top: 8 })
        .align(Alignment.Top)

      }
      .width('100%')
      .height('82%')
      .padding(8)
      .backgroundColor('#F5F5F5')
    }
    .width('100%')
    .height('100%')
    .bindSheet($$this.isBindSheetShow, bindSheetViewBuilder(), { height: '50%' })
  }
}
2、自定义组件--半模态视图
复制代码
@Component
struct BindSheetView {
  @Consume('contentId') contentId: number

  build() {
    Column() {
      if (this.contentId == 1) {
        //====创建表视图====//
        CreatTable()
      }
      if (this.contentId == 2) {
        //====添加数据视图====//
        InsertDataView()
      }
      if (this.contentId == 3) {
        //====更新数据视图====//
        UpdateDataView()
      }
      if (this.contentId == 4) {
        //====删除表视图====//
        DeleteDataView()
      }

    }
    .width('100%')
    .height('100%')
  }
}

@Builder
export function bindSheetViewBuilder() {
  BindSheetView()
}
3、半模态视图--创建表视图
复制代码
//创建部门表的自定义组件
@Component
export struct CreatTable {
  @Consume('isBindSheetShow') isBindSheetShow: boolean //半模态窗口是否打开
  @State depOrEmp: boolean = false

  build() {
    Column() {
      if (!this.depOrEmp) {
        //创建部门表
        Text('创建部门表')
          .fontSize(20)
          .fontWeight(FontWeight.Medium)
          .padding({ top: 30, bottom: 40 })

        Text('确定')
          .fontSize(20)
          .padding({
            left: 20,
            right: 20,
            top: 8,
            bottom: 8
          })
          .backgroundColor('#89CFF0')
          .borderRadius(14)
          .onClick(() => {
            //创建一张表
            let creatTable: string =
              "create table  if not  exists  t_dept(did  integer primary key  autoincrement,dname text  not  null,count integer not null)"
            RdbUtils.executeSql(creatTable)
            //关闭半模态窗口
            this.isBindSheetShow = false
            promptAction.showToast({ message: '部门表创建成功' })
          })

        //切换至员工表
        Text('切换至员工表')
          .fontSize(20)
          .padding({
            left: 20,
            right: 20,
            top: 8,
            bottom: 8
          })
          .backgroundColor('#AFE1AF')
          .borderRadius(14)
          .margin({ top: 60 })
          .onClick(() => {
            this.depOrEmp = true
          })
      } else {

        //创建员工表
        Text('创建员工表')
          .fontSize(20)
          .fontWeight(FontWeight.Medium)
          .padding({ top: 30, bottom: 40 })

        Text('确定')
          .fontSize(20)
          .padding({
            left: 20,
            right: 20,
            top: 8,
            bottom: 8
          })
          .backgroundColor('#89CFF0')
          .borderRadius(14)
          .onClick(() => {
            //创建一张表
            let creatTable: string =
              "create table  if not  exists t_emp(eid  integer primary key  autoincrement,ename text  not  null, did  integer)"
            RdbUtils.executeSql(creatTable)
            //关闭半模态窗口
            this.isBindSheetShow = false
            promptAction.showToast({ message: '员工表创建成功' })
          })

        //切换至部门表
        Text('切换至部门表')
          .fontSize(20)
          .padding({
            left: 20,
            right: 20,
            top: 8,
            bottom: 8
          })
          .backgroundColor('#89CFF0')
          .borderRadius(14)
          .margin({ top: 60 })
          .onClick(() => {
            this.depOrEmp = false
          })

      }

    }
    .width('100%')
    .height('100%')
  }
}
4、半模态视图--添加数据视图
复制代码
@Component
export struct InsertDataView {
  //部门表的表名===双向绑定的
  @LocalStorageLink('tableName') tableName: string = 't_dept';
  @Consume('isBindSheetShow') isBindSheetShow: boolean //半模态窗口是否打开
  @State depOrEmp: boolean = false
  @State dname: string = '' //部门名称
  @State ename: string = '' //员工名称
  @State did: number = 0 //部门编号

  build() {
    Column() {
      if (!this.depOrEmp) {
        //===>向部门表中添加数据
        Text('部门表添加数据')
          .fontSize(20)
          .fontWeight(FontWeight.Medium)
          .padding({ top: 30, bottom: 40 })
        //添加的部门名称
        Row({ space: 12 }) {
          Text('部门名称').fontSize(16)
          TextInput({ placeholder: '请输入添加的部门名称', text: $$this.dname })
            .width('80%')
            .fontSize(16)
            .placeholderFont({ size: 16 })
        }.width('100%').padding({ left: 8, right: 8 })

        Text('确定')
          .fontSize(20)
          .padding({
            left: 20,
            right: 20,
            top: 8,
            bottom: 8
          })
          .backgroundColor('#89CFF0')
          .borderRadius(14)
          .margin({ top: 60 })
          .onClick(() => {
            let insertSql: string = `insert into ${this.tableName} (dname,count) values ('${this.dname}',0)`
            console.log('insertSql:' + insertSql)
            //执行sql语句
            RdbUtils.executeSql(insertSql)
            //关闭半模态窗口
            this.isBindSheetShow = false
            promptAction.showToast({ message: '数据已成功添加到部门表中' })
          })

        Text('切换至员工表')
          .fontSize(20)
          .padding({
            left: 20,
            right: 20,
            top: 8,
            bottom: 8
          })
          .backgroundColor('#AFE1AF')
          .borderRadius(14)
          .margin({ top: 60 })
          .onClick(() => {
            this.depOrEmp = true
          })
      } else {
        //===>向员工表中添加数据
        Text('员工表添加数据')
          .fontSize(20)
          .fontWeight(FontWeight.Medium)
          .padding({ top: 30, bottom: 40 })
        //添加的员工名称
        Row({ space: 12 }) {
          Text('员工名称').fontSize(16)
          TextInput({ placeholder: '请输入新员工的名称', text: $$this.ename })
            .width('80%')
            .fontSize(16)
            .placeholderFont({ size: 16 })
        }
        .width('100%')
        .padding({ left: 8, right: 8 })
        .margin({ bottom: 20 })

        //添加的员工所属的部门编号
        Row({ space: 12 }) {
          Text('部门编号').fontSize(16)
          TextInput({ placeholder: '请输入新员工的所属部门编号', text: $$this.did })
            .width('80%')
            .fontSize(16)
            .placeholderFont({ size: 16 })
        }.width('100%').padding({ left: 8, right: 8 })

        Text('确定')
          .fontSize(20)
          .padding({
            left: 20,
            right: 20,
            top: 8,
            bottom: 8
          })
          .backgroundColor('#89CFF0')
          .borderRadius(14)
          .margin({ top: 60 })
          .onClick(() => {
            let insertSql: string = `insert into t_emp (ename,did) values ('${this.ename}',${this.did})`
            console.log('insertSql:' + insertSql)
            //执行sql语句
            RdbUtils.executeSql(insertSql)
            //关闭半模态窗口
            this.isBindSheetShow = false
            promptAction.showToast({ message: '数据已成功添加到员工表中' })
          })

        Text('切换至部门表')
          .fontSize(20)
          .padding({
            left: 20,
            right: 20,
            top: 8,
            bottom: 8
          })
          .backgroundColor('#89CFF0')
          .borderRadius(14)
          .margin({ top: 36 })
          .onClick(() => {
            this.depOrEmp = false
          })

      }
    }
    .width('100%')
    .height('100%')
  }
}
5、半模态视图--更新数据的视图
复制代码
@Component
export struct UpdateDataView {
  //部门表的表名===双向绑定的
  @LocalStorageLink('tableName') tableName: string = 't_dept';
  @Consume('isBindSheetShow') isBindSheetShow: boolean //半模态窗口是否打开
  @State depOrEmp: boolean = false //判断更新的是哪一张表的内容
  @State dname: string = '' //旧的部门名称
  @State newDName: string = '' //新的部门名称
  @State eid: number = 0 //员工编号
  @State did: number = 0 //更新的部门编号

  build() {
    Column() {
      if (!this.depOrEmp) {
        //更新部门表中的数据
        Text('部门表更新数据')
          .fontSize(20)
          .fontWeight(FontWeight.Medium)
          .padding({ top: 30, bottom: 40 })
        //旧部门名称
        Row({ space: 12 }) {
          Text('旧部门名称').fontSize(16)
          TextInput({ placeholder: '请输入旧的部门名称', text: $$this.dname })
            .width('75%')
            .fontSize(16)
            .placeholderFont({ size: 16 })
        }
        .width('100%')
        .padding({ left: 8, right: 8 })
        .margin({ bottom: 20 })

        //输入新的部门名称
        Row({ space: 12 }) {
          Text('新部门名称').fontSize(16)
          TextInput({ placeholder: '请输入新的部门名称', text: $$this.newDName })
            .width('75%')
            .fontSize(16)
            .placeholderFont({ size: 16 })
        }
        .width('100%')
        .padding({ left: 8, right: 8 })


        Text('确定')
          .fontSize(20)
          .padding({
            left: 20,
            right: 20,
            top: 8,
            bottom: 8
          })
          .backgroundColor('#89CFF0')
          .borderRadius(14)
          .margin({ top: 60 })
          .onClick(() => {
            let updateSql: string =
              `update ${this.tableName} set dname = '${this.newDName}' where dname = '${this.dname}' `
            console.log('updateSql:' + updateSql)
            //执行sql语句
            RdbUtils.executeSql(updateSql)
            //关闭半模态窗口
            this.isBindSheetShow = false
            promptAction.showToast({ message: '部门表的数据更新成功' })
          })

        Text('切换至员工表')
          .fontSize(20)
          .padding({
            left: 20,
            right: 20,
            top: 8,
            bottom: 8
          })
          .backgroundColor('#AFE1AF')
          .borderRadius(14)
          .margin({ top: 36 })
          .onClick(() => {
            this.depOrEmp = true
          })
      } else {
        //更新员工表中的数据
        Text('员工表更新数据')
          .fontSize(20)
          .fontWeight(FontWeight.Medium)
          .padding({ top: 30, bottom: 40 })
        //需要更新的员工编号
        Row({ space: 12 }) {
          Text('员工编号').fontSize(16)
          TextInput({ placeholder: '请输入需要更新的员工编号', text: $$this.eid })
            .width('75%')
            .fontSize(16)
            .placeholderFont({ size: 16 })
        }
        .width('100%')
        .padding({ left: 8, right: 8 })
        .margin({ bottom: 20 })

        //输入新的部门编号
        Row({ space: 12 }) {
          Text('新部门编号').fontSize(16)
          TextInput({ placeholder: '请输入新的部门编号', text: $$this.did })
            .width('75%')
            .fontSize(16)
            .placeholderFont({ size: 16 })
        }
        .width('100%')
        .padding({ left: 8, right: 8 })

        Text('确定')
          .fontSize(20)
          .padding({
            left: 20,
            right: 20,
            top: 8,
            bottom: 8
          })
          .backgroundColor('#89CFF0')
          .borderRadius(14)
          .margin({ top: 60 })
          .onClick(() => {
            let updateSql: string = `update t_emp set did = ${this.did} where eid = ${this.eid} `
            console.log('updateSql:' + updateSql)
            //执行sql语句
            RdbUtils.executeSql(updateSql)
            //关闭半模态窗口
            this.isBindSheetShow = false
            promptAction.showToast({ message: '员工表的数据更新成功' })
          })

        Text('切换至部门表')
          .fontSize(20)
          .padding({
            left: 20,
            right: 20,
            top: 8,
            bottom: 8
          })
          .backgroundColor('#89CFF0')
          .borderRadius(14)
          .margin({ top: 36 })
          .onClick(() => {
            this.depOrEmp = false
          })
      }

    }
    .width('100%')
    .height('100%')
  }
}
6、半模态视图--删除表视图
复制代码
@Component
export struct DeleteDataView {
  //部门表的表名===双向绑定的
  @LocalStorageLink('tableName') tableName: string = 't_dept';
  @Consume('isBindSheetShow') isBindSheetShow: boolean //半模态窗口是否打开
  @State depOrEmp: boolean = false
  @State dname: string = '' //删除的部门名称
  @State eid: number = 0

  build() {
    Column() {
      if (!this.depOrEmp) {
        //删除部门表中的数据
        Text('部门表删除数据')
          .fontSize(20)
          .fontWeight(FontWeight.Medium)
          .padding({ top: 30, bottom: 40 })

        //输入删除的部门名称
        Row({ space: 12 }) {
          Text('部门名称').fontSize(16)
          TextInput({ placeholder: '请输入删除的部门名称' })
            .width('75%')
            .fontSize(16)
            .placeholderFont({ size: 16 })
            .onChange((value) => {
              this.dname = value
            })
        }
        .width('100%')
        .padding({ left: 8, right: 8 })

        Text('确定')
          .fontSize(20)
          .padding({
            left: 20,
            right: 20,
            top: 8,
            bottom: 8
          })
          .backgroundColor('#89CFF0')
          .borderRadius(14)
          .margin({ top: 60 })
          .onClick(async () => {
            //========>先把员工表里面的员工删除,在删除部门表里面的部门
            //查询部门的did值
            let did: number = 0
            let selectDeleteId: string = `select * from ${this.tableName} where dname = '${this.dname}'`
            console.log('selectDeleteId:' + selectDeleteId)
            let resultSet = await RdbUtils.executeQuerySql(selectDeleteId)
            if (resultSet.goToFirstRow()) {
              do {
                did = resultSet.getLong(resultSet.getColumnIndex('did'))
                console.log('did的值为:' + did)
                break
              } while (resultSet.goToNextRow())
            }
            resultSet.close()
            //删除语句===>删除员工表中该部门的员工
            let deleteEmpSql: string = `delete from t_emp where did = ${did}`
            await RdbUtils.executeSql(deleteEmpSql)
            console.log('deleteEmpSql:' + deleteEmpSql)

            //删除语句==>删除部门表中的部门名称
            let deleteSql: string = `delete from ${this.tableName} where dname = '${this.dname}'`
            console.log('旧表中的删除部门操作deleteSql:' + deleteSql)
            //执行删除sql语句
            await RdbUtils.executeSql(deleteSql)
            //===>更新表:目的实现部门表中的部门编号的连续自增长
            //实现两张表的切换:t_dept <===> t_dept1
            let newTableName = await creatAndUpdate(this.tableName)
            //重新设置表名
            this.tableName = newTableName
            console.log('进行删除操作之后,重置的表名为:' + this.tableName)
            //刷新磁盘,更新操作的客户表的表名
            PreferenceUtils.addData(getContext(), 'table', this.tableName)
            this.isBindSheetShow = false
            promptAction.showToast({ message: '部门表数据删除成功' })
          })

        Text('切换至员工表')
          .fontSize(20)
          .padding({
            left: 20,
            right: 20,
            top: 8,
            bottom: 8
          })
          .backgroundColor('#AFE1AF')
          .borderRadius(14)
          .margin({ top: 60 })
          .onClick(() => {
            this.depOrEmp = true
          })

      } else {
        //删除员工表中的数据
        Text('员工表删除数据')
          .fontSize(20)
          .fontWeight(FontWeight.Medium)
          .padding({ top: 30, bottom: 40 })
        //输入删除的员工编号
        Row({ space: 12 }) {
          Text('员工编号').fontSize(16)
          TextInput({ placeholder: '请输入删除的员工编号', text: $$this.eid })
            .width('75%')
            .fontSize(16)
            .placeholderFont({ size: 16 })
        }
        .width('100%')
        .padding({ left: 8, right: 8 })

        Button('确定')
          .fontSize(20)
          .padding({
            left: 20,
            right: 20,
            top: 8,
            bottom: 8
          })
          .backgroundColor('#89CFF0')
          .borderRadius(14)
          .margin({ top: 60 })
          .onClick(() => {
            //删除语句
            let deleteSql: string = `delete from t_emp where eid = ${this.eid}`
            console.log('deleteSql:' + deleteSql)
            //执行删除sql语句
            RdbUtils.executeSql(deleteSql)
            this.isBindSheetShow = false
            promptAction.showToast({ message: '员工表数据删除成功' })
          })

        Button('切换至部门表')
          .fontSize(20)
          .padding({
            left: 20,
            right: 20,
            top: 8,
            bottom: 8
          })
          .backgroundColor('#89CFF0')
          .borderRadius(14)
          .margin({ top: 60 })
          .onClick(() => {
            this.depOrEmp = false
          })

      }
    }
    .width('100%')
    .height('100%')

  }
}
7、自定义构建函数--构建员工卡片
复制代码
//自定义构建函数--构建员工卡片
@Builder
export function EmployeeCard(employee: EmployeeModel, dname: string) {
  Row() {
    //员工头像、员工姓名、员工编号
    Row({ space: 12 }) {
      Image(DepInfo.depHeadList[employee.depId])
        .size({ width: 64, height: 64 })
        .objectFit(ImageFit.Cover)
        .borderRadius(36)
      Column({ space: 8 }) {
        Text() {
          Span('姓名:')
          Span(employee.empName).fontWeight(FontWeight.Medium).fontColor(DepInfo.depColorList[employee.depId])
        }.fontSize(18)

        Text('编号:' + employee.empId.toString()).fontSize(16)
      }
      .alignItems(HorizontalAlign.Start)
      .height('100%')
      .justifyContent(FlexAlign.Center)
    }
    .width('74%')
    .height('100%')
    .padding(8)
    .justifyContent(FlexAlign.Start)
    .alignItems(VerticalAlign.Center)

    //部门编号、部门名称
    Column({ space: 14 }) {
      Text(employee.depId.toString()).fontSize(22)
      Text(dname).fontSize(24)
    }
    .width('26%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
    .backgroundColor(DepInfo.depColorList[employee.depId])
    .borderRadius({ topRight: 16, bottomRight: 16 })

  }
  .shadow({ radius: 16, color: '#DBDBDB', offsetX: 6, offsetY: 6 })
  .width('100%')
  .height(90)
  .borderRadius(16)
  .backgroundColor('#FFFFFF')
}
8、构建方法:按照分类查询指定信息、新部门表与旧部门表之间的切换
复制代码
//按照分类查询指定信息
export async function querySpecificalInfo(id: number, tableName: string): Promise<Array<EmployeeListModel>> {
  let resultList: Array<EmployeeListModel> = []
  let selectSql: string = 'select * from t_emp '
  if (id != 0) {
    //为查询语句添加条件
    selectSql += `where did = ${id}`
  }
  console.log('条件查询的sql语句为:' + selectSql)
  let resultSetEmp = await RdbUtils.executeQuerySql(selectSql)
  if (resultSetEmp.goToFirstRow()) {
    do {
      const employee: EmployeeModel = {
        empId: resultSetEmp.getLong(resultSetEmp.getColumnIndex('eid')), //获取员工编号
        empName: resultSetEmp.getString(resultSetEmp.getColumnIndex('ename')), //获取员工姓名
        depId: resultSetEmp.getLong(resultSetEmp.getColumnIndex('did')), //获取部门编号
      }
      //查询员工编号所对应的部门名称
      let selectDepInfo: string = `select * from ${tableName} where did = ${employee.depId}`
      let result = await RdbUtils.executeQuerySql(selectDepInfo)
      if (result.goToFirstRow()) {
        do {
          const dName: string = result.getString(result.getColumnIndex('dName')) //获取对应部门名称
          const employeeListModel: EmployeeListModel = {
            employee: employee,
            dname: dName
          }
          //将数据放进employeeList数组中
          resultList.push(employeeListModel)
        } while (result.goToNextRow())
      }
    } while (resultSetEmp.goToNextRow())
  }

  return resultList
}

//部门表有数据删除之后,新建一张表存储部门表中留下的数据
//将当前的表名作为参数,传入进来
export async function creatAndUpdate(lastTableName: string): Promise<string> {
  let newTableName: string = '' //新建部门表的表名
  //===>完成对新表名的赋值
  if (lastTableName == 't_dept') {
    newTableName = 't_dept1'
  } else {
    newTableName = 't_dept'
  }
  //===>创建新的部门表
  let creatSql: string =
    `create table  if not  exists  ${newTableName} (did  integer primary key  autoincrement,dname text  not  null,count integer not null)`
  console.log('creatSql:' + creatSql)
  await RdbUtils.executeSql(creatSql)
  console.log('部门表已新建成功,表名为:' + newTableName)
  //===>读取旧表里面的内容,写到新表里面
  //1、查旧表,创建数组存储内容
  let depList: LastDepTable[] = []
  let selectSql: string = `select * from ${lastTableName}` //查询旧表
  console.log('查询旧表的selectSql:' + selectSql)
  let resultSet = await RdbUtils.executeQuerySql(selectSql)
  if (resultSet.goToFirstRow()) {
    do {
      const lastDepTable: LastDepTable = {
        depName: resultSet.getString(resultSet.getColumnIndex('dname')),
        count: resultSet.getLong(resultSet.getColumnIndex('count'))
      }
      //将信息存入数组
      depList.push(lastDepTable)
    } while (resultSet.goToNextRow())
    for (let index = 0; index < depList.length; index++) {
      console.log('deplist数组中的每个元素为:' + depList[index].depName + depList[index].count)
    }
  }
  resultSet.close()
  //2、将数组里面的数据写入新表中: 添加数据操作
  for (let index = 0; index < depList.length; index++) {
    //将数组中的每一个元素写到新表中: 填写的数据有部门名称和部门人数
    let insertSql: string =
      `insert into ${newTableName} (dname,count) values ('${depList[index].depName}',${depList[index].count})`
    console.log('insertSql:' + insertSql)
    //执行sql语句:插入数据
    await RdbUtils.executeSql(insertSql)
  }

  //3、建立新表与员工表之间的联系:实质上是根据部门名称(dname)更新员工表里面的部门编号(did)这个字段
  //===>查新表和旧表
  let selectNewTable: string = `select * from ${newTableName}`
  console.log('selectNewTable:' + selectNewTable)
  let didlist: number[] = []
  let resultSetNew = await RdbUtils.executeQuerySql(selectNewTable)
  if (resultSetNew.goToFirstRow()) {
    do {
      let depName = resultSetNew.getString(resultSetNew.getColumnIndex('dname'))
      //根据depName查旧表,找到旧表里面的部门编号
      let selectLastTable: string = `select * from ${lastTableName} where dname = '${depName}'`
      console.log('3、selectLastTable:' + selectLastTable)
      let resultSetLast = await RdbUtils.executeQuerySql(selectLastTable)
      if (resultSetLast.goToFirstRow()) {
        do {
          let did = resultSetLast.getLong(resultSetLast.getColumnIndex('did')) //获取旧表的部门ID值
          didlist.push(did)
        } while (resultSetLast.goToNextRow())
        resultSetLast.close()
      }
    } while (resultSetNew.goToNextRow())
    resultSetNew.close()
  }
  console.log('didlist的长度为:' + didlist.length)
  //===> 更新员工表的部门编号
  for (let index = 0; index < didlist.length; index++) {
    let lastDepId = didlist[index] // 旧表里面的部门Id值
    let newDepId = index + 1
    let updateSql: string = `update t_emp set did = ${newDepId} where did = ${lastDepId} `
    console.log('更新员工表的updateSql:' + updateSql)
    RdbUtils.executeSql(updateSql)
  }

  //4、删除旧表
  let dropSql: string = `drop table ${lastTableName}`
  //执行删除sql语句
  RdbUtils.executeSql(dropSql)
  console.log('旧表' + lastTableName + '删除成功,' + 'dropSql:' + dropSql)

  //将新表名返回出去
  return newTableName
}
9、构建数据模型:部门、员工等。
复制代码
//部门数据模型
export interface DepartmentModel {
  depId: number //部门编号
  depName: string //部门名称
  count: number //部门员工数
}

//旧表查询的数据接口
export interface LastDepTable {
  depName: string //部门名称
  count: number //部门员工数
}

//员工数据模型
export interface EmployeeModel {
  empId: number //员工编号
  empName: string //员工姓名
  depId: number //所属部门编号
}

//员工列表模型
export interface EmployeeListModel {
  employee: EmployeeModel
  dname: string
}

//部门的颜色列表
export class DepInfo {
  //员工部门分类
  static depColorList: Array<string> = [
    '#E97451', '#E4D00A', '#50C878', '#C9CC3F',
    '#C4A484', '#87CEEB', '#FDDA0D', '#E5AA70'
  ]
  //员工头像列表
  static depHeadList: Array<Resource> = [
    $r('app.media.headImg'), $r('app.media.image2'), $r('app.media.image3'),
    $r('app.media.image4'), $r('app.media.image5'), $r('app.media.image6')
  ]
}
10、封装用户首选项的工具类,持久化数据--记住当前操作的部门表的表名
复制代码
//封装用户首选项工具类 ===> 持久化数据(记住当前操作的客户表的表名)
export class PreferenceUtils {
  //获取实例对象
  static creatPreference(context: Context, storeName: string) {
    const store = preferences.getPreferencesSync(context, { name: storeName })
    return store
  }

  //添加数据
  static async addData(context: Context, storeName: string, value: string) {
    //获取仓库对象
    const store = PreferenceUtils.creatPreference(context, storeName)
    //像仓库中添加数据
    await store.put('table', value)
    //刷新磁盘
    await store.flush()
  }

  //读取数据
  static getData(context: Context, storeName: string) {
    //获取仓库对象
    const store = PreferenceUtils.creatPreference(context, storeName)
    //读取数据
    const keyValue = store.getSync('table', 't_dept')
    return keyValue
  }
}
11、封装关系型数据库的工具类,方便操作关系型数据库
复制代码
//关系型数据库的工具类
export class RdbUtils {
  //创建数据库对象
  private static rdbStore: relationalStore.RdbStore

  //设置RdbStore
  static setStore(store: relationalStore.RdbStore) {
    RdbUtils.rdbStore = store
  }

  //获取操作数据库的对象
  static getStore(): relationalStore.RdbStore {
    return RdbUtils.rdbStore
  }

  //执行sql语句方法
  static executeSql(sql: string): Promise<void> {
    return RdbUtils.getStore().executeSql(sql)
  }

  //查询表格信息
  static executeQuerySql(sql: string): Promise<relationalStore.ResultSet> {
    return RdbUtils.getStore().querySql(sql)
  }
}

五、最终效果

相关推荐
2301_800256115 小时前
【第九章知识点总结3】9.4 Physical model 9.5 pgRouting
数据库
torpidcat5 小时前
bpm :flowable6 ruoyi-vue-pro 启用工作流时 启动报错:act_XXXX doesn‘t exist 未找到表 未自动生成表
数据库
杨超越luckly5 小时前
HTML应用指南:利用GET请求获取全国新东方门店位置信息
前端·数据库·arcgis·html·门店数据
TDengine (老段)5 小时前
TDengine 查询引擎设计与最佳实践
大数据·数据库·物联网·时序数据库·iot·tdengine·涛思数据
我命由我123455 小时前
Java 开发使用 MyBatis PostgreSQL 问题:使用了特殊字符而没有正确转义
java·开发语言·数据库·postgresql·java-ee·mybatis·学习方法
共享家95275 小时前
MySQL 数据类型
android·数据库·mysql
思成不止于此5 小时前
【MySQL 零基础入门】DQL 核心语法(三):学生表排序查询与分页查询篇
数据库·笔记·学习·mysql
听风吟丶5 小时前
微服务调用链追踪实战:用 SkyWalking 实现全链路可视化与故障溯源
数据库
汉堡黄•᷄ࡇ•᷅5 小时前
鸿蒙开发:案例集合List:多列表相互拖拽(删除/插入,偏移动效)(微暇)
华为·harmonyos·鸿蒙·鸿蒙系统