gorm postgresql gorm comment

GORM 与 PostgreSQL 注释实现

在 PostgreSQL 中使用 GORM 时,为表和字段添加注释的方式与 MySQL 有所不同。下面我将展示一个完整的使用示例:

go

复制

下载

package main

import (
	"fmt"
	"log"
	"time"

	"gorm.io/driver/postgres"
	"gorm.io/gorm"
)

// Product 产品模型
type Product struct {
	ID          uint      `gorm:"primaryKey;comment:产品唯一标识符"`
	Name        string    `gorm:"size:100;not null;comment:产品名称"`
	Price       float64   `gorm:"comment:产品价格(美元)"`
	Description string    `gorm:"type:text;comment:产品详细描述"`
	InStock     bool      `gorm:"default:true;comment:库存状态"`
	CreatedAt   time.Time `gorm:"comment:创建时间"`
	UpdatedAt   time.Time `gorm:"comment:最后更新时间"`
}

func main() {
	// 连接到 PostgreSQL 数据库
	dsn := "host=localhost user=postgres password=postgres dbname=gorm_comments port=5432 sslmode=disable TimeZone=Asia/Shanghai"
	db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
	if err != nil {
		log.Fatalf("数据库连接失败: %v", err)
	}
	
	fmt.Println("✅ 成功连接到 PostgreSQL 数据库")
	
	// 创建表并添加注释
	if err := createTableWithComments(db, &Product{}, "产品信息表"); err != nil {
		log.Fatalf("创建表失败: %v", err)
	}
	
	fmt.Println("✅ 表创建完成,注释已添加")
	
	// 插入示例数据
	products := []Product{
		{Name: "Laptop", Price: 1299.99, Description: "高性能笔记本电脑", InStock: true},
		{Name: "Smartphone", Price: 899.99, Description: "最新款智能手机", InStock: true},
		{Name: "Tablet", Price: 599.99, Description: "便携式平板电脑", InStock: false},
	}
	
	result := db.Create(&products)
	if result.Error != nil {
		log.Fatalf("插入数据失败: %v", result.Error)
	}
	
	fmt.Printf("✅ 成功插入 %d 条产品数据\n", len(products))
	
	// 查询数据
	var retrievedProducts []Product
	db.Find(&retrievedProducts)
	
	fmt.Println("\n📦 产品列表:")
	for _, p := range retrievedProducts {
		fmt.Printf("#%d: %s ($%.2f) - 库存状态: %t\n", p.ID, p.Name, p.Price, p.InStock)
	}
	
	// 查看表注释
	showTableComments(db, "products")
}

// createTableWithComments 创建表并添加注释
func createTableWithComments(db *gorm.DB, model interface{}, tableComment string) error {
	// 创建表结构
	if err := db.AutoMigrate(model); err != nil {
		return err
	}
	
	// 获取表名
	stmt := &gorm.Statement{DB: db}
	stmt.Parse(model)
	tableName := stmt.Schema.Table
	
	// 添加表注释
	if err := db.Exec(fmt.Sprintf(`COMMENT ON TABLE %s IS '%s'`, tableName, tableComment)).Error; err != nil {
		return fmt.Errorf("添加表注释失败: %w", err)
	}
	
	return nil
}

// showTableComments 显示表和字段的注释
func showTableComments(db *gorm.DB, tableName string) {
	fmt.Printf("\n📝 表 '%s' 的注释信息:\n", tableName)
	
	// 查询表注释
	var tableComment string
	db.Raw(`
		SELECT obj_description('public.' || ?::regclass, 'pg_class')
	`, tableName).Scan(&tableComment)
	fmt.Printf("表注释: %s\n", tableComment)
	
	// 查询字段注释
	type ColumnComment struct {
		ColumnName string
		Comment    string
	}
	
	var columns []ColumnComment
	db.Raw(`
		SELECT 
			a.attname AS column_name,
			pg_catalog.col_description(a.attrelid, a.attnum) AS comment
		FROM 
			pg_catalog.pg_attribute a
		WHERE 
			a.attrelid = 'public.' || ?::regclass AND 
			a.attnum > 0 AND 
			NOT a.attisdropped
		ORDER BY a.attnum;
	`, tableName).Scan(&columns)
	
	fmt.Println("\n字段注释:")
	for _, col := range columns {
		fmt.Printf("- %-15s: %s\n", col.ColumnName, col.Comment)
	}
}

