使用 sqlc 生成类型安全的Go代码与SQL数据库交互

目录

  • 什么是sqlc
  • [安装sqlc:`brew install sqlc`](#安装sqlc:brew install sqlc)
  • 使用sqlc
    • [1. 创建SQL文件](#1. 创建SQL文件)
    • [2. 编写sqlc配置文件:sqlc.yaml](#2. 编写sqlc配置文件:sqlc.yaml)
    • [3. 生成代码:`sqlc generate`](#3. 生成代码:sqlc generate)
    • [4. 使用生成的代码](#4. 使用生成的代码)

什么是sqlc

sqlc 官方文档

sqlc 是一个用于生成类型安全的 Go 代码的工具,用于与 SQL 数据库进行交互。它通过分析 SQL 查询语句来生成 Go 代码,该代码映射数据库表和列,并提供类型安全的方法来执行查询、插入、更新和删除等操作。

sqlc 支持多种 SQL 数据库,包括 PostgreSQL、MySQL、SQLite、Microsoft SQL Server 等。它通过配置文件定义数据库模式,并生成 Go 代码以便与数据库进行交互。这使得在 Go 项目中使用 SQL 数据库变得更加容易和类型安全。

安装sqlc:brew install sqlc

在 macOS 上,可以使用 Homebrew 进行安装,只需运行以下命令:

bash 复制代码
brew install sqlc

安装完成后,可以验证是否成功安装 sqlc,运行以下命令检查版本信息:

bash 复制代码
sqlc version

查看命令帮助

bash 复制代码
sqlc help

使用sqlc

1. 创建SQL文件

首先,在你的项目中创建 SQL 文件,以定义数据库表结构和 SQL 查询语句。例如,你可以创建一个 create.sql 文件,用于定义数据库表结构,并创建一个 query.sql 文件,用于包含查询语句。在这些 SQL 文件中,你可以定义数据库表、列以及各种 SQL 查询,如创建、查询、更新和删除等。

/sql/create.sql

sql 复制代码
# 数据库初始化
-- 创建库
create database if not exists dbnamexxx;

-- 切换库
use dbnamexxx;

-- 用户表
create table if not exists user
(
    id           bigint auto_increment comment 'id' primary key,
    userAccount  varchar(256)                           not null comment '账号',
    userPassword varchar(512)                           not null comment '密码',
    userRole     varchar(256) default 'user'            not null comment '用户角色:user / admin',
    userName     varchar(256)                           null comment '用户昵称',
    userAvatar   varchar(1024)                          null comment '用户头像',
    gender       tinyint                                null comment '性别',
    createTime   datetime     default CURRENT_TIMESTAMP not null comment '创建时间',
    updateTime   datetime     default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',
    isDelete     tinyint      default 0                 not null comment '是否删除',
    constraint uni_userAccount UNIQUE (userAccount),
) comment '用户';

/sql/query.sql

sql 复制代码
-- name: GetUserInfoById :one
SELECT * FROM `user`
WHERE `id` = ? AND `isDelete` = 0 LIMIT 1;

-- name: ListUsers :many
SELECT * FROM `user`
WHERE `isDelete` = 0
ORDER BY id
LIMIT ?
OFFSET ?;

-- name: CreateUser :execresult
insert into `user` (
    `userAccount`, `userPassword`
    ) values (
        ?, ?
    );

-- name: DeleteUser :exec
UPDATE `user` set `isDelete` = 1 
WHERE id = ?;

2. 编写sqlc配置文件:sqlc.yaml

创建一个名为 sqlc.yaml 的配置文件,用于指定 sqlc 如何生成 Go 代码。在配置文件中,你需要指定 SQL 文件的位置、生成的包名、生成代码的输出目录以及其他选项。这个配置文件告诉 sqlc 如何处理你的 SQL 查询和数据库模式。

/sqlc.yaml

yml 复制代码
version: 2
sql:
  - engine: "mysql"
    # 包含数据库迁移文件的目录[迁移文件存放目录]
    schema: "./sql/create"
    # 指定在哪里查找 SQL 查询语句[sql查询语句存放路径]
    queries: "./sql/query"
    gen:
      go:
        #生成文件目录
        package: "dbsq"
        out: "dbsq"
        emit_prepared_queries: true
        emit_empty_slices: false
        emit_exported_queries: false
        emit_methods_with_db_argument: false
        emit_pointers_for_null_types: true
        emit_enum_valid_method: false
        emit_all_enum_values: false
        emit_interface: false
        # 如果为true,则结构名称将镜像表名称。否则,sqlc会尝试将多个表名单独化。默认为false。
        emit_exact_table_names: false
        # 如果为true,请将JSON标记添加到生成的结构中。默认为false
        emit_json_tags: true
        # 如果为true,则查询结果将作为指向结构的指针返回。返回多个结果的查询将作为指针切片返回。默认为false。
        emit_result_struct_pointers: true
        # 如果为true,则参数将作为指向结构的指针传递。默认为false。
        emit_params_struct_pointers: true
        # 如果为true,json标记中的"Id"将为大写。如果为false,则为camelcase。默认为false
        json_tags_id_uppercase: true
        # camelCase使用camel,pascal使用PascalCase,snake使用snake_case或none使用DB中的列名。默认为无。
        json_tags_case_style: "snake"

3. 生成代码:sqlc generate

在终端中,进入项目根目录,并执行以下命令,使用 sqlc 生成 Go 代码:

bash 复制代码
sqlc generate

sqlc 将分析 SQL 文件并生成相应的 Go 代码,包括类型定义、查询函数等。

4. 使用生成的代码

现在,你可以在你的 Go 项目中使用生成的代码。这些代码包括了与数据库交互的类型安全函数,使你能够执行查询、插入、更新和删除等操作。你可以直接调用这些函数,并将其与你的数据库连接一起使用。

bash 复制代码
package main

import (
    "context"
    "database/sql"
    "log"

    _ "github.com/go-sql-driver/mysql"
    "github.com/your-username/your-project/queries" // 替换成你的项目路径
)

func main() {
    // 连接数据库
    db, err := sql.Open("mysql", "user:password@tcp(host:port)/database")
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()

    // 查询用户信息
    var id int64 = 1
    user, err := q.GetUserInfoById(context.Background(), id)
    if err != nil {
        if err == sql.ErrNoRows {
            log.Println("User not found")
        } else {
            log.Fatal(err)
        }
    }
}
相关推荐
楚枫默寒23 分钟前
mongodb备份脚本(单机+副本集)
数据库
NewCarRen23 分钟前
整合STPA、ISO 26262与SOTIF的自动驾驶安全需求推导与验证
人工智能·安全·自动驾驶·预期功能安全
芯盾时代1 小时前
低空经济网络安全体系
安全·web安全
小蒜学长1 小时前
springboot酒店客房管理系统设计与实现(代码+数据库+LW)
java·数据库·spring boot·后端
鹿鸣天涯1 小时前
关于进一步做好网络安全等级保护有关工作的问题释疑-【二级以上系统重新备案】、【备案证明有效期三年】
网络·安全·web安全
00后程序员张1 小时前
如何提高 IPA 安全性 多工具组合打造可复用的 iOS 加固与反编译防护体系(IPA 安全 iOS 加固 无源码混淆 Ipa Guard 实战)
android·安全·ios·小程序·uni-app·iphone·webview
小妖同学学AI1 小时前
Rust 深度解析:变量、可变性与所有权的“安全边界”
开发语言·安全·rust
准时准点睡觉2 小时前
window安装MYSQL5.5出错:a windows service with the name MYSQL alreadyexists....
数据库·windows·mysql
Yeats_Liao2 小时前
Go Web 编程快速入门 13 - 部署与运维:Docker容器化、Kubernetes编排与CI/CD
运维·前端·后端·golang
Yeats_Liao2 小时前
Go Web 编程快速入门 14 - 性能优化与最佳实践:Go应用性能分析、内存管理、并发编程最佳实践
前端·后端·性能优化·golang