建议看这个之前,先看看这个: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)
}