Share two common code generation tools:

  • gormgen
  • handlergen

gormgen

Generate 3 files based on MySQL data table structure:

  1. Generate the tablestructThe structure of the body
  2. Generate the tableMarkdownThe document
  3. Generate the tableCURDmethods

scenario

In the development of business requirements, after creating the data table, the code generation tool is executed, and all the commonly used CURD operations are generated. The latter method can be, which greatly improves the efficiency of business development.

The sample

Table structure:

CREATE TABLE 'user_demo' (' id 'int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键', 'user_name' varchar(32) NOT NULL DEFAULT COMMENT ', 'nick_name' varchar(100) NOT NULL DEFAULT COMMENT ', 'mobile' varchar(20) NOT NULL DEFAULT '' COMMENT ' 'is_deleted' tinyint(1) NOT NULL DEFAULT '-1' COMMENT 'Whether deleted 1: yes -1: no ', 'created_at' TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'create time ', 'updated_at' timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'UPDATE time ', PRIMARY KEY (' id ')) ENGINE=InnoDB DEFAULT CHARSET= utf8MB4 COMMENT=' Demo ';Copy the code

1. Set the table to be automatically generated in config, and set the parameter to cmd.genTables. If the parameter is set to empty, all tables in the current database will be generated.

[cmd]
genTables = 'user_demo'
Copy the code

2. Execute the script in the root directory

./scripts/gormgen.sh
Copy the code

Execution has been completed, will be in the/internal/API/repository/db_repo generated user_demo_repo directory, at the same time, it will generate three file:

  • gen_model.go
  • gen_table.md
  • gen_user_demo.go

The contents of gen_model.go are as follows:

Package user_demo_repo import "time" //go:generate gormgen -structs userdemo_input. type UserDemo struct { Id INT32 // Primary key UserName String // NickName String // NickName Mobile String // Mobile number IsDeleted INT32 // Whether to delete 1: Yes -1: No CreatedAt time. time 'gorm:"time"' // create time UpdatedAt time. time 'gorm:"time"' // update time}Copy the code

The gen_table.md Markdown content is as follows:

The contents of gen_user_demo.go are as follows:

func NewModel() *UserDemo {... } func NewQueryBuilder() *userDemoRepoQueryBuilder {... } func (t *UserDemo) Create(db *gorm.DB) (id int32, err error) {... } func (t *UserDemo) Delete(db *gorm.DB) (err error) {... } func (t *UserDemo) Updates(db *gorm.DB, m map[string]interface{}) (err error) {... } type userDemoRepoQueryBuilder struct {... } func (qb *userDemoRepoQueryBuilder) buildQuery(db *gorm.DB) *gorm.DB {... } func (qb *userDemoRepoQueryBuilder) Count(db *gorm.DB) (int64, error) {... } func (qb *userDemoRepoQueryBuilder) First(db *gorm.DB) (*UserDemo, error) {... } func (qb *userDemoRepoQueryBuilder) QueryOne(db *gorm.DB) (*UserDemo, error) {... } func (qb *userDemoRepoQueryBuilder) QueryAll(db *gorm.DB) ([]*UserDemo, error) {... } func (qb *userDemoRepoQueryBuilder) Limit(limit int) *userDemoRepoQueryBuilder {... } func (qb *userDemoRepoQueryBuilder) Offset(offset int) *userDemoRepoQueryBuilder {... } func (qb *userDemoRepoQueryBuilder) WhereId(p db_repo.Predicate, value int32) *userDemoRepoQueryBuilder {... } func (qb *userDemoRepoQueryBuilder) OrderById(asc bool) *userDemoRepoQueryBuilder {... } func (qb *userDemoRepoQueryBuilder) WhereUserName(p db_repo.Predicate, value string) *userDemoRepoQueryBuilder {... } func (qb *userDemoRepoQueryBuilder) OrderByUserName(asc bool) *userDemoRepoQueryBuilder {... } func (qb *userDemoRepoQueryBuilder) WhereNickName(p db_repo.Predicate, value string) *userDemoRepoQueryBuilder {... } func (qb *userDemoRepoQueryBuilder) OrderByNickName(asc bool) *userDemoRepoQueryBuilder {... } func (qb *userDemoRepoQueryBuilder) WhereMobile(p db_repo.Predicate, value string) *userDemoRepoQueryBuilder {... } func (qb *userDemoRepoQueryBuilder) OrderByMobile(asc bool) *userDemoRepoQueryBuilder {... } func (qb *userDemoRepoQueryBuilder) WhereIsDeleted(p db_repo.Predicate, value int32) *userDemoRepoQueryBuilder {... } func (qb *userDemoRepoQueryBuilder) OrderByIsDeleted(asc bool) *userDemoRepoQueryBuilder {... } func (qb *userDemoRepoQueryBuilder) WhereCreatedAt(p db_repo.Predicate, value time.Time) *userDemoRepoQueryBuilder {... } func (qb *userDemoRepoQueryBuilder) OrderByCreatedAt(asc bool) *userDemoRepoQueryBuilder {... } func (qb *userDemoRepoQueryBuilder) WhereUpdatedAt(p db_repo.Predicate, value time.Time) *userDemoRepoQueryBuilder {... } func (qb *userDemoRepoQueryBuilder) OrderByUpdatedAt(asc bool) *userDemoRepoQueryBuilder {... }Copy the code

