JavaWeb实战(1)(重点:分页查询、jstl标签与jsp、EL表达式、Bootstrap组件搭建页面、jdbc)

目录

一、jstl标签。

(1)基本概念。

(2)使用前提。

(3)"<%...%>"与"<%=%>"。

(4)使用jstl标签的步骤。

1、导入对应jar包。

2、引入核心标签库。(core)

3、在jsp页面中使用jstl标签(常见标签)。

二、分页查询。

(1)使用循环拿对象,利用EL表达式显示属性。

(2)通过Bootstrap获取分页栏组件快速渲染页面(jsp)。

(3)分页查询思路分析。

1、页面(前端)需要传什么参数?

2、页面需要接收什么参数。

3、Page类。

4、sql语句的书写。

三、正式代码书写。

(1)链接到对应Servlet。

(2)queryUsersByPageServlet类。

(3)service层接口。

(4)serviceImpl实现类。

(5)dao层接口。(数据访问层接口)

(6)dao层实现类。

(7)初步测试其功能是否正常。

(8)完善设计要求。

1、当前所在页为:1。

2、当前所在页为:最后一页。

3、位于当前页时。

4、显示页数(如:1、2...)。

5、测试结果。


一、jstl标签。

(1)基本概念。
  • JSTL(JavaServer Pages Standard Tag Library)是一个为JavaServerPages (JSP) 技术提供的标签库。
  • 它允许开发者在JSP页面中使用标签来执行常见的功能。如条件判断、循环等。
(2)使用前提。
  • 导入两个jar包。

  • 或使用Maven添加对应的依赖也能够使用。
(3)"<%...%>"与"<%=%>"。
  • 简单说:jsp页面就是让Java代码能够在html页面书写。
java 复制代码
<%
   //java方法能写的代码, 都可以在这里写
%>
<%=表达式 %>  把表达式的结果在客户端页面显示  使用EL表达式替换
(4)使用jstl标签的步骤。
1、导入对应jar包。
2、引入核心标签库。(core)
  • 注意:"uri"一定要选择对应的正确核心库标签。
  • 它也叫"c标签"。
  • @tag:目标,lib:库。
java 复制代码
<%--引入JSTL核心标签库--%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
3、在jsp页面中使用jstl标签(常见标签)。
  • 循环:<c:forEach>。
  • if判断:<c:if>。
  • if...else:<choose>。类似于MySQL中的case一样。

二、分页查询。

(1)使用<c:forEach>循环拿对象,利用EL表达式显示属性。
  • 使用"<%%>"、"<%=%>"嵌套代码看着很混乱。
  • 则可以使用jstl标签完成操作!。
java 复制代码
<%
            //从request域拿到数据
            List<UserInfo> users = (List<UserInfo>) request.getAttribute("users");
            for (UserInfo user : users) {

        %>
        <tr>
            <td><%=user.getId()%></td>
            <td><%=user.getName()%></td>
            <td><%=user.getGender()%></td>
            <td><%=user.getAge()%></td>
            <td><%=user.getAddress()%></td>
            <td><%=user.getEmail()%></td>
            <td><%=user.getQq()%></td>
            <td>
                <a class="btn btn-default btn-sm" href="/users/update?id=<%=user.getId()%>">修改</a>&nbsp;
                <a class="btn btn-default btn-sm" href="/users/delete?id=<%=user.getId()%>">删除</a></td>
        </tr>
        <%
            }
        %>
  • 使用<c:forEach>标签。

  • 从所有域中搜索键名"users"值。拿到应该List<UserInfo>集合。

java 复制代码
<c:forEach items="${users}" var="user" varStatus="s">
  • items相当于Javaforeach循环中的"for(String str:str(数组/集合))"的数据集合。

  • var相当于某个体。

  • varStatus代表当前状态(如:位于第几行?)

java 复制代码
<table border="1" class="table table-bordered table-hover">
        <tr class="success">
            <th>编号</th>
            <th>姓名</th>
            <th>性别</th>
            <th>年龄</th>
            <th>籍贯</th>
            <th>QQ</th>
            <th>邮箱</th>
            <th>操作</th>
        </tr>
        <c:forEach items="${users}" var="user" varStatus="s">
            <tr>
                <td>${s.count}</td>
                <td>${user.name}</td>
                <td>${user.gender}</td>
                <td>${user.age}</td>
                <td>${user.address}</td>
                <td>${user.email}</td>
                <td>${user.qq}</td>
                <td>
                    <a class="btn btn-default btn-sm" href="/users/update?id=${user.id}">修改</a>&nbsp;
                    <a class="btn btn-default btn-sm" href="/users/delete?id=${user.id}">删除</a></td>
            </tr>
        </c:forEach>
    </table>

