Golang 对象关系映射框架 GORM 实现自定义 SQL 提示

本贴最后更新于 1080 天前,其中的信息可能已经时过境迁

NO-ORMer 请绕道 👉 Golang, ORMs, and why I am still not using one. (hydrogen18.com)

GORM 原生支持 3 种提示,分别是:

  • Index Hints:MySQL 索引提示;
  • Optimizer Hints:MySQL 优化器提示;
  • Comment Hints:注释提示,在任意 SQL 关键字之前或之后添加 /* */ 块注释。

Hints | GORM - The fantastic ORM library for Golang, aims to be developer friendly.

所以 GORM 对 MySQL 的支持很好,然而本人工作中主要使用 SQL Server,其表提示 WITH(...) 会经常使用,所以查看了 GORM Hints 相关代码后,实现了 SQL Server 的 WITH 表提示,代码如下所示:

TableHints.go

package tool

import (
	"gorm.io/gorm"
	"gorm.io/gorm/clause"
	"gorm.io/hints"
)

// TableHints 自定义 GORM 表提示
//
// @Author zixizixi.cn
type TableHints struct {
	Type string
	Keys []string
}

// ModifyStatement 实现 gorm.StatementModifier 接口方法
func (tableHint TableHints) ModifyStatement(stmt *gorm.Statement) {
	for _, name := range []string{"FROM", "INTO"} {
		stmtClause := stmt.Clauses[name]

		if stmtClause.AfterExpression == nil {
			stmtClause.AfterExpression = tableHint
		} else {
			stmtClause.AfterExpression = hints.Exprs{stmtClause.AfterExpression, tableHint}
		}

		stmt.Clauses[name] = stmtClause
	}
}

// Build 实现 clause.Expression 接口方法
func (tableHint TableHints) Build(builder clause.Builder) {
	if len(tableHint.Keys) > 0 {
		_, _ = builder.WriteString(tableHint.Type)
		_ = builder.WriteByte('(')
		for idx, key := range tableHint.Keys {
			if idx > 0 {
				_ = builder.WriteByte(',')
			}
			_, _ = builder.WriteString(key)
		}
		_ = builder.WriteByte(')')
	}
}

// With Sql Server 使用 WITH(?) 表提示
func (tableHint TableHints) With(names ...string) TableHints {
	return TableHints{Type: "WITH", Keys: names}
}

// UseWithNolock Sql Server 使用 WITH(NOLOCK) 表提示
func (tableHint TableHints) UseWithNolock() TableHints {
	return tableHint.With("NOLOCK")
}

Usage

  • WITH(NOLOCK) 脏读表提示
import (
    "gorm.io/hints"
    "tool"
)

db.Clauses(tool.TableHints{}.UseWithNolock()).Find(&User{})
// SELECT * FROM users WITH(NOLOCK)
  • 其他表提示
import (
    "gorm.io/hints"
    "tool"
)

db.Clauses(tool.TableHints{}.With("NOWAIT")).Find(&User{})
// SELECT * FROM users WITH(NOWAIT)

db.Clauses(tool.TableHints{}.With("ROWLOCK")).Find(&User{})
// SELECT * FROM users WITH(ROWLOCK)

2021 年 12 月 25 日一个人发布于 https://zixizixi.cn/golang-gorm-custom-table-hints

  • golang

    Go 语言是 Google 推出的一种全新的编程语言,可以在不损失应用程序性能的情况下降低代码的复杂性。谷歌首席软件工程师罗布派克(Rob Pike)说:我们之所以开发 Go,是因为过去 10 多年间软件开发的难度令人沮丧。Go 是谷歌 2009 发布的第二款编程语言。

    497 引用 • 1387 回帖 • 288 关注
  • GORM
    8 引用 • 19 回帖
  • SQL
    126 引用 • 381 回帖 • 3 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
iTanken
飘风不终朝,骤雨不终日。 成都

