1. ホーム
  2. スクリプト・コラム
  3. ゴラン

GOウェブデータベース前処理実装

2022-02-14 04:22:15

 前回は、データ操作を行いましたが、すべてプレースホルダーを使用しました

実際にmysqlの前処理を使って、これらを操作することができます。

では、前処理とは何か、見ていきましょう。

前処理とは?

前処理とは何かを理解するために、通常のSQL文の実行過程と前処理の過程を比較すると、次のようになります。

通常のsql文の実行処理です。

  • クライアントはSQL文のプレースホルダー置換を行い、完全なSQL文を取得します。
  • クライアントは完全なSQLステートメントをmysqlサーバーに送信します。
  • mysql サーバは完全な SQL 文を実行し、その結果をクライアントに返します。

前処理実行処理。

  • sql文を2つのパートに分割する
    • コマンド部
    • データ部
  • コマンド部分を先にmysqlサーバーに送信し、mysqlサーバーがsqlの前処理を行う。
  • その後、データ部分をmysqlサーバーに送信し、sql文のプレースホルダー置換を行います。
  • mysqlサーバーは完全なSQLステートメントを実行し、その結果をクライアントに返します。

ステップとフローを見ると、プリプロセスは通常のSQL実行よりも確実に速いことがわかると思います。

では、前処理のメリットは何でしょうか?

SQLを繰り返し実行するようにmysqlサーバーを最適化することで、サーバーのパフォーマンスを向上させることができます。サーバーが前もってコンパイルし、1回のコンパイルで複数回実行することで、その後のコンパイルにかかるコストを節約することができます。
sqlインジェクションの問題を回避する

//preprocessing Insert data operation
func prepareInfo(db *sql.DB) {
 sqlInfo := "insert into user (name,age)values(? ,?) "

 stmt, err := db.Prepare(sqlInfo)
 if err ! = nil {
  fmt.Println("Exec err : ", err)
  return
 }

 ret, err := stmt.Exec("Flower Pig 2", 28)
 if err ! = nil {
  fmt.Println("stmt Exec err : ", err)
  return
 }
 ret, err = stmt.Exec("flowerpig3", 28)
 if err ! = nil {
  fmt.Println("stmt Exec err : ", err)
  return
 }

 rows, err := ret.RowsAffected()
 if err ! = nil {
  fmt.Println("stmt Exec err : ", err)
  return
 }
 fmt.Println("rows = ", rows)

}

Go が MySQL トランザクションを実装

トランザクション処理をオンにすると、ロールバックの仕組みがあり、すべてが成功し、コミットが成功したときのみトランザクションが成功したとみなされるようになる

  • func (db *DB) Begin() (*Tx, error) トランザクションの開始
  • func (tx *Tx) Commit() error トランザクションのコミット
  • func (tx *Tx) Rollback() error トランザクションのロールバック
func trasaction(db *sql.DB) {

 //open a transaction

 tx, err := db.
 if err ! = nil {
  if tx ! = nil {
   tx.Rollback()
  }
  fmt.Printf("Begin err :%v", err)
  return
 }

 sqlStr := "update user set name='xxx' where id=? "
 _, err = tx.Exec(sqlStr, 9)
 if err ! = nil {
  if tx ! = nil {
   tx.Rollback()
  }
  fmt.Printf("Exec err :%v", err)
  return
 }

 sqlStr = "update user set name='xxx' where id=? "
 _, err = tx.Exec(sqlStr, 6)
 if err ! = nil {
  if tx ! = nil {
   tx.Rollback()
  }
  fmt.Printf("Exec err :%v", err)
  return
 }

    //Commit the transaction
 err = tx.Commit()
 if err ! = nil {
  if tx ! = nil {
   tx.Rollback()
  }
  fmt.Printf("Commit err :%v", err)
  return
 }

 fmt.Println("Commit success ")
}

sqlxの用途

サードパーティライブラリsqlxを使うこともできます。

  • サードパーティライブラリsqlxをインストールします。github.com/jmoiron/sqlxを取得します。
  • サードパーティライブラリは、高い開発効率と開発作業の簡素化を実現します。
package main

import (
 "fmt"
 "github.com/jmoiron/sqlx"
 _ "github.com/go-sql-driver/mysql" // exception after commenting out _ call initialization function
)

var db *sqlx.DB

func insertInfo() {

 sqlStr := "insert into user(name,age)values(? ,?) "
 res, err := db.Exec(sqlStr, "xxx", 2)
 if err ! = nil {
  fmt.Printf("Exec err : %v", err)
  return
 }
 id, err := res.LastInsertId()
 if err ! = nil {
  fmt.Printf("LastInsertId err : %v", err)
  return
 }
 fmt.Printf("id == %d", id)

 rows, err := res.RowsAffected()
 if err ! = nil {
  fmt.Printf("RowsAffected err : %v", rows)
  return
 }
 fmt.Printf("rows == %d", rows)
 return

}

func main() {

 var err error
 dsn := "root:123456@tcp(127.0.0.1:3306)/go_test?charset=utf8mb4"
 db, err = sqlx.Connect("mysql", dsn)
 if err ! = nil {
  fmt.Printf("Connect err : %v\n", err)
  return
 }
 db.SetMaxOpenConns(20)
 db.SetMaxIdleConns(10)

 //Insert data
 insertInfo()
}

gin + mysql + rest フルAPI

もちろん、我々はメソッドの実装内部のhttpパッケージについて話す前に、我々はそれを使用する必要はありません、我々はまた、フレームワークに引き渡すことができます、それは本当にビジネスを達成するために効率的ですが、同時に、彼らはまだ多くの研究の原則の特定の実装にダウンする必要があります

以下のステップを実践してください。

  • github.com/gin-gonic/ginライブラリのインポート
  • usersテーブル、id、name、telephoneフィールドを作成します。
CREATE TABLE `users` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(20) DEFAULT '',
`telephone` VARCHAR(20) DEFAULT '',
PRIMARY KEY(`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT 
CHARSET=utf8mb4;


上の画像は、練習中に生成されたデータです。

  • データベースに対する追加、削除、チェック操作のラッピング
  •  ルーティング操作の記述

GOウェブデータベースの前処理については、この記事がすべてです。GOデータベースの前処理についてのより詳しい情報は、スクリプトハウスの過去の記事を検索するか、以下の記事を引き続きご覧になってください。