昨天发布的内容,使用原生写法来访问mysql数据库,然而,在实际项目中,这种写法,不仅需要写sql语句来实现表的增删改查,可维护性低,不易实现对象化和组件化,今天风云用ORM对象关系映射方式再实现一遍。每种语言都有自己的ORM库,golang里叫GORM。
先来介绍一下它的概念
ORM(对象关系映射)的意义在于简化数据库操作,提高开发效率和代码的可维护性。通过将数据库表中的数据映射为编程语言中的对象,ORM使得开发者可以更加自然地处理数据库操作,降低了编写SQL语句的难度,提高了代码的可读性和可维护性12。
1、ORM的定义和基本概念
ORM(Object-Relational Mapping)是一种编程技术,用于将关系型数据库中的数据映射为面向对象编程语言中的对象。它通过描述对象和数据库之间映射的元数据,实现程序中的对象自动持久化到关系数据库中。开发者无需编写复杂的 SQL,即可通过操作对象完成数据操作。
ORM的优势
- 映射关系自动管理:ORM可以自动生成数据库表与对象之间的映射关系,减少了手动编写映射代码的工作量1。
- 对象化操作:ORM将数据库操作抽象为对象操作,使得开发者可以更加自然地处理数据库,提高了开发效率1。
- 减少错误:ORM可以自动生成SQL语句,降低了因手动编写SQL语句而导致的错误1。
- 提高可维护性:ORM可以自动更新映射关系,使得数据库结构的变更不会影响代码的正确性,提高了代码的可维护性1。
- 开发效率高:通过封装数据库操作,简化了增删改查等常见操作
- 代码可读性强:以对象的形式操作数据,代码更易理解。
- 数据库独立性:ORM 能屏蔽大部分数据库差异,方便切换数据库。
- ORM 的不足: 性能开销:封装层可能导致比原生 SQL 略低的性能。复杂查询限制:处理复杂查询时,可能不如原生 SQL 高效。
2、安装与配置 GORM
在 Golang 项目中安装 GORM 及其 MySQL 驱动:
go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql
配置数据库连接
以下代码展示了如何初始化 GORM 并连接到 MySQL 数据库。
package main
import (
"fmt"
"log"
"time"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
type User struct {
ID uint `gorm:"primaryKey"`
Name string `gorm:"size:255"`
Email string `gorm:"uniqueIndex;size:255"`
CreatedAt time.Time
}
func autoMigrate(db *gorm.DB) {
err := db.AutoMigrate(&User{})
if err != nil {
log.Fatalf("自动迁移失败: %v\n", err)
}
fmt.Println("表结构同步成功")
}
func main() {
// 数据库连接字符串
dsn := "netwindcloud:netwindcloud123@tcp(127.0.0.1:3306)/netwindcloud?charset=utf8mb4&parseTime=True&loc=Local"
// 初始化 GORM
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
log.Fatalf("数据库连接失败: %v\n", err)
}
fmt.Println("成功连接到数据库")
// db.AutoMigrate(&User1{})
autoMigrate(db)
}
3、GORM 模型定义与数据库操作
3.1 模型定义
在 GORM 中,表结构通过结构体定义,结构体的字段映射到数据库中的列。
type User struct {
ID uint `gorm:"primaryKey"`
Name string `gorm:"size:255"`
Email string `gorm:"uniqueIndex;size:255"`
CreatedAt time.Time
}
字段标签的含义:
- primaryKey:主键。
- size:列的最大字符长度。
- uniqueIndex:唯一索引。
3.2 自动迁移
使用 AutoMigrate 方法将模型结构同步到数据库。
func autoMigrate(db *gorm.DB) { // 自动迁移
err := db.AutoMigrate(&User{}) // 执行自动迁移
if err != nil { // 如果发生错误,则打印错误并退出程序
log.Fatalf("自动迁移失败: %v\n", err)
}
fmt.Println("表结构同步成功")
}
3.3 数据库基本操作
插入数据
func createUser(db *gorm.DB) { // 创建数据
user := User{Name: "Alice", Email: "alice@example.com"} // 创建一个用户对象
result := db.Create(&user) // 插入数据
if result.Error != nil { // 如果发生错误,则打印错误并退出程序
log.Fatalf("插入数据失败: %v\n", result.Error)
}
fmt.Printf("插入成功,用户ID: %d\n", user.ID)
}
查询数据
func queryUsers(db *gorm.DB) { // 查询数据
var users []User // 定义一个切片,用于存储查询到的用户数据
result := db.Find(&users) // 查询所有用户数据
if result.Error != nil { // 如果发生错误,则打印错误并退出程序
log.Fatalf("查询数据失败: %v\n", result.Error)
}
for _, user := range users { // 遍历查询到的用户数据
fmt.Printf("ID: %d, Name: %s, Email: %s\n", user.ID, user.Name, user.Email)
}
}
更新数据
func updateUser(db *gorm.DB) { // 更新数据
result := db.Model(&User{}).Where("name = ?", "Alice").Update("email", "newalice@example.com") // 更新指定条件的用户邮箱
if result.Error != nil { // 如果发生错误,则打印错误并退出程序
log.Fatalf("更新数据失败: %v\n", result.Error)
}
fmt.Printf("更新成功,影响行数: %d\n", result.RowsAffected)
}
删除数据
func deleteUser(db *gorm.DB) { // 删除数据
result := db.Where("name = ?", "Alice").Delete(&User{})
if result.Error != nil { // 如果发生错误,则打印错误并退出程序
log.Fatalf("删除数据失败: %v\n", result.Error)
}
fmt.Printf("删除成功,影响行数: %d\n", result.RowsAffected)
}
4、GORM 的高级功能
4.1 关联关系
GORM 支持模型之间的关系,包括一对一、一对多和多对多。
一对多示例
type Post struct {
ID uint
Title string
UserID uint
}
type User struct { // 用户结构体
ID uint
Name string
Posts []Post `gorm:"foreignKey:UserID"`
}
预加载关联数据
func preloadData(db *gorm.DB) { // 预加载数据
var users []User // 定义一个切片,用于存储查询到的用户数据
db.Preload("Posts").Find(&users) // 使用Preload方法预加载Posts字段
for _, user := range users { // 遍历查询到的用户数据
fmt.Printf("User: %s, Posts: %v\n", user.Name, user.Posts)
}
}
4.2 原生 SQL 支持
GORM 支持直接执行原生 SQL:
func rawSQL(db *gorm.DB) { // 原生 SQL
// 执行原生 SQL
rows, err := db.Raw("SELECT id, name FROM users WHERE email = ?", "example@example.com").Rows()
if err != nil { // 如果发生错误,则打印错误并退出程序
log.Fatalf("执行原生 SQL 失败: %v\n", err)
}
defer rows.Close() // 关闭结果集
for rows.Next() { // 遍历结果集
var id uint // 定义一个变量,用于存储查询到的用户 ID
var name string // 定义一个变量,用于存储查询到的用户名
rows.Scan(&id, &name) // 扫描结果集
fmt.Printf("ID: %d, Name: %s\n", id, name)
}
}
4.3 分页与排序
func paginateAndSort(db *gorm.DB) { // 分页和排序
var users []User // 定义一个切片,用于存储查询到的用户数据
db.Order("created_at desc").Limit(10).Offset(0).Find(&users) // 执行分页和排序
for _, user := range users { // 遍历查询到的用户数据
fmt.Printf("User: %s\n", user.Name)
}
}
标签:--,数据库,db,ORM,result,MySql,gorm,User
From: https://blog.csdn.net/weixin_42998312/article/details/145126070