Golang与MySQL Bootstrap实现分页链接的最佳实践
Golang与MySQL Bootstrap实现分页链接的最佳实践 如何实现Go语言与MySQL的分页链接?
<!DOCTYPE html>
<html lang="en">
<head>
<title>Bootstrap</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
<h2>分页</h2>
<p>.pagination 类提供了分页链接:</p>
<ul class="pagination">
<li><a href="#">1</a></li>
<li><a href="#">2</a></li>
<li><a href="#">3</a></li>
<li><a href="#">4</a></li>
<li><a href="#">5</a></li>
</ul>
</div>
</body>
</html>
更多关于Golang与MySQL Bootstrap实现分页链接的最佳实践的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于Golang与MySQL Bootstrap实现分页链接的最佳实践的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在Go语言中实现MySQL分页并集成Bootstrap分页链接,需要结合后端分页逻辑和前端的Bootstrap分页组件。以下是完整的实现示例:
1. 后端Go代码(MySQL分页逻辑)
package main
import (
"database/sql"
"fmt"
"html/template"
"log"
"net/http"
"strconv"
_ "github.com/go-sql-driver/mysql"
)
type User struct {
ID int
Name string
}
type Pagination struct {
CurrentPage int
TotalPages int
HasPrev bool
HasNext bool
PrevPage int
NextPage int
Pages []int
}
func main() {
http.HandleFunc("/users", usersHandler)
log.Fatal(http.ListenAndServe(":8080", nil))
}
func usersHandler(w http.ResponseWriter, r *http.Request) {
// 连接MySQL数据库
db, err := sql.Open("mysql", "user:password@tcp(127.0.0.1:3306)/dbname")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer db.Close()
// 获取当前页码,默认为第1页
pageStr := r.URL.Query().Get("page")
page, err := strconv.Atoi(pageStr)
if err != nil || page < 1 {
page = 1
}
// 每页显示数量
pageSize := 10
// 计算偏移量
offset := (page - 1) * pageSize
// 查询总记录数
var totalRecords int
err = db.QueryRow("SELECT COUNT(*) FROM users").Scan(&totalRecords)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// 计算总页数
totalPages := (totalRecords + pageSize - 1) / pageSize
// 查询当前页数据
rows, err := db.Query("SELECT id, name FROM users LIMIT ? OFFSET ?", pageSize, offset)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer rows.Close()
var users []User
for rows.Next() {
var user User
if err := rows.Scan(&user.ID, &user.Name); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
users = append(users, user)
}
// 生成分页信息
pagination := generatePagination(page, totalPages)
// 渲染模板
tmpl, err := template.ParseFiles("users.html")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
data := struct {
Users []User
Pagination Pagination
}{
Users: users,
Pagination: pagination,
}
tmpl.Execute(w, data)
}
func generatePagination(currentPage, totalPages int) Pagination {
// 计算显示的页码范围(最多显示5个页码)
startPage := currentPage - 2
if startPage < 1 {
startPage = 1
}
endPage := startPage + 4
if endPage > totalPages {
endPage = totalPages
startPage = endPage - 4
if startPage < 1 {
startPage = 1
}
}
// 生成页码列表
var pages []int
for i := startPage; i <= endPage; i++ {
pages = append(pages, i)
}
return Pagination{
CurrentPage: currentPage,
TotalPages: totalPages,
HasPrev: currentPage > 1,
HasNext: currentPage < totalPages,
PrevPage: currentPage - 1,
NextPage: currentPage + 1,
Pages: pages,
}
}
2. 前端HTML模板(users.html)
<!DOCTYPE html>
<html lang="en">
<head>
<title>用户列表</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
<h2>用户列表</h2>
<table class="table table-striped">
<thead>
<tr>
<th>ID</th>
<th>姓名</th>
</tr>
</thead>
<tbody>
{{range .Users}}
<tr>
<td>{{.ID}}</td>
<td>{{.Name}}</td>
</tr>
{{end}}
</tbody>
</table>
<!-- Bootstrap分页组件 -->
<nav aria-label="Page navigation">
<ul class="pagination">
{{if .Pagination.HasPrev}}
<li>
<a href="/users?page={{.Pagination.PrevPage}}" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
{{else}}
<li class="disabled">
<span aria-hidden="true">«</span>
</li>
{{end}}
{{range .Pagination.Pages}}
{{if eq . $.Pagination.CurrentPage}}
<li class="active"><span>{{.}}</span></li>
{{else}}
<li><a href="/users?page={{.}}">{{.}}</a></li>
{{end}}
{{end}}
{{if .Pagination.HasNext}}
<li>
<a href="/users?page={{.Pagination.NextPage}}" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
{{else}}
<li class="disabled">
<span aria-hidden="true">»</span>
</li>
{{end}}
</ul>
</nav>
<div class="text-center">
<p>第 {{.Pagination.CurrentPage}} 页,共 {{.Pagination.TotalPages}} 页</p>
</div>
</div>
</body>
</html>
3. 优化版本:使用结构体封装分页逻辑
// 分页结构体
type Paginator struct {
Page int
PageSize int
TotalCount int
TotalPages int
}
func NewPaginator(page, pageSize, totalCount int) *Paginator {
totalPages := (totalCount + pageSize - 1) / pageSize
if page < 1 {
page = 1
}
if page > totalPages {
page = totalPages
}
return &Paginator{
Page: page,
PageSize: pageSize,
TotalCount: totalCount,
TotalPages: totalPages,
}
}
func (p *Paginator) Offset() int {
return (p.Page - 1) * p.PageSize
}
func (p *Paginator) Limit() int {
return p.PageSize
}
// 在查询中使用
func getUsersWithPagination(db *sql.DB, page, pageSize int) ([]User, *Paginator, error) {
var totalCount int
err := db.QueryRow("SELECT COUNT(*) FROM users").Scan(&totalCount)
if err != nil {
return nil, nil, err
}
paginator := NewPaginator(page, pageSize, totalCount)
rows, err := db.Query(
"SELECT id, name FROM users LIMIT ? OFFSET ?",
paginator.Limit(),
paginator.Offset(),
)
if err != nil {
return nil, nil, err
}
defer rows.Close()
var users []User
for rows.Next() {
var user User
if err := rows.Scan(&user.ID, &user.Name); err != nil {
return nil, nil, err
}
users = append(users, user)
}
return users, paginator, nil
}
这个实现方案包含了以下关键点:
- MySQL分页查询:使用
LIMIT和OFFSET实现数据分页 - 分页计算:正确计算总页数和当前页的偏移量
- Bootstrap集成:使用Bootstrap的pagination组件样式
- 模板渲染:通过Go的html/template将分页数据动态渲染到HTML
- 分页逻辑封装:使用结构体封装分页参数和计算方法
访问http://localhost:8080/users?page=2即可查看第2页的数据,分页链接会自动根据当前页码和总页数生成相应的Bootstrap分页组件。

