@ 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