当前位置:网站首页>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
边栏推荐
- High imitation blue playing network disk file sharing to make money network disk PHP system source code
- Fun pocket mall -- sharing the development source code of fun pocket app system
- Thinkphp3 count ` *'problem
- Zhangxiaobai's road of penetration (IV) -- detailed explanation of XSS cross site script vulnerabilities
- 实现领域驱动设计 - 使用ABP框架 - 系列文章汇总
- Zhengzheng e-commerce source code -- Zhengzheng advertising e-commerce system development source code sharing
- Mpai data science platform random forest classification \ explanation of regression parameter adjustment
- Upgrade opsenssh to 8.8p1
- Recyclerview scrolls to the specified location
- PHP multidimensional array sorting
猜你喜欢
Happy shopkeeper source code -- Introduction to happy shopkeeper system development mode
[on]learning dynamic and hierarchical traffic spatiotemporal features with transformer
Rank sum ratio comprehensive evaluation method for common models in mathematical modeling
The first techo day Tencent technology open day in 2022 will be held online on June 28
Upgrade opsenssh to 8.8p1
MySQL and excel tables importing database data (Excel for MySQL)
An easy-to-use seal design tool - (can be converted to ofd file)
How to use SPSS to do grey correlation analysis? Quick grasp of hand-to-hand Teaching
ECSHOP commodity page multi-attribute batch purchase plug-ins ECSHOP wholesale plug-ins multi-attribute order placing, multi-attribute batch purchase of commodities
MySQL common interview questions
随机推荐
Dark horse shopping mall ---2 Distributed file storage fastdfs
How to use SPSS to do grey correlation analysis? Quick grasp of hand-to-hand Teaching
The dist function of R language calculates the distance between two samples in dataframe data, returns the distance matrix between samples, and specifies the distance calculation method through the me
一款好用的印章设计工具 --(可转为ofd文件)
Why should Apple change objc_ Type declaration for msgsend
2022 meisai topic C idea sharing + translation
Web project development process
Mpai data science platform SVM support vector machine classification \ explanation of regression parameter adjustment
ARM V7 连续加载/存储
The R language uses the follow up The plot function visualizes the longitudinal follow-up map of multiple ID (case) monitoring indicators, and uses stress The type parameter specifies the line type of
19. Implementation of MVVM architecture based on WPF event to command
An easy-to-use seal design tool - (can be converted to ofd file)
Development with courtesy -- share the source code of the secondary development of the app system of the imitation shopping mall
Polling and long polling
Dynamic proxy
ECSHOP whole site custom URL supports directory type
Introduction to jiuhongtianxia system development function -- jiuhongtianxia app development source code sharing
How do super rookies get started with data analysis?
Zhangxiaobai's road of penetration (VI) -- the idea and process of SQL injection and the concat series functions and information of SQL_ Schema database explanation
[论]Learning Dynamic and Hierarchical Traffic Spatiotemporal Features with Transformer