如何通过go自定义一个分页插件

 更新时间:2024年03月16日 10:50:18   作者:本郡主是喵  
分页是我们日常开发中经常会遇到的一个需求,下面这篇文章主要给大家介绍了关于如何通过go自定义一个分页插件的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下

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

总结 

到此这篇关于如何通过go自定义一个分页插件的文章就介绍到这了,更多相关go自定义分页插件内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:

相关文章

  • Go语言异常处理(Panic和recovering)用法详解

    Go语言异常处理(Panic和recovering)用法详解

    异常处理是程序健壮性的关键,往往开发人员的开发经验的多少从异常部分处理上就能得到体现。Go语言中没有Try Catch Exception机制,但是提供了panic-and-recover机制,本文就来详细讲讲他们的用法
    2022-07-07
  • go语言if/else语句简单用法示例

    go语言if/else语句简单用法示例

    这篇文章主要介绍了go语言if/else语句用法,结合实例形式分析了go语言if else语句的判定与流程控制技巧,需要的朋友可以参考下
    2016-05-05
  • go语言打包的网页wasm示例详解

    go语言打包的网页wasm示例详解

    这篇文章主要为大家介绍了go打包网页wasm示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪<BR>
    2022-09-09
  • golang踩坑实战之channel的正确使用方式

    golang踩坑实战之channel的正确使用方式

    Golang channel是Go语言中一个非常重要的特性,除了用来处理并发编程的任务中,它还可以用来进行消息传递和事件通知,这篇文章主要给大家介绍了关于golang踩坑实战之channel的正确使用方式,需要的朋友可以参考下
    2023-06-06
  • Golang channel关闭后是否可以读取剩余的数据详解

    Golang channel关闭后是否可以读取剩余的数据详解

    这篇文章主要介绍了Golang channel关闭后是否可以读取剩余的数据,文章通过一个测试例子给大家详细的介绍了是否可以读取剩余的数据,需要的朋友可以参考下
    2023-09-09
  • Go各时间字符串使用解析

    Go各时间字符串使用解析

    这篇文章主要介绍了Go各时间字符串使用解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • go语言环境搭建简述

    go语言环境搭建简述

    本文简单记录了下go语言环境的搭建流程,给小伙伴们一个参考,希望大家能够喜欢。
    2015-01-01
  • 在Golang中正确的修改HTTPRequest的Host的操作方法

    在Golang中正确的修改HTTPRequest的Host的操作方法

    我们工作中经常需要通过HTTP请求Server的服务,比如脚本批量请求接口跑数据,由于一些网关策略,部分Server会要求请求中Header里面附带Host参数,所以本文给大家介绍了如何在Golang中正确的修改HTTPRequest的Host,需要的朋友可以参考下
    2023-12-12
  • Go语言使用Etcd实现分布式锁

    Go语言使用Etcd实现分布式锁

    etcd是近几年比较火热的一个开源的、分布式的键值对数据存储系统,本文将介绍如何利用Etcd实现分布式锁,感兴趣的小伙伴可以跟随小编一起了解一下
    2023-05-05
  • golang 切片截取参数方法详解

    golang 切片截取参数方法详解

    这篇文章主要介绍了golang 切片截取参数方法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01

最新评论