目錄
1.1.4SetMaxOpenConns" >1.1.4SetMaxOpenConns
#1.1.5SetMaxIdleConns" >#1.1.5SetMaxIdleConns
# #
func (db *DB) SetMaxIdleConns(n int)
登入後複製
連線池中的最大閒置連線數" ># #
func (db *DB) SetMaxIdleConns(n int)
登入後複製
連線池中的最大閒置連線數
大於最大開啟連線數,則新的最大閒置連線數會減少到匹配最大開啟連線數的限制。如果" >如果n大於最大開啟連線數,則新的最大閒置連線數會減少到匹配最大開啟連線數的限制。如果
#1.2.1 建置庫建置表格我們先在MySQL中建立一個名為" >#1.2.1 建置庫建置表格我們先在MySQL中建立一個名為
1.2.5删除数据" >1.2.5删除数据
总体" >总体
1.3MySQL预处理" >1.3MySQL预处理
1.3.1什么是预处理?
1.3.2为什么要预处理?" >1.3.2为什么要预处理?
1.3.3 Go实现MySQL预处理" >1.3.3 Go实现MySQL预处理
总结 其实就多了一个db.Prepare(sqlStr)" >总结 其实就多了一个db.Prepare(sqlStr)
1.3.4 SQL注入问题" >1.3.4 SQL注入问题
首頁 後端開發 Golang go語言中sql是什麼

go語言中sql是什麼

Dec 22, 2022 am 11:55 AM
golang go語言

SQL是指“結構化查詢語言”,是一種操作資料庫的語言,包括建立資料庫、刪除資料庫、查詢記錄、修改記錄、新增欄位等。 SQL是關聯式資料庫的標準語言,所有的關聯式資料庫管理系統(RDBMS),例如 MySQL、Oracle、SQL Server、MS Access、Sybase、Informix、Postgres 等,都將 SQL 作為其標準處理語言。

go語言中sql是什麼

本教學操作環境:windows7系統、GO 1.18版本、Dell G3電腦。

SQL是什麼

SQL 是一種操作資料庫的語言,包括建立資料庫、刪除資料庫、查詢記錄、修改記錄、添加字段等。 SQL 雖然是一種被 ANSI 標準化的語言,但它有許多不同的實作版本。

SQL 是 Structured Query Language 的縮寫,中文譯為「結構化查詢語言」。 SQL 是一種電腦語言,用來儲存、檢索和修改關係型資料庫中儲存的資料。

SQL 是關聯式資料庫的標準語言,所有的關聯式資料庫管理系統(RDBMS),例如MySQL、Oracle、SQL Server、MS Access、Sybase、Informix、Postgres 等,都將SQL 作為其標準處理語言。

SQL 的用途

SQL 之所以廣受歡迎,是因為它具有以下用途:

  • 允許用戶訪問關係型資料庫系統中的資料;

  • 允許使用者描述資料;

  • 允許使用者定義資料庫中的數據,並處理該資料;

  • 允許將SQL 模組、函式庫或預處理器嵌入到其它程式語言中;

  • 允許使用者建立和刪除資料庫、表格、資料項(記錄);

  • 允許使用者在資料庫中建立視圖、預存程序、函數;

  • 允許使用者設定對錶、儲存過程和檢視的權限。

Go語言操作資料庫(MySQL)

#在Go語言標準函式庫提供了進行資料庫操作的sql 函式庫,可以利用SQL語言來操作資料庫。

1.1連線

#1.1.1下載依賴

go get -u github.com/go-sql-driver/mysql
登入後複製

#1.1.2使用MySQL驅動

func Open(driverName, dataSourceName string) (*DB, error)
登入後複製

Open開啟一個dirverName指定的資料庫dataSourceName指定資料來源,一般至少包括資料庫檔案名稱和其它連接必要的資訊。

import (
	"database/sql"

	_ "github.com/go-sql-driver/mysql"
)

func main() {
   // DSN:Data Source Name
	dsn := "user:password@tcp(127.0.0.1:3306)/dbname"
	db, err := sql.Open("mysql", dsn)
	if err != nil {
		panic(err)
	}
	defer db.Close()  // 注意这行代码要写在上面err判断的下面
}
登入後複製

1.1.3 初始化連接

