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

【golang】ORM框架操作数据库

文章目录

  • 1. beego-orm
    • 1.1 介绍
    • 1.2 特性
    • 1.3 使用
      • 1.3.1 安装
      • 1.3.2 导入与初始化
      • 1.3.3 模型定义
        • 1.3.3.1 定义模型代码
        • 1.3.3.2 模型常用标签
      • 1.3.4 基本操作(CURD)
        • 1.3.4.1 创建orm实例
        • 1.3.4.2 插入数据
        • 1.3.4.3 查询数据
        • 1.3.4.4 更新数据
        • 1.3.4.5 删除数据
      • 1.3.5 高级查询(QueryTable)
      • 1.3.6 关联关系
        • 1.3.6.1 一对一
        • 1.3.6.2 一对多
        • 1.3.6.3 多对多
        • 1.3.6.4 关联操作
      • 1.3.7 事务处理(Begin&Rollback&Commit)
      • 1.3.8 支持原生sql(Raw)
      • 1.3.9 表结构同步
      • 1.3.10 连接池配置
      • 1.3.11 性能优化
      • 1.3.12 调试
      • 1.3.13 常见问题
        • 1.3.13.1 表名冲突
        • 1.3.13.2 字段映射问题
        • 1.3.13.3 时区问题

1. beego-orm

1.1 介绍

Beego ORM是Beego框架的官方对象关系映射组件,提供了一种面向对象的方式来操作数据库

1.2 特性

  1. 支持多种数据库:MySQL、PostgreSQL、SQLite、Oracle、MSSQL
  2. 自动表结构生成(Syncdb)
  3. 链式查询构建器(QuerySeter)
  4. 关联关系(一对一、一对多、多对多)
  5. 事务支持
  6. 连接池管理
  7. 原生SQL支持

1.3 使用

1.3.1 安装

go get github.com/beego/beego/v2

1.3.2 导入与初始化

import ("github.com/beego/beego/v2/adapter/orm"_ "github.com/go-sql-driver/mysql" // 导入对应数据库驱动,例如mysql
)func init() {// 注册驱动(可选)orm.RegisterDriver("mysql", orm.DRMySQL)// 注册默认数据库orm.RegisterDataBase("default", "mysql", "user:password@tcp(127.0.0.1:3306)/db_name?charset=utf8")// 注册模型orm.RegisterModel(new(User))
}

1.3.3 模型定义

1.3.3.1 定义模型代码
type User struct {Id       int       `orm:"auto;pk"`Username string    `orm:"size(100);unique"`Password string    `orm:"size(100)"`Age      int       `orm:"default(18)"`Created  time.Time `orm:"auto_now_add;type(datetime)"`Updated  time.Time `orm:"auto_now;type(datetime)"`
}// 自定义表名
func (u *User) TableName() string {return "users"
}
1.3.3.2 模型常用标签
标签描述示例
auto自增字段orm:"auto"
pk主键orm:"pk"
size字段大小orm:"size(100)"
default默认值orm:"default(0)"
null允许NULLorm:"null"
index创建索引orm:"index"
unique唯一约束orm:"unique"
auto_now更新时间orm:"auto_now"
auto_now_add创建时间orm:"auto_now_add"
type字段类型orm:"type(text)"

1.3.4 基本操作(CURD)

1.3.4.1 创建orm实例
o := orm.NewOrm()
1.3.4.2 插入数据
user := User{Username: "xujie",Password: "111111",Age:      29,
}// 插入数据语句
id, err := o.Insert(&user)
if err != nil {logs.Error("插入数据失败!!!")return
}
1.3.4.3 查询数据
// 通过主键查询
user := User{Id: 1}
_ := o.Read(&user)// 通过指定字段查询
user := User{Username: "test"}
_ := o.Read(&user, "Username")// 通过Filter方法查询多个
var users []*User// 在user表中查询年龄大于20岁的用户
num, err := o.QueryTable("user").Filter("age__gt", 20).All(&users)
if err != nil {logs.Error("查询数据失败!!!")return
}
1.3.4.4 更新数据
user := User{Id: 1}
if err := o.Read(&user); err == nil {user.Age = 30num, err := o.Update(&user)if err != nil {logs.Error("更新数据失败!!!")return
}
}
1.3.4.5 删除数据
// 根据id字段删除数据
num, _ := o.Delete(&User{Id: 1})

1.3.5 高级查询(QueryTable)

qs := o.QueryTable("user")// 条件查询
qs = qs.Filter("username", "test")             // WHERE username = 'test'
qs = qs.Filter("age__gt", 18)                  // WHERE age > 18
qs = qs.Filter("age__in", 18, 20, 22)          // WHERE age IN (18, 20, 22)
qs = qs.Filter("username__contains", "test")   // WHERE username LIKE '%test%'
qs = qs.Filter("username__startswith", "test") // WHERE username LIKE 'test%'
qs = qs.Filter("username__endswith", "test")   // WHERE username LIKE '%test'
qs = qs.Filter("profile__isnull", true)        // WHERE profile_id IS NULL// 排序
qs = qs.OrderBy("age", "-username") // ORDER BY age ASC, username DESC// 分页
qs = qs.Limit(10).Offset(20) // LIMIT 10 OFFSET 20// 聚合
count, _ := qs.Count()       // SELECT COUNT(*) FROM user
sum, _ := qs.Sum("age")      // SELECT SUM(age) FROM user
avg, _ := qs.Avg("age")      // SELECT AVG(age) FROM user
min, _ := qs.Min("age")      // SELECT MIN(age) FROM user
max, _ := qs.Max("age")      // SELECT MAX(age) FROM user

