# Beerus-DB
# Initial configuration
# Installing dependencies
go get github.com/Beerus-go/Beerus-DB@v1.1.5
go get github.com/go-sql-driver/mysql
# Configuring the data source
dbPool := new(pool.DbPool)
dbPool.InitialSize = 1
dbPool.ExpandSize = 1
dbPool.MaxOpen = 1
dbPool.MinOpen = 0
dbPool.TestConn = true
dbPool.Url = "root:123456@(127.0.0.1:3306)/xt-manager"
db.AddDataSource("dbPoolTest", dbPool)
# Configuring multiple data sources
dbPool := new(pool.DbPool)
dbPool.InitialSize = 1
dbPool.ExpandSize = 1
dbPool.MaxOpen = 1
dbPool.MinOpen = 0
dbPool.TestConn = true
dbPool.Url = "root:123456@(127.0.0.1:3306)/test"
db.AddDataSource("dbPoolTest", dbPool)
dbPool2 := new(pool.DbPool)
dbPool2.InitialSize = 1
dbPool2.ExpandSize = 1
dbPool2.MaxOpen = 1
dbPool2.MinOpen = 0
dbPool.TestConn = true
dbPool2.Url = "root:123456@(127.0.0.1:3306)/test"
db.AddDataSource("dbPoolTest2", dbPool2)
This code only needs to be executed once when the project starts
# Field explanation
- InitialSize: Number of initialized connections
- ExpandSize: The number of connections to be extended at a time when the connections are exhausted (this configuration will be disabled after the maximum number of connections has been reached in the connection pool)
- MaxOpen: Maximum number of connections
- MinOpen: Minimum number of connections
- Url: Database connection string
- TestConn: Test if the connection is valid, once set to true, if the connection obtained is no longer valid, a new connection will be obtained and will be automatically dropped if it fails 3 times
# Single Table Operations
# Search for single table data based on conditions
conditions := builder.Create().
Add("id > ?", 10).
Add("and (user_name = ? or age > ?)", "bee", 18).
Add("order by create_time desc", entity.NotWhere).
Build()
resultMap, err := operation.GetDBTemplate("Data source name").Select("table name", conditions)
# Modify single table data according to conditions
// Conditions set
conditions := builder.Create().
Add("id = ?", 1).
Build()
// Data settings to be modified
data := ResultStruct{UserName: "TestNoSqlUpdate"}
// Execute the modification operation
result, err := operation.GetDBTemplate("Data source name").Update("table name", dbutil.StructToMapIgnore(&data, true),conditions)
# Delete single table data based on conditions
// Set delete conditions
conditions := builder.Create().
Add("id = ?", 2).
Build()
// Perform a delete operation
_, err := operation.GetDBTemplate("Data source name").Delete("table name", conditions)
# Insert a piece of data
data := ResultStruct{
UserName: "TestNoSqlInsert",
UserEmail: "xxxxx@163.com",
UpdateTime: "2021-12-09 13:50:00",
}
result, err := operation.GetDBTemplate("Data source name").Insert("table name", dbutil.StructToMapIgnore(&data, true))
# Description of condition setters
The internal structure is as follows
type Condition struct {
Key string
Val interface{}
}
- Key Set the criteria, which can be anywhere, order by, group by, etc.
- Val Set the value, if the Key is where, then val is the value of the where parameter
The following examples can be seen
conditions := builder.Create().
// Here is the Key set to where condition, so val must be the value of where, that is, the query id > 10 data, placeholder only support ?
Add("id > ?", 10).
// Same as above, but with an extra and in front, because he is the second condition, so you need to use the conjunction, you can use and, or
// Like the example, if and is followed by a conditional combination, you can write it like this, Val is a... type that can be infinitely appended to
Add("and (user_name = ? or age > ?)", "bee", 18).
// Here the Key is set as a sort condition, so Val doesn't need to be given a value, just set it to entity.NotWhere
Add("order by create_time desc", entity.NotWhere).
Builder()
# Entity Mapping Description
Two tags can be used, field, ignore, for the following example
type ResultStruct struct {
Id int `field:"id" ignore:"true"`
UserName string `field:"user_name"`
UserEmail string `field:"user_email"`
UpdateTime string `field:"update_time"`
}
- field The value set is the field name of the database, if this is not set, the field name will be used to match the database by default
- ignore If set to true this field will be excluded from database operations, if the tag is not set or set to false the opposite is true
# Use of entities
The above examples of single table operations already show the usage of entities, but here is a more detailed explanation
// Used directly, this way the ignore is disabled and will not work no matter what it is set to
// Use his return value as a parameter when calling DBTemplete's function
dbutil.StructToMap(&data)
// Making ignore work
// Similarly, use his return value as a parameter when calling DBTemplete's function
dbutil.StructToMapIgnore(&data, true)
# Query results into struct
The query returns each row of data as a map type, which needs to be converted using the following function
// The target struct to be transformed into
res := ResultStruct{}
// The first argument is the data to be transformed, the second argument is a pointer to the target struct
dbutil.MapToStruct(row, &res)
After the above transformation, the data will be available in res
# Custom sql operations
# Query based on array parameters
param := make([]interface{}, 1)
param[0] = 1
// Select multiple entries
resultMap, err := operation.GetDBTemplate("Data source name").SelectList("select * from xt_message_board where id = ?", param)
// Select one
resultMap, err := operation.GetDBTemplate("Data source name").SelectOne("select * from xt_message_board where id = ?", param)
# Search by struct parameter
// struct parameters
res := ResultStruct{Id: 1}
// Select multiple entries, note: placeholders are needed here
resultMap, err := operation.GetDBTemplate("Data source name").SelectListByMap("select * from xt_message_board where id < {id}", dbutil.StructToMap(&res))
// Select one, note: placeholders are needed here
resultMap, err := operation.GetDBTemplate("Data source name").SelectOneByMap("select * from xt_message_board where id < {id}", dbutil.StructToMap(&res))
# Adding, deleting and changing based on array parameters
param := make([]interface{}, 2)
param[0] = "TestUpdate"
param[1] = 1
// Whether adding, deleting or updating, the Exec function is called and the sql and parameters are passed in
operation.GetDBTemplate("Data source name").Exec("update xt_message_board set user_name = ? where id = ?", param)
# Add, delete and update according to struct parameters
res := ResultStruct{Id: 1, UserName: "TestUpdateByMap"}
// Whether adding, deleting, or updating, the ExecByMap function is called, and the sql and parameters are passed in.
operation.GetDBTemplate("Data source name").ExecByMap("update xt_message_board set user_name = {user_name} where id = {id}", dbutil.StructToMap(&res))
# Paging queries
# Use the default countSql
data := ResultStruct{
UserName: "TestNoSqlInsert",
UserEmail: "xxxxx@163.com",
}
// Create paging parameters
param := entity.PageParam{
CurrentPage: 1, // Pages
PageSize: 20, // How many entries per page
Params: dbutil.StructToMap(&data), // Enquiry parameters
}
// Performing a query operation
result, err := operation.GetDBTemplate("Data source name").SelectPage("select * from xt_message_board where user_name = {user_name} and user_email = {user_email}", param)
# Use custom countSql
data := ResultStruct{
UserName: "TestNoSqlInsert",
UserEmail: "xxxxx@163.com",
}
// Your own definition of countSql
countSql := "Your own definition of countSql"
// Create paging parameters
param := entity.PageParam{
CurrentPage: 1, // Pages
PageSize: 20, // How many entries per page
Params: dbutil.StructToMap(&data), // Enquiry parameters
}
// Performing a query operation
result, err := operation.GetDBTemplate("Data source name").SelectPageCustomCount("select * from xt_message_board where user_name = {user_name} and user_email = {user_email}", countSql, param)
# Transaction Management
# Open a transaction
// This id is very useful and will be used later for rollbacks and commits
id, err := db.Transaction()
if err != nil {
t.Error("TestUpdateTx: " + err.Error())
return
}
# Commit and rollback transactions
// Rollback transactions
db.Rollback(id)
// Commit transactions
db.Commit(id)
# Used together it looks like this
// Open a transaction
id, err := db.Transaction()
if err != nil {
t.Error("TestUpdateTx: " + err.Error())
return
}
res := ResultStruct{Id: 1, UserName: "TestUpdateTx"}
// Note: GetDBTemplateTx and ExecByTxMap must be used here.
// The difference between using a transaction and not using a transaction, in terms of the functions called, is that there is an additional Tx
ss, err := operation.GetDBTemplateTx(id, "dbPoolTest").ExecByTxMap("update xt_message_board set user_name = {user_name} where id = {id}", dbutil.StructToMap(&res))
if err != nil {
// Roll back the transaction if there is a problem
db.Rollback(id)
t.Error("TestUpdateTx: " + err.Error())
return
}
// Commit transactions
db.Commit(id)