GO語言學習(九)

GO語言學習(九)

上一期我們了解了實現web的工作中極為重要的net/http抱的細節講解,大家學會了實現web開發的一些底層基礎知識,在這一期我來為大家講解一下web工作的一個重要方法,:使用數據庫,現在就讓我來為大家講解這一篇章,歡迎大家交流學習

sql接口及database

首先和大家解釋一下在golang中沒有提供現成的數據庫驅動方式,英雌在我們實際開發中一般是實現接口,利用這些接口來實現相應的數據庫驅動操作,這樣使用可以在遷移數據庫的時候,只用使用開發好的標準數據庫接口。

sql.register說明

這個存在于database/sql的函數是用來注冊數據庫驅動的,當第三方開發者開發數據庫驅動時,都會實現init函數,在init里面會調用這個Register(name string, driver driver.Driver)完成本驅動的注冊。

我們來看一下mysql、sqlite3的驅動里面都是怎么調用的,下面直接上代碼:

// 實現示例:
//https://github.com/mattn/go-sqlite3驅動
func init() {sql.Register("sqlite3", &SQLiteDriver{})
}//https://github.com/mikespook/mymysql驅動
// Driver automatically registered in database/sql
var d = Driver{proto: "tcp", raddr: "127.0.0.1:3306"}
func init() {Register("SET NAMES utf8")sql.Register("mymysql", &d)
}

**我們看到第三方數據庫驅動都是通過調用這個函數來注冊自己的數據庫驅動名稱以及相應的driver實現。在database/sql內部通過一個map來存儲用戶定義的相應驅動。**示例說明:

var drivers = make(map[string]driver.Driver)drivers[name] = driver

因此通過database/sql的注冊函數可以同時注冊多個數據庫驅動,只要不重復。

我們一般通過使用以下代碼來使用相應的接口和第三方庫

  import ("database/sql"_ "github.com/mattn/go-sqlite3")
一般的新手都會被這個_所迷惑,其實這個就是Go設計的巧妙之處,我們在變量賦值的時候經常看到這個符號,它是用來忽略變量賦值的占位符,那么包引入用到這個符號也是相似的作用,這兒使用_的意思是引入后面的包名而不直接使用這個包中定義的函數,變量等資源。同時我們引入上面的數據庫驅動包之后會自動去調用init函數,然后在init函數里面注冊這個數據庫驅動,這樣我們就可以在接下來的代碼中直接使用這個數據庫驅動了。

driver.Driver講解

Driver是一個數據庫驅動的接口,他定義了一個method: Open(name string),這個方法返回一個數據庫的Conn接口。

type Driver interface {Open(name string) (Conn, error)
}

返回的Conn只能用來進行一次goroutine的操作,也就是說不能把這個Conn應用于Go的多個goroutine里面。如下代碼會出現錯誤,如下所示:

...
go goroutineA (Conn)  //執行查詢操作
go goroutineB (Conn)  //執行插入操作
...

上面這樣的代碼可能會使Go不知道某個操作究竟是由哪個goroutine發起的,從而導致數據混亂,比如可能會把goroutineA里面執行的查詢操作的結果返回給goroutineB從而使B錯誤地把此結果當成自己執行的插入數據。

第三方驅動都會定義這個函數,它會解析name參數來獲取相關數據庫的連接信息,解析完成后,它將使用此信息來初始化一個Conn并返回它。

driver.Conn說明

Conn是一個數據庫連接的接口定義,他定義了一系列方法,這個Conn只能應用在一個goroutine里面,不能使用在多個goroutine里面.

type Conn interface {Prepare(query string) (Stmt, error)Close() errorBegin() (Tx, error)
}
  • **1.**Prepare函數返回與當前連接相關的執行Sql語句的準備狀態,可以進行查詢、刪除等操作。

    **2.**Close函數關閉當前的連接,執行釋放連接擁有的資源等清理工作。因為驅動實現了database/sql里面建議的conn pool,所以你不用再去實現緩存conn之類的,這樣會容易引起問題。

    **3.**Begin函數返回一個代表事務處理的Tx,通過它你可以進行查詢,更新等操作,或者對事務進行回滾、遞交。

driver.Stimt詳解

**Stmt是一種準備好的狀態,和Conn相關聯,而且只能應用于一個goroutine中,不能應用于多個goroutine。**實現代碼如下:

