gorm预加载
参考链接:https://blog.csdn.net/qq_49723651/article/details/124310253
数据库搭建
首先建立学生表,课程表,成绩表
学生表
课程表
成绩表
插入一些信息
代码
结构如下
我将MySQL的信息存在config.ini中,一会儿读取ini文件即可
config.ini
[database]
service = mysql
DbHost = localhost // host
DbPort = 3306 // 端口
DbUser = root // mysql用户名
DbPassword = 061118 // mysql用户密码
DbName = student // 数据库名
db.go
package util
import (
"fmt"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
"time"
)
var db *gorm.DB
var err error
type student struct {
Sno string `gorm:"primary_key"`
Name string
Age int
Grades []grade `gorm:"foreignKey:Sno;association_foreignkey:Sno"`
}
func (student) TableName() string {
return "student"
}
type grade struct {
Sno string
Grade int
Cno string
}
func (grade) TableName() string {
return "grade"
}
type course struct {
Cno string `gorm:"primary_key"`
Cname string
Grades []grade `gorm:"foreignKey:Cno;association_foreignkey:Cno"`
}
func (course) TableName() string {
return "course"
}
func InitDb() {
Init()
str := fmt.Sprintf("%s:%s@(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local",
DbUser,
DbPassword,
DbHost,
DbPort,
DbName)
db, err = gorm.Open(Service, str)
if err != nil {
fmt.Println("数据库连接失败,请检查参数:", err)
}
fmt.Println("connect success")
// SetMaxIdleConns 设置空闲连接池中连接的最大数量
db.DB().SetMaxIdleConns(10)
// SetMaxOpenConns 设置打开数据库连接的最大数量。
db.DB().SetMaxOpenConns(100)
// SetConnMaxLifetime 设置了连接可复用的最大时间。
db.DB().SetConnMaxLifetime(10 * time.Second)
}
func Close() {
db.DB().Close()
}
func Select() {
var st student
db.Where("Name=?", "张三").Find(&st)
fmt.Println(st) // {01 张三 19 []}
// 预加载
db.Preload("Grades").Where("Name=?", "张三").Find(&st)
fmt.Println(st) // {01 张三 19 [{01 90 0001} {01 80 0002} {01 30 0003}]}
// 自定义预加载
db.Preload("Grades", func(db *gorm.DB) *gorm.DB {
// 原生的sql语句, 这里的sno和cno是数据库中的字段,不是结构体中的字段
return db.Where("sno=? and cno=?", "01", "0001")
}).Where("Name=?", "张三").Find(&st)
fmt.Println(st) // {01 张三 19 [{01 90 0001}]}
}
setting.go(读取config.ini)
package util
import (
"fmt"
"gopkg.in/ini.v1"
)
var (
Service string
DbHost string
DbPort string
DbUser string
DbPassword string
DbName string
)
func Init() {
file, err := ini.Load("config/config.ini")
if err != nil {
fmt.Println("配置文件读取错误,请检查文件路径:", err)
}
LoadData(file)
}
func LoadData(file *ini.File) {
Service = file.Section("database").Key("Service ").MustString("mysql")
DbHost = file.Section("database").Key("DbHost").MustString("localhost")
DbPort = file.Section("database").Key("DbPort").MustString("3306")
DbUser = file.Section("database").Key("DbUser").MustString("root")
DbPassword = file.Section("database").Key("DbPassword").MustString("061118")
DbName = file.Section("database").Key("DbName").MustString("student")
}
main.go
package main
import (
_ "github.com/jinzhu/gorm/dialects/mysql"
"test/util"
)
func main() {
util.InitDb()
defer util.Close()
util.Select()
}
运行结果如下
实际上我们可以用viper读取ini文件,可能更简单些,首先导入包
go get -u github.com/spf13/viper
只需要更改db.go的代码,如下所示
package util
import (
"fmt"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
"github.com/spf13/viper"
"time"
)
var db *gorm.DB
var err error
type student struct {
Sno string `gorm:"primary_key"`
Name string
Age int
Grades []grade `gorm:"foreignKey:Sno;association_foreignkey:Sno"`
}
func (student) TableName() string {
return "student"
}
type grade struct {
Sno string
Grade int
Cno string
}
func (grade) TableName() string {
return "grade"
}
type course struct {
Cno string `gorm:"primary_key"`
Cname string
Grades []grade `gorm:"foreignKey:Cno;association_foreignkey:Cno"`
}
func (course) TableName() string {
return "course"
}
//func InitDb() {
// Init()
// str := fmt.Sprintf("%s:%s@(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local",
// DbUser,
// DbPassword,
// DbHost,
// DbPort,
// DbName)
// db, err = gorm.Open(Service, str)
// if err != nil {
// fmt.Println("数据库连接失败,请检查参数:", err)
// }
// fmt.Println("connect success")
//
// // SetMaxIdleConns 设置空闲连接池中连接的最大数量
// db.DB().SetMaxIdleConns(10)
//
// // SetMaxOpenConns 设置打开数据库连接的最大数量。
// db.DB().SetMaxOpenConns(100)
//
// // SetConnMaxLifetime 设置了连接可复用的最大时间。
// db.DB().SetConnMaxLifetime(10 * time.Second)
//}
func InitConfig() {
viper.SetConfigName("config") // 寻找文件的名字
viper.SetConfigType("ini") // 寻找文件的类型
viper.AddConfigPath("config") // 从当前目录下的哪个文件开始查找
err := viper.ReadInConfig()
// 可以按照这种写法,处理特定的找不到配置文件的情况
if err != nil {
if v, ok := err.(viper.ConfigFileNotFoundError); ok {
fmt.Println(v)
} else {
panic(fmt.Errorf("read config err:%s\n", err))
}
}
}
func InitDb() {
InitConfig()
DbUser := viper.GetString("database.DbUser")
//fmt.Println("User:", DbUser)
DbPassword := viper.GetString("database.DbPassword")
DbHost := viper.GetString("database.DbHost")
DbPort := viper.GetString("database.DbPort")
DbName := viper.GetString("database.DbName")
Service := viper.GetString("database.Service")
str := fmt.Sprintf("%s:%s@(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local",
DbUser,
DbPassword,
DbHost,
DbPort,
DbName)
db, err = gorm.Open(Service, str)
if err != nil {
fmt.Println("数据库连接失败,请检查参数:", err)
}
fmt.Println("connect success")
// SetMaxIdleConns 设置空闲连接池中连接的最大数量
db.DB().SetMaxIdleConns(10)
// SetMaxOpenConns 设置打开数据库连接的最大数量。
db.DB().SetMaxOpenConns(100)
// SetConnMaxLifetime 设置了连接可复用的最大时间。
db.DB().SetConnMaxLifetime(10 * time.Second)
}
func Close() {
db.DB().Close()
}
func Select() {
var st student
db.Where("Name=?", "张三").Find(&st)
fmt.Println(st) // {01 张三 19 []}
// 预加载
db.Preload("Grades").Where("Name=?", "张三").Find(&st)
fmt.Println(st) // {01 张三 19 [{01 90 0001} {01 80 0002} {01 30 0003}]}
// 自定义预加载
db.Preload("Grades", func(db *gorm.DB) *gorm.DB {
// 原生的sql语句, 这里的sno和cno是数据库中的字段,不是结构体中的字段
return db.Where("sno=? and cno=?", "01", "0001")
}).Where("Name=?", "张三").Find(&st)
fmt.Println(st) // {01 张三 19 [{01 90 0001}]}
}
运行结果如下: