IndexedDB的包装器JsStore - insert插入参数配置

news2024/11/26 10:20:59

        JsStore是IndexedDB的包装器。它提供了简单的SQL,如api,易于学习和使用。IndexedDb查询可以在web worker中执行,JsStore通过提供一个单独的worker文件来保留这个功能。

        Insert API用于在表中插入新记录,还可以为未在db模式中定义的列插入数据。JsStore保留了IndexedDb的NoSql功能。

insert API参数配置:

属性描述

into

用于指定表的名称

values

用于指定要插入的数据。它接受一个数据数组。

return

是一个可选的&类型的布尔字段。它用于获取插入的数据。

upsert

如果存在则更新数据,否则插入。默认值为false。

validation

是否验证数据。缺省值为true。这可以用来加速插入查询。

skipDataCheck

不要检查或更改数据中的任何内容。缺省值为false。

如果提供true,这将直接插入数据,而不检查任何东西,如数据类型,自动增量等。这在你想要一次插入大量记录并且对模式没有任何约束的情况下是有用的。

ignore

发生错误时忽略记录。当您从用户或任何来源接收一些随机数据时。

一、搭建Demo

        首先还是搭建一个学生列表演示Demo,用来获取学生列表及新增功能页面。

1.1 安装

vue-cli全局安装

npm install -g vue-cli

初始化项目

vue init webpack example

其他插件就不细讲了,可以查看:https://blog.csdn.net/jiciqiang/article/details/115792838目录一、vue安装二、sass安装三、vuex安装四、vue-devtolls安装五、vue-ls安装一、vue安装1.vue-cli全局安装npm install -g vue-cli2.初始化项目vue init webpack projectName3.运行项目注:npm中-g, -d, -s区别1.-g 全局安装,全称--global2.-s 安装到dependencies中,用于生产环境,即--save3.-d 安装到devD.https://blog.csdn.net/jiciqiang/article/details/115792838

1.2 页面创建

        在src/pages/index目录中创建index.vue,代码如下:

<template>
  <div class="jsstore-insert-wrap">
    <el-form :inline="true" class="demo-form-inline">
      <el-form-item label="姓名">
        <el-input size="small" v-model="formData.name" placeholder="请输入姓名"></el-input>
      </el-form-item>
      <el-form-item label="年级">
        <el-input size="small" v-model="formData.grade" placeholder="请输入年级"></el-input>
      </el-form-item>
      <el-form-item label="地址">
        <el-input size="small" v-model="formData.address" placeholder="请输入地址"></el-input>
      </el-form-item>
      <el-form-item label="生日">
        <el-date-picker
            size="small"
            v-model="formData.birthday"
            type="date"
            placeholder="选择生日">
          </el-date-picker>
      </el-form-item>
      <el-form-item>
        <el-button size="small" type="primary">新增</el-button>
      </el-form-item>
    </el-form>

    <el-table :data="tableData" style="width: 100%">
      <el-table-column prop="name" label="姓名"></el-table-column>
      <el-table-column prop="grade" label="年级"></el-table-column>
      <el-table-column prop="address" label="地址"></el-table-column>
      <el-table-column prop="birthday" label="生日"></el-table-column>
    </el-table>
  </div>
</template>

<script>
  export default {
    data(){
      return {
        formData: {
          name: "",
          grade: "",
          address: "",
          birthday: ""
        },
        tableData: []
      }
    },
    created() {
      this.updateList();
    },
    methods: {
      /**
       * 获取学生列表
       */
      updateList(){
        
      },
      //end
    }
  }
</script>

<style lang="scss">
@import './index.scss';
</style>

        在src/router/index.js中,添加路由,代码如下:

import Vue from 'vue'
import Router from 'vue-router'
import Index from '@/pages/index'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'Index',
      component: Index
    }
  ]
})

        此时页面效果如下:

        

二、初始化数据结构

        页面基本结构完成后,现在开始创建数据表结构。首先,在src下创建db目录,新建db/db.js用于实例并连接数据库,新建db/service.js用于定义表结果和表结构初始化。

db.js代码如下:

import { Connection } from "jsstore";
import workerInjector from "jsstore/dist/worker_injector";