type Stmt interface {Close() errorNumInput() intExec(args []Value) (Result, error)Query(args []Value) (Rows, error)
}
  • Close函數關閉當前的鏈接狀態,但是如果當前正在執行query,query還是有效返回rows數據。

  • NumInput函數返回當前預留參數的個數,當返回>=0時數據庫驅動就會智能檢查調用者的參數。當數據庫驅動包不知道預留參數的時候,返回-1。

  • Exec函數執行Prepare準備好的sql,傳入參數執行update/insert等操作,返回Result數據

  • Query函數執行Prepare準備好的sql,傳入需要的參數執行select操作,返回Rows結果集

driver.Tx解釋

事務處理一般就兩個過程,遞交或者回滾。數據庫驅動里面也只需要實現這兩個函數就可以,代碼如下:

type Tx interface {Commit() errorRollback() error
}

**這兩個函數一個用來遞交一個事務,一個用來回滾事務。**大家可以在實際開發中感受一下這個的獨特特性,不懂的歡迎大家在評論區中分享,大家一起討論。

driver.Execer講解

driver.Execer是一個Conn可選擇實現的接口,功能有許多好的妙用,如果未使用這個接口,那么在調用DB.Exec,就會首先調用Prepare返回Stmt,然后執行Stmt的Exec,然后關閉Stmt。下面提供實現這個接口的示例代碼:

type Execer interface {Exec(query string, args []Value) (Result, error)
}

driver.Result講解

driver.Result是執行Update/Insert等操作返回的結果接口定義,LastInsertId函數返回由數據庫執行插入操作得到的自增ID號RowsAffected函數返回執行Update/Insert等操作影響的數據條目數。下面我們來為大家提供一下示例代碼:

type Result interface {LastInsertId() (int64, error)RowsAffected() (int64, error)
}

driver.Rows講解

其實Rows是執行查詢返回的結果集接口定義,Columns函數返回查詢數據庫表的字段信息,這個返回的slice和sql查詢的字段一一對應,而不是返回整個表的所有字段。Close函數用來關閉Rows迭代器。Next函數用來返回下一條數據,把數據賦值給dest。dest里面的元素必須是driver.Value的值除了string,返回的數據里面所有的string都必須要轉換成[]byte。如果最后沒數據了,Next函數最后返回io.EOF。示例代碼如下:

type Rows interface {Columns() []stringClose() errorNext(dest []Value) error
}

driver.RowsAffected講解

RowsAffected其實就是一個int64的別名,但是他實現了Result接口,用來底層實現Result的表示方式,代碼如下:

type RowsAffected int64func (RowsAffected) LastInsertId() (int64, error)func (v RowsAffected) RowsAffected() (int64, error)

driver.Value講解

Value其實就是一個空接口,他可以容納任何的數據,然后其實就是drive的Value是驅動必須能夠操作的Value,Value要么是nil,要么是下面的給出的數據類型。

type Value interface{} // 構建value接口// 數據類型
int64
float64
bool
[]byte
string   [*]除了Rows.Next返回的不能是string.
time.Time

database/sql說明

database/sqldatabase/sql/driver提供的接口基礎上定義了一些更高階的方法,用以簡化數據庫操作,同時內部還建議性地實現一個conn. pool,然后我們就可以得出一下結論,大家可以自己先思考一下,在結合我給的講解:

我們可以看到Open函數返回的是DB對象,里面有一個freeConn,它就是那個簡易的連接池。它的實現相當簡單或者說簡陋,就是當執行db.prepare -> db.prepareDC的時候會defer dc.releaseConn,然后調用db.putConn,也就是把這個連接放入連接池,每次調用db.conn的時候會先判斷freeConn的長度是否大于0,大于0說明有可以復用的conn,直接拿出來用就是了,如果不大于0,則創建一個conn,然后再返回之。

看完這些我在給大家提供代碼,大家可以參考,然后自己在試著敲敲下面的示例代碼:

type DB struct {driver 	 driver.Driverdsn    	 stringmu       sync.Mutex // protects freeConn and closedfreeConn []driver.Connclosed   bool
}

結語

我們這一期簡單的學習了一下數據庫連接的接口實現,并且為大家講解了些許的相關接口的實現,還有更多的知識大家需要自探索,后面我也會出一個專題來為大家詳細解釋的。

下一期我會為大家講解實現MYSQL數據庫,同時作為目前Internet上流行的網站構架方式是LAMP,其中的M即MySQL, 作為數據庫,MySQL以免費、開源、使用方便為優勢成為了很多Web開發的后端數據庫存儲引擎。歡迎大家期待與認可

