zl程序教程

您现在的位置是:首页 >  后端

当前栏目

前端要革命?看我在 JS 里写 SQL

JSSQL前端 革命
2023-09-27 14:28:00 时间

在日新月异的前端领域中,前端工程师能做的事情越来越多,自从nodejs出现后,前端越来越有革了传统后端命的趋势,本文就再补一刀,详细解读如何在js代码中执行标准的SQL语句

为什么要在JS里写SQL?

随着业务复杂度的增长,前端页面可能出现一些数据逻辑复杂的页面,传统的js逻辑处理起来比较复杂,我们先看两个例子:

比如多规格多库存商品界面,难点在于颜色分类、尺码、价格、库存、限购数量以及对应的图片展示之间有复杂的逻辑关系,用户进行不同的选择时,js要经过多次复杂的查询才能算出结果

比如地区联动查询界面,难点在于:


笔者做过一段时间php开发(还做过PM、UI、QA等)忽然想能不能用SQL的方式实现呢?经过一番研究,笔者写了这样一个库: Database.js Database.js基于Web SQL Database,那么Web SQL Database又是啥?

Web SQL Database是WHATWG(Web 超文本应用技术工作组,HTML5草案提出方)在2008 年 1 月提出的第一份正式草案,但并未包含在 HTML 5 规范之中,它是一个独立的规范,它引入了一套使用 SQL 操作客户端数据库的 API。由于提出时间较早,尽管 W3C 官方在 2011 年 11 月声明已经不再维护 Web SQL Database 规范,但这些 API 已经被广泛的实现在了不同的浏览器里,尤其是手机端浏览器。

Web SQL Database 和 Indexed Database有啥区别?

Indexed Database 更类似于 NoSQL 的形式来操作数据库 , 其中最重要的是 Indexed Database 不使用 SQL 作为查询语言。

笔者为了实现在js里面写SQL的需求,果断采用了前者作为底层技术。

Web SQL Database 三个核心方法:

代码示例:

 var db = openDatabase(testDB, 1.0, Test DB, 2 * 1024 * 1024);

 var msg;

 db.transaction(function (context) {

    context.executeSql(CREATE TABLE IF NOT EXISTS testTable (id unique, name));

    context.executeSql(INSERT INTO testTable (id, name) VALUES (0, "Byron"));

    context.executeSql(INSERT INTO testTable (id, name) VALUES (1, "Casper"));

    context.executeSql(INSERT INTO testTable (id, name) VALUES (2, "Frank"));

  });

`对于没有SQL经验的前端同学来讲,上面代码看起来显然有点陌生,也不太友好,于是Database.js诞生了:

笔者以业务当中的一个需求举例: 转转游戏业务列表页 筛选菜单是一个三级联动菜单,每个菜单变动都会影响其他菜单数据,如图:

原始JSON数据结构

可以看出是3级嵌套结构,笔者处理成了扁平化的数据结构(过程略),并分别存入三个数据库,分别存储游戏名称、游戏平台、商品类型,如下图:

举例游戏名称数据结构如下图:

通过chrome控制台Application面板可以直接看到数据库,结构、数据清晰可见 核心代码如下:

  /**

    * 打开数据库

    * @returns {Promise. void }

    */

   openDataBase(){

     //打开数据库,没有则创建

     db.openDatabase(GameMenu,1,zzOpenGameMenu).then(res= {

       //检测数据库是否存在

       db.isExists(game).then(res= {

         //数据库已经存在,直接使用,将数据交付给页面UI组件

         this.setSelectData()

       }).catch(e= {

         //数据库不存在,请求接口并处理数据,然后存入数据库

         this.getData()

       })

     }).catch(e= {

       console.err(e)

     })

   },

  /**

    * 获取分类数据并存储到数据库

    * @returns {Promise. void }

    */

   async getData(){

     //接口请求数据并处理成三个扁平数组

     let data =  await this.getMenuData()

     for(let i in data){

       //创建表并存储数据

       db.create(i,data[i])

     }

     //将数据交付给页面UI组件

     this.setSelectData()

   },

当任意菜单选择变更时,三列数据将重新查询,核心代码如下:

  /**

    * 重新查询数据

    * @param data 点击菜单携带的数据

    * @param index 点击菜单的序号

    * @param all 三个菜单当前选中数据

    */

  async onSelect(data,index,all){

     let target = [],condition = {}

     //业务逻辑:处理查询条件

     if(all[0]   all[0][name]!=defaultData[0].default.name)condition[gameName] =all[0][name]

     if(all[1]   all[1][name]!=defaultData[1].default.name)condition[platName] =all[1][name]

     if(all[2]   all[2][name]!=defaultData[2].default.name)condition[typeName] =all[2][name]

     //创建三个查询任务

     let tasks = [game,plat,type].map((v,k)= {

         //使用db.select方法查询

         return db.select(v,this.formatCondition(v,condition),name,value,rowid desc,name).then((res)= {

           target.push({

             options:res.data,

             defaultOption:defaultData[k].default,

             clickHandle:this.onSelect

           })

         })

     })

   //执行查询

   await Promise.all(tasks)

     //将数据交付给联动菜单组件使用

     this.selectData = target

   }

以上代码即可完成联动菜单所需要的数据管理工作,看起来是不是比较清晰? 使用Database.js的优势 1.将数据结构化存储于Storage中,避免了以文本形式存入Storage或cookie中再解析的性能消耗流程。

2.将复杂数据清晰的在前端进行管理和使用,代码逻辑更清晰,数据查询更简洁!

Database.js使用文档

openDatabase

 //插入数据

 db.query(INSERT INTO testTable(id,title) VALUES (?,?),[1,这是title])

 //多表查询

 db.query(select game.*,plat.* from game left join plat on game.name = plat.gameName)

isExists

 ])

将数据存入数据库的常规流程是先createTable,然后再insert,如果你觉得这样麻烦,可以试一下create方法: create

注意:类库会根据传入的数据类型自动设置数据库的字段类型,这样可以覆盖大多数需求,但如果你的数据中,同一个字段中有不同的数据类型,有可能不能兼容,建议还是使用常规流程手动设置类型


 db.delete(testTable,{name:商品1})

关于condition: 1、传入array形式时,默认查询条件连接方式是AND,如果需要用OR等方式,可以在condition中传入 logic设定,例如{ logic:OR} 2、如果查询条件有AND、OR等多种方式,建议使用string方式传入

select

语法:select(tableName,condition = ,fields = *,order = ,group = ,limit = )


如何使用Database.js

Github地址:https://github.com/zhangsuoyong/Database.js


本文作者:佚名

来源:51CTO


Squel.js – 基于 JavaScript 的 SQL 查询构建器 有时候,我们不知道我们的 SQL 查询是怎样的,因为大部分时候这些语句都是动态创建的。或者,你也正在寻找一个解决方案,使 SQL 查询更可读。Squel.js,一个轻量级的 JavaScript 库,通过一个面向对象的 API 轻松建立 SQL 查询字符串。
js基础学习 JavaScript 是一门跨平台、面向对象的脚本语言,它能使网页可交互(例如拥有复杂的动画,可点击的按钮,通俗的菜单等)。另外还有高级的服务端 Javascript 版本,例如 Node.js,它可以让你在网页上添加更多功能,不仅仅是下载文件(例如在多台电脑之间的协同合作)。在宿主环境(例如 web 浏览器)中,JavaScript 能够通过其所连接的环境提供的编程接口进行控制。