1.3.6 关联关系

1.3.6.1 一对一
type Profile struct {Id   intAge  intUser *User `orm:"reverse(one)"`
}type User struct {Id      intProfile *Profile `orm:"null;rel(one);on_delete(set_null)"`
}
1.3.6.2 一对多
type Post struct {Id    intTitle stringUser  *User  `orm:"rel(fk)"`
}type User struct {Id    intPosts []*Post `orm:"reverse(many)"`
}
1.3.6.3 多对多
type User struct {Id    intRoles []*Role `orm:"rel(m2m)"`
}type Role struct {Id    intUsers []*User `orm:"reverse(many)"`
}
1.3.6.4 关联操作
// 一对多
user := User{Id: 1}
posts := []*Post{{Title: "Post 1"},{Title: "Post 2"},
}
o.InsertMulti(len(posts), posts)// 多对多
role := Role{Id: 1}
m2m := o.QueryM2M(&role, "Users")
m2m.Add(&User{Id: 1})

1.3.7 事务处理(Begin&Rollback&Commit)

o := orm.NewOrm()
err := o.Begin()// 事务操作
user := User{Username: "test"}
_, err = o.Insert(&user)
if err != nil {o.Rollback()return err
}profile := Profile{User: &user}
_, err = o.Insert(&profile)
if err != nil {o.Rollback()return err
}return o.Commit()

1.3.8 支持原生sql(Raw)

// 执行原生SQL
o.Raw("UPDATE user SET name = ? WHERE id = ?", "test", 1).Exec()// 查询
var users []User
num, err := o.Raw("SELECT * FROM user WHERE age > ?", 18).QueryRows(&users)// 单行查询
var user User
err := o.Raw("SELECT * FROM user WHERE id = ?", 1).QueryRow(&user)

1.3.9 表结构同步

// 自动创建表
// force: 是否强制删除重建
// verbose: 是否打印执行日志
_ = orm.RunSyncdb("default", false, true)

1.3.10 连接池配置

// 设置最大空闲连接
orm.SetMaxIdleConns("default", 30)// 设置最大打开连接
orm.SetMaxOpenConns("default", 100)

1.3.11 性能优化

  1. 使用 Filter 替代 Exclude,后者性能较差
  2. 批量操作时使用 InsertMulti
  3. 避免 N+1 查询,使用 RelatedSel 预加载关联数据
  4. 复杂查询考虑使用原生 SQL
  5. 合理设置连接池大小

1.3.12 调试

// 开启调试模式
orm.Debug = true// 查看最后执行的SQL
lastQuery := o.LastQuery()

1.3.13 常见问题

1.3.13.1 表名冲突

实现 TableName 方法自定义表名:

func (u *User) TableName() string {return "users"
}
1.3.13.2 字段映射问题

确保数据库字段名与结构体字段名一致,或使用 column 标签

type User struct {UserName string `orm:"column(username)"`
}
1.3.13.3 时区问题
orm.RegisterDataBase("default", "mysql", "user:password@tcp(127.0.0.1:3306)/db_name?charset=utf8&loc=Local")
http://www.xdnf.cn/news/1352287.html

相关文章:

  • 2-5.Python 编码基础 - 键盘输入
  • STM32CubeIDE V1.9.0下载资源链接
  • 醋酸镨:催化剂领域的璀璨新星
  • LangChain4J-基础(整合Spring、RAG、MCP、向量数据库、提示词、流式输出)
  • 信贷模型域——信贷获客模型(获客模型)
  • 温度对直线导轨的性能有哪些影响?
  • 小白向:Obsidian(Markdown语法学习)快速入门完全指南:从零开始构建你的第二大脑(免费好用的笔记软件的知识管理系统)、黑曜石笔记
  • 数字经济、全球化与5G催生域名新价值的逻辑与实践路径
  • 快速掌握Java非线性数据结构:树(二叉树、平衡二叉树、多路平衡树)、堆、图【算法必备】
  • vue3 - 组件间的传值
  • 【小沐学GIS】基于Godot绘制三维数字地球Earth(Godot)
  • 计算机网络 TLS握手中三个随机数详解
  • 【Golang】有关垃圾收集器的笔记
  • 语义通信高斯信道仿真代码
  • GaussDB 数据库架构师修炼(十八) SQL引擎-计划管理-SQL PATCH
  • Base64编码、AES加密、RSA加密、MD5加密
  • RAG Embeddings 向量数据库
  • 使用Ollama部署自己的本地模型
  • 疯狂星期四文案网第48天运营日记
  • 12 SQL进阶-锁(8.20)
  • Python语法速成课程(二)
  • 科技赋能,宁夏农业绘就塞上新“丰”景
  • 进程的概念:进程调度算法
  • 【GPT入门】第57课 详解 LLamaFactory 与 XTuner 实现大模型多卡分布式训练的方案与实践
  • rust语言 (1.88) egui (0.32.1) 学习笔记(逐行注释)(七) 鼠标在控件上悬浮时的提示
  • linux中文本文件操作之grep命令
  • 【软件设计模式】策略模式
  • MySQL:事务管理
  • Intel RealSense D435 深度相机详解
  • Java 学习笔记(基础篇8)