建议看这个之前,先看看这个:go操作MySQL · Go语言中文文档 (topgoer.com)
嗯...也不能叫做分页插件,就是一个分页工具类。
下载依赖
go get github.com/go-sql-driver/mysql go get github.com/jmoiron/sqlx
sql_util
我们自定义一个sql_util,用来封装数据库连接操作。ExecuteCUD()执行增删改操作。ExecuteSelectAll()执行查询操作。目前没有查询单个的,而且查询到全部数据,判断查询数据长度即可。jointSqlStr() : 负责拼接sql字符串模版和动态绑定的参数
package sql import ( "back-me/main/util" "fmt" _ "github.com/go-sql-driver/mysql" "github.com/jmoiron/sqlx" "strings" ) const ( username = "root" password = "123456" host = "localhost" port = 3306 dbname = "fdis" ) var Db *sqlx.DB func init() { connectToDatabase() } // 连接数据库 func connectToDatabase() { dataSourceName := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?parseTime=true&loc=Local", username, password, host, port, dbname) db, err := sqlx.Open("mysql", dataSourceName) if err != nil { util.Log.Error("sql connection error:" + err.Error()) } // 检查是否连接成功 err = db.Ping() if err != nil { util.Log.Error("sql connection error:" + err.Error()) } Db = db } // 执行增删改操作 func ExecuteCUD(sql string, params ...interface{}) int64 { sql = jointSqlStr(sql, params...) conn, err := Db.Begin() if err != nil { util.Log.Error("Sql Error:" + err.Error()) return -1 } r, err := conn.Exec(sql) if err != nil { util.Log.Error("Sql Error:" + err.Error()) conn.Rollback() return -1 } id, err := r.LastInsertId() if err != nil { util.Log.Error("Sql Error:" + err.Error()) conn.Rollback() return -1 } conn.Commit() return id } // 执行select all func ExecuteSelectAll(stc interface{}, sql string, params ...interface{}) error { sql = jointSqlStr(sql, params...) err := Db.Select(stc, sql) if err != nil { util.Log.Error("Sql Select Error:" + err.Error()) return err } return nil } // 1 5 | 0 5 // 2 5 | 5 5 // 3 5 | 10 5 func jointSqlStr(sqlStr string, args ...interface{}) string { // 以%s分割 strs := strings.Split(sqlStr, "%s") if len(strs) == 0 { return sqlStr } newSql := "" for i, _ := range strs { newSql += strs[i] if i != len(strs)-1 { switch args[i].(type) { case string: newSql += args[i].(string) break case int: newSql += fmt.Sprintf("%v", args[i].(int)) break case uint: newSql += fmt.Sprintf("%v", args[i].(uint)) break } } } return newSql }
page_util
通过,page_util来封装分页相关操作。SelectPage(): 传入我们查询的数据,响应一个封装好的PageResult结构体。
package page import ( "back-me/main/model" "errors" "reflect" ) var PageError = errors.New("page or pageSize cannot be < 1") type Pager struct { Page int `json:"page"` PageSize int `json:"pageSize"` } func NewPager(page int, pageSize int) (*Pager, error) { if page < 1 || pageSize < 1 { return nil, PageError } return &Pager{ page, pageSize, }, nil } func (p *Pager) SelectPage(data interface{}) *model.PageResult { page := p.Page pageSize := p.PageSize page = (page - 1) * pageSize start := page end := page + pageSize l := reflect.ValueOf(data).Elem().Len() if l-1 < start { return model.NewPageResult1(nil, 0, page, pageSize) } else if l-1 >= start && l-1 <= end { return model.NewPageResult1(subData(data, start, l), l, p.Page, p.PageSize) } else { return model.NewPageResult1(subData(data, start, end), l, p.Page, p.PageSize) } } // 包前不包后 func subData(data any, start int, end int) interface{} { v := reflect.ValueOf(data) v = v.Elem() return v.Slice(start, end).Interface() }
result
分页数据公共封装响应。
package model type PageResult struct { Data any `json:"data"` Code int `json:"code"` Mes string `json:"mes"` Total int `json:"total"` Page int `json:"page"` PageSize int `json:"pageSize"` } func NewPageResult(data any, code int, mes string, total int, page int, pageSize int) *PageResult { return &PageResult{ data, code, mes, total, page, pageSize, } } // NewPageResult1 func NewPageResult1(data any, total int, page int, pageSize int) *PageResult { return NewPageResult(data, 200, "ok", total, page, pageSize) }
测试
func TestSelectPage(t *testing.T) { var userVos []vo.User // 查询出的数据,最终封装到这里面 var sqlStr = "SELECT * FROM `tx_user` WHERE PASSWORD LIKE '%s' LIMIT 0, 2" // %s 就是占位符,被后面传入的参数替换 sql.ExecuteSelectAll(&userVos, sqlStr, "%") // 分页 // 0 1 // 2 3 // start < newPager, err := page.NewPager(1, 2) if err != nil { fmt.Println("error:", err.Error()) } pageResult := newPager.SelectPage(&userVos) fmt.Println(pageResult) }