ホームページ  >  記事  >  ウェブフロントエンド  >  jsでSQLを書く方法

jsでSQLを書く方法

一个新手
一个新手オリジナル
2017-10-16 09:29:569809ブラウズ

絶えず変化するフロントエンド分野において、nodejs の出現以来、フロントエンドエンジニアができることはますます増えており、この記事では、フロントエンドが従来のバックエンドの生活に革命を起こす傾向が強まっています。もう一つ追加して、js の使用方法を詳しく説明します コード内で標準 SQL ステートメントを実行します

なぜ js で SQL を書くのですか?

ビジネスの複雑さが増すにつれて、複雑なデータ ロジックを含む一部のページがフロントエンド ページに表示される場合があります。まず、次の 2 つの例を見てみましょう。複数の仕様と複数の在庫がある製品 インターフェイスの難しさは、色の分類、サイズ、価格、在庫、購入数量の制限、および対応する画像表示の間の複雑な論理関係にあります。ユーザーが異なる選択をする場合、js は複数の処理を実行する必要があります。結果を計算するための複雑なクエリ

たとえば、地域連携クエリ インターフェースでは、次の点に問題があります。

地域データをローカルに保存する方法 明らかに、毎回インターフェースをプルするのは非現実的です。ストレージに保存すると、使用するたびに JSON.parse などのクラス文字列を配列やオブジェクトに変換する処理が必要になり、データ量が多いとページラグが発生し、パフォーマンスが非常に低下します。 3 レベルの地域連携クエリは複雑です。郡レベルの地域からクエリを実行する場合は、所属する都市や州によっては、ロジックがさらに複雑になります

  1. 上記の 2 つの例の場合従来の JS ロジックを使用して記述されているため、誰もがすでに頭の中でアルゴリズムを設計しているはずで、forEach、filter、some、find などを使用することは避けられません。私はあらゆる種類のクールな新しいメソッドを使用してさまざまな ES678 の新しいメソッドを書き始め、次のことがわかりました。問題は 2 つありました:

  2. 書いてみると、ロジックが非常に複雑で、100 行のコードがないと実装できないように見えました (もちろん、これを「仕事は順調です」と比較する専門家もいます)

たくさんコメントを書いた後でも、同僚はまだ混乱しているようです(ロジックが非常に複雑なので...)

    著者はしばらくPHP開発を行っています(PMで働いた後もやっています) 、UI、QAなど)を考えていると、ふとSQLを使って実装できないかな?いくつかの調査の後、著者は次のようなライブラリを作成しました:
  1. Database.js
  2. Database.js は Web SQL Database に基づいています。では、Web SQL Database とは何ですか?

Web SQL Database は、2008 年 1 月に WHATWG (Web Hypertext Application Technology Working Group、HTML5 ドラフトの提案者) によって提案された最初の公式ドラフトですが、HTML 5 仕様には含まれていません。 SQL を使用してクライアント データベースを操作するための API セットを導入する仕様。 W3C は 2011 年 11 月に Web SQL Database 仕様を維持しないと公式に発表しましたが、以前に提案されて以来、これらの API はさまざまなブラウザ、特にモバイル ブラウザに広く実装されてきました。

互換性

Web SQL データベースとインデックス付きデータベースの違いは何ですか?

インデックス付きデータベースは、データベースの操作において NoSQL に似ています。最も重要なことは、インデックス付きデータベースはクエリ言語として SQL を使用しないことです。

SQL を js で記述する必要性を実現するために、著者は基盤技術として前者を断固として採用しました。

Web SQL Database の 3 つのコア メソッド:

openDatabase: このメソッドは、既存のデータベースまたは新しいデータベースを使用してデータベース オブジェクトを作成します

transaction: このメソッドにより、次に従ってトランザクションの送信またはロールバックを制御できます。状況

executeSql: このメソッドは SQL クエリを実行するために使用されます
  • コード例:
  • 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 が誕生しました:

著者はビジネスでのニーズの例を挙げています:

Zhuanzhuan ゲーム ビジネス リスト ページ

フィルター メニューは 3 レベルの連携メニューであり、各メニューの変更は影響を与えます図に示すように、その他のメニュー データ:


元の JSON データ構造

は、作成者がそれをフラット データ構造 (.処理は省略) を以下に示すように、ゲーム名、ゲームプラットフォーム、製品タイプの 3 つのデータベースにそれぞれ格納します:

たとえば、ゲーム名のデータ構造は次のとおりです。

通过chrome控制台Application面板可以直接看到数据库,结构、数据清晰可见

核心代码如下:


