速成GO訪問sql,個人筆記

更多個人筆記:(僅供參考,非盈利)
gitee: https://gitee.com/harryhack/it_note
github: https://github.com/ZHLOVEYY/IT_note

本文是基于原生的庫 database/sql進行初步學習
基于ORM等更多操作可以關注我的博客和筆記倉庫

連接 MySQL 和基本 CRUD 操作

需要 go get -u github.com/go-sql-driver/mysql獲取sql驅動
自己先連接到sql的root數據庫,然后創建/fortest數據庫

package mainimport ("database/sql""fmt"_ "github.com/go-sql-driver/mysql" // 添加 MySQL 驅動。沒有直接使用包的對象所以加_"log"
)func main() {db, err := sql.Open("mysql", "root:1234@tcp(127.0.0.1:3306)/fortest") //這里是user:password@tcp(location)/database的形式,我的密碼是1234if err != nil {log.Fatal("連接失敗", err)}defer db.Close()//測試連接err = db.Ping()if err != nil {log.Fatal("連接失敗", err)}fmt.Println("連接成功")//創建表  注意用if no exists避免重復創建_, err = db.Exec(`CREATE TABLE IF NOT EXISTS gameusers (id INT AUTO_INCREMENT PRIMARY KEY,name VARCHAR(50),age INT)`)if err != nil {log.Fatal("創建表失敗:", err)}//插入數據result, err := db.Exec(`INSERT INTO gameusers (name, age) VALUES (?, ?)`, "Alice", 25)if err != nil {log.Fatal(err)}id, _ := result.LastInsertId() //用于獲取最新插入的IDfmt.Printf("插入成功,ID:%d\n", id)//再插入一條_, err = db.Exec(`INSERT INTO gameusers (name, age) VALUES (?, ?)`, "Alice2", 26)if err != nil {log.Fatal(err)}//查詢單條數據var name stringvar age int //方便查詢然后存儲進來err = db.QueryRow("SELECT name, age FROM gameusers WHERE id = ?", id).Scan(&name, &age)if err != nil {log.Fatal(err)}fmt.Printf("查詢結果: name=%s, age=%d\n", name, age)//查詢多條記錄rows, err := db.Query("SELECT * FROM gameusers") //*就是所有列的了// rows, err := db.Query("SELECT id,name,age from gameusers") //顯示指定列if err != nil {log.Fatal("查詢失敗", err)}defer rows.Close()//rows 是一個數據庫結果集,會占用數據庫連接和內存資源,如果不關閉,可能會導致資源泄露for rows.Next() { //類似于迭代器var userID interr := rows.Scan(&userID, &name, &age) //將當前行的數據讀取到指定的變量中if err != nil {log.Fatal("掃描失敗", err)}fmt.Printf("ID:%d ,姓名:%s,年齡:%d\n", userID, name, age)}//更新數據_, err = db.Exec("UPDATE gameusers SET age = ? WHERE id = ?", 26, id)if err != nil {log.Fatal("更新失敗", err)}fmt.Println("更新成功")//刪除數據_, err = db.Exec("DELETE FROM gameusers WHERE id =?", id)if err != nil {log.Fatal("刪除失敗", err)}fmt.Println("刪除成功")}

總結:

  • open():用于建立連接
    • 需要defer關閉數據庫連接防止浪費資源
  • ping():用于測試是否建立連接
  • exec():用于執行創建表,CRUD等操作
  • QueryRow():用于查詢單條數據
  • Query():用于多行查詢
    • 注意結合.Next迭代和Scan寫入
    • 需要defer關閉防止查詢一直連接浪費資源

事務和結構體映射

事務的特點:

  • 原子性:要么全部成功,要么全部失敗
  • 一致性:數據庫從一個一致狀態轉換到另一個一致狀態
  • 隔離性:事務執行不受其他事務影響
  • 持久性:一旦提交,修改就是永久的
    例子理解:
  • 假設你要給 A 轉賬 100 元給 B
  • 需要兩個操作:A 減 100,B 加 100
  • 如果 A 減 100 成功,但 B 加 100 失敗
  • 這時就需要 Rollback,撤銷 A 減 100 的操作
  • 確保賬戶金額不會出錯
package mainimport ("database/sql""fmt"_ "github.com/go-sql-driver/mysql" // 添加 MySQL 驅動。沒有直接使用包的對象所以加_"log"
)// User 結構體映射 users 表
type GameUser struct {ID   intName stringAge  int
}func main() {db, err := sql.Open("mysql", "root:1234@tcp(127.0.0.1:3306)/fortest")if err != nil {log.Fatal("連接失敗", err)}defer db.Close()//測試連接err = db.Ping()if err != nil {log.Fatal("連接失敗", err)}fmt.Println("連接成功")//創建表_, err = db.Exec(`CREATE TABLE IF NOT EXISTS gameusers (id INT AUTO_INCREMENT PRIMARY KEY,name VARCHAR(50),age INT)`)if err != nil {log.Fatal("創建表失敗:", err)}// 開啟事務tx, err := db.Begin()if err != nil {log.Fatal("事務開啟失敗", err)}//插入用戶result, err := tx.Exec("INSERT INTO gameusers (name, age) VALUES (?, ?)", "Bob", 30)if err != nil {tx.Rollback()log.Fatal("插入失敗", err)}id, _ := result.LastInsertId()fmt.Println("插入成功,用戶ID:", id)//更新用戶_, err = tx.Exec("UPDATE users SET age = ? WHERE id = ?", 31, id)if err != nil {tx.Rollback()log.Fatal("更新失敗:", err)}// 提交事務err = tx.Commit() //通過commit進行提交if err != nil {log.Fatal("事務提交失敗:", err)}fmt.Println("事務完成")//查詢并映射到結構體var user GameUsererr = db.QueryRow("SELECT id, name, age FROM gameusers WHERE id =?", id).Scan(&user.ID, &user.Name, &user.Age) //將查詢結果映射到user結構體if err != nil {log.Fatal("查詢失敗", err)}fmt.Printf("用戶信息: %+v\n", user)}

執行完會發現報錯:

連接成功
插入成功,用戶ID: 5
2025/04/25 10:12:03 更新失敗:Error 1146 (42S02): Table 'fortest.users' doesn't exist

(這個用戶id我插入很多次,會自己不斷增加的)
這時候檢查數據庫會發現,bob并沒有被插入,這是因為回滾了。那么接下來只要把上面代碼中更新部分的users改為gameusers就可以了

如果不希望總是寫tx.Rollback()
也可以增加:

    // 定義一個函數,確保在出錯時回滾事務defer func() {if err != nil {tx.Rollback()return}}()

這樣就會在最后進行統一的判斷

批量插入和預處理語句

預處理可以防sql注入,通過永遠使用 ? 占位符,避免直接拼接 SQL 語句

func main() {db, err := sql.Open("mysql", "root:1234@tcp(127.0.0.1:3306)/fortest")if err != nil {log.Fatal("連接錯誤", err)}defer db.Close()//準備預處理stmt, err := db.Prepare("INSERT INTO gameusers (name,age) values (?,?)")if err != nil {log.Fatal("預處理失敗", err)}defer stmt.Close()//批量插入users := []struct {   //定義結構體列表的同時初始化name stringage  int}{{"Charlie", 22},{"David", 28},{"Eve", 19},}for _, u := range users {_, err := stmt.Exec(u.name, u.age) //通過Exec傳遞參數進去if err != nil {log.Fatal("批量插入失敗", err)}}fmt.Println("批量插入完成")//查詢所有用戶rows, err := db.Query("SELECT id,name,age FROM gameusers")if err != nil {log.Fatal("查詢失敗", err)}defer rows.Close()for rows.Next() { //讀取數據var id intvar name stringvar age interr = rows.Scan(&id, &name, &age)if err != nil {log.Fatal("讀取是吧", err)}fmt.Printf("id:%d,name:%s,age:%d\n", id, name, age)}
}

還有比如查詢大數據時,限制返回行數(如 LIMIT),以及設置連接數和空閑連接數SetMaxOpenConns、SetMaxIdleConns等等,可以進一步拓展學習

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

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

相關文章

【C++指南】告別C字符串陷阱:如何實現封裝string?

🌟 各位看官好,我是egoist2023! 🌍 種一棵樹最好是十年前,其次是現在! 💬 注意:本章節只詳講string中常用接口及實現,有其他需求查閱文檔介紹。 🚀 今天通過了…

系統架構師2025年論文《論軟件架構評估2》

論軟件系統架構評估 v2.0 摘要: 某市醫院預約掛號系統建設推廣應用項目是我市衛生健康委員會 2019 年發起的一項醫療衛生行業便民惠民信息化項目,目的是實現轄區內患者在轄區各公立醫療機構就診時,可以通過多種線上渠道進行預約掛號,提升就醫體驗。我作為系統架構師參與此…

BEVDet4D: Exploit Temporal Cues in Multi-camera 3D Object Detection

背景 對于現有的BEVDet方法,它對于速度的預測誤差要高于基于點云的方法,對于像速度這種與時間有關的屬性,僅靠單幀數據很難預測好。因此本文提出了BEVDet4D,旨在獲取時間維度上的豐富信息。它是在BEVDet的基礎上進行拓展,保留了之前幀的BEV特征,并將其進行空間對齊后與當…

el-upload 上傳邏輯和ui解耦,上傳七牛

解耦的作用在于如果后面要我改成從阿里云oss上傳文件,我只需要實現上傳邏輯從七牛改成阿里云即可,其他不用動。實現方式有2部分組成,一部分是上傳邏輯,一部分是ui。 上傳邏輯 大概邏輯就是先去服務端拿上傳token和地址&#xff0…

酒水類目電商代運營公司-品融電商:全域策略驅動品牌長效增長

酒水類目電商代運營公司-品融電商:全域策略驅動品牌長效增長 在競爭日益激烈的酒水市場中,品牌如何快速突圍并實現長效增長?品融電商憑借「效品合一 全域增長」方法論與全鏈路運營能力,成為酒水類目代運營的領跑者。從品牌定位、視…

機器學習特征工程中的數值分箱技術:原理、方法與實例解析

標題:機器學習特征工程中的數值分箱技術:原理、方法與實例解析 摘要: 分箱技術作為機器學習特征工程中的關鍵環節,通過將數值數據劃分為離散區間,能夠有效提升模型對非線性關系的捕捉能力,同時增強模型對異…

【MySQL專欄】MySQL數據庫的復合查詢語句

文章目錄 1、首先練習MySQL基本語句的練習①查詢工資高于500或崗位為MANAGER的雇員,同時還要滿足他們的姓名首字母為大寫的J②按照部門號升序而雇員的工資降序排序③使用年薪進行降序排序④顯示工資最高的員工的名字和工作崗位⑤顯示工資高于平均工資的員工信息⑥顯…

Python爬蟲(5)靜態頁面抓取實戰:requests庫請求頭配置與反反爬策略詳解

目錄 一、背景與需求?二、靜態頁面抓取的核心流程?三、requests庫基礎與請求頭配置?3.1 安裝與基本請求3.2 請求頭核心參數解析?3.3 自定義請求頭實戰 四、實戰案例:抓取豆瓣讀書Top250?1. 目標?2. 代碼實現3. 技術要點? 五、高階技巧與反反爬策略?5.1 動態…

HTML給圖片居中

在不同的布局場景下&#xff0c;讓 <img> 元素居中的方法有所不同。下面為你介紹幾種常見的居中方式 1. 塊級元素下的水平居中 如果 <img> 元素是塊級元素&#xff08;可以通過 display: block 設置&#xff09;&#xff0c;可以使用 margin: 0 auto 來實現水平居…

【高頻考點精講】前端構建工具對比:Webpack、Vite、Rollup和Parcel

前端構建工具大亂斗:Webpack、Vite、Rollup和Parcel誰是你的菜? 【初級】前端開發工程師面試100題(一) 【初級】前端開發工程師面試100題(二) 【初級】前端開發工程師的面試100題(速記版) 最近在后臺收到不少同學提問:“老李啊,現在前端構建工具這么多,我該選哪個?…

趕緊收藏!教您如何用 GitHub 賬號,獲取永久免費的 Docker 容器!!快速搭建我們的網站/應用!

文章目錄 ?? 介紹 ???? 演示環境 ???? 永久免費的 Docker 容器 ???? 注冊與登錄? 創建 Docker 容器?? 部署你的網站?? 注意事項?? 使用場景?? 相關鏈接 ???? 介紹 ?? 還在為搭建個人網站尋找免費方案而煩惱? 今天發現一個寶藏平臺!只需一個 Git…

Java大師成長計劃之第3天:Java中的異常處理機制

&#x1f4e2; 友情提示&#xff1a; 本文由銀河易創AI&#xff08;https://ai.eaigx.com&#xff09;平臺gpt-4o-mini模型輔助創作完成&#xff0c;旨在提供靈感參考與技術分享&#xff0c;文中關鍵數據、代碼與結論建議通過官方渠道驗證。 在 Java 編程中&#xff0c;異常處理…

大數據去重

實驗4 大數據去重 1.實驗目的 通過Hadoop數據去重實驗&#xff0c;學生可以掌握準備數據、偽分布式文件系統配置方法&#xff0c;以及在集成開發環境Eclipse中實現Hadoop數據去重方法。 2.實驗要求 了解基于Hadoop處理平臺的大數據去重過程&#xff0c;理解其主要功能&…

http協議、全站https

一、http協議 1、為何要學http協議? 用戶用瀏覽器訪問網頁,默認走的都是http協議,所以要深入研究web層,必須掌握http協議 2、什么是http協議 1、全稱Hyper Text Transfer Protocol(超文本傳輸協議) ### 一個請求得到一個響應包 普通…

使用 Logstash 遷移 MongoDB 數據到 Easysearch

大家好&#xff01;在前面的文章中&#xff0c;我們已經詳細介紹了如何通過 Logstash 和 Canal 工具實現 MySQL 數據向 Easysearch 的遷移。如果您正在使用 MongoDB 作為數據存儲&#xff0c;并希望將其數據遷移到 Easysearch 中&#xff0c;這篇指南或許能為您提供一些幫助。 …

亞馬遜英國站FBA費用重構:輕小商品迎紅利期,跨境賣家如何搶占先機?

一、政策背景&#xff1a;成本優化成平臺與賣家共同訴求 2024年4月&#xff0c;亞馬遜英國站&#xff08;Amazon.co.uk&#xff09;發布近三年來力度最大的FBA費用調整方案&#xff0c;標志著英國電商市場正式進入精細化成本管理時代。這一決策背后&#xff0c;是多重因素的疊…

使用Qt Quick Controls創建自定義日歷組件

目錄 引言相關閱讀1. DayOfWeekRow2. MonthGrid3. WeekNumberColumn 項目結構及實現工程結構圖代碼實現及解析1. 組件封裝2. 主界面實現 運行效果 總結下載鏈接 引言 Qt6 Quick框架提供了一套豐富的日歷相關組件&#xff0c;包括 MonthGrid、DayOfWeekRow 和 WeekNumberColumn…

【AI微信小程序開發】大轉盤小程序項目代碼:自設轉盤選項和概率(含完整前端+后端代碼)

系列文章目錄 【AI微信小程序開發】AI減脂菜譜小程序項目代碼:根據用戶身高/體重等信息定制菜譜(含完整前端+后端代碼)【AI微信小程序開發】AI菜譜推薦小程序項目代碼:根據剩余食材智能生成菜譜(含完整前端+后端代碼)【AI微信小程序開發】圖片工具小程序項目代碼:圖片壓…

redis相關問題整理

Redis 支持多種數據類型&#xff1a; 字符串 示例&#xff1a;存儲用戶信息 // 假設我們使用 redis-plus-plus 客戶端庫 auto redis Redis("tcp://127.0.0.1:6379"); redis.set("user:1000", "{name: John Doe, email: john.doeexample.com}"…

Vue-組件的懶加載,按需加載

在Vue項目中實現組件的懶加載&#xff08;也稱為按需加載或代碼分割&#xff09;&#xff0c;可以大大提升應用的加載速度和性能。懶加載主要通過Webpack的代碼分割功能實現&#xff0c;特別是使用動態導入&#xff08;import()語法&#xff09;。 為什么要使用懶加載&#xf…