PostgreSQL 注释关键点

  1. 添加字段注释

    go

    复制

    下载

    type Product struct {
        ID uint `gorm:"primaryKey;comment:产品唯一标识符"`
        // ...
    }

    GORM 在创建表时会自动为字段添加注释

  2. 添加表注释

    go

    复制

    下载

    // 添加表注释
    db.Exec(`COMMENT ON TABLE products IS '产品信息表'`)
  3. 查询注释信息

    sql

    复制

    下载

    -- 表注释
    SELECT obj_description('public.products'::regclass, 'pg_class');
    
    -- 字段注释
    SELECT 
        a.attname AS column_name,
        pg_catalog.col_description(a.attrelid, a.attnum) AS comment
    FROM 
        pg_catalog.pg_attribute a
    WHERE 
        a.attrelid = 'public.products'::regclass;

注意事项

  1. 表注释需要单独添加:与 MySQL 不同,PostgreSQL 不能在 CREATE TABLE 语句中添加表注释

  2. 特殊字符处理:注释中的单引号需要转义

    go

    复制

    下载

    `comment:用户''名称` // 两个单引号表示一个单引号
  3. 表名大小写:PostgreSQL 默认小写表名,如果使用大写需加双引号

    go

    复制

    下载

    db.Exec(`COMMENT ON TABLE "UserTable" IS '注释'`)
  4. GORM 版本:确保使用 GORM v1.20.0+ 以获得完整的注释支持

运行此代码后,您将在数据库中看到带有完整注释的产品表,并能通过查询验证注释是否已正确添加。

