GORM has officially introduced support for Go Generics in its latest version (>= v1.30.0
). This addition significantly enhances usability and type safety while reducing issues such as SQL pollution caused by reusing gorm.DB
instances. Additionally, we’ve improved the behaviors of Joins
and Preload
and incorporated transaction timeout handling to prevent connection pool leaks.
This update introduces generic APIs in a carefully designed way that maintains full backward compatibility with existing APIs. You can freely mix traditional and generic APIs in your projects—just use generics for new code without worrying about compatibility with existing logic or GORM plugins (such as encryption/decryption, sharding, read/write splitting, tracing, etc.).
To prevent misuse, we have intentionally removed certain APIs in the generics version that are prone to ambiguity or concurrency issues, such as FirstOrCreate
and Save
. At the same time, we are designing a brand new gorm
CLI tool, which will offer stronger code generation capabilities, enhanced type safety, and lint support in the future — further reducing the risk of incorrect usage.
We strongly recommend using the new generics-based API in new projects or during refactoring efforts to enjoy a better development experience, improved type guarantees, and a more maintainable codebase.
Generic APIs
GORM’s generic APIs closely mirror the functionality of the original ones. Here are some common operations using the new generics APIs:
ctx := context.Background() |
The generics APIs fully support GORM’s advanced features by accepting optional parameters, such as clause configurations or plugin-based options (e.g., hints, resolvers), enabling powerful and flexible behaviors.
// OnConflict: Handle conflict during insert |
Joins / Preload Enhancements
The new GORM generics interface brings enhanced support for association queries (Joins
) and eager loading (Preload
), offering more flexible association methods, more expressive query capabilities, and a significantly simplified approach to building complex queries.
- Joins: Easily specify different join types (e.g.,
InnerJoin
,LeftJoin
) and customize join conditions based on associations, making complex cross-table queries clearer and more intuitive.
// Load only users who have a company |
- Preload: Simplifies conditions for eager loading and introduces the
LimitPerRecord
option, which allows limiting the number of related records loaded per primary record when eager loading collections.
// A basic Preload example |
Complex Raw SQL
The generics interface continues to support Raw
SQL execution for complex or edge-case scenarios:
users, err := gorm.G[User](DB).Raw("SELECT name FROM users WHERE id = ?", user.ID).Find(ctx) |
However, we strongly recommend using our new code generation tool to achieve type-safe, maintainable, and secure raw queries—reducing risks like syntax errors or SQL injection.
Code Generator Workflow
- 1. Install the CLI tool:
go install gorm.io/cmd/gorm@latest |
- 2. Define query interfaces:
Simply define your query interface using Go’s interface
syntax, embedding SQL templates as comments:
type Query[T any] interface { |
- 3. Run the generator:
gorm gen -i ./examples/example.go -o query |
- 4. Use the generated API:
import "your_project/query" |
Summary
This release marks a significant step forward for GORM in both generics support and the brand-new gorm
command-line tool. These features have been in the planning stage for quite some time, and we’re excited to finally bring an initial implementation to the community.
In the coming updates, we’ll continue refining the generics API, enhancing the CLI tool, and updating the official https://gorm.io documentation accordingly—aiming to provide a clearer, more efficient developer experience.
We deeply appreciate the support from all GORM users and sponsors over the years. GORM’s growth over the past 12 years simply wouldn’t have been possible without you ❤️