(2)通过Bootstrap获取分页栏组件快速渲染页面(jsp)。

  • 渲染后。

(3)分页查询思路分析。
1、页面(前端)需要传什么参数?
  • 页码。(当前位于第几页)
  • 页容量。(每页显示的数据条数)
  • 带条件的分页查询。
2、页面需要接收什么参数。
  • 记录。(根据分页或条件查询的数据记录)
  • 总记录。(查询的所有数据有多少条?)
  • 总页数(最终分页)。(根据总记录与页容量计算!)
  • 页码。
  • 页容量。
  • 将上面5个数据封装到Page类对象中,并存在域中!

  • 将上面的5个数据封装成一个类Page。简单且实用。(面向对象)
3、Page类。

  • totalPage(总页数)不能提供setter()方法。因为这个是根据总记录数和页容量进行计算。

  • 如果有40条数据。每一页显示5条。则总页数 =8页。
  • 如果有41条数据。每一页显示5条。则总页数 = 9页。
  • 总页数 = 总记录数 % 页容量 == 0? 总记录数/页容量: 总记录数/页容量 +1。
java 复制代码
public Long getTotalPage() {
        //总页数 = 总记录数 % 页容量 == 0? 总记录数/页容量:  总记录数/页容量 +1
        return count%pageSize==0?count/pageSize:(count/pageSize+1);
    }
java 复制代码
package com.fs.entity;

import java.util.List;

/**
 * @Title: Page
 * @Author HeYouLong
 * @Package com.fs.entity
 * @Date 2024/11/29 下午4:48
 * @description: 分页实体类
 */
public class Page<T> {
    private Long count ; //总记录数
    private Long totalPage; //总页数
    private Integer pageIndex; //当前页码
    private Integer pageSize;  //每页显示记录数(页容量)
    private List<T> records;  //

    public Long getCount() {
        return count;
    }

    public void setCount(Long count) {
        this.count = count;
    }

    public Long getTotalPage() {
        return count % pageSize == 0 ? count / pageSize : (count / pageSize) + 1;
    }

    /*public void setTotalPage(Long totalPage) {
        this.totalPage = totalPage;
    }*/

    public Integer getPageIndex() {
        return pageIndex;
    }

    public void setPageIndex(Integer pageIndex) {
        this.pageIndex = pageIndex;
    }

    public Integer getPageSize() {
        return pageSize;
    }

    public void setPageSize(Integer pageSize) {
        this.pageSize = pageSize;
    }

    public List<T> getRecords() {
        return records;
    }

    public void setRecords(List<T> records) {
        this.records = records;
    }
}
4、sql语句的书写。
  • sql语句需要写两条。调用两个方法。
  • 记录(根据分页得到的查询结果)。
  • 求当前页记录: select * from .... limit 开始序号,页容量。

  • 总记录(count)。
  • 求总记录数: select count(1) from...

  • limit的开始序号与页容量。
  • 开始序号 = (页码-1)*页容量。
  • 如40条数据。每页5条。
  • 页码 开始序号
  • 1 0
  • 2 5
  • 3 10

三、正式代码书写。

(1)链接到对应Servlet。


(2)queryUsersByPageServlet类。
  • 具体代码。具体解释在注释中。
java 复制代码
package com.fs.web;

import com.fs.entity.Page;
import com.fs.entity.UserInfo;
import com.fs.service.UserInfoService;
import com.fs.service.impl.UserInfoServiceImpl;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

/**
 * @Title: queryUsersByPageServlet
 * @Author HeYouLong
 * @Package com.fs.web
 * @Date 2024/11/29 下午5:01
 * @description: 分页查询用户信息
 */
@WebServlet("/users/queryUsersByPage")
public class queryUsersByPageServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.设置编码
        resp.setContentType("text/html;charset=utf-8");
        //获取请求参数
        //页码
        String pageIndexStr = req.getParameter("pageIndex");
        int pageIndex = Integer.parseInt(pageIndexStr);
        //默认设置页容量=2
        int pageSize = 2;
        //2.调用业务层
        UserInfoService userInfoService = new UserInfoServiceImpl();
        //调用分页查询方法
        //注意返回的是一个封装了5个数据的Page对象
        Page<UserInfo> page = userInfoService.queryByPage(pageIndex,pageSize);

        //将分页查询的所有用户信息保存到request域中
        req.setAttribute("page",page);
        //请求转发
        req.getRequestDispatcher("/users/list.jsp").forward(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    }
}
  • 注意修改:将循环的EL表达式改成"page(对象)",并且是它的属性查询后的记录数(records)。