/**
       * 打开数据库
       * @returns {Promise.<void>}
       */
      openDataBase(){
        //打开数据库,没有则创建
        db.openDatabase(&#39;GameMenu&#39;,1,&#39;zzOpenGameMenu&#39;).then(res=>{
          //检测数据库是否存在
          db.isExists(&#39;game&#39;).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[&#39;0&#39;] && all[&#39;0&#39;][&#39;name&#39;]!=defaultData[0].default.name)condition[&#39;gameName&#39;] = all[&#39;0&#39;][&#39;name&#39;]
        if(all[&#39;1&#39;] && all[&#39;1&#39;][&#39;name&#39;]!=defaultData[1].default.name)condition[&#39;platName&#39;] = all[&#39;1&#39;][&#39;name&#39;]
        if(all[&#39;2&#39;] && all[&#39;2&#39;][&#39;name&#39;]!=defaultData[2].default.name)condition[&#39;typeName&#39;] = all[&#39;2&#39;][&#39;name&#39;]

        //创建三个查询任务
        let tasks = [&#39;game&#39;,&#39;plat&#39;,&#39;type&#39;].map((v,k)=>{
            //使用db.select方法查询
            return db.select(v,this.formatCondition(v,condition),&#39;name,value&#39;,&#39;rowid desc&#39;,&#39;name&#39;).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

  • 功能:打开数据库,不存在则创建

  • 语法:openDatabase(dbName,dbVersion,dbDescription,dbSize,callback)

  • 参数:

    • dbName:数据库名

    • dbVersion:数据库版本(打开已存在数据库时,版本号必须一致,否则会报错)

    • dbDescription:数据库描述

    • dbSize:数据库预设大小,默认1M

    • callback:回调函数

query

  • 功能:执行sql语句,支持多表查询

  • 语法:query(sqlStr,args = [],callback,errorCallback)

  • 参数:

    • sqlStr:sql语句

    • args(Array):传入的数据,替换sql中的?符号

    • callback:成功回调

    • errorCallback:失败回调

    1   //插入数据
    2   db.query(&#39;INSERT INTO testTable(id,title) VALUES (?,?)&#39;,[1,&#39;这是title&#39;])
    3 
    4   //多表查询
    5  db.query(&#39;select game.*,plat.* from game left join plat on game.name = plat.gameName&#39;)

isExists

  • 功能:检测表是否存在

  • 语法:isExists(tableName)

  • 参数:

    • tableName:表名

createTable

  • 功能:创建一张表

  • 语法:createTable(tableName,fields)

  • 参数:

    • tableName:表名

    • fields:表结构(需指定字段类型)

  • 示例  

                1   db.createTable(&#39;testTable&#39;,{
        2       name:&#39;varchar(200)&#39;,
        3       price:&#39;int(100)&#39;
        4   })

insert

  • 功能:插入一条或多条数据

  • 语法:insert(tableName,data)

  • 参数:

    • tableName:表名

    • data(Object or Array):插入的数据,多条数据请传入数组类型

  • 示例: javascript //插入单条 db.insert('testTable',{ name:'商品1', price:10 }) //插入多条 db.insert('testTable',[ {name:'商品1',price:10}, {name:'商品2',price:20}, {name:'商品3',price:30}, ])

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

create

  • 功能:直接创建数据库并存入数据

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

  • 语法:create(tableName,data)

  • 参数:

    • tableName:表名

    • data(Object or Array):插入的数据,多条数据请传入数组类型

  • 示例:

1   //插入数据
2   db.query(&#39;INSERT INTO testTable(id,title) VALUES (?,?)&#39;,[1,&#39;这是title&#39;])
3
4   //多表查询
5  db.query(&#39;select game.*,plat.* from game left join plat on game.name = plat.gameName&#39;)

delete

  • 功能:删除数据

  • 语法:delete(tableName,condition)

  • 参数:

    • tableName:表名

    • condition(String or Obejct):查询条件

  • 示例:

1       //删除一条数据
2       db.delete(&#39;testTable&#39;,{name:&#39;商品1&#39;})

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

select

  • 功能:查询数据

  • 注意:如果需要多表查询,可参照query方法

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

  • 参数:

    • tableName:表名

    • condition(String or Obejct):查询条件

    • fields(String or Array):返回字段,默认*,支持distinct

    • order(String or Array):排序规则

    • group(String or Array):分组规则

    • limit(String or Array):分页规则

  • 示例:


    1 //查询name=商品1的数据,并按照price倒序
**update**
- 功能:更新数据
- 语法:update(tableName,data,condition = &#39;&#39;)
- 参数:
    - tableName:表名
    - data(String or Obejct):更改数据
    - condition(String or Obejct):查询条件
- 示例:
1       //将商品1的价格改为99
2       db.update(&#39;testTable&#39;,{
3             price:99
4         },{
5             name:&#39;商品1&#39;
6         })

truncate

  • 功能:清空表

  • 语法:truncate(tableName)

  • 参数:

    • tableName:表名

drop

  • 功能:删除表

  • 语法:drop(tableName)

  • 参数:

    • tableName:表名

以上がjsでSQLを書く方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。