近期正在探索前端、后端、系統(tǒng)端各類常用組件與工具,對其一些常見的組件進行再次整理一下,形成標準化組件專題,后續(xù)該專題將包含各類語言中的一些常用組件。歡迎大家進行持續(xù)關注。
成都創(chuàng)新互聯(lián)服務項目包括申扎網(wǎng)站建設、申扎網(wǎng)站制作、申扎網(wǎng)頁制作以及申扎網(wǎng)絡營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術優(yōu)勢、行業(yè)經(jīng)驗、深度合作伙伴關系等,向廣大中小型企業(yè)、政府機構等提供互聯(lián)網(wǎng)行業(yè)的解決方案,申扎網(wǎng)站推廣取得了明顯的社會效益與經(jīng)濟效益。目前,我們服務的客戶以成都為中心已經(jīng)輻射到申扎省份的部分城市,未來相信會繼續(xù)擴大服務區(qū)域并繼續(xù)獲得客戶的支持與信任!
本節(jié)我們分享一個基于Golang的SQL解析器 sqlparser
使用方式如下:
當不同的SQL錯誤,將返回特定的錯誤信息,具體可以查看其官方提供的 README
讀取配置文件并啟動,在配置文件中設置的監(jiān)聽端口監(jiān)聽客戶端請求。
收到客戶端連接請求后,啟動一個goroutine單獨處理該請求。
首選進行登錄驗證,驗證過程完全兼容MySQL認證協(xié)議,由于用戶名和密碼在配置文件中已經(jīng)設置好,所以可以利用該信息驗證連接請求是否合法。
當用戶名和密碼都正確時,轉(zhuǎn)入下面的步驟,否則返回出錯信息給客戶端。
認證通過后,客戶端發(fā)送SQL語句。
kingshard對客戶端發(fā)送過來的SQL語句,進行詞法和語義分析,識別出SQL的類型和生成SQL的路由計劃。如果有必要還會改寫SQL,然后轉(zhuǎn)發(fā)到相應的DB。也有可能不做詞法和語義分析直接轉(zhuǎn)發(fā)到相應的后端DB。如果轉(zhuǎn)發(fā)SQL是分表且跨多個DB,則每個DB對應啟動一個goroutine發(fā)送SQL和接收該DB返回的結(jié)果。
接收并合并結(jié)果,然后轉(zhuǎn)發(fā)給客戶端。
Go語言操作數(shù)據(jù)庫非常的簡單,
他也有一個類似JDBC的東西"database/sql"
實現(xiàn)類是"github.com/go-sql-driver/mysql"
使用過JDBC的人應該一看就懂
對日期的處理比較晦澀,沒有JAVA流暢:
復制代碼代碼如下:
package main
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
"log"
"time"
)
/*
create table t(
id int primary key auto_increment,
name varchar(20) not null,
ts timestamp
);
*/
func insert(db *sql.DB) {
stmt, err := db.Prepare("insert into t(name,ts) values(?,?)")
defer stmt.Close()
if err != nil {
log.Println(err)
return
}
ts, _ := time.Parse("2006-01-02 15:04:05", "2014-08-28 15:04:00")
stmt.Exec("edmond", ts)
}
func main() {
db, err := sql.Open("mysql", "xx:xx@tcp(127.0.0.1:3306)/mvbox?charset=utf8")
if err != nil {
log.Fatalf("Open database error: %s\n", err)
}
defer db.Close()
err = db.Ping()
if err != nil {
log.Fatal(err)
}
Gorm是Go語言開發(fā)用的比較多的一個ORM。它的功能比較全:
但是這篇文章中并不會直接看Gorm的源碼,我們會先從database/sql分析。原因是Gorm也是基于這個包來封裝的一些功能。所以只有先了解了database/sql包才能更加好的理解Gorm源碼。
database/sql 其實也是一個對于mysql驅(qū)動的上層封裝?!眊ithub.com/go-sql-driver/mysql”就是一個對于mysql的驅(qū)動,database/sql 就是在這個基礎上做的基本封裝包含連接池的使用
下面這個是最基本的增刪改查操作
操作分下面幾個步驟:
因為Gorm的連接池就是使用database/sql包中的連接池,所以這里我們需要學習一下包里的連接池的源碼實現(xiàn)。其實所有連接池最重要的就是連接池對象、獲取函數(shù)、釋放函數(shù)下面來看一下database/sql中的連接池。
DB對象
獲取方法
釋放連接方法
連接池的實現(xiàn)有很多方法,在database/sql包中使用的是chan阻塞 使用map記錄等待列表,等到有連接釋放的時候再把連接傳入等待列表中的chan 不在阻塞返回連接。
之前我們看到的Redigo是使用一個chan 來阻塞,然后釋放的時候放入空閑列表,在往這一個chan中傳入struct{}{},讓程序繼續(xù) 獲取的時候再從空閑列表中獲取。并且使用的是鏈表的結(jié)構來存儲空閑列表。
database/sql 是對于mysql驅(qū)動的封裝,然而Gorm則是對于database/sql的再次封裝。讓我們可以更加簡單的實現(xiàn)對于mysql數(shù)據(jù)庫的操作。