Starting with this article, let’s take a look at the components and development practices that Go-Zero requires to develop a project.
Let’s start with the Model layer and talk about the GO-Zero API and packaging details. First of all, apis connected to the Model layer focus on core/ Stores. We first look at the operation of mysql such database, API method we came to core/stores/ SQLX, so the next few articles with a general introduction to the use of SQLX and design ideas.
Quick to use
func main(a) {
/ / 1
const datasource = "user:password@/dbname"
mysqlDB := sqlx.NewMysql(datasource)
/ / 2
um := model.NewUserModel(mysqlDB,"User")
/ / 3
ul := logic.NewUserLogic(um)
/ / 4
engine.AddRoutes(nginxApi(ul))
engine.Start()
}
// NewUserModel, NewUserLogic is similar
func NewUserModel(conn sqlx.SqlConn, table string) *UserModel {
return &UserModel{conn: conn, table: table}
}
// nginxApi injects logic into Handle and binds routing and handler
func nginxApi(ul *logic.UserLogic) []rest.Route {
return []rest.Route{
{
Method: http.MethodGet,
Path: "/user/:id".// /user/54er6;
Handler: handler.NewUserHandler(ul).GetUserById,
}
}
Copy the code
To sum up:
NewMysql
Creating a database connection- Create the corresponding
model
And pass the connection to the correspondingNewModel
It needs to be written by developers.” model
It’s for the next level uplogic
To provide services- will
logic
Injected into thehandler
, at the same timehandler
Binding to routes is enabledServer
This gives us the simplest structure for model-logic-handler. Then let’s look at how data is manipulated in the Model layer:
var userBuilderQueryRows = strings.Join(builderx.FieldNames(&User{}), ",")
type User struct {
Avatar string `db:"avatar"` / / avatar
UserName string `db:"user_name"` / / name
Sex int `db:"sex"` // 1 male,2 female
MobilePhone string `db:"mobile_phone"` / / cell phone number
}
func (um *UserModel) Insert(user *User) (int64, error) {
const insertsql = `insert into `+um.table+` (`+userBuilderQueryRows+`) values(? ,? ,?) `
// insert "delete using the same way"
res, err := um.conn.Exec(insertsql, user.Avatar, user.UserName, user.Sex, user.MobilePhone)
iferr ! =nil {
logx.Errorf("insert User Position Model Model err, err=%v", err)
return - 1, err
}
id, err := res.LastInsertId()
iferr ! =nil {
logx.Errorf("insert User Model to Id parse id err,err=%v", err)
return - 1, err
}
return id, nil
}
func (um *UserModel) FindOne(uid int64) (*User, error) {
var user User
// query
const querysql = `select `+userBuilderQueryRows+` from `+um.table+` where id=? limit 1`
err := um.conn.QueryRow(&user, querysql, uid)
iferr ! =nil {
logx.Errorf("userModile.findOne error ,id=%d,err=%s", uid, err.Error())
if err == sqlx.ErrNotFound {
return nil, ErrNotFound
}
return nil, err
}
return &user, nil
}
Copy the code
insert/update/delete
:conn.Exec(insertsql/updatesql/deletesql, args...)
query
:conn.QueryRow(&model, querysql, args...)
This is the simplest CRUD structure: first build the Model, then manipulate the model to operate.
The code structure
The file name | role |
---|---|
bulkinserter.go | Bulk insert |
mysql.go | NewMysql |
orm.go | Parsing, serializationmodel The operation of the |
sqlconn.go | abstractcrud Interface for operation |
tx.go | The transaction operations |
From sqlconn.go interinterface relationship:
CommonSqlConn and txSession are where the real implementation is. Let’s start with an overview of API functions:
API | parameter | role |
---|---|---|
Exec(query, args…) | SQL, SQL parameter | insert/update/delete |
Prepare(query) | sql | Precompiled SQL |
QueryRow(&model, query, args…) | Model, SQL, SQL parameters | Query a row of data and assign it to “model” |
QueryRowPartial(&model, query, args…) | Model, SQL, SQL parameters | Select Partial columns from model |
QueryRows/QueryRowsPartial | Same as above | Query the multi-line API |
Transact(func(session Session) error) | The transaction operations | By wrapping the operations in the parameters in transactions, the developer can only focus on writing the functions in the parameters |
conclusion
Go-zero’S SQLX shields go’s native SQL operations. Developers only need to focus on SQL compilation and data objects encapsulated by services. There is no need to manually prepare and Scan data when assigning data as in native development.
This section gives you a brief overview of the interrelationships between interfaces and the apis that developers usually focus on. The next section will focus on how Go-Zero can help you assign data and prevent traffic from directly killing your database in the event of a large number of concurrent requests.
reference
- go-zero sqlx
- Go database/sql tutorial
Welcome to Go-Zero
Project address: github.com/tal-tech/go…
If you like the article, please click on github star 🤝