(3)service层接口。
java 复制代码
/**
     * 分页查询
     * @param pageIndex
     * @param pageSize
     * @return
     */
    Page<UserInfo> queryByPage(int pageIndex, int pageSize);
(4)serviceImpl实现类。
  • 注意这里需要写两个dao层方法。
  • 1.查询总记录数。2.查询当前分页条件下的记录。(数据)
java 复制代码
@Override
    public Page<UserInfo> queryByPage(int pageIndex, int pageSize) {
        UserInfoDao userInfoDao = new UserInfoDaoImpl();
        //1.查询总记录数
        long count = userInfoDao.count();
        // 2.查询当前分页的记录(数据)
        List<UserInfo> records =userInfoDao.selectByPage(pageIndex,pageSize);
        //包装成page对象
        Page<UserInfo> page = new Page<>();
        page.setPageIndex(pageIndex);
        page.setPageSize(pageSize);
        page.setCount(count);
        page.setRecords(records);
        return page;
    }
}
(5)dao层接口。(数据访问层接口)
java 复制代码
/**
     * 查询总记录数
     * @return
     */
    long count();

    /**
     * 分页查询
     * @param pageIndex
     * @param pageSize
     * @return
     */
    List<UserInfo> selectByPage(int pageIndex, int pageSize);
  • 因为查询的结果是返回是一个基本数据类型的数据。
  • 所以使用ScalarHandler类接收参数。
(6)dao层实现类。
java 复制代码
@Override
    public long count() {
        Connection conn = null;
        try {
            conn = JdbcUtil.getConnection();
            QueryRunner queryRunner = new QueryRunner();
            String sql = "select count(1) from tb_userinfo";
            //查询单个值,resultSet处理器 ScalarHandler
            return queryRunner.query(conn,sql,new ScalarHandler<Long>());
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }finally {
            JdbcUtil.close(conn);
        }
    }

    @Override
    public List<UserInfo> selectByPage(int pageIndex, int pageSize) {
        Connection conn = null;
        try {
            conn = JdbcUtil.getConnection();
            QueryRunner queryRunner = new QueryRunner();
            String sql = "select * from tb_userinfo limit ?,?";
            return queryRunner.query(conn,sql,new BeanListHandler<>(UserInfo.class),(pageIndex-1)*pageSize,pageSize);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }finally {
            JdbcUtil.close(conn);
        }
    }
(7)初步测试其功能是否正常。
  • 先登录。
  • 进入首页。点击查询用户信息按钮。
  • 功能正常。
  • 现在对下面的分页栏进行修改。增加总记录数、总页数显示。

(8)完善设计要求。

(注意本代码中使用bootstrap组件快速开发)

1、当前所在页为:1。
  • 不显示上一页按钮。点击下一页跳到下一页数据。
  • 通过<c:if>标签进行判断。
2、当前所在页为:最后一页。
  • 不显示下一页按钮。点击上一页跳到上一页数据。
3、位于当前页时。
  • 从超链接变成不能点击的。以单纯文本显示。
  • 所在按钮背景变"蓝"。
4、显示页数(如:1、2...)。
  • 根据当前的分页总数计算。
  • 根据<c:forEach>进行普通循环。

java 复制代码
<%@ page import="com.fs.entity.UserInfo" %>
<%@ page import="java.util.List" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--引入JSTL核心标签库--%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<!-- 网页使用的语言 -->
<html lang="zh-CN">
<head>
    <!-- 指定字符集 -->
    <meta charset="utf-8">
    <!-- 使用Edge最新的浏览器的渲染方式 -->
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <!-- viewport视口:网页可以根据设置的宽度自动进行适配,在浏览器的内部虚拟一个容器,容器的宽度与设备的宽度相同。
    width: 默认宽度与设备的宽度相同
    initial-scale: 初始的缩放比,为1:1 -->
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
    <title>用户信息管理系统</title>

    <!-- 1. 导入CSS的全局样式 -->
    <link href="../css/bootstrap.min.css" rel="stylesheet">
    <!-- 2. jQuery导入,建议使用1.9以上的版本 -->
    <script src="../js/jquery-2.1.0.min.js"></script>
    <!-- 3. 导入bootstrap的js文件 -->
    <script src="../js/bootstrap.min.js"></script>
    <style type="text/css">
        td, th {
            text-align: center;
        }
    </style>
</head>
<body>

