Web开发学习笔记:Ionic4与SQLite数据库交互

以下代码使用IDE:vscode; 语言模式:TypeScript

1.使用命令创建一个service

ionic g service DBManager

创建成功后目录中会有两个文件

2.在app.module.ts中添加对DBManagerService类的引用同时在providers中添加DBManagerService类

Web开发学习笔记:Ionic4与SQLite数据库交互_第1张图片

 

3.在DBManagerService类中编写对应的代码

3.1 在constructor中使用win.openDatabase方法连接或创建数据库

this.dataBase = this.win.openDatabase('bookkeeping.db', '1.0', 'bookkeepingDB', 5 * 1024 * 1024);

其中dataBase与win均为定义的类中全局变量

public dataBase: any;
private win: any = window;

注:

第一次使用win.openDatabase时如果数据库不存在会自动创建,保存的路径个浏览器不同使用QQ浏览器的话位置应该为:C:\Users\Administrator\AppData\Local\Tencent\QQBrowser\User Data\Default\databases\http_localhost_8100,我的电脑该路径下有一个24的文件,使用Navicat Premium打开就是创建的数据库

3.2创建数据库中数据表的初始化方法

 // 创建数据库
  CreateDataBase() {
    const createSql = ' CREATE TABLE IF NOT EXISTS money_useinfo( ' +
      ' REC_CREATEOR TEXT ' +
      ',REC_CREATE_TIME TEXT ' +
      ',REC_MODIFIER TEXT' +
      ',REC_MODIFY_TIME TEXT' +
      ',SEQ_NO INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL DEFAULT 0 ' +
      ',MONEY_USE_TIME TEXT' +
      ',MONEY_UST_TYPE TEXT' +
      ',AMOUNT INTEGER' +
      ',MONEY_USE_DESC TEXT' +
      ',BACK1 TEXT' +
      ',BACK2 TEXT' +
      ',BACK3 TEXT' +
      ',BACK4 TEXT' +
      ',BACK5 TEXT' +
      ',BACK6 TEXT' +
      ',BACK7 TEXT' +
      ',BACK8 TEXT' +
      ',BACK9 TEXT' +
      ',BACK10 TEXT' +
      ')';
    this.dataBase.transaction((tx) => {
      // 建表
      tx.executeSql(createSql);
    }, (error) => {// 失败回调
      console.log('Transaction ERROR: ' + error.message);
    }, () => {// 成功回调
      console.log('数据库创建成功');
    });
    // this.sqlitePorter.importSqlToDb(this.dataBase, createSql);
    // console.log('创建表');
    // this.sqlite.create({
    //   name: 'bookkeeping.db',
    //   location: 'default'
    // }).then((db: SQLiteObject) => {
    //   const createSql = 'CREATE TABLE Artist ([Id] PRIMARY KEY, [Title]);';
    //   db.executeSql(createSql).then(res => console.log('Imported')).catch(e => console.error(e));
    //   // this.sqlitePorter.importSqlToDb(db, createSql)
    //   //   .then(() => console.log('Imported'))
    //   //   .catch(e => console.error(e));
    //   console.log('数据库创建成功');
    // });
  }

 

3.3创建查询方法(中间使用了Promise(是一個表示非同步運算的最終完成或失敗的物件))

/**
   * 数据表数据查询
   * @param tableName 类型:string 查询数据的数据表名称
   * @param sqlParam 类型:Array 拼接SQLWHERE条件语句需要的参数信息
   * @param selectCol 类型:string 查询结果列(可选参数,参数如果不传值则默认为 * )
   */
  SelectData(tableName: string, sqlParam: Array, selectCol?: string): Promise {
    let promise = new Promise((resolve, reject) => {
      this.dataBase.transaction((tx) => {
        let selectSql = ' SELECT ';
        let sqlWhere = ' WHERE 1=1 ';
        sqlParam.forEach(item => {
          if (isNumber(item.colValue)) { // 判断值是否为数值类型
            sqlWhere += ' AND ' + item.colName + '=' + item.colValue;
          } else if (isString(item.colValue)) { // 判断值是否为字符类型
            sqlWhere += ' AND ' + item.colName + '=\'' + item.colValue + '\'';
          }
        });
        // console.log('selectCol参数值: ' + selectCol);
        if (selectCol === undefined) {
          selectCol = '*';
        }
        selectSql += selectCol + ' FROM ' + tableName + sqlWhere;
        // console.log('查询SQL: ' + selectSql);
        // 执行SQL并返回结果
        tx.executeSql(selectSql, [], (tx, result) => {// 成功回调
          // this.QueryData = TableStructureInfo.MerageFrom(result, tableName); // 将查询结果转为数组
          resolve({tx: tx, res: result });
        }, (error) => {// 失败回调
          reject({tx: tx, err: error});
          console.log('数据库操作失败: ' + error.message);
        });
      });
    });
    return promise;
  }