let connection = new Connection();
connection.addPlugin(workerInjector);

export default connection;

service.js代码如下:

import connection from './db.js';
import { DATA_TYPE } from "jsstore";

export const DATA_TABLE_NAME = {
	STUDENT: "Student",
}

/**
 * 实例化数据表
 */
const getDatabase = () => {
	//学生表
	const tbStudent = {
		name: DATA_TABLE_NAME.STUDENT,
		columns: {
			id: { primaryKey: true, autoIncrement: true },
			name: { notNull: true, dataType: DATA_TYPE.String },
			grade: { notNull: true, dataType: DATA_TYPE.String },
			birthday: { notNull: true, dataType: DATA_TYPE.DateTime },
			address: { notNull: false, dataType: DATA_TYPE.String },
			createtime: { notNull: true, dataType: DATA_TYPE.DateTime },
			updatetime: { notNull: true, dataType: DATA_TYPE.DateTime },
		}
	}

	const dataBase = {
			name: "DemoTestSystem",
			tables: [tbStudent],
			version: 1
	};
	return dataBase;
}

/**
 * 初始化数据库
 */
export const initJsStore = async () => {
	const dataBase = await getDatabase();
	return await connection.initDb(dataBase);
}

        此时在App.vue中,初始化数据表,如果表已存在,则不会再次创建。代码如下:

import { initJsStore } from '@/db/service.js'
export default {
  name: 'App',
  data(){
    return {
      
    }
  },
  async beforeCreate(){
    try {
    	const isDbCreated = await initJsStore();
    	if (isDbCreated) {
    		console.log("db created");
    	} else {
    		console.log("db opened");
    	}
    } catch (ex) {
    	this.$message.error(ex.message);
    }
  }
}

        当执行npm run dev运行项目后,F12打开控制台,切换到Application项中查看IndexedDB,会发现定义的表已创建,如下图:

         

三、查询数据列表

        这次我们先将列表数据查询功能完成,在src/db目录下,再创建一个model目录,用于存储student.js数据表操作文件。代码如下:

/**
 * 学生表
 */
import connection from '@/db/db.js'
import { DATA_TABLE_NAME } from '@/db/service.js'

class StudentService {
	constructor(){
		this.tableName = DATA_TABLE_NAME.STUDENT;
	}

  /**
   * 获取学生数据列表
   */
  selectData(){
    return connection.select({
      from: this.tableName
    })
  }

}

export const Student = new StudentService();

        上面已将查询数据列表的selectData()函数定义好了,我们可以在pages/index/index.vue页面中调用了,代码如下:

  import { Student } from '@/db/model/student'
  export default {
    data(){
      return {
        formData: {
          name: "",
          grade: "",
          address: "",
          birthday: ""
        },
        tableData: []
      }
    },
    created() {
      this.updateList();
    },
    methods: {
      /**
       * 获取学生列表
       */
      updateList(){
        Student.selectData().then(res => {
          this.tableData = res;
        })
      },
      //end
    }
  }

        以上步骤完成后,页面还是没有任何数据,这是我们还没有插入数据。

四、参数用法

        Insert API以下选项,在不同情况下,可以使用对应属性得到自己想要的结果。

4.1 基本用法

        先使用 intovalues 属性完成数据插入操作,在StudentService类中,创建insertData()函数,代码如下:

class StudentService {
	constructor(){
		this.tableName = DATA_TABLE_NAME.STUDENT;
	}

  /**
   * 获取学生数据列表
   */
  selectData(){
    return connection.select({
      from: this.tableName
    })
  }

  /**
   * 执行数据
   * @param {Object} data
   */
  insertData(data){

    //添加记录时间
    if('undefined'!==typeof data['id']){
      Object.assign(data, {
        updatetime: new Date()
      })
    }else{
      Object.assign(data, {
        createtime: new Date(),
        updatetime: new Date()
      })
    }

    return connection.insert({
      into: this.tableName,
      values: [data]
    });
  }

}

        在页面中新增按钮添加点击事件,完成数据提交操作,代码如下:

<el-form-item>
    <el-button size="small" type="primary" @click="submitEvent">新增</el-button>
