前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >gorm多条数据级联查询关联查询gorm连接池gorm事务

gorm多条数据级联查询关联查询gorm连接池gorm事务

作者头像
hotqin888
发布2019-11-20 14:41:47
4.1K0
发布2019-11-20 14:41:47
举报
文章被收录于专栏:hotqin888的专栏hotqin888的专栏

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/hotqin888/article/details/103115322

因为gorm支持级联查询。xorm的jion查询虽然很棒,但是查出来的不能生成嵌套结构体。而gorm就可以,经过摸索,这种关联啊,预加载啊,虽然没搞清楚他们之间的区别,但总算能满足自己的查询需要了。 网络上都是单条记录的关联查询,而我需要对多条记录进行关联查询,目前只知道使用preload

代码语言:javascript
复制
//查询某个用户打赏记录
func GetUserPay(uid int64, limit, offset int) (pays []*Pay, err error) {
	//获取DB
	db := GetDB()
	// err = db.Where("user_id", uid).Find(&pays).Error
	err = db.Model(&pays).Preload("User").Preload("Article").Where("user_id=?", uid).Limit(limit).Offset(offset).Find(&pays).Error //查询所有device记录
	// err = db.Model(&pays).Related(&pays.User, "Users").Error
	return pays, err
	// 多连接及参数
	// db.Joins("JOIN pays ON pays.user_id = users.id", "jinzhu@example.org").Joins("JOIN credit_cards ON credit_cards.user_id = users.id").Where("user_id = ?", uid).Find(&pays)
}

还有就是连接池,因为在beego中用,除了beego的orm外,还用了xorm,这次再加入gorm,就3个了,他们如何连接数据库也是费了不少心思。说gorm用连接池,每次使用的时候要调用一下? 使用了gorm的事务,作为小程序赞赏时,用户账户扣款,文章获得赞赏,用户账户余额减少。

代码语言:javascript
复制
//添加某个文章某个用户打赏记录
func AddUserPay(articleid, uid int64, amount int) error {
	//获取DB
	db := GetDB()
	// 注意,当你在一个事务中应使用 tx 作为数据库句柄
	tx := db.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()

	if err := tx.Error; err != nil {
		return err
	}
	//保证文章id正确
	var article Article
	err := db.Where("id = ?", articleid).First(&article).Error
	if err != nil {
		tx.Rollback()
		return err
	}
	// user := User{Name: "Jinzhu", Age: 18, Birthday: time.Now()}
	// db.Create(&user)
	if err := tx.Create(&Pay{UserID: uid, ArticleID: articleid, Amount: amount}).Error; err != nil {
		tx.Rollback()
		return err
	}
	//更新用户账户余额money
	//1.首先保证账户存在
	// money := Money{UserID: uid}
	var money Money
	err = db.Where("user_id = ?", uid).First(&money).Error
	if err != nil {
		tx.Rollback()
		return err
	}
	//2.用户账户余额保证大于0
	newamount := money.Amount - amount
	if newamount < 0 {
		tx.Rollback()
		return err
	}
	//3.账户修改余额
	rowsAffected := tx.Model(&money).Update("amount", newamount).RowsAffected
	if rowsAffected == 0 {
		tx.Rollback()
		return nil
	}

	return tx.Commit().Error

}

连接池的问题:

代码语言:javascript
复制
//定义全局的db对象,我们执行数据库操作主要通过他实现。
var _db *gorm.DB

func init() {
	var err error
	var dns string
	db_type := beego.AppConfig.String("db_type")
	db_name := beego.AppConfig.String("db_name")
	db_path := beego.AppConfig.String("db_path")
	if db_path == "" {
		db_path = "./"
	}

	dns = fmt.Sprintf("%s%s.db", db_path, db_name)
	_db, err = gorm.Open(db_type, dns)
	// _db.LogMode(true)
	if err != nil {
		panic("连接数据库失败, error=" + err.Error())
	}
	// defer gdb.Close()
	//禁止表名复数形式
	_db.SingularTable(true)
	// 开发的时候需要打开调试日志
	// _db.LogMode(true)
	//设置数据库连接池参数
	_db.DB().SetMaxOpenConns(100) //设置数据库连接池最大连接数
	_db.DB().SetMaxIdleConns(20)  //连接池最大允许的空闲连接数,如果没有sql任务需要执行的连接数大于20,超过的连接会被连接池关闭。

	_db.CreateTable(&Pay{}, &Money{}, &Recharge{})
	// if !gdb.HasTable(&Pay1{}) {
	// 	if err = gdb.CreateTable(&Pay1{}).Error; err != nil {
	// 		panic(err)
	// 	}
	// }
}

//获取gorm db对象,其他包需要执行数据库查询的时候,只要通过tools.getDB()获取db对象即可。
//不用担心协程并发使用同样的db对象会共用同一个连接,
// db对象在调用他的方法的时候会从数据库连接池中获取新的连接
// 注意:使用连接池技术后,千万不要使用完db后调用db.Close关闭数据库连接,
// 这样会导致整个数据库连接池关闭,导致连接池没有可用的连接
func GetDB() *gorm.DB {
	return _db
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-11-17 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云开发 CloudBase
云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档