查询方法调用

// 调用查询方法
      this.dbManagerService.SelectData('money_useinfo', this.globalVariable.sqlParamInfo)
      .then((success) => {
        this.QueryData = success.res.rows; // 将结果中的数据赋值给QueryData对象,在前端可以直接使用ngfor访问QueryData
        console.log('当前查询返回结果:', this.QueryData);
        // return this.QueryData;
      }, (error) => {
        console.log(error);
      });

查询结果的使用:


     
     {{item.MONEY_USE_TIME}}   
     {{item.MONEY_UST_TYPE}}   
     {{item.AMOUNT}}   
     {{item.MONEY_USE_DESC}}   
  
  

注:

Promise相关连接:

https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Guide/Using_promises

https://www.cnblogs.com/brookshi/p/6422353.html

3.4创建数据新增方法

  /**
   * 数据表新增数据
   * @param tableName 类型:string 新增数据的数据表名称
   * @param sqlParam 类型:Array 拼接SQL语句需要的参数信息
   */
  InsertData(tableName: string, sqlParam: Array) {
    this.dataBase.transaction((tx) => {
      let insertSql = ' INSERT INTO ' + tableName;
      let sqlCols = '';
      let sqlColsValue = '';
      sqlParam.forEach(item => {
        if (sqlCols !== '') {
          sqlCols += ',' + item.colName;
        } else {
          sqlCols += item.colName;
        }
        if (sqlColsValue !== '') {
          if (isNumber(item.colValue)) { // 判断值是否为数值类型
            sqlColsValue += ',' + item.colValue;
          } else if (isString(item.colValue)) { // 判断值是否为字符类型
            sqlColsValue += ',\'' + item.colValue + '\'';
          }
        } else {
          if (isNumber(item.colValue)) { // 判断值是否为数值类型
            sqlColsValue += item.colValue;
          } else if (isString(item.colValue)) { // 判断值是否为字符类型
            sqlColsValue += '\'' + item.colValue + '\'';
          }
        }
      });

      insertSql += ' (' + sqlCols + ') ' + 'values(' + sqlColsValue + ')';
      console.log('新增SQL: ' + insertSql);
      tx.executeSql(insertSql);
    }, (error) => {// 失败回调
      console.log('数据库操作失败: ' + error.message);
    }, () => {// 成功回调
      console.log('新增成功');
    });
  }

新增方法调用

this.dbManagerService.InsertData('money_useinfo', this.globalVariable.sqlParamInfo);

以上查询、新增方法只适合使用ionic serve 命令 在浏览器上启动的服务

以下修改、删除方法适用于真机测试/浏览器调试

3.5创建修改方法

