Golang操作SQLite数据库可以通过标准库的database/sql包配合第三方驱动实现,也可以借助sqlx这类扩展库简化操作,下面将从基础到实践逐步讲解完整的实现过程。
环境准备与依赖引入
首先需要安装SQLite的Golang驱动,常用的驱动是github.com/mattn/go-sqlite3,执行以下命令安装依赖:
go get github.com/mattn/go-sqlite3
如果使用sqlx扩展库,还需要安装sqlx依赖:
go get github.com/jmoiron/sqlx
使用标准库实现CRUD操作
数据库连接
使用database/sql包连接SQLite数据库,SQLite是文件型数据库,连接字符串为数据库文件的路径,如果文件不存在会自动创建。
package main
import (
"database/sql"
"fmt"
"log"
_ "github.com/mattn/go-sqlite3"
)
func main() {
// 连接SQLite数据库,test.db为数据库文件名
db, err := sql.Open("sqlite3", "./test.db")
if err != nil {
log.Fatal("数据库连接失败:", err)
}
defer db.Close()
// 验证数据库连接是否正常
err = db.Ping()
if err != nil {
log.Fatal("数据库连接验证失败:", err)
}
fmt.Println("SQLite数据库连接成功")
}
创建数据表
操作数据前需要先创建对应的数据表,这里以用户表user为例,包含id、name、age三个字段。
// 创建用户表
func createTable(db *sql.DB) {
createTableSQL := `CREATE TABLE IF NOT EXISTS user (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
age INTEGER
);`
_, err := db.Exec(createTableSQL)
if err != nil {
log.Fatal("创建数据表失败:", err)
}
fmt.Println("用户表创建成功")
}
新增数据(Create)
向user表中插入一条用户数据,使用Exec方法执行插入语句,通过占位符传递参数避免SQL注入。
// 插入用户数据
func insertUser(db *sql.DB, name string, age int) {
insertSQL := `INSERT INTO user (name, age) VALUES (?, ?)`
result, err := db.Exec(insertSQL, name, age)
if err != nil {
log.Fatal("插入数据失败:", err)
}
// 获取插入数据的自增ID
id, err := result.LastInsertId()
if err != nil {
log.Fatal("获取插入ID失败:", err)
}
fmt.Printf("插入用户成功,用户ID为: %dn", id)
}
查询数据(Read)
查询数据分为查询单条和查询多条,单条查询使用QueryRow方法,多条查询使用Query方法,需要手动关闭结果集。
// 查询单条用户数据
func querySingleUser(db *sql.DB, id int) {
var name string
var age int
querySQL := `SELECT name, age FROM user WHERE id = ?`
err := db.QueryRow(querySQL, id).Scan(&name, &age)
if err != nil {
log.Fatal("查询单条数据失败:", err)
}
fmt.Printf("查询到用户: ID=%d, 姓名=%s, 年龄=%dn", id, name, age)
}
// 查询所有用户数据
func queryAllUsers(db *sql.DB) {
querySQL := `SELECT id, name, age FROM user`
rows, err := db.Query(querySQL)
if err != nil {
log.Fatal("查询所有数据失败:", err)
}
defer rows.Close()
fmt.Println("所有用户列表:")
for rows.Next() {
var id, age int
var name string
err := rows.Scan(&id, &name, &age)
if err != nil {
log.Fatal("解析数据失败:", err)
}
fmt.Printf("ID=%d, 姓名=%s, 年龄=%dn", id, name, age)
}
// 检查遍历过程中是否有错误
if err = rows.Err(); err != nil {
log.Fatal("遍历数据出错:", err)
}
}
更新数据(Update)
更新user表中指定ID的用户年龄,使用Exec方法执行更新语句,通过RowsAffected获取受影响的行数。
// 更新用户年龄
func updateUserAge(db *sql.DB, id int, newAge int) {
updateSQL := `UPDATE user SET age = ? WHERE id = ?`
result, err := db.Exec(updateSQL, newAge, id)
if err != nil {
log.Fatal("更新数据失败:", err)
}
affectedRows, err := result.RowsAffected()
if err != nil {
log.Fatal("获取受影响行数失败:", err)
}
fmt.Printf("更新成功,受影响行数: %dn", affectedRows)
}
删除数据(Delete)
删除user表中指定ID的用户数据,同样通过RowsAffected确认删除是否生效。
// 删除用户数据
func deleteUser(db *sql.DB, id int) {
deleteSQL := `DELETE FROM user WHERE id = ?`
result, err := db.Exec(deleteSQL, id)
if err != nil {
log.Fatal("删除数据失败:", err)
}
affectedRows, err := result.RowsAffected()
if err != nil {
log.Fatal("获取受影响行数失败:", err)
}
fmt.Printf("删除成功,受影响行数: %dn", affectedRows)
}
使用sqlx简化CRUD操作
sqlx是对database/sql的扩展,支持结构体映射,不需要手动调用Scan方法解析数据,操作更简洁。首先需要定义对应的结构体:
import (
"github.com/jmoiron/sqlx"
_ "github.com/mattn/go-sqlite3"
)
// 用户结构体,对应user表
type User struct {
ID int `db:"id"`
Name string `db:"name"`
Age int `db:"age"`
}
sqlx查询示例
使用sqlx的Get方法查询单条数据,Select方法查询多条数据,自动映射到结构体。
// sqlx查询单条用户
func querySingleUserWithSqlx(db *sqlx.DB, id int) {
var user User
querySQL := `SELECT id, name, age FROM user WHERE id = ?`
err := db.Get(&user, querySQL, id)
if err != nil {
log.Fatal("sqlx查询单条数据失败:", err)
}
fmt.Printf("sqlx查询到用户: %+vn", user)
}
// sqlx查询所有用户
func queryAllUsersWithSqlx(db *sqlx.DB) {
var users []User
querySQL := `SELECT id, name, age FROM user`
err := db.Select(&users, querySQL)
if err != nil {
log.Fatal("sqlx查询所有数据失败:", err)
}
fmt.Println("sqlx查询所有用户:")
for _, user := range users {
fmt.Printf("%+vn", user)
}
}
sqlx插入示例
sqlx的插入操作和标准库类似,也支持结构体参数传递,这里展示基础插入方式:
// sqlx插入用户
func insertUserWithSqlx(db *sqlx.DB, name string, age int) {
insertSQL := `INSERT INTO user (name, age) VALUES (?, ?)`
result, err := db.Exec(insertSQL, name, age)
if err != nil {
log.Fatal("sqlx插入数据失败:", err)
}
id, err := result.LastInsertId()
if err != nil {
log.Fatal("sqlx获取插入ID失败:", err)
}
fmt.Printf("sqlx插入用户成功,用户ID为: %dn", id)
}
完整调用示例
将上面的方法整合起来,按顺序执行创建表、增删改查操作:
func main() {
// 标准库操作示例
db, err := sql.Open("sqlite3", "./test.db")
if err != nil {
log.Fatal(err)
}
defer db.Close()
createTable(db)
insertUser(db, "张三", 25)
insertUser(db, "李四", 30)
querySingleUser(db, 1)
queryAllUsers(db)
updateUserAge(db, 1, 26)
querySingleUser(db, 1)
deleteUser(db, 2)
queryAllUsers(db)
// sqlx操作示例
sqlxDB, err := sqlx.Open("sqlite3", "./test.db")
if err != nil {
log.Fatal(err)
}
defer sqlxDB.Close()
insertUserWithSqlx(sqlxDB, "王五", 28)
querySingleUserWithSqlx(sqlxDB, 3)
queryAllUsersWithSqlx(sqlxDB)
}
注意事项
- SQLite是文件型数据库,需要确保程序对数据库文件所在目录有读写权限
- 操作完成后及时关闭数据库连接,避免资源泄露
- 执行查询操作后,如果是多条查询需要手动关闭rows结果集
- SQL语句中的占位符在SQLite驱动中统一使用问号?,不要使用其他占位符
- 生产环境中建议添加事务支持,保证数据操作的原子性
GolangSQLiteCRUDdatabase_sqlsqlx修改时间:2026-06-29 20:43:07