当前位置:网站首页>Go novice exploration road 2
Go novice exploration road 2
2022-06-25 12:36:00 【Velly_ zheng】
go The second way for novices to explore
Minor objectives of the current period
The previous section , Has been used go Realization mysql Database connection and data CRUD operation ; however , Nowadays, the actual business implementation rarely writes native sql sentence , therefore , Keep pace with the times , The small goal of this period is to use ORM The model implements the operation of the database .
go ORM Realization
1. orm plug-in unit
Compared a lot orm frame , But by contrast , I think for novices , Only master beego Self contained orm The framework is enough , Familiar with and master the self-contained orm, Then some other principles will naturally be understood .
Installation package
go get github.com/astaxie/beego/client/orm
2. Database design
Here for the convenience of later implementation , Here we begin to design a relatively complete database table
- User table user
- Organization chart group
- User information sheet user_info
- Address table address
- Area code table address_code
- Template table template
- Order information sheet order_info
- Distribution information table delivery_info
- After sale list after_sale
- Template snapshot table template_snapshot
- Public field table common_field
user surface :
| Name | explain |
|---|---|
| id | Self growth id |
| group_id | organization id |
| status | state , There were on off freeze |
| created_at | Creation time |
| updated_at | Update time |
| deleted_at | Delete time |
user_info surface :
| Name | explain |
|---|---|
| id | Self growth id |
| user_id | user id |
| user_name | user name |
| nickname | nickname |
| avatar_url | Image address |
| phone | cell-phone number |
| birth | Date of birth |
| mailbox | |
| vip | Whether it is vip |
| vip_account | vip account number |
| created_at | Creation time |
| updated_at | Update time |
group surface :
| Name | explain |
|---|---|
| id | Self growth id |
| parent_id | Superior organization id |
| name | Organization name |
| status | The state of organization on off |
| created_at | Creation time |
| updated_at | Update time |
address surface :
| Name | explain |
|---|---|
| id | Self growth id |
| user_id | user id |
| province | Province Code |
| city | City Code |
| area | Area code |
| detail_address | Detailed address |
| status | state |
| created_at | Creation time |
| updated_at | Update time |
address_code surface :
| Name | explain |
|---|---|
| id | unique index id |
| partner_id | The superior id |
| name | province 、 City or district name |
| created_at | Creation time |
| updated_at | Update time |
template surface :
| Name | explain |
|---|---|
| id | Self growth id |
| name | Template name |
| create_user_id | Create user id |
| template_version | Template version number |
| template_type | Template type ,input or output |
| template_content | Template content , object type , Containing fields id and Fill in the attribute in the field ( If required ) |
| status | state |
| created_at | Creation time |
| updated_at | Update time |
template_snapshot surface :
| Name | explain |
|---|---|
| id | Self growth id |
| template_ id | Templates id |
| name | Template name |
| create_user_id | Create user id |
| template_version | Template version number |
| template_type | Template type ,input or output |
| template_content | Template content , object type , Containing fields id and Fill in the attribute in the field ( If required ) |
| created_at | Creation time |
| updated_at | Update time |
common_field surface :
| Name | explain |
|---|---|
| id | Self growth id |
| column_ type | Field type ,input radio |
| column_name | The English name of the field in the table |
| column_title | The field displays the Chinese name |
| admin_id | Create administrator id |
| status | state on off |
| options | If it is radio type , You need to write options, Add a drop-down list value to choose from Including English and Chinese names |
| created_at | Creation time |
| updated_at | Update time |
order_info surface :
| Name | explain |
|---|---|
| id | Self growth id |
| send_user_id | Order user id |
| receive_user_id | Recipient user id |
| send_address | Addressee address |
| receive_address | Addressee address |
| content | Shipment item information |
| status | The order status Not delivered Shipped |
| weight | weight |
| express_company | Logistics company id |
| expense | Express fee |
| customer_remark | User notes |
| shop_remark | Merchant remarks |
| created_at | Creation time |
| updated_at | Update time |
delivery_info surface :
| Name | explain |
|---|---|
| id | Self growth id |
| order_id | Order id |
| express_id | courier number |
| status | Express status In transit Sending Sign for |
| send_time | Sending time |
| receive_time | Pick up time |
| weight | weight |
| expense | Express fee |
| insured | Is it insured |
| insured_amount | The insured amount |
| remark | Shipping notes |
| created_at | Creation time |
| updated_at | Update time |
** after_sale surface :**
| Name | explain |
|---|---|
| id | Self growth id |
| express_id | courier number |
| back_express_id | Courier no. of returned items |
| status | Returning Confirm receipt |
| send_time | Sending time |
| receive_time | Pick up time |
| expense | Express fee |
| remark | Shipping notes |
| created_at | Creation time |
| updated_at | Update time |
chart 
3. Concrete realization
In fact, the specific implementation involves more
in general , If it's easy to implement , That is, there is a direct main.go file , Write the database connection operation and database creation operation .
But such rough writing , Not suitable for work , Because no one would write that , It's so inappropriate .
Here we recommend another way to write
Use go-gormigrate/gormigrate plug-in unit , adopt migrate Corresponding to instruction generation table surface
3.1 Command execution script

