Golang使用sqlite3數(shù)據(jù)庫(kù)實(shí)現(xiàn)CURD操作
工具類項(xiàng)目慢慢喜歡使用sqlite3數(shù)據(jù)庫(kù)。工具類項(xiàng)目不存在并發(fā)問題,部署項(xiàng)目也不需要額外去安裝數(shù)據(jù)庫(kù)服務(wù)端,非常省事。
1、安裝sqlite3驅(qū)動(dòng)
go get github.com/mattn/go-sqlite3
2、go連接sqlite3初始化方法
var db *sql.DB
func init() {
// 打開或創(chuàng)建一個(gè) SQLite 數(shù)據(jù)庫(kù)文件
var err error
db, err = sql.Open("sqlite3", "./db.db")
if err != nil {
log.Fatal(err)
}
// 測(cè)試連接
if err = db.Ping(); err != nil {
log.Fatal(err)
}
}
這里涉及到一個(gè)init()函數(shù)。在 Go 語(yǔ)言中,init() 函數(shù)是一個(gè)特殊的函數(shù),它在程序開始執(zhí)行時(shí)自動(dòng)調(diào)用,這里就可以拿來連接數(shù)據(jù)庫(kù)初始化操作。每個(gè)包都可以包含任意數(shù)量的 init() 函數(shù),并且這些函數(shù)會(huì)在包被導(dǎo)入時(shí)自動(dòng)執(zhí)行。init() 函數(shù)通常用于初始化操作,例如設(shè)置變量、打開文件或數(shù)據(jù)庫(kù)連接等。
init() 函數(shù)的特點(diǎn):
自動(dòng)調(diào)用:init() 函數(shù)不需要顯式調(diào)用,它們?cè)诎粚?dǎo)入時(shí)自動(dòng)執(zhí)行。
執(zhí)行順序:
- 如果一個(gè)包中有多個(gè) init() 函數(shù),它們會(huì)按照在源代碼中的順序依次執(zhí)行。
- 如果一個(gè)包導(dǎo)入了其他包,那么被導(dǎo)入包的 init() 函數(shù)會(huì)在導(dǎo)入它的包的 init() 函數(shù)之前執(zhí)行。
- 無參數(shù)和返回值:init() 函數(shù)沒有參數(shù)也沒有返回值。
- 不能被其他函數(shù)調(diào)用:init() 函數(shù)只能由運(yùn)行時(shí)系統(tǒng)調(diào)用,不能被其他函數(shù)調(diào)用。
3、測(cè)試Users結(jié)構(gòu)體
type Users struct {
ID int
Name string
Email string
}
結(jié)構(gòu)體字段的首字母是否大寫決定了該字段是否對(duì)包外可見(即是否具有公共訪問權(quán)限)
知識(shí)點(diǎn):
首字母大寫:如果一個(gè)標(biāo)識(shí)符(包括結(jié)構(gòu)體字段、函數(shù)名、變量名等)的首字母是大寫的,那么它就是可以被其他包訪問的,即它是“導(dǎo)出的”或“公開的”。
首字母小寫:如果一個(gè)標(biāo)識(shí)符的首字母是小寫的,那么它只能在其定義的包內(nèi)部訪問,對(duì)于其他包是不可見的,即它是“未導(dǎo)出的”或“私有的”。
4、users表CURD操作
// CreateUser 創(chuàng)建新用戶
func (u *Users) CreateUser() (int64, error) {
stmt, err := db.Prepare("INSERT INTO users (name, email) VALUES (?, ?)")
if err != nil {
return 0, err
}
res, err := stmt.Exec(u.Name, u.Email)
if err != nil {
return 0, err
}
return res.LastInsertId()
}
// GetUserByID 根據(jù) ID 獲取用戶
func (u *Users) GetUserByID(id int) error {
row := db.QueryRow("SELECT id, name, email FROM users WHERE id = ?", id)
return row.Scan(&u.ID, &u.Name, &u.Email)
}
// GetAllUsers 獲取所有用戶
func GetAllUsers() ([]*Users, error) {
rows, err := db.Query("SELECT id, name, email FROM users")
if err != nil {
return nil, err
}
defer rows.Close()
var users []*Users
for rows.Next() {
user := &Users{}
if err := rows.Scan(&user.ID, &user.Name, &user.Email); err != nil {
return nil, err
}
users = append(users, user)
}
if err := rows.Err(); err != nil {
return nil, err
}
return users, nil
}
// UpdateUser 更新用戶信息
func (u *Users) UpdateUser() (int64, error) {
stmt, err := db.Prepare("UPDATE users SET name = ?, email = ? WHERE id = ?")
if err != nil {
return 0, err
}
res, err := stmt.Exec(u.Name, u.Email, u.ID)
if err != nil {
return 0, err
}
return res.RowsAffected()
}
// DeleteUser 刪除用戶
func (u *Users) DeleteUser() (int64, error) {
stmt, err := db.Prepare("DELETE FROM users WHERE id = ?")
if err != nil {
return 0, err
}
res, err := stmt.Exec(u.ID)
if err != nil {
return 0, err
}
return res.RowsAffected()
}
這里的CURD操作,都是方法。方法是一種特殊類型的函數(shù),它有一個(gè)接收者(receiver)。接收者可以是任何類型的值或指針。這里的接收者就是(u *Users),用的是指針。
5、go使用sqlite3數(shù)據(jù)庫(kù)實(shí)現(xiàn)CURD操作
// main.go
package main
import (
"database/sql"
"fmt"
"log"
_ "github.com/mattn/go-sqlite3" // 導(dǎo)入 sqlite3 驅(qū)動(dòng)
)
type Users struct {
ID int
Name string
Email string
}
var db *sql.DB
func init() {
// 打開或創(chuàng)建一個(gè) SQLite 數(shù)據(jù)庫(kù)文件
var err error
db, err = sql.Open("sqlite3", "./db.db")
if err != nil {
log.Fatal(err)
}
// 測(cè)試連接
if err = db.Ping(); err != nil {
log.Fatal(err)
}
// 創(chuàng)建用戶表
createTableSQL := `
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
email TEXT NOT NULL UNIQUE
);
`
// 執(zhí)行 SQL 語(yǔ)句
_, err = db.Exec(createTableSQL)
if err != nil {
log.Fatal(err)
}
}
// CreateUser 創(chuàng)建新用戶
func (u *Users) CreateUser() (int64, error) {
stmt, err := db.Prepare("INSERT INTO users (name, email) VALUES (?, ?)")
if err != nil {
return 0, err
}
res, err := stmt.Exec(u.Name, u.Email)
if err != nil {
return 0, err
}
return res.LastInsertId()
}
// GetUserByID 根據(jù) ID 獲取用戶
func (u *Users) GetUserByID(id int) error {
row := db.QueryRow("SELECT id, name, email FROM users WHERE id = ?", id)
return row.Scan(&u.ID, &u.Name, &u.Email)
}
// GetAllUsers 獲取所有用戶
func GetAllUsers() ([]*Users, error) {
rows, err := db.Query("SELECT id, name, email FROM users")
if err != nil {
return nil, err
}
defer rows.Close()
var users []*Users
for rows.Next() {
user := &Users{}
if err := rows.Scan(&user.ID, &user.Name, &user.Email); err != nil {
return nil, err
}
users = append(users, user)
}
if err := rows.Err(); err != nil {
return nil, err
}
return users, nil
}
// UpdateUser 更新用戶信息
func (u *Users) UpdateUser() (int64, error) {
stmt, err := db.Prepare("UPDATE users SET name = ?, email = ? WHERE id = ?")
if err != nil {
return 0, err
}
res, err := stmt.Exec(u.Name, u.Email, u.ID)
if err != nil {
return 0, err
}
return res.RowsAffected()
}
// DeleteUser 刪除用戶
func (u *Users) DeleteUser() (int64, error) {
stmt, err := db.Prepare("DELETE FROM users WHERE id = ?")
if err != nil {
return 0, err
}
res, err := stmt.Exec(u.ID)
if err != nil {
return 0, err
}
return res.RowsAffected()
}
func main() {
fmt.Println("main函數(shù)開始...")
// 創(chuàng)建用戶
user := &Users{Name: "buddha", Email: "3539949705@qq.com"}
id, err := user.CreateUser()
if err != nil {
log.Fatalf("Failed to create user: %v", err)
}
fmt.Printf("Created user with ID: %d\n", id)
// 獲取用戶
user = &Users{}
if err := user.GetUserByID(int(id)); err != nil {
log.Fatalf("Failed to get user: %v", err)
}
fmt.Printf("User: ID: %d, Name: %s, Email: %s\n", user.ID, user.Name, user.Email)
// 更新用戶
user.Name = "buddha2080"
user.Email = "3539949704@qq.com"
affectedRows, err := user.UpdateUser()
if err != nil {
log.Fatalf("Failed to update user: %v", err)
}
fmt.Printf("Updated %d rows\n", affectedRows)
// 獲取所有用戶
users, err := GetAllUsers()
if err != nil {
log.Fatalf("Failed to get all users: %v", err)
}
for _, u := range users {
fmt.Printf("User: id: %d, name: %s, email: %s\n", u.ID, u.Name, u.Email)
}
// 刪除用戶
affectedRows, err = user.DeleteUser()
if err != nil {
log.Fatalf("Failed to delete user: %v", err)
}
fmt.Printf("Deleted %d rows\n", affectedRows)
fmt.Println("main函數(shù)結(jié)束...")
}
到此這篇關(guān)于Golang使用sqlite3數(shù)據(jù)庫(kù)實(shí)現(xiàn)CURD操作的文章就介紹到這了,更多相關(guān)Go sqlite3數(shù)據(jù)庫(kù)CURD操作內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
深入探索Go語(yǔ)言中的高效數(shù)據(jù)結(jié)構(gòu)堆
堆,作為一種基本的數(shù)據(jù)結(jié)構(gòu),以其在優(yōu)先隊(duì)列和排序算法中提供高效解決方案的能力而聞名。在本文中,我們將深入探討堆的內(nèi)部工作原理,包括其特性、實(shí)現(xiàn)細(xì)節(jié)以及在現(xiàn)代編程中的應(yīng)用2008-06-06
go帶緩沖chan實(shí)現(xiàn)消息隊(duì)列功能
本文主要介紹了go帶緩沖chan實(shí)現(xiàn)消息隊(duì)列功能,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-02-02
Golang運(yùn)行報(bào)錯(cuò)找不到包:package?xxx?is?not?in?GOROOT的解決過程
這篇文章主要給大家介紹了關(guān)于Golang運(yùn)行報(bào)錯(cuò)找不到包:package?xxx?is?not?in?GOROOT的解決過程,文中通過圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2022-07-07
Go語(yǔ)言通過反射實(shí)現(xiàn)獲取各種類型變量的值
反射是程序在運(yùn)行期間獲取變量的類型和值、或者執(zhí)行變量的方法的能力,這篇文章主要為大家講講Go語(yǔ)言通過反射獲取各種類型變量值的方法,需要的可以參考下2023-07-07
Go語(yǔ)言學(xué)習(xí)技巧之如何合理使用Pool
這篇文章主要給大家介紹了關(guān)于Go語(yǔ)言學(xué)習(xí)技巧之如何合理使用Pool的相關(guān)資料,Pool用于存儲(chǔ)那些被分配了但是沒有被使用,而未來可能會(huì)使用的值,以減小垃圾回收的壓力。文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下。2017-12-12
使用Go語(yǔ)言開發(fā)任務(wù)待辦清單Web應(yīng)用
在學(xué)習(xí) Go 的過程中,一個(gè)非常適合入門的 Web 項(xiàng)目就是 TodoList(任務(wù)待辦清單),本文將為大家詳細(xì)介紹一下具體實(shí)現(xiàn)方法,希望對(duì)大家有所幫助2025-09-09
Golang?Compare?And?Swap算法詳細(xì)介紹
CAS算法是一種有名的無鎖算法。無鎖編程,即不使用鎖的情況下實(shí)現(xiàn)多線程之間的變量同步,也就是在沒有線程被阻塞的情況下實(shí)現(xiàn)變量的同步,所以也叫非阻塞同步Non-blocking?Synchronization2022-10-10

