数据库分页显示的几种实现方式

曾经面试有个人问我分页的几种实现方式和框架这些,现在才回,有点晚,这里只用了一种实现方式,利用spring boot的jpa中page对象的实现。还有数据库自带的limit语句,和SSM框架中的mybatis语句中常用,以后遇到了更新这几种实现方式,这种最方便。持续关注哦!

这里将几个实战例子,从数据库到前台一口气实现。

项目文件目录

效果预览

 list分页

修改 

新增

操作友好提示

一、使用 page对象的实现步骤

1. 创建实体对象类User

package com.youngpeng.blog.entity;

import lombok.Data;
import org.hibernate.annotations.DynamicUpdate;

import javax.persistence.Entity;
import javax.persistence.Id;
import java.util.Date;

@Entity
@Data
@DynamicUpdate
public class User {
    @Id
    private String id;
    private String name;
    private String email;

    // @DynamicUpdate 针对时间自动更新而言
    private Date createTime;
    private Date updateTime;

    // 构造函数

    public User() {
    }

    public User(String id, String name, String email) {
        this.id = id;
        this.name = name;
        this.email = email;
    }

}

2. 写数据库代理层接口UserRepository  (JPA/ DAO/ REPOSITORY)

package com.youngpeng.blog.repository;

import com.youngpeng.blog.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;

/**
 * 增删改查的接口,一般别写
 */
public interface UserRepository extends JpaRepository<User,String> {

}

3. 写service接口UserService 

package com.youngpeng.blog.service;

import com.youngpeng.blog.entity.User;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

public interface UserService {
    User save(User user);

    void deleteById(String id);

    User findOne(String id);

    Page<User> findAll(Pageable pageable);
}

4. 写UserService 接口的实现逻辑UserServiceImpl 

package com.youngpeng.blog.service.serviceImpl;

import com.youngpeng.blog.entity.User;
import com.youngpeng.blog.repository.UserRepository;
import com.youngpeng.blog.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserRepository userRepository;

    @Override
    public User save(User user) {

        return userRepository.save(user);
    }

    @Override
    public void deleteById(String id) {
        userRepository.delete(id);
    }

    @Override
    public User findOne(String id) {
        return userRepository.findOne(id);
    }

    @Override
    public Page<User> findAll(Pageable pageable) {
        // 1. 调用JPA分页查询的方法
        Page<User> userPage = userRepository.findAll(pageable);
        // 2. 转换为list,
        List<User> userList = userPage.getContent();
        // 3. 返回
        // public PageImpl(List<T> content, Pageable pageable, long total) {}
        // public PageImpl(List<T> content) {}
        return new PageImpl<>(userList, pageable, userPage.getTotalElements());
    }
}

5. 写Controller层的方法调用,这是前后端交互的接口,URL首先进入该层处理

package com.youngpeng.blog.controller;

import com.youngpeng.blog.entity.User;
import com.youngpeng.blog.form.CreateUser;
import com.youngpeng.blog.service.UserService;
import com.youngpeng.blog.utils.GeneraterKey;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.validation.Valid;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/user")
@Slf4j
public class UserController {

    @Autowired
    private UserService userService;

    /**
     * 以分页的形式显示用户列表信息
     * 1. 接收参数page, size.
     * 2. 初始化pagerequest,
     * 3. 查询
     * 4. 返回结果
     */
    @GetMapping("/list")
    public ModelAndView userlist(@RequestParam(value = "page" ,defaultValue = "1") int page,
                                 @RequestParam(value = "size" ,defaultValue = "2") int size,
                                 Map<String, Object> map){
        // 初始化pagerequest
        PageRequest pageRequest = new PageRequest(page-1, size);
        // 调用service 层 的 page 接口查询
        Page<User> userPage =  userService.findAll(pageRequest);

        map.put("userPage", userPage);
        map.put("currentPage",page);
        map.put("size", size);
        return new ModelAndView("/user/list", map);
    }