在此謝謝大家的支持,你的關注和點贊會是我繼續努力寫文章的動力,也感謝大家能夠持續關注博主,謝謝大家的支持,周末會給大家寫一篇福利文章,大家敬請期待~~~

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/84138.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/84138.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/84138.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

解決MybatisPlus使用Druid1.2.11連接池查詢PG數據庫報Merge sql error的一種辦法

目錄 前言 一、問題重現 1、環境說明 2、重現步驟 3、錯誤信息 二、關于LATERAL 1、Lateral作用場景 2、在四至場景中使用 三、問題解決之道 1、源碼追蹤 2、關閉sql合并 3、改寫處理SQL 四、總結 前言 在博客:【寫在創作紀念日】基于SpringBoot和PostG…

嵌入式學習--江協51單片機day8

這個本來應該周末寫的,可是一直想偷懶,只能是拖到周一了,今天把51結個尾,明天開始學32了。 學習內容LCD1602,直流電機,AD/DA,紅外遙控 LCD1602 內部的框架結構 屏幕小于數據顯示區&#xff…

HUAWEI華為MateBook D 14 2021款i5,i7集顯非觸屏(NBD-WXX9,NbD-WFH9)原裝出廠Win10系統

適用型號:NbD-WFH9、NbD-WFE9A、NbD-WDH9B、NbD-WFE9、 鏈接:https://pan.baidu.com/s/1qTCbaQQa8xqLR-4Ooe3ytg?pwdvr7t 提取碼:vr7t 華為原廠WIN系統自帶所有驅動、出廠主題壁紙、系統屬性聯機支持標志、系統屬性專屬LOGO標志、Office…

【Python】Python 裝飾器的用法總結

在 Python 中,裝飾器(Decorator) 是一種設計模式,用于在不修改函數或類代碼的情況下動態地擴展其功能。裝飾器廣泛應用于日志記錄、性能監控、權限驗證等場景,提供了一種簡潔優雅的方式來“包裹”現有的代碼。本文將介…

【C++】控制臺小游戲

移動&#xff1a;W向上&#xff0c;S上下&#xff0c;A向左&#xff0c;D向右 程序代碼&#xff1a; #include <iostream> #include <conio.h> #include <windows.h> using namespace std;bool gameOver; const int width 20; const int height 17; int …

「MATLAB」計算校驗和 Checksum

什么是校驗和 是一個算法&#xff0c;將一串數據累加&#xff0c;得到一個和。 MATLAB程序 function c_use Checksum(packet) %Checksum 求校驗和 % 此處checksum提供詳細說明checksum 0;for i 1:length(packet)value hex2dec(packet(i));checksum checksum value; …

JavaScript面試題之消息隊列

JavaScript消息隊列詳解&#xff1a;單線程的異步魔法核心 在JavaScript的單線程世界中&#xff0c;消息隊列&#xff08;Message Queue&#xff09;是實現異步編程的核心機制&#xff0c;它像一位高效的調度員&#xff0c;讓代碼既能“一心多用”又避免卡頓。本文將深入剖析消…

京東外賣分潤系統部署實操!0門檻入駐+全平臺接入+自定義比例...這些人,賺翻了!

隨著京東外賣的發展勢頭日漸迅猛&#xff0c;許多創業者們的態度也逐漸從原本的觀望轉變為了切實的行動&#xff0c;并開始通過各個渠道詢問起了京東外賣自動分潤系統部署相關的各項事宜&#xff0c;連帶著以京東外賣自動分潤系統質量哪家強為代表的多個問題&#xff0c;也成為…

【辦公類-18-06】20250523(Python)“口腔檢查涂氟信息”批量生成打印(學號、姓名、學校、班級、身份證、戶籍、性別、民族)

背景需求: 6月是常規體檢,前幾天發了體檢表(驗血單),用Python做了姓名等信息的批量打印 【辦公類-18-04】20250520(Python)“驗血單信息”批量生成打印(學校、班級、姓名、性別)-CSDN博客文章瀏覽閱讀969次,點贊19次,收藏11次。【辦公類-18-04】20250520(Python)…

Python郵件處理:POP與SMTP

poplib簡介 poplib 是Python 3中的官方郵件庫&#xff0c;實現了POP的標準&#xff1a;RFC1939&#xff0c;用于郵件的收取。與之類似的還有imaplib 。 &#xff08;注&#xff1a;本文僅拿pop舉例&#xff09; poplib的使用方法&#xff0c;就是幾步&#xff1a; 先創建一…

