mysql group by json字段合并(干货)

本文介绍了如何在Go语言的GORM库中使用原始SQL进行查询,包括参数绑定、命名参数、性能提升策略以及高级查询构建技巧,如Clauses、StatementModifier等,以确保安全并提高数据库操作效率。
摘要由CSDN通过智能技术生成

原始SQL

查询原始 SQLScan

type Result struct { 
  ID    int
   Name string
   Age   int
 }

var result Result 
db.Raw( "从用户中选择 id、姓名、年龄,其中 id = ?" , 3 ). Scan(&result)

db.Raw( "从用户中选择 id、姓名、年龄 WHERE name = ?" , "jinzhu" ).Scan(&result)

var Age int
 db.Raw( "从用户中选择 SUM(年龄),其中角色 = ?" , "admin" ).Scan(&age)

var users []User 
db.Raw( "UPDATE users SET name = ? WHEREage = ? RETURNING id, name" , "jinzhu" , 20 ).Scan(&users)

Exec使用原始 SQL

db.Exec( "DROP TABLE users" ) 
db.Exec( "更新订单 SETshipped_at = ? WHERE id IN ?" , time.Now(), [] int64 { 1 , 2 , 3 })


db.Exec( "UPDATE users SET Money = ? WHERE name = ?" , gorm.Expr( "money * ? + ?" , 10000 , 1 ), "jinzhu" )

注意GORM 允许缓存准备好的语句来提高性能,查看性能了解详细信息

命名参数

GORM 支持使用sql.NamedArg,map[string]interface{}{}或 struct 命名参数,例如:

db.Where( "name1 = @name OR name2 = @name" , sql.Named( "name" , "jinzhu" )).Find(&user) 


db.Where( "name1 = @name OR name2 = @name" , map [ string ] interface {}{ "name" : "jinzhu2" }).First(&result3) 



db.Raw( "SELECT * FROM users WHERE name1 = @name OR name2 = @name2 OR name3 = @name" , 
   sql.Named( "name" , "jinzhu1" ), sql.Named( "name2" , "jinzhu2" )).Find(&user) 


db.Exec( "UPDATE users SET name1 = @name, name2 = @name2, name3 = @name" , 
   sql.Named( "name" , "jinzhunew" ), sql.Named( "name2" , "jinzhunew2" )) 


db.Raw( "SELECT * FROM users WHERE (name1 = @name AND name3 = @name) AND name2 = @name2" , map [ string ]接口{}{ "name" : "jinzhu" , "name2" : "jinzhu2 " }).Find(&user) 
   


type NamedArgument struct {
  名称字符串
  Name2字符串
}

db.Raw( "SELECT * FROM users WHERE (name1 = @Name AND name3 = @Name) AND name2 = @Name2" , 
   NamedArgument{Name: "jinzhu" , Name2: "jinzhu2" }).Find(&user)

试运行模式

生成SQL及其参数而不执行,可用于准备或测试生成的 SQL,查看Session了解详细信息

stmt := db.Session(&gorm.Session{DryRun: true }).First(&user, 1 ).Statement 
stmt.SQL.String() 
 stmt.Vars

ToSQL

返回SQL未执行而生成的。

GORM使用database/sql的参数占位符来构造SQL语句,它会自动转义参数以避免SQL注入,但生成的SQL不提供安全保证,请仅用于调试。

sql := db.ToSQL(func(tx *gorm.DB) *gorm.DB {
  return tx.Model(&User{}).Where("id = ?", 100).Limit(10).Order("age desc").Find(&[]User{})
})
sql

Row & Rows

Get result as *sql.Row

row := db.Table("users").Where("name = ?", "jinzhu").Select("name", "age").Row()
row.Scan(&name, &age)


row := db.Raw("select name, age, email from users where name = ?", "jinzhu").Row()
row.Scan(&name, &age, &email)

Get result as *sql.Rows

rows, err := db.Model(&User{}).Where("name = ?", "jinzhu").Select("name, age, email").Rows()
defer rows.Close()
for rows.Next() {
  rows.Scan(&name, &age, &email)

  
}


rows, err := db.Raw("select name, age, email from users where name = ?", "jinzhu").Rows()
defer rows.Close()
for rows.Next() {
  rows.Scan(&name, &age, &email)

  
}

Checkout FindInBatches for how to query and process records in batch
Checkout Group Conditions for how to build complicated SQL Query

Scan *sql.Rows into struct

Use ScanRows to scan a row into a struct, for example:

rows, err := db.Model(&User{}).Where("name = ?", "jinzhu").Select("name, age, email").Rows() 
defer rows.Close()

var user User
for rows.Next() {
  
  db.ScanRows(rows, &user)

  
}

Connection

Run mutliple SQL in same db tcp connection (not in a transaction)

db.Connection(func(tx *gorm.DB) error {
  tx.Exec("SET my.role = ?", "admin")

  tx.First(&User{})
})

Advanced

Clauses

GORM uses SQL builder generates SQL internally, for each operation, GORM creates a *gorm.Statement object, all GORM APIs add/change Clause for the Statement, at last, GORM generated SQL based on those clauses

For example, when querying with First, it adds the following clauses to the Statement

var limit = 1
clause.Select{Columns: []clause.Column{{Name: "*"}}}
clause.From{Tables: []clause.Table{{Name: clause.CurrentTable}}}
clause.Limit{Limit: &limit}
clause.OrderBy{Columns: []clause.OrderByColumn{
  {
    Column: clause.Column{
      Table: clause.CurrentTable,
      Name:  clause.PrimaryKey,
    },
  },
}}

Then GORM build finally querying SQL in the Query callbacks like:

Statement.Build("SELECT", "FROM", "WHERE", "GROUP BY", "ORDER BY", "LIMIT", "FOR")

Which generate SQL:

SELECT * FROM `users` ORDER BY `users`.`id` LIMIT 1

You can define your own Clause and use it with GORM, it needs to implements Interface

Check out examples for reference

Clause Builder

For different databases, Clauses may generate different SQL, for example:

db.Offset(10).Limit(5).Find(&users)

Which is supported because GORM allows database driver register Clause Builder to replace the default one, take the Limit as example

Clause Options

GORM defined Many Clauses, and some clauses provide advanced options can be used for your application

Although most of them are rarely used, if you find GORM public API can’t match your requirements, may be good to check them out, for example:

db.Clauses(clause.Insert{Modifier: "IGNORE"}).Create(&user)

StatementModifier

GORM provides interface StatementModifier allows you modify statement to match your requirements, take Hints as example

import "gorm.io/hints"

db.Clauses(hints.New("hint")).Find(&User{})

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值