</el-form-item>

        methods中添加submitEvent()事件,当执行数据成功后,重新获取列表数据,调用updateList()函数,代码如下:

methods: {
  /**
   * 提交数据
   */
  submitEvent(e){
	Student.insertData(this.formData).then(res => {
	  console.log('success', res);

	  this.updateList();
	});
  },
  /**
   * 获取学生列表
   */
  updateList(){
	Student.selectData().then(res => {
	  this.tableData = res;
	})
  },
  //end
}

        写用这里,我们可以在页面填入学生信息,进行数据插入操作了。如下图操作,点击新增保存学生信息,则Student表中则执行一条数据,控制台也返回success 1,即成功执行1条数据。

4.2 显示生日

        在上面操作中,发现生日并未显示出来,这是存储的生日数据类型为Date,此时我们需要将其转化成字符串进行显示。

table中稍作修改,为其添加formatDate过滤器,代码如下:

<el-table :data="tableData" style="width: 100%">
  <el-table-column prop="name" label="姓名"></el-table-column>
  <el-table-column prop="grade" label="年级"></el-table-column>
  <el-table-column prop="address" label="地址"></el-table-column>
  <el-table-column prop="birthday" label="生日">
	<template slot-scope="scope">
	  <span>{{scope.row.birthday | formateDate}}</span>
	</template>
  </el-table-column>
</el-table>

定义formateDate过滤函数,代码如下:

export default {
	data(){
	  return {
		formData: {
		  name: "",
		  grade: "",
		  address: "",
		  birthday: ""
		},
		tableData: []
	  }
	},
	filters: {
	  //格式化日期
	  formateDate(val){
		return (date => {
		  return `${date.getFullYear()}-${date.getMonth()+1}-${date.getDate()}`;
		})(new Date(val));
	  }
	},
	
	
	//略...
}

        此时页面中生日则显示出来了,如下图:

4.3 返回新增数据

        在上面操作中会发现,不借助其他属性情况下,插入新数据成功后,只会返回执行成功几条数据,并不会返回新增数据结果。这在有些情况下,程序需要知道新插入数据生成的id等相关数据,此时我们只要insert中添加 return属性即可。代码如下:

insertData(data){
	//添加记录时间
	if('undefined'!==typeof data['id']){
	  Object.assign(data, {
		updatetime: new Date()
	  })
	}else{
	  Object.assign(data, {
		createtime: new Date(),
		updatetime: new Date()
	  })
	}

	return connection.insert({
	  into: this.tableName,
	  values: [data],
	  return: true
	});
}

        此时再添加一条数据,控制台返回了插入成功的数据,并带回了递增的ID值,结果如下:

4.4 覆盖存在数据

        首先我们先将src/pages/index/index.vue文件进行改造下,让其能进行编辑操作,代码如下:

<template>
  <div class="jsstore-insert-wrap">
    <el-form :inline="true" class="demo-form-inline">
      
	  //略...
	  
      <el-form-item>
        <el-button size="small" type="primary" @click="submitEvent">{{!formData.id||formData.id==0?'新增':'保存'}}</el-button>
        <el-button size="small" type="info" @click="cancelEvent" v-if="formData.id&&formData.id>0">取消编辑</el-button>
      </el-form-item>
    </el-form>

    <el-table :data="tableData" style="width: 100%">
      
	  //略...
	  
      <el-table-column label="操作">
        <template slot-scope="scope">
          <el-button type="primary" size="small" icon="el-icon-edit" circle @click="editEvent(scope.row)"></el-button>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

<script>
  import { Student } from '@/db/model/student'
  export default {
    data(){
      return {
        formData: {
          name: "",
          grade: "",
          address: "",
          birthday: ""
        },
        tableData: []
      }
    },
    
	//略...
	
    methods: {
      /**
       * 提交数据
       */
      submitEvent(e){
        Student.insertData(this.formData).then(res => {
          console.log('success', res);

          this.updateList();
        });
      },
      /**
       * 编辑事件
       */
      editEvent(data){
        this.formData = data;
      },
      cancelEvent(){
        this.formData = {
          name: "",
          grade: "",
          address: "",
          birthday: ""
        }
      },
      /**
       * 获取学生列表
       */
      updateList(){
        Student.selectData().then(res => {
          this.tableData = res;
        })
      },
      //end
    }
  }