Concrete realization :migrate.go
package command
import (
"ExcelHandleProject/src/config/mysql"
"ExcelHandleProject/src/migration"
"ExcelHandleProject/src/pkg/logger"
"fmt"
"github.com/go-gormigrate/gormigrate/v2"
"github.com/spf13/cobra"
)
var migrateCmd = &cobra.Command{
Use: "migrate",
Short: " Perform database migration ",
Run: migrate,
}
func init() {
rootCmd.AddCommand(migrateCmd)
}
func migrate(cmd *cobra.Command, args []string) {
migrations := migration.GetMigrations()
fmt.Printf("migrations %#v \n", migrations)
//mList by *gormigrate.Migration type
for conn, mList := range migrations {
//conn by admin and default,db For objects connected to the database
db := mysql.GormClientByConn(conn)
m := gormigrate.New(db, gormigrate.DefaultOptions, mList)
if err := m.Migrate(); err != nil {
logger.Fatalf("Could not migrate: %v", err)
}
}
logger.Printf("Migration did run successfully")
}
root.go
package command
import "github.com/spf13/cobra"
var (
rootCmd = &cobra.Command{
Use: "excel",
}
)
func Execute() error {
return rootCmd.Execute()
}
main.go
package main
import "ExcelHandleProject/cmd/command"
func main() {
_ = command.Execute()
}
perform go run cmd/main.go migrate Command to create a defined in the database model
3.2 Defined migration file

Concrete realization :migration.go
package migration
import (
"ExcelHandleProject/src/config/mysql"
"github.com/go-gormigrate/gormigrate/v2"
)
// Defining interfaces , contain SAdditionally() function
type Migration interface {
Additionally() []*gormigrate.Migration
}
// Back to the assembly
// type byte yes uint8 Another name for rune yes int32 Another name for Representing one unicode code
// When a variable is declared , The system automatically assigns a zero value to this type
// Short mode := Variable definition and initialization syntax , but := Limited Defining variables , Initialization is also displayed ; Cannot provide data type ; Can only be used inside a function
//var It is usually used to indicate the type of variable that needs to be displayed
func GetMigrations() map[string][]*gormigrate.Migration {
// Define initialization variables migrations
var migrations map[string][]*gormigrate.Migration
migrations = make(map[string][]*gormigrate.Migration)
//mysql.Connections() return slice, The stored content is configs Under folder app.yml To configure
//v by default and admin
for _, v := range mysql.Connections() {
migrations[v] = append(migrations[v], NewInitialMigration().Additionally(v)...)
}
return migrations
}
initial_migration.go
package migration
import (
"ExcelHandleProject/src/model"
"github.com/go-gormigrate/gormigrate/v2"
"gorm.io/gorm"
)
type InitialMigration struct {
}
func (*InitialMigration) Additionally(conn string) []*gormigrate.Migration {
//switch By default case Last brought break sentence , If necessary, perform the following case, have access to fallthrough
//go-gormigrate/gormigrate grammar gormigrate.Migration{}
switch conn {
case "default":
return []*gormigrate.Migration{
// Here is just an example , Everyone writes other things by themselves
{
ID: "201608301430",
Migrate: func(tx *gorm.DB) error {
return tx.AutoMigrate(&model.User{
})
},
Rollback: func(tx *gorm.DB) error {
return tx.Migrator().DropTable((&model.User{
}).TableName())
},
},
}
default:
return []*gormigrate.Migration{
}
}
}
// Create a InitialMigration object
func NewInitialMigration() *InitialMigration {
return new(InitialMigration)
}
3.3 Database connection implementation

