mysql 代码生成
MySQL 用法## 概述
mysql 代码生成支持从 sql 文件和数据库链接生成, 且支持生成带缓存逻辑代码。
mysql 生成的代码内容有数据表对应的 golang 结构体、CURD 操作方法,缓存逻辑等信息,更多详细的数据库代码生成可参考指南 goctl model
任务目标
- 熟悉 goctl 生成 mysql 代码的命令使用,了解目前支持的指令和功能
- 初步了解 goctl 生成 mysql 代码的格式
- 初步掌握从 sql 文件编写到 mysql 代码的生成流程
准备条件
代码生成
首先执行如下指令将示例 sql 文件存储到本地的
user.sql
文件中。CREATE TABLE user (
id bigint AUTO_INCREMENT,
name varchar(255) NULL COMMENT 'The username',
password varchar(255) NOT NULL DEFAULT '' COMMENT 'The user password',
mobile varchar(255) NOT NULL DEFAULT '' COMMENT 'The mobile phone number',
gender char(10) NOT NULL DEFAULT 'male' COMMENT 'gender,male|female|unknown',
nickname varchar(255) NULL DEFAULT '' COMMENT 'The nickname',
type tinyint(1) NULL DEFAULT 0 COMMENT 'The user type, 0:normal,1:vip, for test golang keyword',
create_at timestamp NULL,
update_at timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE mobile_index (mobile),
UNIQUE name_index (name),
PRIMARY KEY (id)
) ENGINE = InnoDB COLLATE utf8mb4_general_ci COMMENT 'user table';
新建工作空间和目录工程
$ mkdir -p ~/workspace/model/mysql
将上文中存储的
user.sql
文件移动到~/workspace/model/mysql
目录下生成 model 代码
$ cd ~/workspace/model/mysql
$ goctl model mysql ddl --src user.sql --dir .
Done.
当你看到
Done.
输出则代表生成成功了,接下来我们来看一下生成的代码内容:# 列出当前目录下的文件
$ ls
user.sql usermodel.go usermodel_gen.go vars.go
# 查看目录树
$ tree
.
├── user.sql
├── usermodel.go
├── usermodel_gen.go
└── vars.go
0 directories, 4 files
代码查看
- user.sql
- usermodel.go
- usermodel_gen.go
- vars.go
CREATE TABLE user (
id bigint AUTO_INCREMENT,
name varchar(255) NULL COMMENT 'The username',
password varchar(255) NOT NULL DEFAULT '' COMMENT 'The user password',
mobile varchar(255) NOT NULL DEFAULT '' COMMENT 'The mobile phone number',
gender char(10) NOT NULL DEFAULT 'male' COMMENT 'gender,male|female|unknown',
nickname varchar(255) NULL DEFAULT '' COMMENT 'The nickname',
type tinyint(1) NULL DEFAULT 0 COMMENT 'The user type, 0:normal,1:vip, for test golang keyword',
create_at timestamp NULL,
update_at timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE mobile_index (mobile),
UNIQUE name_index (name),
PRIMARY KEY (id)
) ENGINE = InnoDB COLLATE utf8mb4_general_ci COMMENT 'user table';
package mysql
import "github.com/zeromicro/go-zero/core/stores/sqlx"
var _ UserModel = (*customUserModel)(nil)
type (
// UserModel is an interface to be customized, add more methods here,
// and implement the added methods in customUserModel.
UserModel interface {
userModel
}
customUserModel struct {
*defaultUserModel
}
)
// NewUserModel returns a model for the database table.
func NewUserModel(conn sqlx.SqlConn) UserModel {
return &customUserModel{
defaultUserModel: newUserModel(conn),
}
}
// Code generated by goctl. DO NOT EDIT.
package mysql
import (
"context"
"database/sql"
"fmt"
"strings"
"time"
"github.com/zeromicro/go-zero/core/stores/builder"
"github.com/zeromicro/go-zero/core/stores/sqlc"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"github.com/zeromicro/go-zero/core/stringx"
)
var (
userFieldNames = builder.RawFieldNames(&User{})
userRows = strings.Join(userFieldNames, ",")
userRowsExpectAutoSet = strings.Join(stringx.Remove(userFieldNames, "`id`", "`update_time`", "`create_at`", "`created_at`", "`create_time`", "`update_at`", "`updated_at`"), ",")
userRowsWithPlaceHolder = strings.Join(stringx.Remove(userFieldNames, "`id`", "`update_time`", "`create_at`", "`created_at`", "`create_time`", "`update_at`", "`updated_at`"), "=?,") + "=?"
)
type (
userModel interface {
Insert(ctx context.Context, data *User) (sql.Result, error)
FindOne(ctx context.Context, id int64) (*User, error)
FindOneByMobile(ctx context.Context, mobile string) (*User, error)
FindOneByName(ctx context.Context, name sql.NullString) (*User, error)
Update(ctx context.Context, data *User) error
Delete(ctx context.Context, id int64) error
}
defaultUserModel struct {
conn sqlx.SqlConn
table string
}
User struct {
Id int64 `db:"id"`
Name sql.NullString `db:"name"` // The username
Password string `db:"password"` // The user password
Mobile string `db:"mobile"` // The mobile phone number
Gender string `db:"gender"` // gender,male|female|unknown
Nickname string `db:"nickname"` // The nickname
Type int64 `db:"type"` // The user type, 0:normal,1:vip, for test golang keyword
CreateAt sql.NullTime `db:"create_at"`
UpdateAt time.Time `db:"update_at"`
}
)
func newUserModel(conn sqlx.SqlConn) *defaultUserModel {
return &defaultUserModel{
conn: conn,
table: "`user`",
}
}
func (m *defaultUserModel) Delete(ctx context.Context, id int64) error {
query := fmt.Sprintf("delete from %s where `id` = ?", m.table)
_, err := m.conn.ExecCtx(ctx, query, id)
return err
}
func (m *defaultUserModel) FindOne(ctx context.Context, id int64) (*User, error) {
query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", userRows, m.table)
var resp User
err := m.conn.QueryRowCtx(ctx, &resp, query, id)
switch err {
case nil:
return &resp, nil
case sqlc.ErrNotFound:
return nil, ErrNotFound
default:
return nil, err
}
}
func (m *defaultUserModel) FindOneByMobile(ctx context.Context, mobile string) (*User, error) {
var resp User
query := fmt.Sprintf("select %s from %s where `mobile` = ? limit 1", userRows, m.table)
err := m.conn.QueryRowCtx(ctx, &resp, query, mobile)
switch err {
case nil:
return &resp, nil
case sqlc.ErrNotFound:
return nil, ErrNotFound
default:
return nil, err
}
}
func (m *defaultUserModel) FindOneByName(ctx context.Context, name sql.NullString) (*User, error) {
var resp User
query := fmt.Sprintf("select %s from %s where `name` = ? limit 1", userRows, m.table)
err := m.conn.QueryRowCtx(ctx, &resp, query, name)
switch err {
case nil:
return &resp, nil
case sqlc.ErrNotFound:
return nil, ErrNotFound
default:
return nil, err
}
}
func (m *defaultUserModel) Insert(ctx context.Context, data *User) (sql.Result, error) {
query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?)", m.table, userRowsExpectAutoSet)
ret, err := m.conn.ExecCtx(ctx, query, data.Name, data.Password, data.Mobile, data.Gender, data.Nickname, data.Type)
return ret, err
}
func (m *defaultUserModel) Update(ctx context.Context, newData *User) error {
query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, userRowsWithPlaceHolder)
_, err := m.conn.ExecCtx(ctx, query, newData.Name, newData.Password, newData.Mobile, newData.Gender, newData.Nickname, newData.Type, newData.Id)
return err
}
func (m *defaultUserModel) tableName() string {
return m.table
}
package mysql
import "github.com/zeromicro/go-zero/core/stores/sqlx"
var ErrNotFound = sqlx.ErrNotFound