在gorm ORM框架中, 使用Raw原生查询方法和Table/Model构建的 *gorm.DB 对象 , 他们都返回的是*gorm.DB。 但是他们是有区别的, 主要区别在于:使用 Raw方法创建的*gorm.DB 对象时无法再次拼接其他的查询条件的; 而使用Table/Model 方法创建的*gorm.DB 对象是可以链式添加其他的查询条件的。
gorm Raw 原生SQL查询方法
定义:func (db *gorm.DB) Raw(sql string, values ...interface{}) (tx *gorm.DB)
示例:
下面先使用 Raw后再使用.Where 等其他的方法后将不会有任何的作用,最终生成的SQL都是Raw里面的sql,后面的where,分页等都不会生效,即最终的sql还是: select * from information_schema.tables where TABLE_SCHEMA=(select database())
tx:=global.GetDb()
list := make([]model.SchemaTables,0)
tx.Raw("select * from information_schema.tables where TABLE_SCHEMA=(select database()) ").Where("TABLE_NAME LIKE ?","%"+param.TableName+"%").Offset(0).Limit(20).Find(&list)
Table/Model方法构建的 *gorm.DB对象
gorm里面通过使用Table/Model方法构建的 *gorm.DB 对象, 后面是可以链式的添加其他查询条件的
如:
tx:=global.GetDb()
list := make([]model.SchemaTables,0)
tx.Table("information_schema.tables").Where("TABLE_SCHEMA=(select database())").Where("TABLE_NAME LIKE ?","%"+param.TableName+"%").Offset(0).Limit(10).Find(&list)
上面的代码最终生成的sql语句是: SELECT * FROM `information_schema`.`tables` WHERE TABLE_SCHEMA=(select database()) AND TABLE_NAME LIKE '%tb%' LIMIT 10
总结:
当我们需要执行多个链式查询条件的时候,我们可以先通过 Table/Model来构建 *gorm.DB对象,然后在链式附加其他查询条件; 如果我们不需要其他查询条件,就可以使用Raw原生查询方法来执行。 注意在使用Raw原生查询方法是,如果是直接拼接SQL,需要注意使用Quote转码特殊字符, 可以使用*gorm.DB查询条件里面的Statement.Quote()方法来对查询参数进行转码,即 tx.Statement.Quote(xxx)
gorm相关方法参考
gorm Raw方法参考
func (db *DB) Raw(sql string, values ...interface{}) (tx *DB) {
tx = db.getInstance()
tx.Statement.SQL = strings.Builder{}
if strings.Contains(sql, "@") {
clause.NamedExpr{SQL: sql, Vars: values}.Build(tx.Statement)
} else {
clause.Expr{SQL: sql, Vars: values}.Build(tx.Statement)
}
return
}
gorm Table方法参考
// Table specify the table you would like to run db operations
//
// // Get a user
// db.Table("users").Take(&result)
func (db *DB) Table(name string, args ...interface{}) (tx *DB) {
tx = db.getInstance()
if strings.Contains(name, " ") || strings.Contains(name, "`") || len(args) > 0 {
tx.Statement.TableExpr = &clause.Expr{SQL: name, Vars: args}
if results := tableRegexp.FindStringSubmatch(name); len(results) == 3 {
if results[1] != "" {
tx.Statement.Table = results[1]
} else {
tx.Statement.Table = results[2]
}
}
} else if tables := strings.Split(name, "."); len(tables) == 2 {
tx.Statement.TableExpr = &clause.Expr{SQL: tx.Statement.Quote(name)}
tx.Statement.Table = tables[1]
} else if name != "" {
tx.Statement.TableExpr = &clause.Expr{SQL: tx.Statement.Quote(name)}
tx.Statement.Table = name
} else {
tx.Statement.TableExpr = nil
tx.Statement.Table = ""
}
return
}
gorm Model方法参考
// Model specify the model you would like to run db operations
//
// // update all users's name to `hello`
// db.Model(&User{}).Update("name", "hello")
// // if user's primary key is non-blank, will use it as condition, then will only update that user's name to `hello`
// db.Model(&user).Update("name", "hello")
func (db *DB) Model(value interface{}) (tx *DB) {
tx = db.getInstance()
tx.Statement.Model = value
return
}