MySQL-gorm-概要

1.save,update,create……才会对数据库更新,save语句浪费资源
GORM 要求使用 column: 指定列名,size: 指定长度,或 type: 精确指定 SQL 类型。
- 如果不指定 column,GORM 会把 Go 字段名转换为 snake_case 作为列名:UserName -> user_name,Username -> username。
- 附件:CONF_.docx(点击下载)
MySQL 基础知识
作用
MySQL是一个开源的关系型数据库管理系统,用于存储、管理和检索结构化数据。它支持SQL语言,提供ACID事务特性,广泛应用于Web应用开发。
基础语法详解
1. 数据库操作
-- 创建数据库
CREATE DATABASE database_name
[CHARACTER SET charset_name]
[COLLATE collation_name];
-- 使用数据库
USE database_name;
-- 删除数据库
DROP DATABASE database_name;
2. 表操作
-- 创建表
CREATE TABLE table_name (
column1 datatype [constraints],
column2 datatype [constraints],
...
[table_constraints]
);
-- 参数解释:
-- datatype: INT, VARCHAR(n), TEXT, DATE, DATETIME, DECIMAL(p,s)等
-- constraints:
-- PRIMARY KEY - 主键
-- NOT NULL - 非空
-- UNIQUE - 唯一
-- AUTO_INCREMENT - 自增
-- DEFAULT value - 默认值
-- FOREIGN KEY - 外键
-- 示例
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
email VARCHAR(100) NOT NULL,
age INT DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
3. 数据操作语言 (DML)
-- INSERT - 插入数据
INSERT INTO table_name (column1, column2, ...)
VALUES (value1, value2, ...);
-- SELECT - 查询数据
SELECT column1, column2, ...
FROM table_name
[WHERE condition]
[ORDER BY column [ASC|DESC]]
[LIMIT number];
-- UPDATE - 更新数据
UPDATE table_name
SET column1 = value1, column2 = value2, ...
[WHERE condition];
-- DELETE - 删除数据
DELETE FROM table_name
[WHERE condition];
4. 高级查询
-- JOIN 连接查询
SELECT columns
FROM table1
[INNER|LEFT|RIGHT] JOIN table2
ON table1.column = table2.column;
-- 聚合函数
SELECT COUNT(*), AVG(column), SUM(column), MAX(column), MIN(column)
FROM table_name
[GROUP BY column];
-- 子查询
SELECT * FROM table1
WHERE column IN (SELECT column FROM table2 WHERE condition);
GORM 基础知识
作用
GORM是Go语言的ORM(对象关系映射)库,它提供了面向对象的方式操作数据库,简化了数据库操作,支持MySQL、PostgreSQL、SQLite等数据库。
基础语法详解
1. 模型定义
import "gorm.io/gorm"
// 基础模型
type User struct {
gorm.Model // 包含ID, CreatedAt, UpdatedAt, DeletedAt
Name string `gorm:"type:varchar(100);not null"`
Email string `gorm:"type:varchar(100);uniqueIndex"`
Age int `gorm:"default:18"`
IsActive bool `gorm:"default:true"`
}
// 标签说明:
// type: 字段类型
// not null: 非空约束
// uniqueIndex: 唯一索引
// default: 默认值
// primaryKey: 主键
// autoIncrement: 自增
2. 连接数据库
import (
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
// 函数签名: gorm.Open(dialector, &gorm.Config{})
dsn := "user:password@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
3. 自动迁移
// 函数签名: db.AutoMigrate(dst ...interface{}) error
err := db.AutoMigrate(&User{}, &Product{})
4. CRUD 操作
Create – 创建记录
// 函数签名: db.Create(value interface{}) *gorm.DB
user := User{Name: "John", Email: "[email protected]"}
result := db.Create(&user)
// 批量创建
users := []User{
{Name: "Alice", Email: "[email protected]"},
{Name: "Bob", Email: "[email protected]"},
}
db.Create(&users)
Read – 查询记录
// 函数签名: db.First(dest interface{}, conds ...interface{}) *gorm.DB
var user User
db.First(&user, 1) // 根据主键查询
db.First(&user, "name = ?", "John")
// 查询所有记录
var users []User
db.Find(&users)
// 条件查询
db.Where("age > ?", 18).Find(&users)
db.Where("name LIKE ?", "%john%").Find(&users)
// 排序和限制
db.Order("created_at desc").Limit(10).Find(&users)
Update – 更新记录
// 函数签名: db.Model(dest interface{}).Updates(values interface{}) *gorm.DB
db.Model(&user).Update("Name", "John Updated")
db.Model(&user).Updates(User{Name: "New Name", Age: 30})
db.Model(&user).Updates(map[string]interface{}{"Name": "John", "Age": 25})
Delete – 删除记录
// 函数签名: db.Delete(dest interface{}, conds ...interface{}) *gorm.DB
db.Delete(&user) // 软删除(如果模型有DeletedAt字段)
db.Where("age < ?", 18).Delete(&User{}) // 条件删除
5. 关联关系
// 一对一关系
type User struct {
gorm.Model
Profile Profile
}
type Profile struct {
gorm.Model
UserID uint
Bio string
}
// 一对多关系
type User struct {
gorm.Model
Orders []Order
}
type Order struct {
gorm.Model
UserID uint
Amount float64
}
// 多对多关系
type User struct {
gorm.Model
Languages []Language `gorm:"many2many:user_languages;"`
}
type Language struct {
gorm.Model
Name string
}
6. 事务处理
// 函数签名: db.Transaction(fc func(tx *gorm.DB) error) error
err := db.Transaction(func(tx *gorm.DB) error {
if err := tx.Create(&user1).Error; err != nil {
return err
}
if err := tx.Create(&user2).Error; err != nil {
return err
}
return nil
})
7. 钩子函数(Hooks)
type User struct {
gorm.Model
Name string
}
// 创建前的钩子
func (u *User) BeforeCreate(tx *gorm.DB) error {
if u.Name == "" {
return errors.New("name cannot be empty")
}
return nil
}
// 更新前的钩子
func (u *User) BeforeUpdate(tx *gorm.DB) error {
u.UpdatedAt = time.Now()
return nil
}
完整示例
package main
import (
"fmt"
"log"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
type User struct {
ID uint `gorm:"primaryKey"`
Name string `gorm:"size:100;not null"`
Email string `gorm:"size:100;uniqueIndex"`
CreatedAt int64
}
func main() {
dsn := "root:password@tcp(127.0.0.1:3306)/testdb?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
log.Fatal(err)
}
// 自动迁移
db.AutoMigrate(&User{})
// 创建用户
user := User{Name: "Alice", Email: "[email protected]"}
db.Create(&user)
// 查询用户
var result User
db.First(&result, user.ID)
fmt.Printf("User: %+v\n", result)
// 更新用户
db.Model(&result).Update("Name", "Alice Updated")
// 删除用户
db.Delete(&result)
}
MySQL学习资源
B站视频: 搜索"MySQL从入门到精通"、"MySQL实战教程"
推荐课程:
"MySQL数据库全套教程" - 涵盖基础到高级
"SQL语句精讲" - 重点学习SQL语法
"MySQL性能优化" - 进阶学习
GORM学习资源
B站视频: 搜索"GORM教程"、"Go语言ORM实战"
官方文档: https://gorm.io/docs/
推荐课程:
"GORM从入门到实战"
"Go语言Web开发+GORM"
附件文档全文:GORM 文档与 CONF 文档
GORM 全面详细讲解
GORM(Go ORM)是Go语言生态中最流行的全功能ORM框架,专为Go语言设计,支持MySQL、PostgreSQL、SQLite、SQL Server等主流数据库,提供了优雅的链式调用、自动迁移、关联查询、事务管理等核心能力,大幅降低Go语言操作数据库的开发成本,是企业级Go项目的首选数据库操作框架。
目前GORM有两个主要版本,推荐新项目直接使用GORM v2(功能更完善、性能更优、API更统一),v1已进入维护阶段,不再新增功能:
- GORM v1:旧版核心包github.com/jinzhu/gorm,仅支持Go 1.12+,部分功能设计冗余;
- GORM v2:新版核心包gorm.io/gorm,要求Go 1.16+,重构了底层架构,新增批量操作、预加载优化、自定义插件等功能,是当前的主流版本。
下文所有讲解均基于GORM v2。
GORM v2将核心框架与数据库驱动解耦,需分别安装核心包和对应数据库的驱动(以最常用的MySQL为例):
Bash |
其他数据库驱动安装:
Bash |
通过gorm.Open建立数据库连接,第一个参数为驱动实例,第二个参数为GORM配置项(gorm.Config{})。
Go |
关键注意:*gorm.DB是并发安全的,项目中建议全局初始化一次,所有goroutine复用即可。
GORM通过Go结构体映射数据库表,称为「模型(Model)」,支持通过结构体标签(tag) 配置字段与列的映射关系,同时提供AutoMigrate实现「表结构自动同步」(仅创建表、添加列/索引,不会删除/修改现有列,避免数据丢失)。
Go |
Tag键 | 作用 |
primaryKey | 标记该字段为主键(支持复合主键:多个字段加该tag) |
autoIncrement | 主键自增(仅支持数值类型) |
size:n | 设置字段长度(如size:50,对应MySQL varchar(50)) |
not null | 设置字段非空 |
default:val | 设置字段默认值(如default:0、default:'unknown') |
unique | 为字段创建唯一索引 |
index | 为字段创建普通索引 |
comment:xxx | 为字段添加注释(生成表结构时自动带上) |
column:xxx | 自定义列名(如gorm:"column:user_name",覆盖默认蛇形命名) |
type:xxx | 自定义字段类型(如gorm:"type:longtext",对应MySQL longtext) |
- | 忽略该字段(不映射到数据库列) |
GORM提供优雅的链式调用实现增删改查,核心操作均基于*gorm.DB,且支持条件链式拼接(如Where+Limit+Order)。
Go |
Go |
GORM查询支持链式条件拼接,核心方法:First(单条,按主键升序)、Take(单条,无排序)、Last(单条,按主键降序)、Find(多条,返回切片)。
Go |
GORM的Where支持字符串占位符、结构体、Map三种条件格式,满足不同场景需求:
Go |
GORM更新分为模型更新和直接更新,推荐使用条件+指定字段更新,避免误更全部数据。
Go |
Go |
Go |
注意:无条件的更新/删除会被GORM阻止(防止误操作全表),如需强制执行,需添加Unscoped()或指定条件。
GORM支持物理删除(真正删除数据库记录)和软删除(仅更新DeletedAt字段,记录仍存在,查询时自动过滤),默认开启软删除(模型包含gorm.DeletedAt字段时)。
Go |
Go |
GORM支持手动事务和自动事务,满足不同场景的事务需求,核心基于Begin()开启事务,返回*gorm.DB事务对象,通过Commit()提交、Rollback()回滚。
Go |
通过Transaction(func(tx *gorm.DB) error)实现,函数内无错误则自动提交,有错误则自动回滚:
Go |
GORM支持主流的数据库关联关系,通过模型嵌套和Preload(预加载)实现关联查询,避免N+1查询问题(先查主表,再循环查关联表)。
Go |
对于复杂的查询(如多表联查、聚合查询、存储过程),GORM支持直接执行原生SQL,通过Raw和Exec实现:
Go |
初始化连接时的gorm.Config{}支持多种配置,优化框架行为:
Go |
- 全局复用*gorm.DB:*gorm.DB并发安全,项目中在init或启动函数中初始化一次,全局调用;
- 设置连接池参数:必须通过db.DB()获取底层sql.DB,设置SetMaxOpenConns和SetMaxIdleConns,避免高并发下连接耗尽;
- 优先使用条件更新/删除:禁止无条件的Update/Delete,防止误操作全表;
- 查询指定字段:使用Select指定需要的字段,避免查询全字段,提升数据库查询性能;
- 批量操作优先:插入/更新大量数据时,使用CreateInBatches/批量更新,避免循环单条操作,减少SQL请求次数;
- 开启SQL日志:开发环境开启日志(logger.Info),方便调试;生产环境关闭或设置为logger.Error,减少日志开销;
- 使用软删除:默认开启软删除(模型加DeletedAt),防止误删除数据,便于数据恢复;
- 关联查询用Preload:避免N+1查询问题,提升关联查询性能;
- 复杂逻辑用原生SQL:ORM无法覆盖所有复杂场景,此时直接使用Raw/Exec执行原生SQL,更高效;
- 事务包裹原子操作:涉及多表修改/多次数据库操作的原子逻辑,必须用事务包裹,保证数据一致性。
GORM v2是Go语言生态中功能完善、易用性高的ORM框架,核心优势如下:
- 支持主流数据库(MySQL/PostgreSQL/SQLite/SQL Server),解耦核心框架与驱动,扩展方便;
- 优雅的链式调用API,大幅降低数据库操作的代码量,提升开发效率;
- 内置自动迁移、软删除、事务管理、关联查询、批量操作等核心能力,满足企业级开发需求;
- 支持原生SQL执行,兼顾ORM的便捷性和原生SQL的灵活性;
- 并发安全的*gorm.DB,适合高并发Go项目。
开发中需重点掌握模型定义(Tag配置)、核心CURD、事务管理、关联查询四大核心能力,同时遵循最佳实践(连接池、批量操作、条件操作等),才能充分发挥GORM的优势,打造高效、稳定的Go数据库应用。
|(注:文档部分内容可能由 AI 生成)
MySQL 和 Redis 的配置文件格式选择是一个常见的问题。以下是对 cnf 格式和 YAML 格式的详细解释:
### cnf 格式配置文件的用途
**1. 原生支持**
- **MySQL**:my.cnf 是 MySQL 的官方默认配置文件格式,MySQL 服务启动时会自动读取
- **Redis**:redis.conf 是 Redis 的官方默认配置文件格式,Redis 服务启动时会自动读取
**2. 格式特点**
- 采用 INI 风格的配置格式,使用 `[section]` 划分不同配置区域
- 配置项采用 `key = value` 的形式,简洁明了
- 支持注释(以 `#` 开头)
- 是数据库和缓存服务的标准配置格式,被广泛使用
**3. 适用场景**
- **直接运行服务**:当直接在服务器上安装和运行 MySQL/Redis 时,使用 cnf 格式的配置文件
- **容器化部署**:在 Docker 容器中运行时,通常通过挂载 cnf 配置文件来覆盖默认配置
- **服务启动参数**:可以通过 `--defaults-file` 参数指定配置文件路径
### YAML 格式配置文件的用途
**1. 编排工具支持**
- **Docker Compose**:使用 docker-compose.yml 来定义和运行多容器 Docker 应用
- **Kubernetes**:使用 YAML 文件来定义 Pod、Service、Deployment 等资源
**2. 格式特点**
- 采用缩进的层次结构,更具可读性
- 支持列表、嵌套对象等复杂数据结构
- 配置更加结构化,适合定义多组件的关系
**3. 适用场景**
- **容器编排**:在使用 Docker Compose 或 Kubernetes 时,使用 YAML 文件定义服务配置
- **应用配置管理**:作为应用程序的配置文件,管理多个服务的配置
- **配置自动化**:便于版本控制和配置管理工具处理
### 两种格式的关系和使用建议
**1. 各司其职**
- **cnf 格式**:负责服务内部的具体配置参数
- **YAML 格式**:负责服务的编排和部署配置
**2. 在 Docker 环境中的使用**
- **docker-compose.yml**:定义服务的部署参数(端口映射、 volumes、环境变量等)
- **my.cnf/redis.conf**:通过 volumes 挂载到容器中,配置服务的具体参数
**3. 最佳实践**
- **保持分离**:将部署配置(YAML)与服务内部配置(cnf)分开管理
- **版本控制**:将两种配置文件都纳入版本控制系统
- **环境隔离**:为不同环境(开发、测试、生产)准备不同的配置文件
### 总结
- **cnf 格式**:是 MySQL 和 Redis 的原生配置格式,专注于服务内部的详细参数配置
- **YAML 格式**:是容器编排和配置管理的标准格式,专注于服务的部署和管理
- **两者配合使用**:在现代容器化环境中,通常同时使用这两种格式,各司其职,共同构成完整的配置体系
因此,即使在使用 YAML 进行容器编排的情况下,cnf 格式的配置文件仍然是必不可少的,因为它负责定义服务的具体运行参数。