</script>

        此时,我们点击编辑按钮,修改内容中生日进行保存操作,会报”Key already exists in the object store.“错误,这是因为编辑保存时,里面带入了id自递值已存在。所以这时需要设置upsert,将其置为true表示覆盖原数据。如下图:

         我们将insert中添加upsert,则可以正常保存数据了。代码如下:

  insertData(data){

    //添加记录时间
    if('undefined'!==typeof data['id']){
      Object.assign(data, {
        updatetime: new Date()
      })
    }else{
      Object.assign(data, {
        createtime: new Date(),
        updatetime: new Date()
      })
    }

    return connection.insert({
      into: this.tableName,
      values: [data],
      return: true,
      upsert: true
    });
  }

        此时修改数据保存后,则不会报错了。页面效果如下:

         当然,编辑操作,建议使用update API进行处理,这里只是演示下,通过insert也可以完成编辑操作。

4.5 验证数据

        validation是否验证数据。缺省值为true。这可以用来加速插入查询。当validation为false时,它只检查和更新:autoincrement和默认值。

当validation默认为true时,我们在填写信息时,将生日漏填,直接点击保存,则控制台会报”Supplied value for column 'birthday' have wrong data type“错误。

         我们将validation设置为false,代码如下:

  insertData(data){

    //添加记录时间
    if('undefined'!==typeof data['id']){
      Object.assign(data, {
        updatetime: new Date()
      })
    }else{
      Object.assign(data, {
        createtime: new Date(),
        updatetime: new Date()
      })
    }

    return connection.insert({
      into: this.tableName,
      values: [data],
      return: true,
      upsert: true,
      validation: false
    });
  }

        此时生日信息不填写,点击保存则不会再报错了。效果如下图:

4.6 跳过数据检查

        不要检查或更改数据中的任何内容。缺省值为false。如果提供true,这将直接插入数据,而不检查任何东西,如数据类型,自动增量等。这在你想要一次插入大量记录并且对模式没有任何约束的情况下是有用的。

        validation和skipDataCheck之间的区别是,validation为autoIncrement列和默认值生成autoIncrement字段,但skipDataCheck不改变数据中的任何内容,则主键自增也会失效。

        如果我们将skipDataCheck置为true,代码如下:

  insertData(data){

    //添加记录时间
    if('undefined'!==typeof data['id']){
      Object.assign(data, {
        updatetime: new Date()
      })
    }else{
      Object.assign(data, {
        createtime: new Date(),
        updatetime: new Date()
      })
    }

    return connection.insert({
      into: this.tableName,
      values: [data],
      return: true,
      upsert: true,
      skipDataCheck: true
    });
  }

        如下图所示,页面会报错”Failed to execute 'put' on 'IDBObjectStore': Evaluating the object store's key path did not yield a value.“,主键则无法自动生成。

注:建议不要使用skipDataCheck,如果你有自动增量字段,否则你的自动增量数据可能无法与插入的数据同步,并可能产生问题。

4.7 ignore

        发生错误时忽略记录。当您从用户或任何来源接收一些随机数据时,这很有帮助。

        例:假设你有5行,其中3行无效。它可以是-空值,数据类型不匹配,主键的现有值等。然后将插入2行,其中3行将被忽略。所以结果是2。

        缺省情况下,ignore值为false。因此,当任何错误发生时,您将得到错误&整个事务被中止。

        我们将ignore置为true,代码如下:

  insertData(data){

    //添加记录时间
    if('undefined'!==typeof data['id']){
      Object.assign(data, {
        updatetime: new Date()
      })
    }else{
      Object.assign(data, {
        createtime: new Date(),
        updatetime: new Date()
      })
    }

    return connection.insert({
      into: this.tableName,
      values: [data],
      return: true,
      upsert: true,
      ignore: true
    });
  }

        此时我们在页面中新增数据,将生日缺失,点击保存后,控制台不会报任何错误,并且可以正常返回结果,且为空数组,表示插入数据失败。

         这里Insert API的选项就已讲完了,希望对大家有所帮助。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/471644.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用InitializingBean和DisposableBean来管理bean的生命周期