Open函數可能只是驗證其參數格式是否正確,實際上並不建立與資料庫的連線。如果要檢查資料來源的名稱是否真實有效,應該呼叫Ping方法

package main

import (
	"database/sql"
	"fmt"
	_ "github.com/go-sql-driver/mysql"
)

//需要注意 这里需要引用自己的mysql文件

var db *sql.DB
func initDB()(err error)  {
	//账号 密码 端口号(tcp)127.0.0.1:3306 表名 字符集  校验时间
	dsn := "root:123456@tcp(127.0.0.1:3306)/gomysql?charset=utf8mb4&parseTime=true"
	//加载驱动
	//这里需要是=而不是:=因为我们是给全局变量(db)赋值
	db,err = sql.Open("mysql",dsn)
	if err!=nil {
		return err
	}
	//尝试和数据库建立连接(校验dsn正确)
	//然后用了ping命令
	err=db.Ping()
	if err!=nil {
		return err
	}
	return nil
}
func main() {
	err := initDB()
	if err!=nil {
		fmt.Printf("connect failed,err:%v\n",err)
		return
	}
}
登入後複製

1.1.4SetMaxOpenConns

SetMaxOpenConns設定與數據函式庫建立連線的最大數目。如果n大於0且小於最大閒置連線數,會將最大閒置連線數減少到符合最大開啟連線數的限制。如果n<=0,不會限制最大開啟連線數,預設為0(無限制)

#1.1.5SetMaxIdleConns

# #
func (db *DB) SetMaxIdleConns(n int)
登入後複製
連線池中的最大閒置連線數

如果n大於最大開啟連線數,則新的最大閒置連線數會減少到匹配最大開啟連線數的限制。如果

n<=0,不會保留閒置連線

1.2CRUD

#1.2.1 建置庫建置表格我們先在MySQL中建立一個名為

sql_test

的資料庫

CREATE DATABASE sql_test;
登入後複製
###進入該資料庫:###
use sql_test;
登入後複製
###執行下列指令建立一張用於測試的資料表:###
CREATE TABLE `user` (
    `id` BIGINT(20) NOT NULL AUTO_INCREMENT,
    `name` VARCHAR(20) DEFAULT &#39;&#39;,
    `age` INT(11) DEFAULT &#39;0&#39;,
    PRIMARY KEY(`id`)
)ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;
登入後複製
## ##########1.2.2 查詢############單行查詢#########單行查詢###db.QueryRow()###執行一次查詢,並期望傳回最多一行結果(即Row)。 QueryRow總是傳回非nil的值,直到傳回值的Scan方法被呼叫時,才會傳回被延遲的錯誤。 (如:找不到結果)###
func (db *DB) QueryRow(query string, args ...interface{}) *Row
登入後複製
func queryRowDemo() {
   sqlStr := "select id, name, age from user where id=?"
   var u user
   // 非常重要:确保QueryRow之后调用Scan方法,否则持有的数据库链接不会被释放
   err := db.QueryRow(sqlStr, 1).Scan(&u.id, &u.name, &u.age)
   if err != nil {
      fmt.Printf("scan failed, err:%v\n", err)
      return
   }
   fmt.Printf("id:%d name:%s age:%d\n", u.id, u.name, u.age)
}
登入後複製
############多行查詢######
func (db *DB) Query(query string, args ...interface{}) (*Rows, error)
登入後複製
// 查询多条数据示例
func queryMultiRowDemo() {
	sqlStr := "select id, name, age from user where id > ?"
	rows, err := db.Query(sqlStr, 0)
	if err != nil {
		fmt.Printf("query failed, err:%v\n", err)
		return
	}
	// 非常重要:关闭rows释放持有的数据库链接
	defer rows.Close()

	// 循环读取结果集中的数据
	for rows.Next() {
		var u user
		err := rows.Scan(&u.id, &u.name, &u.age)
		if err != nil {
			fmt.Printf("scan failed, err:%v\n", err)
			return
		}
		fmt.Printf("id:%d name:%s age:%d\n", u.id, u.name, u.age)
	}
}
登入後複製
############1.2.3 插入數據#########插入、更新和刪除操作都使用###Exec###方法。 ###
func (db *DB) Exec(query string, args ...interface{}) (Result, error)
登入後複製
###Exec執行一次指令(包括查詢、刪除、更新、插入等),傳回的Result是對已執行的SQL指令的總結。參數args表示query中的佔位參數。 ######具體插入資料範例程式碼如下:###
// 插入数据
func insertRowDemo() {
	sqlStr := "insert into user(name, age) values (?,?)"
	ret, err := db.Exec(sqlStr, "王五", 38)
	if err != nil {
		fmt.Printf("insert failed, err:%v\n", err)
		return
	}
	theID, err := ret.LastInsertId() // 新插入数据的id
	if err != nil {
		fmt.Printf("get lastinsert ID failed, err:%v\n", err)
		return
	}
	fmt.Printf("insert success, the id is %d.\n", theID)
}
登入後複製
#############1.2.4更新資料########具體更新資料範例程式碼如下: ###
// 更新数据
func updateRowDemo() {
	sqlStr := "update user set age=? where id = ?"
	ret, err := db.Exec(sqlStr, 39, 3)
	if err != nil {
		fmt.Printf("update failed, err:%v\n", err)
		return
	}
	n, err := ret.RowsAffected() // 操作影响的行数
	if err != nil {
		fmt.Printf("get RowsAffected failed, err:%v\n", err)
		return
	}
	fmt.Printf("update success, affected rows:%d\n", n)
}
登入後複製