    /**创建一个空对象出来存储
     * 1. 首先判断URL中有无ID号
     * 2. 有 - 根据ID查询数据。 无 - 自动生成ID号赋值
     * 3. 将前端传来的数据拷贝到对象中,无,显示空,有值- 则修改
     *
     * @param createUser
     * @param bindingResult
     * @param map
     * @return
     */
    @GetMapping("/create")
    public ModelAndView create(@Valid CreateUser createUser,
            BindingResult bindingResult,
            Map<String, Object> map){
        User userNew = new User();
        //判断前端数据正误
        if (bindingResult.hasErrors()){
            map.put("msg", bindingResult.getFieldError().getDefaultMessage());
            map.put("url", "/user/list");
            return new ModelAndView("common/error",map);
        }

        // 判断有无ID号
        if (StringUtils.isEmpty(createUser.getId() )){
            // 新建 -- 设置id 号
            userNew.setId(GeneraterKey.genUniqueKey());
        }else {
            //  修改 -- 查询出来显示
            userNew = userService.findOne(createUser.getId());
        }

        // 下面是同一的拷贝
        // createUser.setName(userNew.getName()); --- error 反了
        try {
            userNew.setName(createUser.getName());
            userNew.setEmail(createUser.getEmail());
            /**
             * 这里更改之后千万别忘了保存到数据库
             */
            userService.save(userNew);
        }catch (Exception e){
            // log.error("[注册、修改操作发生错误]{}",e);
            map.put("msg", "[注册、修改操作发生错误]");
            map.put("url", "/user/list");
            return new ModelAndView("common/error",map);
        }
        map.put("user", userNew);
        map.put("url", "/user/list");
        return new ModelAndView("/common/success",map);
    }

    /**
     * 新增和修改的页面都在这个页面进行单独操作
     * @param id
     * @param map
     * @return
     */
    @GetMapping("/index")
    public ModelAndView index(@RequestParam(value = "id", required = false) String id,
                              Map<String, Object> map){
        //  如果有id值传进来,就打包查询返回
        User user = new User();
        if ( !StringUtils.isEmpty(id) ){
            user = userService.findOne(id);
        }
        map.put("userInfo", user);
        return new ModelAndView("/user/index", map);
    }

    @GetMapping("/delete")
    public ModelAndView delete(@RequestParam(value = "id") String id,
                               Map<String, Object> map){
        try{
            // 直接执行删除操作
            userService.deleteById(id);
        }catch (Exception e){
            map.put("msg", "删除发生错误");
            map.put("url", "/user/list");
            return new ModelAndView("common/error",map);
        }
        map.put("msg", "删除成功");
        map.put("url", "/user/list");
        return new ModelAndView("common/success",map);
    }
}

6. 写前台代码 list.ftl

这里注意,list显示用户,但是单独的用户操作写在index页面中,细细评味其中逻辑

<link href="https://cdn.bootcss.com/twitter-bootstrap/3.3.1/css/bootstrap.min.css"
      rel="stylesheet"/>
<h1 style="text-align: center">用户信息列表</h1>
<#--表格主体-->
<div class="container">
    <div class="row clearfix">
        <div class="col-md-12 column">
            <table class="table  table-bordered">
                <thead>
                <tr>
                    <th>编号</th>
                    <th>姓名</th>
                    <th>邮箱</th>
                    <th>创建时间</th>
                    <th>修改时间</th>
                    <th colspan="2">操作</th>
                </tr>
                </thead>
                <tbody>
                <#--一列一用户。 每一列都是循环-->
                <#list userPage.content as userPage>
                    <tr>
                        <td>${userPage.id}</td>
                        <td>${userPage.name}</td>
                        <td>${userPage.email}</td>
                        <td>${userPage.createTime}</td>
                        <td>${userPage.updateTime}</td>

                        <td><a href="/user/index?id=${userPage.id}">修改</a></td>
                        <td><a href="/user/delete?id=${userPage.id}">删除</a></td>
                    </tr>
                </#list>
                </tbody>
            </table>
        </div>
    </div>
</div>

<#--新增一个用户-->
<button type="button" ><a href="/user/index">新增一个用户</a></button>