mysql.go
package mysql
import (
"ExcelHandleProject/src/config"
"ExcelHandleProject/src/lvm/runtime"
"database/sql"
"encoding/json"
"fmt"
_ "github.com/go-sql-driver/mysql"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"log"
"time"
)
var connections []string
var connClientMapping map[string]*sql.DB
// Definition mysql Database connection parameters
type mysqlConnectParams struct {
Name string `json:"name"`
Host string `json:"host"`
Port uint `json:"port"`
User string `json:"user"`
Password string `json:"password"`
}
func init() {
// call config package , Get configured map aggregate
// Execute first config Bag init() function , Read again app.yml In the document database.mysql To configure
conf := config.GetMap("database.mysql")
//make(Type, length), Initialize a slice, perhaps map perhaps chan object , And it can only be these three objects , This is also the return value Type, Instead of Pointers ,new Return pointer
//slice Is an abstraction of an array go The length of the array cannot be changed , slice Length is not fixed , You can append elements
// Create a collection
connClientMapping = make(map[string]*sql.DB)
//returns a slice with length and capacity of 0
connections = make([]string, 0)
for k, v := range conf {
//json.Marshal() Serialized data
jByte, err := json.Marshal(v)
if err != nil {
//%#v Output go The value of the language grammar format
log.Fatal(fmt.Sprintf("parse mysql config err: %#v", err))
return
}
// Defining variables param, The type is mysqlConnectParams
param := mysqlConnectParams{
}
//json.Unmarshal() Deserialized data , take json The string is decoded to the corresponding data structure
err = json.Unmarshal(jByte, ¶m)
if err != nil {
log.Fatal(fmt.Sprintf("parse mysql config err: %#v", err))
return
}
// by slice connections dynamic add elements
connections = append(connections, k)
// Splicing connect string, Connect to database
connClientMapping[k] = connect(buildDsn(param))
}
fmt.Printf("connClientMappings %#v \n", connClientMapping)
}
//function The difference between lowercase and uppercase letters of names :
// Regardless of the method name , Constant , Variable name or structure name , If the initial is capitalized , Can be accessed by other packages ; If the initials are lowercase , It can only be used in this package
func Connections() []string {
return connections
}
//gorm Connect to database ,dsn := "user:[email protected](127.0.0.1:3306)/dbname?charset=utf8&parseTime=True&loc=Local"
//parseTime=true the date or datetime like 0000-00-00 00:00:00 is converted into zero value of time.Time
// fmt.Sprintf Format output %s character string %d integer
//loc=Local set the location for time
func buildDsn(p mysqlConnectParams) string {
dsn := fmt.Sprintf("%s:%[email protected](%s:%d)/%s?charset=utf8&parseTime=true", p.User, p.Password, p.Host, p.Port, p.Name)
return dsn
}
// For external calls
func ClientByConn(conn string) *sql.DB {
return connClientMapping[conn]
}
func GormClientByConn(conn string) *gorm.DB {
if conn == "" {
return nil
}
//sqlDB by admin or default Database connection string
sqlDB := connClientMapping[conn]
fmt.Printf("sqlDB conn %#v %#v \n", sqlDB, conn)
//sqlDB by *sql.DB,gorm usage , Connect to database
gormDB, err := gorm.Open(mysql.New(mysql.Config{
Conn: sqlDB,
}), &gorm.Config{
})
if err != nil {
panic(err)
}
return gormDB
}
// gorm Database connection obtain dsn After the string
// gorm.Open(mysql.Open(dsn), &gorm.Config{})
// database/sql Package connection to database sql.Open("driver-name", *dsn)
func connect(dsn string) *sql.DB {
// Connect to database
db, err := sql.Open("mysql", dsn)
if err != nil {
// Encountered an unrecoverable error , No return error, choice go die, Active trigger panic; Array out of bounds will also trigger panic
//panic Will stop the program currently executing ( It's not just a collaborative process ), And os.Exit(-1) Dissimilarity ,panic Will process the current goroutine already defer The task that hangs up , After the execution, in
// Then exit the whole program
panic(err)
}
// Set the maximum length of time that the connection can be reused 3 minute
// signify , All connections will be created the first time 3 Minutes expired , Cannot reuse after expiration
// Clean up operations are automatically run once per second to remove expired connections from the pool
db.SetConnMaxLifetime(time.Minute * 3)
// Set the maximum number of concurrent connections , If 10 Connections are open and in use , And if the application needs another connection , The application will be forced to wait
// until 10 One of the open connections is released as idle
db.SetMaxOpenConns(10)
// By default sql.DB A maximum of... Is allowed in the connection pool 2 Free connections
// Set the maximum number of idle connections
// Theoretically , Allowing more free connections in the pool will improve performance , It can reduce the possibility of establishing a connection from scratch , Help save resources
// maxIdleConn Should be less than or equal to maxOpenConn
db.SetMaxIdleConns(10)
runtime.RegisterShutdown(func () {
_ = db.Close()
})
return db
}
3.4 The configuration file