<think>好的,用户现在问的是GORM中LIKE的使用方法。我需要先回顾一下之前和用户的对话历史。之前用户询问过如何输出GORM生成的SQL,现在转向查询条件中的LIKE操作,可能是想实现模糊搜索。 首先,用户可能正在开发一个需要搜索功能的项目,比如用户管理,需要根据姓名、邮箱等字段进行模糊查询。他们可能已经掌握了基本的CRUD操作,现在想了解如何在GORM中正确使用LIKE语句。 接下来,我需要考虑GORM中实现LIKE的不同方法。常见的包括使用字符串拼接%、使用`gorm.Expr`,以及处理特殊字符的情况。此外,用户可能对SQL注入有顾虑,所以需要强调参数化查询的重要性,避免直接拼接用户输入。 另外,用户可能想知道不同数据库的适配问题,比如PostgreSQL的ILIKE,或者如何处理大小写敏感的问题。可能需要提到使用`Collate`方法或者自定义排序规则。 还需要考虑示例的清晰度,提供多种场景的代码片段,比如前后模糊匹配、多个条件的组合使用,以及使用结构体或map来构建查询条件。同时,要提醒用户注意通配符的位置对查询性能的影响,比如前导通配符可能导致索引失效。 可能用户在实际使用中遇到特殊字符如%或_时需要转义,这部分需要详细说明,避免查询出错。另外,复合查询中的LIKE使用,比如结合AND和OR,也是常见的应用场景,需要给出示例。 总结一下,回答需要结构清晰,分点列出不同的使用方式,每个部分给出代码示例和说明,强调安全性和性能注意事项,最后总结最佳实践,帮助用户全面理解并正确应用LIKE操作。</think>在 GORM 中使用 `LIKE` 进行模糊查询主要有以下 6 种典型用法,包含特殊场景处理和性能优化建议: --- ### 一、基础用法(占位符方式) ```go // 前后模糊匹配(推荐安全写法) db.Where("name LIKE ?", "%张%").Find(&users) // 生成 SQL: SELECT * FROM `users` WHERE name LIKE '%张%' // 前缀匹配 db.Where("email LIKE ?", "user%@example.com").Find(&users) // 生成 SQL: SELECT * FROM `users` WHERE email LIKE 'user%@example.com' // 后缀匹配 db.Where("phone LIKE ?", "%8888").Find(&users) ``` --- ### 二、表达式方式(支持复杂条件) ```go // 使用 gorm.Expr 构建表达式 db.Where(gorm.Expr("address LIKE ?", "%北京%")).Find(&users) // 组合多个条件 db.Where( gorm.Expr("(name LIKE ? OR email LIKE ?)", "%john%", "%@gmail.com"), ).Find(&users) ``` --- ### 三、链式调用(结合其他条件) ```go q := db.Model(&User{}). Select("id", "name"). Where("age > ?", 18). Where("name LIKE ?", "李%"). Order("created_at DESC") // 生成 SQL: // SELECT `id`,`name` FROM `users` // WHERE age > 18 AND name LIKE '李%' // ORDER BY created_at DESC ``` --- ### 四、结构体条件(自动忽略零值) ```go type SearchParams struct { Name string Email string `gorm:"column:email_address"` } params := SearchParams{ Name: "%admin%", Email: "%@company.com" } db.Where(params).Find(&users) // 生成 SQL:SELECT * FROM `users` // WHERE `name` LIKE '%admin%' // AND `email_address` LIKE '%@company.com' ``` --- ### 五、Map 条件(灵活字段组合) ```go conditions := map[string]interface{}{ "name LIKE": "%测试%", "status": 1, } db.Where(conditions).Find(&users) // 生成 SQL:SELECT * FROM `users` // WHERE name LIKE '%测试%' AND status = 1 ``` --- ### 六、高级场景处理 #### 1. 大小写不敏感查询(PostgreSQL) ```go db.Where("name ILIKE ?", "%john%").Find(&users) ``` #### 2. 转义特殊字符 ```go // 搜索包含 % 本身的内容 db.Where("comment LIKE ?", "%\\%%").Find(&comments) // 使用双反斜杠转义 // 生成 SQL:SELECT * FROM `comments` WHERE comment LIKE '%\%%' ``` #### 3. 全文索引优化 ```go // 使用 MATCH AGAINST(需要 MySQL 5.6+) db.Where("MATCH(content) AGAINST(? IN BOOLEAN MODE)", "+gorm +like").Find(&articles) ``` --- ### 性能优化建议 1. **索引策略**: - 避免前导通配符 `%xxx`,优先使用 `xxx%` - 对长文本字段考虑前缀索引 ```sql CREATE INDEX idx_name_prefix ON users(name(10)) ``` 2. **参数绑定**: ```go // 错误示范(SQL 注入风险) db.Where(fmt.Sprintf("name LIKE '%%%s%%'", input)) // 正确做法(参数化查询) db.Where("name LIKE ?", "%"+input+"%") ``` 3. **查询缓存**: ```go stmt := db.Where("name LIKE ?", "%张%").Statement stmt.Cache(time.Hour, "user_search_cache") ``` --- ### 最佳实践总结 1. **安全第一**:始终使用参数化查询防止 SQL 注入 2. **模式选择**: - `xxx%`:适合前缀匹配(可用索引) - `%xxx`:适合后缀匹配(需配合倒排索引) - `%xxx%`:全模糊匹配(谨慎使用) 3. **特殊字符处理**:对用户输入进行转义 4. **性能监控**:对频繁使用的 LIKE 查询进行 EXPLAIN 分析 --- 当需要处理更复杂的搜索场景时,建议结合 Elasticsearch 或数据库内置的全文检索功能(如 PostgreSQL 的 tsvector)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

leijmdas

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值