1.InitializingBean接口 1.1.InitializingBean接口概述 Spring中提供了一个InitializingBean接口&#xff0c;该接口为bean提供了属性初始化后的处理方法&#xff0c;它只包括afterPropertiesSet方法&#xff0c;凡是继承该接口的类&#xff0c;在bean的属性初始化后都会执行…

docker compose 安装kafka集群

使用docker compsose部署kafka&#xff0c;方便快捷&#xff0c;启动方便。 1. 拉去镜像 docker pull bitnami/zookeeper:3.6 docker pull bitnami/kafka:3.0 docker pull hlebalbau/kafka-manager 2. 编辑docker compose文件 version: "3" services: zookeeper…

HummerRisk V1.0.1:k8s检测扩充、批量删除及修复bug

HummerRisk V1.0.1发布&#xff1a; K8s检测规则扩充新增 Rancher 和 KubeSphere类型、增加批量删除、增加阿里云检测类型&#xff0c;并修复了一些V1.0.0中发现的bug。感谢社区小伙伴发现并提交的问题。 HummerRisk 保持高速的迭代&#xff0c;期待您的关注。 https://docs…

FreeRTOS 信号量(四) ------ 互斥信号量

文章目录 一、互斥信号量简介二、创建互斥信号量1. xSemaphoreCreateMutex()2. xSemaphoreCreateMutexStatic() 三、互斥信号量创建过程分析四、释放互斥信号量五、获取互斥信号量 一、互斥信号量简介 互斥信号量其实就是一个拥有优先级继承的二值信号量&#xff0c;在同步的应…

【报错解决】错误代码18456,SQL Server 登录失败

【报错解决】错误代码18456&#xff0c;SQL Server 登录失败 一、故障原因二、解决办法2.1 使用Windows身份认证登录2.2 windows身份登录后&#xff0c;依次选择&#xff1a;安全性->登录名->sa&#xff0c;然后右击选择属性2.3 在常规选项中重新设置密码2.4 在设置中选择…

创新案例|语言教育App头牌Duolingo如何重新点燃用户增长350%

Duolingo是全球最大的语言教育APP&#xff0c;拥有数亿用户&#xff0c;然而用户增长正在放缓&#xff0c;本案例以Duolingo增长 通过数据建模洞察关键指标&#xff0c;并围绕指标用增长实验驱动&#xff0c;设计植根于创新的增长模式&#xff0c;包括启动排行榜&#xff0c;重…

基于MBD的控制系统建模与仿真软件工具集

随着新能源汽车和自动驾驶技术的快速发展&#xff0c;汽车电子电气架构的发展已成为汽车行业推陈出新的主要动力&#xff1a;车内电控系统变得越来越复杂、软件迭代周期越来越短&#xff0c;汽车电子软件开发和测试的质量与效率要求也越来越高。汽车电控系统的设计开发已然成为…

定时器+中断 闪烁led

文章目录 运行环境&#xff1a;1.1 定时器和中断1)定时器2)轮询和中断 2.1配置1&#xff09;定时器配置2)中断配置3)RCC和SYS 3.1代码分析3.2添加代码1)中断处理函数IRQ中添加代码2)launch设置 4.1定时器启动和定时器中断启动函数5.1实验效果 运行环境&#xff1a; ubuntu18.0…

VSCode 上的 swift 开发配置

安装Xcode和VsCode 在下列网址下载安装即可 VsCode: https://code.visualstudio.com/ Xcode:https://developer.apple.com/xcode/resources/ 或者apptore 打开xcode要求安装的东西都允许安装一下 启用 Swift 语言支持 确保你已经安装了 Xcode 和 VSCode。这是开始运行的最简…

【ITSS】信息技术服务标准(ITSS)的介绍以及发展历程

