✨JavaWeb项目:实战亲自动手手敲上线小项目部分功能的第二天✨

本文详细介绍了在JavaWeb项目中实现模糊查询和分页查询的步骤。通过修改查询条件,调整SQL语句,解决数据类型转换异常,并优化分页查询逻辑,确保在不同页面状态下的正确跳转和数据加载。文章还分享了在遇到问题时的解决方法,包括空值判断和异常处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

系列链接:
✨JavaWeb项目实战亲自动手手敲上线小项目的第一天✨
✨JavaWeb项目实战亲自动手手敲上线小项目的第二天✨
✨JavaWeb项目实战亲自动手手敲上线小项目的第三天✨
✨JavaWeb项目:实战亲自动手手敲上线小项目部分功能的第四天优化✨

实现流程思想与过程

那今天就不多说流程了,直接去实现功能就是了。

1. 模糊查询功能实现

那在前面说过我们已经实现了对学生列表的全查,那接下来就进行一下优化对其进行查询条件的限定,之后根据对应条件去返回对的查询结果。

  1. 那我们首先就去修改我们的list.jsp中的关于模糊查询的条件:
    结果如下:
				<form action="/Educational/student/getStudentList" method="get">
                    学生名称: 
					<input type="text" name="stuname"  value="${stuname}" />
                     学生学号: 
					<input type="text" name="stuno"   value="${stuno}" />
					性别: 
					<select name="sex">
							<option value="-1">--请选择--</option>
							<option value="1"></option>
							<option value="0"></option>
						</select>
					<input type="submit" value="查询" />

                </form>
  1. 那之后发送一个请求给form表单的action,那就又到了我们的GetStudentServlet,那之前不是没有参数的吗,现在我们就去获取参数,那传参了,下面的调取service的GetStudents的方法也要有参数。
				//1. 获取参数
        String stuname = req.getParameter("stuname");
        String stuno = req.getParameter("stuno");
        String sex = req.getParameter("sex");
        //2. 调取service方法
        StudentService service = new StudentServiceImpl();
        List<Student> students = service.getStudents(stuname,stuno,Integer.parseInt(sex));
        

那我们依次都要对service,还有实现类都要加上参数。
那更新后的StudentService接口方法为:

package com.lby.service;

import com.lby.bean.Student;

import java.util.List;

/**
 * @Author: King-lby
 * @Date Created in 2021-08-24 9:46
 */
public interface StudentService {
    /**
     * 获取学员的信息列表
     */
    public List<Student> getStudents(String name,String stuno,int sex);
}

还有StudentSerivceImpl类:还有调用过程中要返回的都要加上参数.


   @Override
    public List<Student> getStudents(String name,String stuno,int sex) {
        return dao.getStudents(name,stuno,sex);
    }

dao层的StudentDao也要更新:

public List<Student> getStudents(String name,String stuno,int sex);

