当前位置: 首页 > article >正文

go使用sqlite3数据库实现CURD操作

工具类项目慢慢喜欢使用sqlite3数据库。工具类项目不存在并发问题,部署项目也不需要额外去安装数据库服务端,非常省事。

1、安装sqlite3驱动
go get github.com/mattn/go-sqlite3
2、go连接sqlite3初始化方法
var db *sql.DB

func init() {
	// 打开或创建一个 SQLite 数据库文件
	var err error
	db, err = sql.Open("sqlite3", "./db.db")
	if err != nil {
		log.Fatal(err)
	}
	// 测试连接
	if err = db.Ping(); err != nil {
		log.Fatal(err)
	}
}

这里涉及到一个init()函数。在 Go 语言中,init() 函数是一个特殊的函数,它在程序开始执行时自动调用,这里就可以拿来连接数据库初始化操作。每个包都可以包含任意数量的 init() 函数,并且这些函数会在包被导入时自动执行。init() 函数通常用于初始化操作,例如设置变量、打开文件或数据库连接等。

init() 函数的特点:

  • 自动调用:init() 函数不需要显式调用,它们在包被导入时自动执行。
  • 执行顺序:
    • 如果一个包中有多个 init() 函数,它们会按照在源代码中的顺序依次执行。
    • 如果一个包导入了其他包,那么被导入包的 init() 函数会在导入它的包的 init() 函数之前执行。
    • 无参数和返回值:init() 函数没有参数也没有返回值。
    • 不能被其他函数调用:init() 函数只能由运行时系统调用,不能被其他函数调用。
3、测试Users结构体
type Users struct {
	ID    int
	Name  string
	Email string
}

结构体字段的首字母是否大写决定了该字段是否对包外可见(即是否具有公共访问权限)

知识点:

  • 首字母大写:如果一个标识符(包括结构体字段、函数名、变量名等)的首字母是大写的,那么它就是可以被其他包访问的,即它是“导出的”或“公开的”。
  • 首字母小写:如果一个标识符的首字母是小写的,那么它只能在其定义的包内部访问,对于其他包是不可见的,即它是“未导出的”或“私有的”。
4、users表CURD操作
// CreateUser 创建新用户
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 根据 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操作,都是方法。方法是一种特殊类型的函数,它有一个接收者(receiver)。接收者可以是任何类型的值或指针。这里的接收者就是(u *Users),用的是指针。

5、go使用sqlite3数据库实现CURD操作
// main.go
package main

import (
	"database/sql"
	"fmt"
	"log"

	_ "github.com/mattn/go-sqlite3" // 导入 sqlite3 驱动
)

type Users struct {
	ID    int
	Name  string
	Email string
}

var db *sql.DB

func init() {
	// 打开或创建一个 SQLite 数据库文件
	var err error
	db, err = sql.Open("sqlite3", "./db.db")
	if err != nil {
		log.Fatal(err)
	}
	// 测试连接
	if err = db.Ping(); err != nil {
		log.Fatal(err)
	}
	// 创建用户表
	createTableSQL := `
	CREATE TABLE IF NOT EXISTS users (
		id INTEGER PRIMARY KEY,
		name TEXT NOT NULL,
		email TEXT NOT NULL UNIQUE
	);
	`
	// 执行 SQL 语句
	_, err = db.Exec(createTableSQL)
	if err != nil {
		log.Fatal(err)
	}
}

// CreateUser 创建新用户
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 根据 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函数开始...")

	// 创建用户
	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函数结束...")
}

在这里插入图片描述


http://www.kler.cn/a/416387.html

相关文章:

  • 根据导数的定义计算导函数
  • 使用YOLOv3进行实时活体检测:Python与OpenCV实现
  • 使用Grafana K6来测测你的系统负载能力
  • 分布式锁的实现原理
  • 深入讲解Spring Boot和Spring Cloud,外加图书管理系统实战!
  • 【模型剪枝】YOLOv8 模型剪枝实战 | 稀疏化-剪枝-微调
  • 深度学习—参数初始化及激活函数Day35
  • Redis(非关系型数据库)的作用 详细解读
  • Java中如何获取泛型类型信息
  • 【C++ 算法进阶】算法提升二十四
  • Mac——鼠标增强插件Mos
  • 力扣200 岛屿数量 Java版本
  • 怎么 php 基本都是外包 ?
  • 【湿度数据处理】中国地面气候资料日值数据集(V3.0)(MATLAB全代码)
  • MyBatis(mybatis_plus)中TypeHandler的使用教程
  • Java的LinkedList、HashSet与TreeSet
  • 基础Web安全|SQL注入
  • 【知识科普】设计模式之-责任链模式
  • 无人机+自组网+指挥车:空地一体化组网指挥系统技术详解
  • GO/Golang
  • AI开发:逻辑回归的概念 应用及开发初学- Python
  • 日常应用开发遇到的小问题二三则
  • Uniapp 安装安卓、IOS模拟器并调试
  • 长时间无事可做是个危险信号
  • aws出现创建ec2连接报错(网络问题)
  • webpack5 的五大核心配置(二)