gorm 预加载 连接查询(两表联查,三表联查)的坑

@ GO gorm 连接查询

gorm 关接查询(两表联查,三表联查)

新人一枚,代码不够漂亮,望多多担待

多少雄心壮志跃跃欲试,宝剑尚未佩妥,出门已是江湖

1,gorm模型如下:

// 文章
type Topics struct {
	Id         int        `gorm:"primary_key"`
	Title      string     `gorm:"not null"`
	UserId     int        `gorm:"not null"`
	CategoryId int        `gorm:"not null"`
	Category   Categories `gorm:"foreignkey:CategoryId"`//文章所属分类外键
	User       Users      `gorm:"foreignkey:UserId"`//文章所属用户外键
}

// 用户
type Users struct {
	Id   int    `gorm:"primary_key"`
	Name string `gorm:"not null"`
}

// 分类
type Categories struct {
	Id   int    `gorm:"primary_key"`
	Name string `gorm:"not null"`
}

gorm官方文档对foreign key 有这么一句话:To define a belongs to relationship, the foreign key must exists, default foreign key uses owner’s type name plus its primary key(要定义属于关系,外键必须存在,默认外键使用所有者的类型名及其主键)也就是说默认外键满足其所有者的类型名和主键

2, 查询代码

func GetDB() *gorm.DB {
	//“mysql”, “mysql用户名:密码@tcp(ip地址:端口号)/samples?charset=utf8&parseTime=True&loc=Local”)
	db, err := gorm.Open("mysql", "root:root@tcp(127.0.0.1:3306)/test?charset=utf8&parseTime=True&loc=Local")
	if err != nil {
		fmt.Println("db error:", err)
	} else {
		fmt.Println("database connection success")
	}
	defer db.Close()
	return db
}

func main() {
	to := Topics{}
	to.Id = 1
	to.TopicByID(1)
}

func (Topics) TopicByID(id int) (*Topics, error) {
	db := GetDB()
	var topic Topics

	//db.Where("id=?", id).First(&topic)
	// 关联的关键代码
	//db.Model(&topic).Related(&topic.Category, "CategoryId")
	//result := db.Model(&topic).Related(&topic.User, "UserId")

	result := db.First(&topic)
	//result := db.Where("id=?", id).Preload("Category").Preload("User").First(&topic)
	fmt.Println("result:", result)
	if err := result.Error; err != nil {
		fmt.Println(err)
		return &topic, err
	}
	//result := db.where("id=?",id)
	if result.RecordNotFound() == true {
		return &topic, errors.New("文章不存在!")
	}
	fmt.Println("result:", result)

	return &topic, nil
}

Preload 预加载)gorm官方文档为:

db.Preload("Orders").Find(&users)
//// SELECT * FROM users;
//// SELECT * FROM orders WHERE user_id IN (1,2,3,4);

db.Preload("Orders", "state NOT IN (?)", "cancelled").Find(&users)
//// SELECT * FROM users;
//// SELECT * FROM orders WHERE user_id IN (1,2,3,4) AND state NOT IN ('cancelled');

db.Where("state = ?", "active").Preload("Orders", "state NOT IN (?)", "cancelled").Find(&users)
//// SELECT * FROM users WHERE state = 'active';
//// SELECT * FROM orders WHERE user_id IN (1,2) AND state NOT IN ('cancelled');

db.Preload("Orders").Preload("Profile").Preload("Role").Find(&users)
//// SELECT * FROM users;
//// SELECT * FROM orders WHERE user_id IN (1,2,3,4); // has many
//// SELECT * FROM profiles WHERE user_id IN (1,2,3,4); // has one
//// SELECT * FROM roles WHERE id IN (4,5,6); // belongs to
in子查询与inner join连接查询相比,在一定的实际执行执行计划下,他们的io开销和性能是没有优劣的

in和inner join 优劣: https://www.cnblogs.com/kerrycode/p/6868488.html

有任何问题请留言,大家一起讨论,互相学习。

猜你喜欢

转载自blog.csdn.net/daimading/article/details/85258007