<div class="container">
    <h3 style="text-align: center">用户信息列表</h3>
    <div style="float: left;">

        <form class="form-inline">
            <div class="form-group">
                <label for="exampleInputName2">姓名</label>
                <input type="text" class="form-control" id="exampleInputName2">
            </div>
            <div class="form-group">
                <label for="exampleInputName3">籍贯</label>
                <input type="text" class="form-control" id="exampleInputName3">
            </div>

            <div class="form-group">
                <label for="exampleInputEmail2">邮箱</label>
                <input type="email" class="form-control" id="exampleInputEmail2">
            </div>
            <button type="submit" class="btn btn-default">查询</button>
        </form>

    </div>

    <div style="float: right;margin: 5px;">

        <a class="btn btn-primary" href="add.html">添加新用户</a>
        <a class="btn btn-primary" href="add.html">删除选中用户</a>
    </div>

    <table border="1" class="table table-bordered table-hover">
        <tr class="success">
            <th><input type="checkbox"></th>
            <th>编号</th>
            <th>姓名</th>
            <th>性别</th>
            <th>年龄</th>
            <th>籍贯</th>
            <th>QQ</th>
            <th>邮箱</th>
            <th>操作</th>
        </tr>
        <c:forEach items="${page.records}" var="user" varStatus="s">
            <tr>
                <td><input type="checkbox"></td>
                <td>${s.count}</td>
                <td>${user.name}</td>
                <td>${user.gender}</td>
                <td>${user.age}</td>
                <td>${user.address}</td>
                <td>${user.email}</td>
                <td>${user.qq}</td>
                <td>
                    <a class="btn btn-default btn-sm" href="/users/update?id=${user.id}">修改</a>&nbsp;
                    <a class="btn btn-default btn-sm" href="/users/delete?id=${user.id}">删除</a></td>
            </tr>
        </c:forEach>
    </table>
    <nav aria-label="Page navigation">
        <ul class="pagination">
            <li>
                <c:if test="${page.pageIndex>1}">
                    <a href="/users/queryUsersByPage?pageIndex=${page.pageIndex-1}" aria-label="Previous">
                        <span aria-hidden="true"><<</span>
                    </a>
                </c:if>
            </li>
            <%--var相当于i begin 开始 end 结束  step 步长(每次加1)--%>
            <c:forEach var="i" begin="1" end="${page.totalPage}" step="1">
                <c:choose>
                    <c:when test="${page.pageIndex==i}">
                        <li class="active"><span>${i}</span></li>
                    </c:when>
                    <c:otherwise>
                        <li><a href="/users/queryUsersByPage?pageIndex=${i}">${i}</a></li>
                    </c:otherwise>
                </c:choose>
            </c:forEach>
            <li>
                <c:if test="${page.pageIndex <page.totalPage}">
                    <a href="/users/queryUsersByPage?pageIndex=${page.pageIndex+1}" aria-label="Next">
                        <span aria-hidden="true">>></span>
                    </a>
                </c:if>
            </li>
            <span style="font-size: 25px;margin-left: 5px;">
                    共条${page.count}记录,共${page.totalPage}页
                </span>
        </ul>
    </nav>
</div>
</body>
</html>
5、测试结果。
  • 初步测试1。

  • 位于第一页时,没有上一页按钮。

  • 位于最后一页时,没有下一页按钮。

  • 最终效果。
相关推荐
Bling_9 分钟前
Springboot Bean创建流程、三种Bean注入方式(构造器注入、字段注入、setter注入)、循坏依赖问题
java·spring boot·spring·容器
开疆智能24 分钟前
机器人技术:ModbusTCP转CCLINKIE网关应用
java·服务器·科技·机器人·自动化
心向阳光的天域43 分钟前
黑马跟学.苍穹外卖.Day03
java·开发语言·spring boot
对酒当歌丶人生几何44 分钟前
SpringBoot实现国际化
java·spring boot·后端·il8n
雪芽蓝域zzs1 小时前
JavaWeb开发(九)JSP技术
java·开发语言
上海拔俗网络1 小时前
“智能筛查新助手:AI智能筛查分析软件系统如何改变我们的生活
java·团队开发
weixin_437398211 小时前
Elasticsearch学习(1) : 简介、索引库操作、文档操作、RestAPI、RestClient操作
java·大数据·spring boot·后端·学习·elasticsearch·全文检索
MasterNeverDown1 小时前
spring boot controller放到那一层
java·spring boot·后端
Yang-Never2 小时前
Kotlin->Kotlin协程的取消机制
android·java·开发语言·kotlin·android studio·idea
星迹日2 小时前
数据结构:LinkedList与链表—无头单向链表(一)
java·数据结构·经验分享·笔记·链表·单向链表