还有dao层的实现类StudentDaoImpl:

 @Override
    public List<Student> getStudents(String name,String stuno,int sex) {

那把参数都传入了,就要根据相应的参数进行一个动态的筛选查询了,所以我们要去改我们的查询sql语句,那我们可以用一个StringBuffer工具类,那为什么用StringBuffer呢,而不选择用String呢,那是因为String是一个固定长度的字符串,而StringBuffer是一个动态的进行内存的更新,也就是内存可以扩容,所以方便我们进行查询语句的一个动态的变化,(因为我们可根据上面的三个参数进行总共有 A 3 3 A_{3}^{3} A33种选择筛选条件的变化)

 @Override
    public List<Student> getStudents(String name,String stuno,int sex) {
        List list = new ArrayList<Student>();
        List params = new ArrayList();
        try {
            StringBuffer  sqlbuf=new StringBuffer(" select * from student where 1=1 ");//注意前后加空格,这是字符串的拼接
            if(name!=null&&name.length()>0){
                //拼接字符串
                sqlbuf.append(" and stuname like ? ");//注意前后加空格,这是字符串的拼接
                params.add("%"+name+"%");//模糊查要添加%别忘了
            }
            if(stuno!=null&&stuno.length()>0){
                //拼接字符串
                sqlbuf.append(" and stuname=? ");//注意前后加空格,这是字符串的拼接
                params.add(stuno);
            }
            if(sex!=-1){
                //拼接字符串
                sqlbuf.append(" and sex=? ");//注意前后加空格,这是字符串的拼接
                params.add(sex);
            }

            resultSet = query(sqlbuf.toString(), params);//没有参数,返回结果集,使用父类变量resultSet

那我们会发现我们的页面查询会报异常:数据类型转换格式出现了问题
在这里插入图片描述29行出现了错误,那是哪里:
在这里插入图片描述那就是这个问题我他丫的今天啥也没干,就陪着他折腾了一整天,我疯了,网上众说纷纭啊,那我这里最后在老师的帮助下解决了,解决完就是晚上八点了
我服了,我是废物,那具体的解决方法就是直接对其进行一个三目判断:
将第29行改为:

  List<Student> students = service.getStudents(stuname,stuno,sex==null?-1:Integer.parseInt(sex));

那这个1是我设置的男性的值,0是女性,-1则是请选择,那还是不要去设置1或者0,因为我试过了,如果设置的是1,那不管你的sex如何改变都会是男学生,0则全是不管选择什么都是女学生。还是-1对应null比较好。


就这样解决了
就这样没了,心里空落落的,好难受。

好吧,解决后的效果如下:
请添加图片描述当查询条件为男性时:
请添加图片描述当学号查询条件为stu1001时:
在这里插入图片描述当模糊查询含有李的学生姓名时:
在这里插入图片描述
那我们会发现我们在点击查询后,我们的查询条件是没有保存的,那我们就可以在GetStudentServlet的跳转页面的操作后面添加:

//3. 跳转页面
        //如果后台想给前台传数据,是一定要给给前台存值的
        req.setAttribute("stulist",students);//将students对象的数据存到stulist中

        //存储模糊查询条件
        req.setAttribute("stuname",stuname);
        req.setAttribute("stuno",stuno);
        req.setAttribute("sex",sex);

        /**
         * 那我们跳转页面到Educational/student/list.jsp查看存储的数据
         */
        //注意:这个路径是我们之前在left.jsp中已经有一个请求的路径了,所以只要接上之前的就好了,不用全部写完,当然直接用绝对路径的方式也是可行的,还是很好用的。
        //注意2:不要加‘/’,加了就变成从根目录web查找路径了
        req.getRequestDispatcher("list.jsp").forward(req,resp);

那之后我们的模糊查询就可以进行单击一个查询条件之后,再次根据选择添加条件去模糊查询了。

那优化后的模糊查询效果展示就不展示了,浪费空间,大家可自行猜想,那就直接下一环节。

2. 分页查询

那我们在完成了模糊查询后,再继续我们的分页查询。
惯例:

  1. 那我们首先在list.jsp中发送请求,然后就发送一个请求地址Educational/student/getStudentList到GetStudentServlet
<tr>
          <td colspan="20" style="text-align: center;">
		<a style="text-decoration: none;" href="/Educational/student/getStudentList">首页</a>
		<a style="text-decoration: none;" href="/Educational/student/getStudentList">上一页</a>
		<a style="text-decoration: none;" href="/Educational/student/getStudentList">下一页</a>
		<a style="text-decoration: none;" href="/Educational/student/getStudentList">尾页</a>
		共1234条
		每页显示
		10/23
    </td>
</tr>
  1. 那我们的GetStudentServlet会干什么事呢?

    2.1 还是传参,但是是接收两部分参数:
    
//1.2 分页数据 limit 开始设置,显示条数
        //页码值
        String pageIndex = req.getParameter("pageIndex");//接收参数,然后传给service层

还是一样的流程,我们的StudentService接口:

public interface StudentService {
    /**
     * 获取学员的信息列表
     * pageIndex    页码值
     * pageSize     每页显示条数
     */
    public List<Student> getStudents(String name,String stuno,int sex,int pageIndex,int pageSize);
}

我们的StudentServiceImpl实现类:

public class StudentServiceImpl implements StudentService {

    private StudentDao dao = new StudentDaoImpl();
    @Override
    public List<Student> getStudents(String name,String stuno,int sex,int pageIndex,int pageSize) {
        return dao.getStudents(name,stuno,sex,pageIndex,pageSize);
    }
}

我们的StudentDao接口:

public interface StudentDao {
    /**
     * 获取学员的信息列表
     */
    public List<Student> getStudents(String name,String stuno,int sex,int pageIndex,int pageSize);
}

还有我们的StudentDaoImpl实现类:

 @Override
    public List<Student> getStudents(String name,String stuno,int sex,int pageIndex,int pageSize) {
    。。。
    }

那就和模糊查询一样,我们也要去修改sql,所以我们在几个if的最外层加上:

 //分页
            sqlbuf.append(" limit ?,? ");// 1 5 limit 0 5
            

这里给大家说一下,那我们假设我们第一页,然后每页显示5条,那就要limit从下标:0开始,5条每页,对吧,那就有一个公式,大家可以记一下:

limit (pageIndex-1)*pageSize,pageSize;//起始位置,总页码数

所以我们的向集合中这样添加:

			params.add((pageIndex-1)*pageSize);
            params.add(pageSize);

那我们返回去看我们的GetStudentServlet,我们这里有一个和模糊查询一下的问题:空值问题,哎,所以这次我们就提前定义一个index变量,判断空值:

//1.2 分页数据 limit 开始设置,显示条数
        //页码值
        String pageIndex = req.getParameter("pageIndex");//接收参数,然后传给service层
        //如果页面没有传入pageIndex的值,则默认查询第一页
        int index = pageIndex==null?1:Integer.parseInt(pageIndex);

        //2. 调取service方法
        StudentService service = new StudentServiceImpl();
        List<Student> students = service.getStudents(stuname,stuno,sex==null?-1:Integer.parseInt(sex),index,5);
        //3. 跳转页面

那这样,我们的首页空值问题和跳转以及每页显示列表条数问题就解决了,那我们的往后进行,
我们的上一页,下一页怎么办?
那我们的上一页或者下一页是怎么来的?是当前页码值-1,而当前页码值就是我们之前接收的pageIndex,那我们这个页码怎么从后台到前台进行一个获取呢?还是和模糊查询一样,所以我们在存储模糊查询条件后面加上:

 //存储分页数据
        req.setAttribute("index",pageIndex);

那我们存入了当前页码值之后去跳转list.jsp,那我们的分页部分代码也就进行了优化:

<tr>
          <td colspan="20" style="text-align: center;">
		<a style="text-decoration: none;" href="/Educational/student/getStudentList">首页</a>
		<a style="text-decoration: none;" href="/Educational/student/getStudentList?pageIndex=${index-1}">上一页</a>
		<a style="text-decoration: none;" href="/Educational/student/getStudentList?pageIndex=${index+1}">下一页</a>
		<a style="text-decoration: none;" href="/Educational/student/getStudentList">尾页</a>1234条
		每页显示
		10/23
    </td>
</tr>

我们测试一下:就是这样的一个效果
在这里插入图片描述
但是也有问题:当我们点击到了最后一页的时候,我们再次点击下一页,那就回显示:
在这里插入图片描述
同样的还有点击到首页时,我们还去点击上一页,那就会报错:
在这里插入图片描述
那又遇到了异常,我们要怎么解决呢?那先分析问题,我们在到最后一页时还点击下一页没有信息显示,而点击到首页还点击上一页,直接就是报了一个空指针异常,那我们就让他们在手尾的时候去进行一个空值判断就好了,我们采用EL表达式:

  <a style="text-decoration: none;" href="/Educational/student/getStudentList?pageIndex=${index-1<=1?1:index-1}">上一页</a>
  <a style="text-decoration: none;" href="/Educational/student/getStudentList?pageIndex=${index+1}">下一页</a>

那我们的下一页是和总页数去作比较的,那总页数又是怎么来的。
那我们可以在GetStudentServlet中定义:
//获取总页数=总条数%每页显示的条数>0?总条数/每页显示条数+1:总条数/每页显示条数;
//问题又来了,总条数从哪来,那我们可以在service层的StudnentService接口定义一个方法:

/**
     * 获得总条数(基于模糊查询)
     */
    public int total(String name,String stuno,int sex);

那同样的,我们在dao层也去添加,还有他们的实实现类:
那我们的StudentServiceImpl实现类:
那就直接Alt+Enter:然后我们改一下返回结果

public class StudentServiceImpl implements StudentService {

    private StudentDao dao = new StudentDaoImpl();
    @Override
    public List<Student> getStudents(String name,String stuno,int sex,int pageIndex,int pageSize) {
        return dao.getStudents(name,stuno,sex,pageIndex,pageSize);
    }

    @Override
    public int total(String name, String stuno, int sex) {
        return dao.total(name, stuno, sex);
    }
}

我们的StudentDao接口:

public interface StudentDao {
    /**
     * 获取学员的信息列表
     */
    public List<Student> getStudents(String name,String stuno,int sex,int pageIndex,int pageSize);
    /**
     * 获得总条数(基于模糊查询)
     */
    public int total(String name,String stuno,int sex);
}

还有StudentDaoImpl实现类:

@Override
    public int total(String name, String stuno, int sex) {
            int total = 0;
        try {
            List params = new ArrayList();
            StringBuffer  sqlbuf=new StringBuffer(" select count(*) from student where 1=1 ");//注意前后加空格,这是字符串的拼接
            if(name!=null&&name.length()>0){
                //拼接字符串
                sqlbuf.append(" and stuname like ? ");//注意前后加空格,这是字符串的拼接
                params.add("%"+name+"%");//模糊查要添加%别忘了
            }
            if(stuno!=null&&stuno.length()>0){
                //拼接字符串
                sqlbuf.append(" and stuno=? ");//注意前后加空格,这是字符串的拼接
                params.add(stuno);
            }
            if(sex!=-1){
                //拼接字符串
                sqlbuf.append(" and sex=? ");//注意前后加空格,这是字符串的拼接
                params.add(sex);
            }
            resultSet = query(sqlbuf.toString(),params);
            while(resultSet.next()){
                total=resultSet.getInt(1);//第一列
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            closeAll();
        }
        return total;
    }

那这里我们的resultSet其实就是一个值,那我们就在最外层设置total=0,之后我们while循环,获取第一列,最后closeAll()关闭资源,然后返回我们的total。
那我们再回到GetStudentServlet去调用:

 //获取总页数=总条数%每页显示的条数>0?总条数/每页显示条数+1:总条数/每页显示条数;
 //问题又来了,总条数从哪来
     int total = service.total(stuname,stuno,sex==null?-1:Integer.parseInt(sex));//总条数
     int totalPages = total%5>0?total/5+1:total/5;//总页数

那调用后,我们去把之前的存储分页数据给填充起来:

//存储分页数据
        req.setAttribute("index",index);
        req.setAttribute("size",5);
        req.setAttribute("total",total);
        req.setAttribute("totalPages",totalPages);

那之后我们再去把之前的list,jsp里的分页效果给迭代一下:

 <td colspan="20" style="text-align: center;">
		<a style="text-decoration: none;" href="/Educational/student/getStudentList">首页</a>
		<a style="text-decoration: none;" href="/Educational/student/getStudentList?pageIndex=${index-1<=1?1:index-1}">上一页</a>
		<a style="text-decoration: none;" href="/Educational/student/getStudentList?pageIndex=${index+1>=totalPages?totalPages:index+1}">下一页</a>
		<a style="text-decoration: none;" href="/Educational/student/getStudentList?pageIndex=${totalPages}">尾页</a>
		共${total}条
		每页显示
		${index}/${totalPages}
  </td>

那到这里,我们的份额查询就告一段落了,我们再去查看一下效果:
在这里插入图片描述我们可以看到,当我们点击首尾页时,就没有再报错了,而且大家可以仔细看一下左下角的链接。
那我之后又去测试了模糊查询,发现有问题,按理来说应该是只有这一个条件筛选出来的信息,但是当我点击下一页时还是将所有数据都进行了查询,那我其实看到了,我们的左下角请求链接并没有变化,也就说我们的模糊查询的条件没有拼接上,那我们
再去list.jsp的分页部分进行迭代:

<td colspan="20" style="text-align: center;">
			<a style="text-decoration: none;" href="/Educational/student/getStudentList?stuname=${stuname}&stuno=${stuno}&sex=${sex}">首页</a>
			<a style="text-decoration: none;" href="/Educational/student/getStudentList?pageIndex=${index-1<=1?1:index-1}&stuname=${stuname}&stuno=${stuno}&sex=${sex}">上一页</a>
			<a style="text-decoration: none;" href="/Educational/student/getStudentList?pageIndex=${index+1>=totalPages?totalPages:index+1}&stuname=${stuname}&stuno=${stuno}&sex=${sex}">下一页</a>
			<a style="text-decoration: none;" href="/Educational/student/getStudentList?pageIndex=${totalPages}&stuname=${stuname}&stuno=${stuno}&sex=${sex}">尾页</a>
			共${total}条
			每页显示
			${index}/${totalPages}
 </td>

那我们再来看效果:
在这里插入图片描述
我们再看就会发现我们的stuname,stuno,sex数据都拼接成功了,而且也不会再出现返回全查的结果了。
好了,由于本人的时间今天都浪费在处理Bug上面去了,导致我们的时间很少,再加上我学完内容再写出来,现在都已经凌晨了,那y也是因为本人的接收能力不高,所以今天就学到这里,更新到这里。内容有点少,希望大家见谅。
当然若本篇内容对您有所帮助,请三连点赞,关注,收藏支持下。
别问,问就是在这里插入图片描述
创作不易,白嫖很爽,但是求各位手下留情。
如果本篇博客有任何错误或者疏漏,请批评斧正,感激不尽 !
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

少年,又是你

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值