信息技术服务标准&#xff08;ITSS)介绍 ITSS是Information TechnologyService Standards的缩写&#xff0c;中文意思是信息技术服务标准&#xff0c;是在工业和信息化部、国家标准化委的领导和支持下&#xff0c;由ITSS工作组研制的一套IT服务领域的标准库和一套提供IT服务的方…

AD9208的4通道 14-bit、2.4GSPS采样率之中文版资料

板卡概述 FMC137 是一款基于 VITA57.4 标准规范的 JESD204B 接口FMC 子 卡 模 块 &#xff0c; 该 模 块 可 以 实 现 4 路 14-bit 、 2GSPS/2.6GSPS/3GSPSADC 采集功能。该板卡 ADC 器件采用 ADI 公司的 AD9208 芯片&#xff0c;&#xff0c;与 ADI 公司的 AD9689 可以实现…

python 零基础入门难度如何?

在入门前先来了解一下Python是什么。 Python&#xff0c;他其实是一种受众非常广的语言&#xff0c;简单易学&#xff0c;在网上有大把大把的入门教程&#xff0c;学习曲线平滑。除了“简单”“万能”之外&#xff0c;还有众多库&#xff0c;Python的标准库非常强大&#xff0…

TEMPUS FUGIT: 1

环境准备 靶机链接&#xff1a;百度网盘 请输入提取码 提取码&#xff1a;d3du 虚拟机网络链接模式&#xff1a;NET模式 攻击机系统&#xff1a;kali linux 2022.03 信息收集 探测目标靶机开放端口和服务情况。 nmap -p- -A -sV 192.168.255.132 nmap --scriptvuln -p …

lvs作业

文章目录 NAT模式DR模式 基于 CentOS 7 构建 LVS-DR 群集。 对比 LVS 负载均衡群集的 NAT 模式和 DR 模式&#xff0c;比较其各自的优势 。基于 CentOS 7 构建 LVS-DR 群集。 NAT模式 在 LVS 的 NAT 模式中&#xff0c;LVS 将客户端请求的 IP 地址和端口号修改为 LVS 的 NAT …

golang/goland memo

文章目录 golanggolang开发工具goland Build constraints exclude all the Go files in xxxxxxgoland 解决 Unresolved reference xxx问题goland 解决 cannot resolve directory xxxx问题 golang GOROOT&#xff1a;Go的安装目录。 GOPATH 是一个环境变量&#xff0c;用于指定…

软件设计师笔记--计算机系统知识

文章目录 前言学习资料计算机系统CPU运算器控制器进制原码反码补码移码浮点数寻址奇偶校验码海明码循环冗余校验码RISC和CISC流水线存储器Cache中断输入输出控制方式总线加密技术与认证技术加密算法可靠性公式 前言 博主是非科班出身的&#xff0c;但从大一开始自学编程&#…

【JAVA程序设计】(C00132)基于SSM的固定资产管理系统

基于SSM的固定资产管理系统 项目简介项目获取开发环境项目技术运行截图 项目简介 本系统为基于SSM的固定资产管理系统&#xff0c;本系统分为二种用户&#xff1a;超级管理员和普通管理员&#xff1b; 超级管理员功能&#xff1a; 首页查看、设备管理、平台账户管理、设备台账…

JavaScript经典教程(五)-- JavaScript基础 -- for、while、forEach、递归、字符串

186&#xff1a;JavaScript基础 - for、while、forEach、递归、字符串 1、循环 &#xff08;1&#xff09;for循环 1、标准语句 for(初始条件;判断条件;迭代语句){操作内容; }也可以这样写&#xff1a;把初始条件和迭代语句拆出 var a 0; for(;a < 5;){alert(a);a; }其…

【软件测试】项目测试—MySQL数据库操作应用场景?必会知识详全(超详细)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 数据库在软件测试…

ASEMI代理亚德诺AD8130ARZ-REEL7芯片应用与参数分析

编辑-Z 本文将对AD8130ARZ-REEL7芯片进行详细的应用与参数分析&#xff0c;包括其主要特征、接口定义、电气特性以及使用注意事项等方面&#xff0c;旨在为广大读者提供对该芯片更全面的了解。 1、主要特征 AD8130ARZ-REEL7芯片是一种用于高速、低功耗差分信号放大的电路&…