app.yml
database:
mysql:
default:
name: excel
host: localhost
port: 3306
user: ***
password: ***
4. Pay attention to problems
This code involves a lot , At present, only the core , If there are other problems or Need all , Follow up github
Summary
The above is just an implementation method , You are welcome to recommend better ones to share
边栏推荐
- PHP files running online
- Time series analysis - how to use unit root test (ADF) correctly?
- Development with courtesy -- share the source code of the secondary development of the app system of the imitation shopping mall
- Heyangdao store management system -- share the development source code of heyangdao system
- Dark horse shopping mall ---6 Brand, specification statistics, condition filtering, paging sorting, highlighting
- Repair the error that ECSHOP background orders prompt insufficient inventory when adding goods. Please reselect
- Micro engine generates QR code
- Micro engine remote attachment 7 Niu cloud upload
- The first techo day Tencent technology open day in 2022 will be held online on June 28
- ECSHOP product attribute color specification size stock item No. automatic combination
猜你喜欢

MySQL and excel tables importing database data (Excel for MySQL)

一款好用的印章设计工具 --(可转为ofd文件)

Service charge and time setting code sharing involved in crmeb withdrawal process

Today, I will explain to you what is DFI and its development prospects

Execution order of MySQL query statements join, on and where

Explanation of ideas and sharing of pre-processing procedures for 2021 US game D (with pre-processing data code)

What is the primordial universe

ECSHOP upload video_ ECSHOP video list, video classification, video related product guide

How to use SPSS to do grey correlation analysis? Quick grasp of hand-to-hand Teaching

Installation and removal of MySQL under Windows
随机推荐
揭秘GaussDB(for Redis):全面對比Codis
R language uses GLM function to build Poisson logarithmic linear regression model, processes three-dimensional contingency table data to build saturation model, and poisgof function of epidisplay pack
Spicy food advertising e-commerce system development function and spicy food advertising e-commerce app system development source code sharing
2022 Baidu collection batch automatic push assistant
Lighten the source code -- lighten the app system development function introduction to the beautiful world lighten the app system development source code in China
sudo: ulimit: command not found
实现领域驱动设计 - 使用ABP框架 - 系列文章汇总
How can we make an annual income of onemillion yuan by making our own media video?
【OceanBase】OceanBase简介及其与MySQL的比较
Installation and removal of MySQL under Windows
MySQL common interview questions
Thinkphp3 count ` *'problem
ECSHOP commodity wholesale multi attribute multi specification multi inventory batch purchase ECSHOP wholesale plug-in ECSHOP multi attribute order
15、wpf之button样式小记
Mpai data science platform random forest classification \ explanation of regression parameter adjustment
The whole page turns gray
ECSHOP product attribute color specification size stock item No. automatic combination
ARM V7 连续加载/存储
2022 meisai topic C idea sharing + translation
The difference between this and super and their respective functions