/**
   * 数据删除
   * @param tableName  删除数据的数据表名称
   * @param sqlPrimaryDateParam 主键数据,元素格式[{colName: colName,colValue: colValue}]
   * @param sqlUpdateDataParam  修改数据,元素格式[{colName: colName,colValue: colValue}]
   */
  UpdateData(tableName: string, sqlPrimaryDateParam: Array, sqlUpdateDataParam: Array): number {
    // tslint:disable-next-line: prefer-const
    let resultFlag = 0;
    // tslint:disable-next-line: prefer-const
    let updSql = ' UPDATE ' + tableName + ' SET ';
    // tslint:disable-next-line: variable-name
    let updSql_where = ' WHERE 1=1 ';
    // tslint:disable-next-line: variable-name
    let updSql_set = ' ';
    let count = 0;

    // console.log('修改数据信息:', sqlUpdateDataParam);
    // 拼接SET语句
    sqlUpdateDataParam.forEach(colInfo => {
      // console.log('当前信息:', colInfo);
      if (count === 0 && count === sqlUpdateDataParam.length - 1 ) {
        if (isString(colInfo.colValue)) {
          updSql_set = colInfo.colName + '=\'' + colInfo.colValue + '\'';
        } else if (isNumber(colInfo.colValue)) {
          updSql_set = colInfo.colName + '=' + colInfo.colValue;
        }
      } else if (count < sqlUpdateDataParam.length - 1 )  {
        if (isString(colInfo.colValue)) {
          updSql_set += colInfo.colName + '=\'' + colInfo.colValue + '\',';
        } else if (isNumber(colInfo.colValue)) {
          updSql_set += colInfo.colName + '=' + colInfo.colValue + ',';
        }
      } else if (count !== 0 && count === sqlUpdateDataParam.length - 1) {
        if (isString(colInfo.colValue)) {
          updSql_set += colInfo.colName + '=\'' + colInfo.colValue + '\'';
        } else if (isNumber(colInfo.colValue)) {
          updSql_set += colInfo.colName + '=' + colInfo.colValue;
        }
      }
      count++;
    });

    // 拼接WHERE条件语句
    sqlPrimaryDateParam.forEach(colInfo => {
      if (isString(colInfo.colValue)) {
        updSql_where += ' AND ' +  colInfo.colName + '=\'' + colInfo.colValue + '\'';
      } else if (isNumber(colInfo.colValue)) {
        updSql_where += ' AND ' +  colInfo.colName + '=' + colInfo.colValue ;
      }
    });
    updSql += updSql_set + updSql_where;
    // console.log('修改SQL:', updSql);
    if (this.win.sqlitePlugin) {
      // this.sqlitePorter.importSqlToDb(this.dataBase, insertSql);
      this.sqlite.create({
        name: 'bookkeeping.db',
        location: 'default'
      }).then((db: SQLiteObject) => {
        this.sqlitePorter.importSqlToDb(db, updSql);
        const toast = this.toastController.create({
          message: '修改成功',
          duration: 3000, // 3秒后自动消失
          position: 'middle', // 位置
          showCloseButton: true,
          closeButtonText: '关闭'
        });
        toast.then((ok) => {
          ok.present(); //  符合触发条件后立即执行显示
        });
      }, (err) => {
        console.log('修改失败:', err);
        const toast = this.toastController.create({
          message: '修改失败!',
          duration: 3000, // 3秒后自动消失
          position: 'middle', // 位置
          showCloseButton: true,
          closeButtonText: '关闭'
        });
        toast.then((ok) => {
          ok.present();
        });
        resultFlag = -1;
      });
    } else {
      this.dataBase.transaction((tx) => {
        tx.executeSql(updSql);
      }, (error) => {// 失败回调
        console.log('修改失败:', error);
        const toast = this.toastController.create({
          message: '修改失败',
          duration: 3000, // 3秒后自动消失
          position: 'middle', // 位置
          showCloseButton: true,
          closeButtonText: '关闭'
        });
        toast.then((ok) => {
          ok.present();
        });
        resultFlag = -1;
      }, () => {// 成功回调
        const toast = this.toastController.create({
          message: '修改成功',
          duration: 3000, // 3秒后自动消失
          position: 'middle', // 位置
          showCloseButton: true,
          closeButtonText: '关闭'
        });
        toast.then((ok) => {
          ok.present();
        });
      });
    }
    return resultFlag;
  }

修改方法调用

SubmitData(data: any) {
    try {
      // 修改数据信息
      const AccountDate = new Date(data.AccountDate);
      data.AccountDate = AccountDate.toLocaleDateString();
      this.globalVariable.sqlParamInfo = []; // 重置
      this.globalVariable.sqlParamInfo.push({ colName: 'MONEY_USE_TIME', colValue: data.AccountDate });
      this.globalVariable.sqlParamInfo.push({ colName: 'MONEY_UST_TYPE', colValue: data.UseType });
      this.globalVariable.sqlParamInfo.push({ colName: 'AMOUNT', colValue: data.Amount });
      this.globalVariable.sqlParamInfo.push({ colName: 'MONEY_USE_DESC', colValue: data.Remark });


      // 修改数据WHERE条件信息
      this.sqlPrimaryDateParam.push({ colName: 'SEQ_NO', colValue: this.newData.SEQ_NO });
      // console.log('当前按钮点击类型:', this.operationType);
        this.globalVariable.sqlParamInfo.push({ colName: 'REC_MODIFIER', colValue: 'PaladinXu' });
        this.globalVariable.sqlParamInfo.push({ colName: 'REC_MODIFY_TIME', colValue: new Date().toLocaleString() });
        const resultFlag = this.dbManagerService.UpdateData('money_useinfo', this.sqlPrimaryDateParam, this.globalVariable.sqlParamInfo);
    } catch (error) {
      console.log('错误信息:', error);
    }
  }

 

