1.项目流程
确定需求->代码编码(数据库创建,创建项目-(包结构,工具类,工具包,逻辑代码编写))->测试阶段->上线
2. 包的主要结构
3.包结构的调取关系
servlet 调取service ,service 调取dao, dao操作bean
4.包的填充
填充顺序:bean, dao, impl, service, service.impl, servlet
(1) bean(实体类包):用来和数据库表做对应关系的
代码编写规范:类名=表名,列名=属性名
属性的类型建议使用包装类
(2)dao包:用来定义操作数据库的方法
命名规范:bean实体类+Dao
(3)dao.impl包:定义dao的实现类
命名规范:接口名+Impl
(4)service包:用来定义业务逻辑的方法
命名规范:bean实体类+Service
(5)service.impl包:定义service的实现类
命名规范:接口名+Impl
(6)web/servlet包:定义处理请求的servlet
命名规范版本1:功能名+Servlet,示例:InsertUsersServlet,DeleteUsersServlet
ps:数据库中的一条数据==java中的一个对象
service接口层的代码在javaweb开发期间,和dao层的接口是一样的
将项目中所用到的jar包放到tomcat的lib文件夹下
新建的项目,记得把项目路径改成/
5.准备工作:创建数据表,导入jar包,实体类,工具类,配置好连接数据库的属性文件
数据表
导入jar包
连接数据库的属性文件
url=jdbc:mysql://localhost:3306/mydemo1?characterEncoding=utf8&useSSL=false&serverTimezone=UTC uname=root upass=1380341 driverClass=com.mysql.cj.jdbc.Driver
实体类
最初的实体类,后续还有很多更改
package bean; public class Users { //属性 private Integer userid; private String username; private Integer age; private String sex; private String password; //无参 public Users() { } //全参 public Users(Integer userid, String username, Integer age, String sex, String password) { this.userid = userid; this.username = username; this.age = age; this.sex = sex; this.password = password; } //重写toString(),get(),set()方法 @Override public String toString() { return "Users{" + "userid=" + userid + ", username='" + username + '\'' + ", age=" + age + ", sex='" + sex + '\'' + ", password='" + password + '\'' + '}'; } public Integer getUserid() { return userid; } public void setUserid(Integer userid) { this.userid = userid; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
工具类 DBUtilsPlus
package util; import com.alibaba.druid.pool.DruidDataSource; import java.sql.*; import java.util.List; import java.util.ResourceBundle; // BaseDao 将链接数据库的步骤进行封装,简化后续JDBC操作 public class DBUtilsPlus { // 德鲁伊 数据库连接池 private static DruidDataSource dataSource; //1.定义常用的工具类(Protected修饰的属性或方法可以在子类中被调用) protected Connection connection; protected PreparedStatement pps; protected ResultSet resultSet; static { dataSource=new DruidDataSource(); ResourceBundle db = ResourceBundle.getBundle("jdbc"); dataSource.setUrl(db.getString("url")); dataSource.setDriverClassName(db.getString("driverclass")); dataSource.setUsername(db.getString("uname")); dataSource.setPassword(db.getString("upass")); //设置链接数量 // dataSource.setInitialSize(30); dataSource.setMaxActive(8); } //3.得到链接对象 protected Connection getConnection(){ try { connection = dataSource.getConnection(); } catch (SQLException throwables) { throwables.printStackTrace(); } return connection; } //4.创建通道 protected PreparedStatement getPps(String sql){ getConnection(); try { pps = connection.prepareStatement(sql); } catch (SQLException throwables) { throwables.printStackTrace(); } return pps; } //5.绑定占位符的值 insert into A(sid,sname,sex,age .... ) values(?,?,?,?) //List 参数存储的是给占位符所赋的值 //setParameter(new ArrayList()) public void setParameter(List list){ try { if (list != null&&list.size()>0) { //对List集合进行有效性验证 for (int i=0;i<list.size();i++) { pps.setObject(i+1,list.get(i)); } } } catch (SQLException throwables) { throwables.printStackTrace(); } } //6.执行sql-增删改 protected int updateDB(String sql,List list){ int i = 0; try { getPps(sql);//sql setParameter(list);//list-绑定的是占位符的参数 i = pps.executeUpdate(); } catch (SQLException throwables) { throwables.printStackTrace(); } return i; } //7.执行sql-查询 protected ResultSet selectDB(String sql,List list){ try { getPps(sql);//sql setParameter(list);//list-绑定的是占位符的参数 resultSet=pps.executeQuery(); } catch (SQLException throwables) { throwables.printStackTrace(); } return resultSet; } //8.关闭资源 public void closeAll(){ try { if (resultSet != null) { resultSet.close(); } if (pps != null) { pps.close(); } if (connection != null) { connection.close(); } } catch (SQLException throwables) { throwables.printStackTrace(); } } }
6.编程思路
写完实体类后Users之后
(1)根据逻辑,dao操作bean,我们想到接下来是在dao包定义Users类的UsersDao接口类
(2)定义了UsersDao接口类,我们又需要UsersDaoImpl实现类。
(3)根据逻辑,service调取dao,我们创建UsersService接口类。
(4)同理,定义了UsersService接口类,我们又需要UsersServiceImpl实现类。
(5)根据逻辑servlet 调取service,我们每一个功能,都需要创建一个servlet类
比如登录功能,我们就需要一个LoginServlet类,由他开始调取 UsersService,再由UsersService调取UsersDao,UsersDao来操作Users
实现流程图
1.登录功能代码实现
思路:页面请求—>servlet处理类调取service ,service 调取dao, dao操作bean
编程思路:1.根据请求创建页面实例
1.首先有了请求,我们先将index.jsp动态页面,建成一个登陆界面
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>$Title$</title> </head> <body> <h1>登录</h1> <form action="/login" method="post"> 用户名:<input type="text" name="username"><br> 密码:<input type="password" name="userpass"><br> <input type="submit" value="登录"> </form> </body> </html>
2创建LoginServlet处理类
2.有了请求之后根据调取逻辑,首先是servlet调取service,所以要创建LoginServlet处理类,继承HttpServlet 类重写service方法。
这里先加入了接收参数部分
package web; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; public class LoginServlet extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //1.接参数 req.setCharacterEncoding("utf-8"); String username = req.getParameter("username");//要和表单的name值相同 String userpass =req.getParameter("userpass"); //写逻辑 //返结果 return null; } }
3.配置web.xml文件
有了servlet之后,我们需要同时在web.xml文件中配置servlet
<servlet> <servlet-name>loginuser</servlet-name> <servlet-class> web.LoginServlet </servlet-class> </servlet> <servlet-mapping> <servlet-name>loginuser</servlet-name> <url-pattern>/login</url-pattern> </servlet-mapping>
登录是我们的第一个功能,我们先按照根据调用逻辑开始写一个登录的方法
servlet 调取service ,service 调取dao, dao操作bean
4.UsersService与UsersDao的Login方法
UsersService的Login方法
public Users Login(String username,String pass);
UsersDao的Login方法
public Users Login(String username,String pass);
这两个Login方法一模一样,
但 UsersDao接口是用来定义操作数据库的方法的
而UsersService接口是用来定义业务逻辑方法的
二者有本质区别,具体表现在他们各自的实现类上。
UsersService的实现类UsersServiceImpl,就是返回一个调取UsersDao的login方法的方法
service 调取dao
5.UsersServiceImpl实现业务调用逻辑
package service.impl; import bean.Users; import dao.UsersDao; import dao.impl.UsersDaoImpl; import service.UsersService; public class UsersServiceImpl implements UsersService { UsersDao usersDao=new UsersDaoImpl(); @Override public Users Login(String username, String pass) { return usersDao.Login(username,pass); } }
而 UsersDao的实现类UsersDaoImpl则需要实现具体的方法
要实现登录方法,我们就需要查询数据库的username,password数据,找的用户名密码相匹配的数据,因此需要用到DBUtilsPlus中的selectDB(sql,params)这个方法。
编程思路:首先继承工具类 DBUtilsPlus,因为我们需要使用它的selectDB(sql,params)方法操作数据库,而selectDB(sql,params);方法有两个参数,分别是sql与params,而我们的代码就是 要想办法获取这两个参数。
6. UsersDaoImpl实现操作数据库的逻辑
@Override public Users Login(String username, String pass) { Users u1 = null; try { String sql="select * from users where username=? and password=?"; List params=new ArrayList(); params.add(username); params.add(pass); resultSet=selectDB(sql,params); //将结果集的内容拿到java对象中(当结果集有数据时,就会进入得到循环中,每一次循环都会拿到数据库的中一行数据) while(resultSet.next()){ u1=new Users(); u1.setUserid(resultSet.getInt("userid")); u1.setAge(resultSet.getInt("age")); u1.setPassword(resultSet.getString("password")); u1.setSex(resultSet.getString("sex")); u1.setUsername(resultSet.getString("username")); } } catch (SQLException e) { e.printStackTrace(); } finally { closeAll(); } return u1; }
现在操作逻辑,业务逻辑都有了,我们可以补齐LoginServlet代码了,LoginServlet接收用户名密码参数后,首先调用LoginService逻辑,最后返回结果成功or失败给页面。
7.完善LoginOutServlet代码
package web; import bean.Users; import service.UsersService; import service.impl.UsersServiceImpl; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; import java.io.PrintWriter; public class LoginServlet extends HttpServlet { //重写方法时 二选一 //1重写Service() //2重写doget()与dopost()方法 @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //1.接参数 req.setCharacterEncoding("utf-8"); String username = req.getParameter("username");//要和表单的name值相同 String userpass =req.getParameter("userpass"); //写逻辑:面向接口编程 UsersService usersService=new UsersServiceImpl(); Users u = usersService.Login(username, userpass); //3.返结果 resp.setContentType("text/html;charset=utf-8"); PrintWriter writer = resp.getWriter(); if (u==null){ //登录失败(在后端给前端返回一个弹窗-若用js,就不要再用重定向或转发跳页面了否则405错误) //location.href是属于重定向跳转页面 writer.print("<script type='text/javascript'>alert('用户名或密码不正确');location.href='index.jsp'</script>"); }else { //登录成功 HttpSession session = req.getSession(); session.setAttribute("u1",u); writer.print("<script type='text/javascript'>alert('登录成功');location.href='success.jsp'</script>"); } } }
8.返回结果页面
如果登录成功,我们又需要一个成功页面
<%@ page import="bean.Users" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <% Users u1 =(Users) session.getAttribute("u1"); %> <h1> success.jsp,<%=u1.getUsername()%>欢迎您: </h1> </body> </html>
做完成功页面,我们的第一个功能,登录功能就完成了
2.测试登录功能
使用maven之后,在这里运行Tomcat
程序启动之后在控制台点击链接,可以直接跳转页面
养成没实现一个功能就测试一次的习惯
输入正确的用户明密码
错误的用户名密码
然后回到页面
3.项目踩坑
第一个坑:maven不会导jar包。
解决方案
删除掉之前lib的设置,打开https://mvnrepository.com/网站,按照jar包关键字,搜索jar包,再将其坐标发送到pom.xml文件中。
详细经过
点击复制,再打开 pom.xml文件
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.27</version> </dependency> <!-- https://mvnrepository.com/artifact/com.alibaba/druid --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.2.8</version> </dependency> <dependency> <groupId>org.apache.taglibs</groupId> <artifactId>taglibs-standard-impl</artifactId> <version>1.2.5</version> <scope>runtime</scope> </dependency> <!-- https://mvnrepository.com/artifact/javax.servlet.jsp.jstl/jstl --> <dependency> <groupId>javax.servlet.jsp.jstl</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency>
第二个坑:sevlet版本过低,这里自带的2.3
解决方案
首先修改pom文件
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> <scope>provided</scope> </dependency>
然后在web.xml文件中修改新的头文件
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0">
第三个坑,找不到jdbc,其中三处错误
错误一:属性文件名叫db.properties,而工具类的 文件名却是jdbc
解决方案:修改静态代码块,与错误三一起修改
错误二:属性文件需要在resources包下,而不是直接在项目包下
解决方案:在mian/java包下新建一个resources包,把db.properties复制过去
错误三:driverClass没有生效,原因是jdbc工具类中,driverclass没有按照小驼峰规范,用了小写
解决方案:修改静态代码块
static { dataSource=new DruidDataSource(); ResourceBundle db = ResourceBundle.getBundle("db"); dataSource.setUrl(db.getString("url")); dataSource.setDriverClassName(db.getString("driverClass")); dataSource.setUsername(db.getString("uname")); dataSource.setPassword(db.getString("upass")); //设置链接数量 // dataSource.setInitialSize(30); dataSource.setMaxActive(8); }
ps:新的项目需要改tomcat路径
完成第一个功能,接着完成第二个功能,退出
思路:页面请求—>servlet处理类调取service ,service 调取dao, dao操作bean
跟登录功能的思路大体相同。
4.退出功能代码实现
编程思路:1.有了退出请求,我们先将success.jsp动态页面,建成一个退出的按钮
<a href="/loginout">退出</a>
我们采用超链接的方式,因为方便 。
2.创建LoginOutServlet处理类
退出请求根据调取逻辑,首先是 servlet调取service,所以要创建LoginOutServlet处理类接收参数
public class LoginOutServlet extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //1.接参数 //2.写逻辑 //3.返结果 super.service(req, resp); } }
3.配置web.xml文件
有了servlet之后,我们需要同时在web.xml文件中配置servlet
<!--1.退出--> <servlet> <servlet-name>loginout</servlet-name> <servlet-class> web.LoginOutServlet </servlet-class> </servlet> <servlet-mapping> <servlet-name>loginout</servlet-name> <url-pattern>/loginout</url-pattern> </servlet-mapping>
4.代码实现
退出直接返回index页面即可,不需要接参数,直接写逻辑与结果
public class LoginOutServlet extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //接参数 //写逻辑:清除session,跳转页面 HttpSession session = req.getSession(); session.invalidate(); //3返结果:跳转目标页面 resp.sendRedirect("index.jsp"); } }
5.测试退出功能
此刻我们发现一个小缺陷,因为点击退出之后会清空session导致 u1为空
因为u1是从session中取出来的,退出之后清空了session,这对我们的以后的测试很不方便
所以我们需要给他一个三目运算符,让它以空字符串的形势输出
<%@ page import="bean.Users" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <% Users u1 =(Users) session.getAttribute("u1"); %> <h1> success.jsp,<%=u1==null?"":u1.getUsername()%>欢迎您: <a href="/loginout">退出</a> </h1> </body> </html>
1.查询全部功能代码实现
思路:页面请求—>servlet处理类调取service ,service 调取dao, dao操作bean
1.创建查询全部按钮
根据请求,我们先在success.jsp页面创建一个查询全部的按钮
<input type="button" value="查询用户列表" onclick="javascript:location.href='/selectusers'">
2.创建SelectUsersServlet处理类
有了请求,自然是创建SelectUsersServlet处理类,继承HttpServlet 类重写service方法
public class SelectUsersServlet extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.service(req, resp); } }
3.配置web.xml文件
有了servlet之后,我们需要同时在web.xml文件中配置servlet请求
<!--3.查询全部--> <servlet> <servlet-name>selectall</servlet-name> <servlet-class> web.SelectUsersServlet </servlet-class> </servlet> <servlet-mapping> <servlet-name>selectall</servlet-name> <url-pattern>/selectusers</url-pattern> </servlet-mapping>
4.UsersService与UsersDao的selectUsers方法
下一步就是创建UsersService的selectUsers方法。与UsersDao的selectUsers方法
根据需求,返回的是一个集合对象,所以我们使用List集合来接收对象
//查询全部的方法 public List<Users> selectAll();
5.UsersServiceImpl实现业务调用逻辑
很简单,返回一个usersDao.selectAll()就行
@Override public List<Users> selectAll() { return usersDao.selectAll(); }
SelectUsersServlet处理类的逻辑
//写逻辑 UsersService usersService=new UsersServiceImpl(); List<Users> users=usersService.selectAll();
6. UsersDaoImpl实现操作数据库
public List<Users> selectAll() { //既然是查询,还是要用到selectDB(sql,params)这个方法 //那就要先得到这两个参数 List userList = null; try { String sql= "select * from users"; //userList就是params userList = new ArrayList(); resultSet=selectDB(sql,null); while(resultSet.next()){ Users u1 =new Users(); u1.setUserid(resultSet.getInt("userid")); u1.setAge(resultSet.getInt("age")); u1.setPassword(resultSet.getString("password")); u1.setSex(resultSet.getString("sex")); u1.setUsername(resultSet.getString("username")); userList.add(u1); } } catch (SQLException e) { e.printStackTrace(); }finally { closeAll(); } return userList; }
7.完善LoginOutServlet代码
package web; import bean.Users; import service.UsersService; import service.impl.UsersServiceImpl; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.List; public class SelectUsersServlet extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //接参数 //写逻辑 UsersService usersService=new UsersServiceImpl(); List<Users> users=usersService.selectAll(); //返结果 req.setAttribute("ulist",users); req.getRequestDispatcher("/list.jsp").forward(req,resp); } }
8.返回结果页面
我们需要做一个表格来接收数据,否则页面会很难看
创建两行N列的表格进行展示,第二个tr,使用循环,进行数据展示
<%@ page import="bean.Users" %> <%@ page import="java.util.List" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <% Users u1 =(Users) session.getAttribute("u1"); %> <h1>list.jsp,<%=u1==null?"":u1.getUsername()%>欢迎您:</h1> <% List<Users> ulist = (List<Users>)request.getAttribute("ulist"); %> <table border="1" cellspacing="0" width="500"> <tr> <td>用户编号</td> <td>用户姓名</td> <td>用户性别</td> <td>用户年龄</td> <td>用户密码</td> <td>操作</td> </tr> <%for (Users u:ulist){%> <tr> <td><%=u.getUserid()%></td> <td><%=u.getUsername()%></td> <td><%=u.getSex()%></td> <td><%=u.getAge()%></td> <td><%=u.getPassword()%></td> </tr> <%}%> </table>> </body> </html>
此时,我们的第三个请求功能查询全部的代码就完成了
2.测试登录功能
登录之后点击查询用户列表按钮
本次功能运气很好,没有踩坑
唯一美中不足的地方是多了一个多了一个>
原因是
接下来第四个功能:是分页展示数据 也是本项目的难点之一
3.分页展示功能的准备工作
分页逻辑
了解分页逻辑之后,我们需要在util包创建一个工具类PageUtil
package util; public class PageUtil { //页码值 public static final int PAGESIZE=3; }
修改success页面代码
<input type="button" value="查询用户列表" onclick="javascript:location.href='/selectusers?pageindex=1'">
ps:这里用index而不是page,因为page是jsp页面的内置对象,为了区分开,所以我们选用了index作为参数,这时候我们就需要接收参数了,先从SelectUsersServlet处理类开始改代码
4.分页展示功能的代码实现
思路:页面请求—>servlet处理类调取service ,service 调取dao, dao操作bean
1.SelectUsersServlet接收参数index
public class SelectUsersServlet extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //接参数 String pageindex = req.getParameter("pageindex"); int index =Integer.parseInt(pageindex); //写逻辑 UsersService usersService=new UsersServiceImpl(); List<Users> users=usersService.selectAll(); //返结果 req.setAttribute("ulist",users); req.getRequestDispatcher("/list.jsp").forward(req,resp); } }
2.修改UsersService与UsersDao的selectUsers方法以及他们的Impl实现类
给这个方法加两个参数,一个是页码值,一个是每页展示多少数据
//查询全部的方法 public List<Users> selectAll(int pageindex,int size);
修改UsersServiceImpl实现类
@Override public List<Users> selectAll(int pageIndex,int size) { return usersDao.selectAll(pageIndex,size); }
修改UsersDaoImp实现类
@Override public List<Users> selectAll(int pageIndex,int size) { //既然是查询,还是要用到selectDB(sql,params)这个方法 //那就要先得到这两个参数 List userList = new ArrayList(); try { String sql="select * from users limit ?,?"; //userList就是params List params = new ArrayList(); params.add((pageIndex-1)*size); params.add(size); resultSet=selectDB(sql,params); while(resultSet.next()){ Users u1 =new Users(); u1.setUserid(resultSet.getInt("userid")); u1.setSex(resultSet.getString("username")); u1.setAge(resultSet.getInt("age")); u1.setPassword(resultSet.getString("sex")); u1.setUsername(resultSet.getString("password")); userList.add(u1); } } catch (SQLException e) { e.printStackTrace(); }finally { closeAll(); } return userList; }
3.SelectUsersServlet返回index(后端给前端传数据值)
设计存值问题我们给当前页面一个名字pindex
import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.List; public class SelectUsersServlet extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //接参数 String pageindex = req.getParameter("pageindex"); int index =Integer.parseInt(pageindex); //写逻辑 UsersService usersService=new UsersServiceImpl(); List<Users> users=usersService.selectAll(index, PageUtil.PAGESIZE); //返结果(后端给前端传数据,必然涉及到存值问题) req.setAttribute("ulist",users); req.setAttribute("pindex",index); req.getRequestDispatcher("/list.jsp").forward(req,resp); } }
4.返回结果页面
<%@ page import="bean.Users" %> <%@ page import="java.util.List" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <% Users u1 =(Users) session.getAttribute("u1"); %> <h1>list.jsp,<%=u1==null?"":u1.getUsername()%>欢迎您:</h1> <% List<Users> ulist = (List<Users>)request.getAttribute("ulist"); int pindex=(Integer)request.getAttribute("pindex"); %> <table border="1" cellspacing="0" width="500"> <tr> <td>用户编号</td> <td>用户姓名</td> <td>用户性别</td> <td>用户年龄</td> <td>用户密码</td> <td>操作</td> </tr> <%for (Users u:ulist){%> <tr> <td><%=u.getUserid()%></td> <td><%=u.getUsername()%></td> <td><%=u.getSex()%></td> <td><%=u.getAge()%></td> <td><%=u.getPassword()%></td> </tr> <%}%> <tr> <td colspan="5"> <a href="/selectusers?pageindex=1">首页</a> <a href="/selectusers?pageindex=<%=pindex-1<=1?1:pindex-1%>">上一页</a> <a href="/selectusers?pageindex=<%=pindex+1%>">下一页</a> <a href="/selectusers">尾页</a> 当前页:<%=pindex%> </td> </tr> </table>> </body> </html>
此时功能已经实现,但是还有问题,尾页没有进行限制,因为我们还需要有一个新的方法。查询所有,知道有多少条数据,才能控制总页数。
bug1:无限点下一页
bug2:尾页
5.功能踩坑
踩坑原因:sql语句格式错误
这里当时少一个空格
6.完善下一页与尾页限制功能
思路:页面请求—>servlet处理类调取service ,service 调取dao, dao操作bean
1.定义查询总数据的方法,以及他们的实现类
UsersService与UsersDao的selectUsers方法中定义方法
//查询总条数 public int totalCount();
2.UsersServiceImpl实现类
@Override public int totalCount() { return usersDao.totalCount(); }
3.UsersDaoImpl实现类
@Override public int totalCount() { int count=0; try { String sql="select count(*) from users where status=0"; resultSet=selectDB(sql,null); while(resultSet.next()){ //int count=resultSet.getInt("count(*)"); count=resultSet.getInt(1);//列的位置从1开始数 } } catch (SQLException e) { e.printStackTrace(); } finally { closeAll(); } return count; }
4.SelectUsersServlet返回index(后端给前端传数据值)
package web; import bean.Users; import service.UsersService; import service.impl.UsersServiceImpl; import util.PageUtil; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.List; public class SelectUsersServlet extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //接参数 String pageindex = req.getParameter("pageindex"); int index =Integer.parseInt(pageindex); //写逻辑 UsersService usersService=new UsersServiceImpl(); List<Users> users=usersService.selectAll(index,PageUtil.PAGESIZE); // 每页展示数据时,不够一页,也会单独占一页的位置 //总页数=总条数%每页显示条数>0?总条数/每页显示条数+1:总条数/每页显示条数 int total = usersService.totalCount(); int totalPages=total%PageUtil.PAGESIZE>0?total/PageUtil.PAGESIZE+1:total/PageUtil.PAGESIZE; //返结果(后端给前端传数据,必然涉及到存值问题) req.setAttribute("ulist",users); req.setAttribute("pindex",index); req.setAttribute("totalCount",total); req.setAttribute("totalpages",totalPages); req.getRequestDispatcher("/list.jsp").forward(req,resp); } }
5.返回结果页面
<%@ page import="bean.Users" %> <%@ page import="java.util.List" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <% Users u1 =(Users) session.getAttribute("u1"); %> <h1>list.jsp,<%=u1==null?"":u1.getUsername()%>欢迎您:</h1> <% List<Users> ulist=(List<Users>)request.getAttribute("ulist"); int pindex= (Integer)request.getAttribute("pindex"); int totalCount = (Integer)request.getAttribute("totalCount"); int totalPages = (Integer)request.getAttribute("totalPages"); %> <table border="1" cellspacing="0" width="500"> <tr> <td>用户编号</td> <td>用户姓名</td> <td>用户性别</td> <td>用户年龄</td> <td>用户密码</td> </tr> <%for (Users u:ulist){%> <tr> <td><%=u.getUserid()%></td> <td><%=u.getUsername()%></td> <td><%=u.getSex()%></td> <td><%=u.getAge()%></td> <td><%=u.getPassword()%></td> </tr> <%}%> <tr> <td colspan="5"> <a href="/selectusers?pageindex=1">首页</a> <a href="/selectusers?pageindex=<%=pindex-1<=1?1:pindex-1%>">上一页</a> <a href="/selectusers?pageindex=<%=pindex+1>=totalPages?totalPages:pindex+1%>">下一页</a> <a href="/selectusers?pageindex=<%=totalPages%>">尾页</a> 当前页:<%=pindex%> 总页数:<%=totalPages%>, 总条数:<%=totalCount%> </td> </tr> </table> </body> </html>
6最终测试结果
后续内容会持续更新