推荐标签 标签

  • 笔记

    好记性不如烂笔头。

    308 引用 • 793 回帖
  • Redis

    Redis 是一个开源的使用 ANSI C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API。从 2010 年 3 月 15 日起,Redis 的开发工作由 VMware 主持。从 2013 年 5 月开始,Redis 的开发由 Pivotal 赞助。

    286 引用 • 248 回帖 • 48 关注
  • API

    应用程序编程接口(Application Programming Interface)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节。

    77 引用 • 430 回帖 • 2 关注
  • Spark

    Spark 是 UC Berkeley AMP lab 所开源的类 Hadoop MapReduce 的通用并行框架。Spark 拥有 Hadoop MapReduce 所具有的优点;但不同于 MapReduce 的是 Job 中间输出结果可以保存在内存中,从而不再需要读写 HDFS,因此 Spark 能更好地适用于数据挖掘与机器学习等需要迭代的 MapReduce 的算法。

    74 引用 • 46 回帖 • 558 关注
  • Thymeleaf

    Thymeleaf 是一款用于渲染 XML/XHTML/HTML5 内容的模板引擎。类似 Velocity、 FreeMarker 等,它也可以轻易的与 Spring 等 Web 框架进行集成作为 Web 应用的模板引擎。与其它模板引擎相比,Thymeleaf 最大的特点是能够直接在浏览器中打开并正确显示模板页面,而不需要启动整个 Web 应用。

    11 引用 • 19 回帖 • 361 关注
  • sts
    2 引用 • 2 回帖 • 195 关注
  • uTools

    uTools 是一个极简、插件化、跨平台的现代桌面软件。通过自由选配丰富的插件,打造你得心应手的工具集合。

    6 引用 • 14 回帖 • 1 关注
  • 安装

    你若安好,便是晴天。

    132 引用 • 1184 回帖
  • WiFiDog

    WiFiDog 是一套开源的无线热点认证管理工具,主要功能包括:位置相关的内容递送;用户认证和授权;集中式网络监控。

    1 引用 • 7 回帖 • 589 关注
  • JSON

    JSON (JavaScript Object Notation)是一种轻量级的数据交换格式。易于人类阅读和编写。同时也易于机器解析和生成。

    52 引用 • 190 回帖 • 1 关注
  • iOS

    iOS 是由苹果公司开发的移动操作系统,最早于 2007 年 1 月 9 日的 Macworld 大会上公布这个系统,最初是设计给 iPhone 使用的,后来陆续套用到 iPod touch、iPad 以及 Apple TV 等产品上。iOS 与苹果的 Mac OS X 操作系统一样,属于类 Unix 的商业操作系统。

    85 引用 • 139 回帖 • 1 关注
  • 架构

    我们平时所说的“架构”主要是指软件架构,这是有关软件整体结构与组件的抽象描述,用于指导软件系统各个方面的设计。另外还有“业务架构”、“网络架构”、“硬件架构”等细分领域。

    142 引用 • 442 回帖
  • GAE

    Google App Engine(GAE)是 Google 管理的数据中心中用于 WEB 应用程序的开发和托管的平台。2008 年 4 月 发布第一个测试版本。目前支持 Python、Java 和 Go 开发部署。全球已有数十万的开发者在其上开发了众多的应用。

    14 引用 • 42 回帖 • 774 关注
  • Hexo

    Hexo 是一款快速、简洁且高效的博客框架,使用 Node.js 编写。

    21 引用 • 140 回帖 • 2 关注
  • Elasticsearch

    Elasticsearch 是一个基于 Lucene 的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于 RESTful 接口。Elasticsearch 是用 Java 开发的,并作为 Apache 许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。

    117 引用 • 99 回帖 • 211 关注
  • Wide

    Wide 是一款基于 Web 的 Go 语言 IDE。通过浏览器就可以进行 Go 开发,并有代码自动完成、查看表达式、编译反馈、Lint、实时结果输出等功能。

    欢迎访问我们运维的实例: https://wide.b3log.org

    30 引用 • 218 回帖 • 624 关注
  • Jenkins

    Jenkins 是一套开源的持续集成工具。它提供了非常丰富的插件,让构建、部署、自动化集成项目变得简单易用。

    53 引用 • 37 回帖 • 3 关注
  • CSS

    CSS(Cascading Style Sheet)“层叠样式表”是用于控制网页样式并允许将样式信息与网页内容分离的一种标记性语言。

    197 引用 • 550 回帖
  • Mobi.css

    Mobi.css is a lightweight, flexible CSS framework that focus on mobile.

    1 引用 • 6 回帖 • 741 关注
  • abitmean

    有点意思就行了

    30 关注
  • Ruby

    Ruby 是一种开源的面向对象程序设计的服务器端脚本语言,在 20 世纪 90 年代中期由日本的松本行弘(まつもとゆきひろ/Yukihiro Matsumoto)设计并开发。在 Ruby 社区,松本也被称为马茨(Matz)。

    7 引用 • 31 回帖 • 218 关注
  • 钉钉

    钉钉,专为中国企业打造的免费沟通协同多端平台, 阿里巴巴出品。

    15 引用 • 67 回帖 • 336 关注
  • 面试

    面试造航母,上班拧螺丝。多面试,少加班。

    325 引用 • 1395 回帖 • 1 关注
  • 一些有用的避坑指南。

    69 引用 • 93 回帖
  • 服务

    提供一个服务绝不仅仅是简单的把硬件和软件累加在一起,它包括了服务的可靠性、服务的标准化、以及对服务的监控、维护、技术支持等。

    41 引用 • 24 回帖
  • 以太坊

    以太坊(Ethereum)并不是一个机构,而是一款能够在区块链上实现智能合约、开源的底层系统。以太坊是一个平台和一种编程语言 Solidity,使开发人员能够建立和发布下一代去中心化应用。 以太坊可以用来编程、分散、担保和交易任何事物:投票、域名、金融交易所、众筹、公司管理、合同和知识产权等等。

    34 引用 • 367 回帖 • 2 关注
  • BookxNote

    BookxNote 是一款全新的电子书学习工具,助力您的学习与思考,让您的大脑更高效的记忆。

    笔记整理交给我,一心只读圣贤书。

    1 引用 • 1 回帖 • 3 关注