use

Use the generated method like this:

// Query example:  user_demo_repo.NewQueryBuilder(). WhereUserName(db_repo.EqualPredicate, "tom"). OrderById(true). QueryOne(u.db.GetDbR().WithContext(ctx.RequestContext()))Copy the code

handlergen

Generate file based on the interface method in type Interface defined in Handler file.

scenario

The person in charge of research and development of this requirement defines the method to be developed by defining the Type interface, and executes the code generation tool. The empty implementation of each method will be generated in a separate file, and developers only need to implement their own methods, which is convenient for division of labor and code management.

The sample

For example, the type interface defined in test_Handler looks like this:

Var _ Handler = (* Handler)(nil) type Handler interface {// I To avoid implementation by other packages I () // Create Create user Create() core.handlerfunc // Update Edit user Update() core.handlerfunc // Delete Delete user Delete() core.handlerfunc // Detail User details Detail() core.handlerfunc  } type handler struct { logger *zap.Logger cache cache.Repo userService user_service.UserService } func New(logger *zap.Logger, db db.Repo, cache cache.Repo) Handler { return &handler{ logger: logger, cache: cache, userService: user_service.NewUserService(db, cache), } } func (h *handler) i() {}Copy the code

Execute the script at root:

Sh test_Handler // test_Handler indicates the name of the package that needs to generate handlerCopy the code

After the execution, can be in/internal/API/controller/test_handler generated in the four files:

  • func_create.go
  • func_update.go
  • func_detail.go
  • func_delete.go

Func_create. go goes as follows:

type createRequest struct{}

type createResponse struct{}

func (h *handler) Create() core.HandlerFunc {
	return func(c core.Context) {

	}
}
Copy the code

CreateRequest is the input parameter structure and createResponse is the output parameter structure.

Func_update.go goes as follows:

type updateRequest struct{}

type updateResponse struct{}

func (h *handler) Update() core.HandlerFunc {
	return func(c core.Context) {

	}
}
Copy the code

Func_detail. go has the following contents:

type detailRequest struct{}

type detailResponse struct{}

func (h *handler) Detail() core.HandlerFunc {
	return func(c core.Context) {

	}
}
Copy the code

Func_delete. go reads as follows:

type deleteRequest struct{}

type deleteResponse struct{}

func (h *handler) Delete() core.HandlerFunc {
	return func(c core.Context) {

	}
}
Copy the code

The above code is in the Go-gin-API project at github.com/xinliangnot…