1.2.5删除数据

具体删除数据的示例代码如下:

// 删除数据
func deleteRowDemo() {
	sqlStr := "delete from user where id = ?"
	ret, err := db.Exec(sqlStr, 3)
	if err != nil {
		fmt.Printf("delete failed, err:%v\n", err)
		return
	}
	n, err := ret.RowsAffected() // 操作影响的行数
	if err != nil {
		fmt.Printf("get RowsAffected failed, err:%v\n", err)
		return
	}
	fmt.Printf("delete success, affected rows:%d\n", n)
}
登入後複製

总体

package main

import (
	"database/sql"
	"fmt"
	_ "github.com/go-sql-driver/mysql"
)

// 定义一个全局对象db
var db *sql.DB

// 定义一个初始化数据库的函数
func initDB() (err error) {
	// DSN:Data Source Name
	dsn := "root:123456@tcp(127.0.0.1:3306)/sql_test?charset=utf8&parseTime=True"
	// 不会校验账号密码是否正确
	// 注意!!!这里不要使用:=,我们是给全局变量赋值,然后在main函数中使用全局变量db
	db, err = sql.Open("mysql", dsn)
	if err != nil {
		return err
	}
	// 尝试与数据库建立连接(校验dsn是否正确)
	err = db.Ping()
	if err != nil {
		return err
	}
	return nil
}
type user struct {
	id   int
	age  int
	name string
}
func queryRowDemo() {
	sqlStr := "select id, name, age from user where id=?"
	var u user
	// 非常重要:确保QueryRow之后调用Scan方法,否则持有的数据库链接不会被释放
	err := db.QueryRow(sqlStr, 1).Scan(&u.id, &u.name, &u.age)
	if err != nil {
		fmt.Printf("scan failed, err:%v\n", err)
		return
	}
	fmt.Printf("id:%d name:%s age:%d\n", u.id, u.name, u.age)
}
// 查询多条数据示例
func queryMultiRowDemo() {
	sqlStr := "select id, name, age from user where id > ?"
	rows, err := db.Query(sqlStr, 0)
	if err != nil {
		fmt.Printf("query failed, err:%v\n", err)
		return
	}
	// 非常重要:关闭rows释放持有的数据库链接
	defer rows.Close()

	// 循环读取结果集中的数据
	for rows.Next() {
		var u user
		err := rows.Scan(&u.id, &u.name, &u.age)
		if err != nil {
			fmt.Printf("scan failed, err:%v\n", err)
			return
		}
		fmt.Printf("id:%d name:%s age:%d\n", u.id, u.name, u.age)
	}
}
func insertRowDemo()  {
	sqlStr := "insert into user(name,age) value (?,?)"
	//
	ret,err := db.Exec(sqlStr,"王五",40)
	if err!=nil {
		fmt.Printf("inserf failed,err:%v\n",err)
		return
	}
	//插入成功之后需要返回这个id
	theID,err:=ret.LastInsertId()
	if err != nil{
		fmt.Printf("get the last insertid failed,err:%v\n",theID)
		return
	}
	fmt.Printf("insert success,theID is:%v\n",theID)

}
func updateRowDemo()  {

	sqlStr := "update user set name =? where id = ?"
	//执行含有sqlStr参数的语句
	ret,err:=db.Exec(sqlStr,"赵四",4)
	if err!=nil {
		fmt.Printf("update failed,err:%v\n",err)
		return
	}
	AnoID,err:=ret.RowsAffected()
	if err!=nil {
		fmt.Printf("updateRowAffected failed,err:%v\n",err)
		return
	}
	fmt.Printf("update success AnoID:%v\n",AnoID)

}
// 删除数据
func deleteRowDemo() {
	sqlStr := "delete from user where id = ?"
	ret, err := db.Exec(sqlStr, 5)
	if err != nil {
		fmt.Printf("delete failed, err:%v\n", err)
		return
	}
	n, err := ret.RowsAffected() // 操作影响的行数
	if err != nil {
		fmt.Printf("get RowsAffected failed, err:%v\n", err)
		return
	}
	fmt.Printf("delete success, affected rows:%d\n", n)
}
func main() {
	err := initDB() // 调用输出化数据库的函数
	if err != nil {
		fmt.Printf("init db failed,err:%v\n", err)
		return
	}
	//queryRowDemo()
	//insertRowDemo()
    //updateRowDemo()
    deleteRowDemo()
	queryMultiRowDemo()
}
登入後複製