<#-- 分页切换按钮-->
<div class="container">
    <div class="row clearfix">
        <div class="col-md-12 column">
            <ul class="pagination pagination-lg pull-right ">
                <#--如果是第一页,禁止点击
                    否则链接到上一页-->
                <#if currentPage lte 1>
                    <li class="disabled"><a href="#">上一页</a></li>
                <#else>
                    <li><a href="/user/list?page=${currentPage-1}&size=${size}">上一页</a></li>
                </#if>

                <#-- 页数应该动态的增加
                如果是当前页 - 禁止点击
                负责点击链接到相应的页面-->
                <#list 1..userPage.getTotalPages() as index>
                    <#if currentPage == index>
                        <li class="disabled"><a href="#">${index}</a></li>
                    <#else>
                        <li><a href="/user/list?page=${index}&size=${size}">${index}</a></li>
                    </#if>
                </#list>
                <#if currentPage gte userPage.getTotalPages()>
                    <li class="disabled"><a href="#">下一页</a></li>
                <#else>
                    <li ><a href="/user/list?page=${currentPage+1}&size=${size}">下一页</a></li>
                </#if>

            </ul>
        </div>
    </div>
</div>

7.写index.ftl

<#--主要内容-->
<div id="page-content-wrapper">
    <div class="container">

        <div class="row clearfix">
            <div class="col-md-12 column">
                <form role="form" method="Get" action="/user/create">
                    <div class="form-group">
                        <label>名称:</label>
                        <input type="text" class="form-control" name="name" value="${(userInfo.name)!""}"/>

                        <label>邮箱:</label>
                        <input type="text" class="form-control" name="email" value="${(userInfo.email)!""}"/>
                    </div>
                    <input  type="hidden" class="form-control" name="id" value="${(userInfo.id)!""}"/>
                    <button type="submit" class="btn btn-default">提交</button>
                </form>
            </div>
        </div>
    </div>

8. 友好提示页面 error 、 success


<html>
<head>
    <meta charset="UTF-8">
    <link href="https://cdn.bootcss.com/twitter-bootstrap/3.0.1/css/bootstrap.min.css" rel="stylesheet">
    <title>操作发生错误</title>
</head>
<body>

<div class="container">
    <div class="row clearfix">
        <div class="col-md-12 column">
            <div class="alert alert-dismissable alert-warning">
                <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
                <h4>发生错误!</h4>
                <strong>${msg!""}</strong>
                <a id="jump" href="${url}" class="alert-link">3</a><span>秒后自动跳转原来页面</span>
            </div>
        </div>
    </div>
</div>

</body>


    <#--setTimeout(location.href="${url}",3000);-->
<script type="text/javascript">
    onload=function(){
        setInterval(go, 1000);
    };
    var x=3; //利用了全局变量来执行
    function go(){
        x--;
        if(x>0){
            document.getElementById("jump").innerHTML=x;  //每次设置的x的值都不一样了。
        }else{
            location.href="${url}";
        }
    }
</script>

</html>

 

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Mybatis提供了两种方式实现数据库分页: 1. 使用MySQL的LIMIT和OFFSET语句进行分页 在SQL中使用LIMIT和OFFSET语句对数据进行分页,其中LIMIT表示每页显示的记录数,OFFSET表示从第几条记录开始显示。 在Mapper.xml中编写SQL实现分页功能: ```xml <!-- 使用MySQL数据库分页 --> <select id="selectByPage" parameterType="map" resultMap="baseResultMap"> select * from table limit #{start}, #{rows} </select> ``` Java代码中传入参数,计算出start和rows的值,并调用Mapper方法: ```java Map<String, Integer> paramMap = new HashMap<>(); paramMap.put("start", (pageNo - 1) * pageSize); paramMap.put("rows", pageSize); List<Record> recordList = mapper.selectByPage(paramMap); ``` 2. 使用Mybatis的分页插件PageHelper进行分页 PageHelper是Mybatis官方提供的分页插件,使用PageHelper可以更简单地实现分页功能。 首先在pom.xml中导入PageHelper的依赖: ```xml <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>5.2.0</version> </dependency> ``` 在Mapper.xml中使用PageHelper进行分页: ```xml <select id="selectByPage" resultMap="baseResultMap"> select * from table order by id desc </select> ``` 同时在Java代码中配置PageHelper: ```java import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; PageHelper.startPage(pageNo, pageSize, true); List<Record> records = mapper.selectByPage(); PageInfo<Record> pageInfo = new PageInfo<>(records); ``` 其中,startPage方法用来配置分页参数,pageNum表示页码,pageSize表示每页显示的条数,orderBy表示排序方式。然后调用Mapper方法查询数据,并将查询结果传入PageInfo中,PageInfo中包含了分页的相关信息,如总共多少页,当前页码等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值