gormcnm
is a cutting-edge generic package designed to transform how you use GORM in Go. By leveraging the full power of Go’s generics, it offers a type-safe, efficient, and highly productive way to reference database columns in your models. This eliminates the risks associated with hardcoded column names, enhancing refactoring safety, maintainability, and enabling faster development with fewer bugs.
gormcnm
resembles MyBatis Plus
in the Java ecosystem, which allows developers to dynamically retrieve column names using expressions like Example::getName
. Similarly, gormcnm
brings type-safe column referencing to Go. By using gormcnm
, developers can easily perform database queries with compile-time validation and avoid hardcoding strings in queries.
gormcnm
works like SQLAlchemy
in the Python ecosystem, where developers can reference model attributes like Example.name
for dynamic column access, enabling type-safe column referencing in Go. Similarly, gormcnm
enables type-safe dynamic column references in Go, like cls.Name.Eq("abc")
.
gormcnm
keeps your column references consistent and type-safe, ensuring that your code is cleaner, more robust, and easier to maintain. With gormcnm
, any changes in your model definitions are effortlessly reflected across your application without breaking queries, making it the ultimate safety net for your database interactions.
With gormcnm
, you unlock the full potential of Go’s generics, achieving type-safe, refactor-proof, and developer-friendly database interactions effortlessly. No more brittle hardcoded strings or runtime surprises—gormcnm
acts as your ultimate safety net, ensuring database queries remain consistent, scalable, and easy to refactor as your application evolves.
As a progressive package, gormcnm
seamlessly integrates into your existing GORM workflow, allowing developers to adopt it incrementally and at their own pace. You can decide when and where to leverage its type-safe features while continuing to benefit from the simplicity and familiarity of GORM’s core API, ensuring that adopting gormcnm
requires minimal learning effort and no disruption to your current projects.
go get github.com/yyle88/gormcnm
- Generics-based Type Safety: Harness Go's generics to create type-safe column names, ensuring that column references are validated at compile-time.
- Seamless Refactoring: Changing model field names or types automatically updates all references, reducing errors and making refactoring effortless.
- Progressive Adoption: Designed to be integrated incrementally, allowing developers to adopt its features at their own pace without disrupting existing workflows.
MyBatis Plus
-like Column References:gormcnm
enables type-safe dynamic column references in Go, likecls.Name.Eq("abc")
.SQLAlchemy
-like Access: LikeSQLAlchemy
in Python,gormcnm
enables type-safe dynamic column references in Go, making queries cleaner and less error-prone.- Compile-time Validation: Prevent runtime errors caused by incorrect column names or mismatched types with robust compile-time validation.
- Improved Developer Experience: Enjoy full IDE support with auto-completion, linting, and refactoring tools tailored for generics.
- Minimized Human Error: Eliminate typos and hardcoded magic strings with well-defined constants for column names.
- Self-documenting Code: Queries written with
gormcnm
are explicit and readable, making it easier to understand and maintain the codebase. - Reduced Boilerplate: Automatically generate type-safe column definitions with the gormcngen package, saving time and effort.
Suppose you have a GORM model defined as follows:
type Example struct {
Name string `gorm:"primary_key;type:varchar(100);"`
Type string `gorm:"column:type;"`
Rank int `gorm:"column:rank;"`
}
In Java, the MyBatis Plus
tool can obtain the column name through Example::getName
, assemble the query statement, fetch the result, and then use result.getName()
to get the value of the field:
@Autowired
private ExampleMapper exampleMapper;
public void test() {
Example result = exampleMapper.selectOne(
new LambdaQueryWrapper<Example>().eq(Example::getName, "abc")
);
if (result != null) {
System.out.println(result.getName());
System.out.println(result.getRank());
}
}
In Python, the SQLAlchemy
tool can obtain the column name through Example.name
, assemble the query statement, fetch the result, and then use result.name
to get the value of the field:
def test():
result = session.query(Example).filter(Example.name == "abc").first()
if result:
print(result.name)
print(result.rank)
In Go, there's no equivalent to Example::Name
; instead, example.Name
directly retrieves the field value, requiring hard-coded queries.
Typically, you would write a query with hardcoded column names like this:
err := db.Where("name=?", "abc").First(&res).Error
While this works, hardcoding column names introduces risks during refactoring or type changes. A simple oversight could lead to runtime errors or type mismatches.
With gormcnm
, you can define type-safe columns like this:
const (
columnName = gormcnm.ColumnName[string]("name")
columnType = gormcnm.ColumnName[string]("type")
columnRank = gormcnm.ColumnName[int]("rank")
)
This allows you to write type-safe queries with compile-time validation:
var res Example
if err := db.Where(columnName.Eq("abc")).
Where(columnType.Eq("xyz")).
Where(columnRank.Gt(100)).
Where(columnRank.Lt(200)).
First(&res).Error; err != nil {
panic(errors.WithMessage(err, "wrong"))
}
fmt.Println(res)
This approach ensures that column types and names are consistent, reducing the risk of bugs.
- Effortless Refactoring: Column names and types are strongly typed with generics. Renaming fields or changing column types updates all references automatically.
- Compile-time Type Safety: Catch issues like type mismatches or incorrect column references during compilation, reducing debugging time.
- Progressive Integration: Start using
gormcnm
in specific parts of your codebase and expand its use as needed, ensuring a smooth and non-disruptive transition. - Cleaner Code: Replace magic strings with constants, making your queries more readable, maintainable, and understandable.
- Faster Development: IDE features like auto-completion and refactoring tools speed up coding and reduce the chance of human errors.
MyBatis Plus
-like Syntax:gormcnm
uses a type-safe column referencing pattern likeMyBatis Plus
in Java, enabling dynamic column access and safe queries.SQLAlchemy
-like Access: Similar toSQLAlchemy
in Python,gormcnm
provides type-safe dynamic column references in Go.- Self-documenting Queries: Type-safe column references make your queries clearer and more descriptive, aiding collaboration and future maintenance.
- Reduced Debugging Effort: Locating column-related bugs is easier since all references use well-defined constants.
- Minimized Human Error: Avoid typos and hardcoded values that lead to runtime errors by centralizing column definitions.
- Seamless Model Synchronization: Model changes are consistently reflected in your queries, ensuring your application always uses up-to-date column definitions.
In addition to the type-safe queries previously shown, gormcnm
also supports complex and flexible operations such as updating multiple columns with conditions. Here's a comprehensive example:
result := db.Model(&Example{}).Where(
Qx(columnName.Eq("aaa")).
AND(
Qx(columnType.Eq("xxx")),
Qx(columnRank.Eq(123)),
).Qx3(),
).UpdateColumns(columnRank.Kw(100).Kw(columnType.Kv("zzz")).AsMap())
require.NoError(t, result.Error)
require.Equal(t, int64(1), result.RowsAffected)
To make things even more efficient, you can use the gormcngen package to automatically generate column definitions for your models. The generated code might look like this:
type ExampleColumns struct {
Name gormcnm.ColumnName[string]
Type gormcnm.ColumnName[string]
Rank gormcnm.ColumnName[int]
}
func (*Example) Columns() *ExampleColumns {
return &ExampleColumns{
Name: "name",
Type: "type",
Rank: "rank",
}
}
From now on, you can retrieve the column name like Example::getName
in MyBatis Plus
, obtain the column name class object with cls = res.Columns()
, and then use cls.Name.Eq("abc")
for the query in GORM.
Once the columns are generated, you can use them in your queries:
var res models.Example
var cls = res.Columns()
if err := db.Where(cls.Name.Eq("abc")).
Where(cls.Type.Eq("xyz")).
Where(cls.Rank.Gt(100)).
Where(cls.Rank.Lt(200)).
First(&res).Error; err != nil {
panic(errors.WithMessage(err, "wrong"))
}
fmt.Println(res)
Here’s an example demonstrating how to use gormcnm
for retrieving data based on complex conditions:
var res models.Example
var cls = res.Columns()
require.NoError(t, db.Where(
Qx(cls.Name.BetweenAND("aba", "abd")).
AND(
Qx(cls.Type.IsNotNULL()),
).Qx2(),
).First(&one).Error)
require.Equal(t, "abc", res.Name)
Simply import the package:
import "github.com/yyle88/gormcnm"
- Reliable Refactoring: Confidently rename fields or change types knowing that all column references will remain consistent.
- Enhanced Safety: Compile-time validation ensures no mismatches or incorrect references.
- Productivity Boost: Type-safe column references and IDE auto-completion save development time and reduce errors.
- Progressive Adoption: Designed for gradual integration, letting you start small and scale as needed without disrupting your workflow.
- Clean and Maintainable Code: Queries are more readable and self-explanatory, improving collaboration and future modifications.
- Fewer Runtime Bugs: Centralized column definitions reduce the chances of human error.
- Automatic Code Generation: The gormcngen package simplifies setup, automating column definition generation.
gormcnm
brings a simple, type-safe, and productive approach to working with GORM in Go. By removing hardcoded column names and leveraging Go's generics, it ensures that your database queries are safe, consistent, and easy to maintain. Whether you're building small applications or managing complex systems, gormcnm
helps you write robust, refactor-friendly code, accelerating development and improving the quality of your work.
By adopting gormcnm
, you can significantly enhance the quality of your GORM queries, reduce human error, and accelerate development—all while maintaining a clean, maintainable codebase.
CREATION_IDEAS && README OLD DOC
gormcnm
is open-source and released under the MIT License. See the LICENSE file for more information.
Welcome to contribute to this project by submitting pull requests or reporting issues.
If you find this package helpful, give it a star on GitHub!
Thank you for your support!
Happy Coding with gormcnm
! 🎉
Give me stars. Thank you!!!