1.3MySQL预处理

1.3.1什么是预处理?

普通SQL语句执行过程:

  • 客户端对SQL语句进行占位符替换得到完整的SQL语句。

  • 客户端发送完整SQL语句到MySQL服务端

  • MySQL服务端执行完整的SQL语句并将结果返回给客户端

预处理执行过程:

  • 把SQL语句分成两部分,命令部分与数据部分

  • 先把命令部分发送给MySQL服务端MySQL服务端进行SQL预处理

  • 然后把数据部分发送给MySQL服务端,MySQL服务端对SQL语句进行占位符替换

  • MySQL服务端执行完整的SQL语句并将结果返回给客户端

1.3.2为什么要预处理?

  • 优化MySQL服务器重复执行SQL的方法,可以提升服务器性能,提前让服务器编译,一次编译多次执行,节省后续编译的成本。

  • 避免SQL注入问题。

1.3.3 Go实现MySQL预处理

func (db *DB) Prepare(query string) (*Stmt, error)
登入後複製

查询操作的预处理示例代码如下:

// 预处理查询示例
func prepareQueryDemo() {
	sqlStr := "select id, name, age from user where id > ?"
	stmt, err := db.Prepare(sqlStr)
	if err != nil {
		fmt.Printf("prepare failed, err:%v\n", err)
		return
	}
	defer stmt.Close()
	rows, err := stmt.Query(0)
	if err != nil {
		fmt.Printf("query failed, err:%v\n", err)
		return
	}
	defer rows.Close()
	// 循环读取结果集中的数据
	for rows.Next() {
		var u user
		err := rows.Scan(&u.id, &u.name, &u.age)
		if err != nil {
			fmt.Printf("scan failed, err:%v\n", err)
			return
		}
		fmt.Printf("id:%d name:%s age:%d\n", u.id, u.name, u.age)
	}
}
登入後複製

插入、更新和删除操作的预处理十分类似,这里以插入操作的预处理为例:

// 预处理插入示例
func prepareInsertDemo() {
	sqlStr := "insert into user(name, age) values (?,?)"
	stmt, err := db.Prepare(sqlStr)
	if err != nil {
		fmt.Printf("prepare failed, err:%v\n", err)
		return
	}
	defer stmt.Close()
	_, err = stmt.Exec("小王子", 18)
	if err != nil {
		fmt.Printf("insert failed, err:%v\n", err)
		return
	}
	_, err = stmt.Exec("沙河娜扎", 18)
	if err != nil {
		fmt.Printf("insert failed, err:%v\n", err)
		return
	}
	fmt.Println("insert success.")
}
登入後複製

总结 其实就多了一个db.Prepare(sqlStr)

1.3.4 SQL注入问题

我们任何时候都不应该自己拼接SQL语句!