3.6创建删除方法

  /**
   * 数据删除
   * @param tableName  删除数据的数据表名称
   * @param sqlPrimaryParam 删除数据的主键
   * @param sqlDataParam  对应主键的数据
   */
  DeleteData(tableName: string, sqlPrimaryParam: Array, sqlDataParam: Array): number {
    let resultFlag = 0;
    let delSql = ' DELETE FROM ' + tableName;
    // tslint:disable-next-line: variable-name
    let delSql_where = ' WHERE 1=1 ';
    // tslint:disable-next-line: variable-name
    let condition_in = ' IN (';
    // tslint:disable-next-line: variable-name
    let condition_in_data = ' ';
    if (sqlPrimaryParam.length > 0) {
      sqlPrimaryParam.forEach(item => {
        // console.log('当前主键:', item);
        if (sqlDataParam.length === 1) {
          // console.log('当前主键对应值:', sqlDataParam[0][item]);
          if (isString(sqlDataParam[0][item])) {
            delSql_where += ' AND ' + item + '=\'' + sqlDataParam[0][item] + '\'';
          } else if (isNumber(sqlDataParam[0][item])) {
            delSql_where += ' AND ' + item + '=' + sqlDataParam[0][item] + '';
          } else if (isArray(sqlDataParam[0][item])) {
            let index = 0;
            if (sqlDataParam[0][item].length > 0) {
              sqlDataParam[0][item].forEach(element => {
                if (index < sqlDataParam[0][item].length - 1) {
                  if (isString(element)) {
                    condition_in_data += ' \' ' + element + '\',';
                  } else if (isNumber(element)) {
                    condition_in_data += element + ',';
                  }
                } else {
                  if (isString(element)) {
                    condition_in_data += ' \' ' + element + '\'';
                  } else if (isNumber(element)) {
                    condition_in_data += element + ')';
                  }
                }
                index++;
              });
              condition_in = ' AND ' + item + condition_in + condition_in_data;
            }
            if (condition_in_data !== '') {
              delSql += delSql_where + condition_in;
            } else {
              delSql += delSql_where;
            }
          }
        } else {
          const toast = this.toastController.create({
            message: '删除条件对应值为空或个数过多,不允许删除',
            duration: 3000, // 3秒后自动消失
            position: 'middle', // 位置
            showCloseButton: true,
            closeButtonText: '关闭'
          });
          toast.then((ok) => {
            ok.present(); //  符合触发条件后立即执行显示
          });
          resultFlag = -1;
          return resultFlag;
        }
      });
    }
    console.log('删除SQL:', delSql);
    if (this.win.sqlitePlugin) {
      // this.sqlitePorter.importSqlToDb(this.dataBase, insertSql);
      this.sqlite.create({
        name: 'bookkeeping.db',
        location: 'default'
      }).then((db: SQLiteObject) => {
        this.sqlitePorter.importSqlToDb(db, delSql);
        const toast = this.toastController.create({
          message: '删除成功',
          duration: 3000, // 3秒后自动消失
          position: 'middle', // 位置
          showCloseButton: true,
          closeButtonText: '关闭'
        });
        toast.then((ok) => {
          ok.present(); //  符合触发条件后立即执行显示
        });
      }, (err) => {
        const toast = this.toastController.create({
          message: err,
          duration: 3000, // 3秒后自动消失
          position: 'middle', // 位置
          showCloseButton: true,
          closeButtonText: '关闭'
        });
        toast.then((ok) => {
          ok.present();
        });
        resultFlag = -1;
      });
    } else {
      this.dataBase.transaction((tx) => {
        tx.executeSql(delSql);
      }, (error) => {// 失败回调
        const toast = this.toastController.create({
          message: error,
          duration: 3000, // 3秒后自动消失
          position: 'middle', // 位置
          showCloseButton: true,
          closeButtonText: '关闭'
        });
        toast.then((ok) => {
          ok.present();
        });
        resultFlag = -1;
      }, () => {// 成功回调
        const toast = this.toastController.create({
          message: '删除成功',
          duration: 3000, // 3秒后自动消失
          position: 'middle', // 位置
          showCloseButton: true,
          closeButtonText: '关闭'
        });
        toast.then((ok) => {
          ok.present();
        });
      });
    }
    return resultFlag;
  }

调用删除方法

// 提交按钮点击form触发ngSubmit
  deleteData(data: string) {
    if (this.SEQ_NO_CHECKBOX.length > 0) {
      this.globalVariable.sqlParamInfo = []; // 重置
      this.globalVariable.sqlParamInfo.push({ SEQ_NO: this.SEQ_NO_CHECKBOX });
      // console.log('主键信息:', this.globalVariable.sqlParamInfo);

      const resultFlag = this.dbManagerService.DeleteData('money_useinfo', ['SEQ_NO'], this.globalVariable.sqlParamInfo);
      if (resultFlag === 0) {
        this.cancelBtnClick();
        this.selectData(this.SELECT_CONDITIONS);
      }
    } else {
      const toast = this.toastController.create({
        message: '请选择要删除的记录!',
        duration: 3000, // 3秒后自动消失
        position: 'middle', // 位置
        showCloseButton: true,
        closeButtonText: '关闭'
      });
      toast.then((ok) => {
        ok.present(); //  符合触发条件后立即执行显示
      });
    }
  }

以上代码可能有很多冗余或者是写的麻烦了,只是与大家用于交流学习,大家可能有更好的思路或者方法可以留言交流

你可能感兴趣的:(Web开发学习笔记)