IP風險度自檢,多維度守護網絡安全

如今IP地址不再只是網絡連接的標識符&#xff0c;更成為評估安全風險的核心維度。IP風險度通過多維度數據建模&#xff0c;量化IP地址在網絡環境中的安全威脅等級&#xff0c;已成為企業反欺詐、內容合規、入侵檢測的關鍵工具。據Gartner報告顯示&#xff0c;2025年全球78%的企…

Flink集成資源管理器

Flink集成資源管理器 Apache Flink 支持多種資源管理器&#xff0c;主要包括以下幾種?&#xff1a; YARN ResourceManager ?&#xff1a;適用于使用 Hadoop YARN 作為資源管理器的環境。YARN ResourceManager 負責管理集群中的資源&#xff0c;包括 CPU、內存等&#xff0c;并…

upload 文件上傳審計

目錄 LOW Medium HIgh Impossible 概述 很多Web站點都有文件上傳的接口&#xff08;比如注冊時上傳頭像等&#xff09;&#xff0c;由于沒有對上傳的文件類型進行嚴格限制&#xff0c;導致可以上傳一些文件&#xff08;比如Webshell&#xff09;。 上傳和SQL、XSS等都是主流…

【freertos-kernel】list

freertos list 基本類型結構體ListItem_t &#xff08;list.h&#xff09;List_t &#xff08;list.h&#xff09; 宏函數函數vListInitialisevListInitialiseItemvListInsertEndvListInsertuxListRemove 基本類型 freertos為了兼容性&#xff0c;重新定義了基本類型&#xff…

游戲盾的功有哪些?

游戲盾的功能主要包括以下幾方面&#xff1a; 一、網絡攻擊防護 DDoS攻擊防護&#xff1a; T級防御能力&#xff1a;游戲盾提供分布式云節點防御集群&#xff0c;可跨地區、跨機房動態擴展防御能力和負載容量&#xff0c;輕松達到T級別防御&#xff0c;有效抵御SYN Flood、UD…

PycharmFlask 學習心得:路由(3-4)

對路由的理解&#xff1a; 用戶輸入網址 例如&#xff1a;http://localhost:5000/hello 瀏覽器會向這個地址發起一個 HTTP 請求&#xff08;比如 GET 請求&#xff09; 請求到達 Flask 的服務器 Flask 監聽著某個端口&#xff08;如 5000&#xff09;&#xff0c;收到請求后…

課程與考核

6.1 課程講解與實戰考核 6.1.1 SQL注入篇考核 考核目標&#xff1a;通過手動注入與工具結合&#xff0c;獲取目標數據庫敏感信息。 題目示例&#xff1a; 目標URL&#xff1a;http://vuln-site.com/product?id1 要求&#xff1a; 判斷注入類型&#xff08;聯合查詢/報錯注…

線程池介紹,分類,實現(工作原理,核心組成,拒絕策略),固態線程池的實現+詳細解釋(支持超時取消機制和不同的拒絕策略)

目錄 線程池 介紹 分類 實現 工作原理 核心組成 拒絕策略 固態線程池 功能 std::future 實現 拒絕策略支持 提交任務 超時取消 用戶檢測取消 安全銷毀 代碼 測試 線程池 介紹 線程池(圖解,本質,模擬實現代碼),添加單例模式(懶漢思路代碼)_線程池單例-CSDN博…

紡線機與PLC通訊故障?ETHERCAT/CANopen網關秒解協議難題

在紡織行業智能化轉型浪潮中&#xff0c;設備間高效通信是實現自動化生產的關鍵。JH-ECT009疆鴻智能EtherCAT轉CANopen協議轉換網關&#xff0c;憑借出色的協議適配能力&#xff0c;成功架起倍福PLC與自動紡線機間的通信橋梁&#xff0c;為紡織廠自動化生產注入強勁動力。 紡織…

深度剖析并發I/O模型select、poll、epoll與IOCP核心機制

核心概要&#xff1a;select、poll、epoll 和 IOCP 是四種用于提升服務器并發處理能力的I/O模型或機制。前三者主要屬于I/O多路復用范疇&#xff0c;允許單個進程或線程監視多個I/O流的狀態&#xff1b;而 IOCP 則是一種更為徹底的異步I/O模型。 一、引言&#xff1a;為何需要這…