// sql注入示例
func sqlInjectDemo(name string) {
	sqlStr := fmt.Sprintf("select id, name, age from user where name=&#39;%s&#39;", name)
	fmt.Printf("SQL:%s\n", sqlStr)
	var u user
	err := db.QueryRow(sqlStr).Scan(&u.id, &u.name, &u.age)
	if err != nil {
		fmt.Printf("exec failed, err:%v\n", err)
		return
	}
	fmt.Printf("user:%#v\n", u)
}
登入後複製

此时以下输入字符串都可以引发SQL注入问题

sqlInjectDemo("xxx&#39; or 1=1#")
sqlInjectDemo("xxx&#39; union select * from user #")
sqlInjectDemo("xxx&#39; and (select count(*) from user) <10 #")
登入後複製
数据库 占位符语法
MySQL <span style="font-family:Microsoft Yahei, Hiragino Sans GB, Helvetica, Helvetica Neue, 微软雅黑, Tahoma, Arial, sans-serif">?</span>
PostgreSQL $1, $2
SQLite ?$1
Oracle <span style="font-family:Microsoft Yahei, Hiragino Sans GB, Helvetica, Helvetica Neue, 微软雅黑, Tahoma, Arial, sans-serif">:name</span>

【相关推荐:Go视频教程编程教学

以上是go語言中sql是什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1665
14
CakePHP 教程
1424
52
Laravel 教程
1322
25
PHP教程
1270
29
C# 教程
1249
24
在Go語言中使用Redis Stream實現消息隊列時,如何解決user_id類型轉換問題? 在Go語言中使用Redis Stream實現消息隊列時,如何解決user_id類型轉換問題? Apr 02, 2025 pm 04:54 PM

Go語言中使用RedisStream實現消息隊列時類型轉換問題在使用Go語言與Redis...

GoLand中自定義結構體標籤不顯示怎麼辦? GoLand中自定義結構體標籤不顯示怎麼辦? Apr 02, 2025 pm 05:09 PM

GoLand中自定義結構體標籤不顯示怎麼辦?在使用GoLand進行Go語言開發時,很多開發者會遇到自定義結構體標籤在�...

Go語言中哪些庫是由大公司開發或知名的開源項目提供的? Go語言中哪些庫是由大公司開發或知名的開源項目提供的? Apr 02, 2025 pm 04:12 PM

Go語言中哪些庫是大公司開發或知名開源項目?在使用Go語言進行編程時,開發者常常會遇到一些常見的需求,�...

Golang的目的:建立高效且可擴展的系統 Golang的目的:建立高效且可擴展的系統 Apr 09, 2025 pm 05:17 PM

Go語言在構建高效且可擴展的系統中表現出色,其優勢包括:1.高性能:編譯成機器碼,運行速度快;2.並發編程:通過goroutines和channels簡化多任務處理;3.簡潔性:語法簡潔,降低學習和維護成本;4.跨平台:支持跨平台編譯,方便部署。

在Go編程中,如何正確管理Mysql和Redis的連接與釋放資源? 在Go編程中,如何正確管理Mysql和Redis的連接與釋放資源? Apr 02, 2025 pm 05:03 PM

Go編程中的資源管理:Mysql和Redis的連接與釋放在學習Go編程過程中,如何正確管理資源,特別是與數據庫和緩存�...

多進程日誌寫入如何保證並發安全又高效? 多進程日誌寫入如何保證並發安全又高效? Apr 02, 2025 pm 03:51 PM

高效處理多進程日誌寫入的並發安全問題多進程同時寫入同一個日誌文件,如何保證並發安全且高效?這是一個...

Golang vs. Python:性能和可伸縮性 Golang vs. Python:性能和可伸縮性 Apr 19, 2025 am 12:18 AM

Golang在性能和可擴展性方面優於Python。 1)Golang的編譯型特性和高效並發模型使其在高並發場景下表現出色。 2)Python作為解釋型語言,執行速度較慢,但通過工具如Cython可優化性能。

使用Go語言連接Oracle數據庫時是否需要安裝Oracle客戶端? 使用Go語言連接Oracle數據庫時是否需要安裝Oracle客戶端? Apr 02, 2025 pm 03:48 PM

使用Go語言連接Oracle數據庫時是否需要安裝Oracle客戶端?在使用Go語言開發時,連接Oracle數據庫是一個常見需求�...

See all articles