下面来说一个问题,就是对于一张表的操作,涉及到了很多的servlet页面
比如对于一个user表,里面有很多的相关的servlet页面
如果是这样一种情况,那么user表涉及到七八个页面,category表又涉及到七八个页面,那么整个项目下来servlet页面会多的不计其数。所以我们必须想个办法减少servlet的数量。
先来说一下页面实现原理
看一下servlet的实现原理
先来做一个都兜底的页面BaseServlet,他必须是一个Servlet,所以必须继承HttpServlet页面
先来说一下这个页面的设计思想
再来说一下在BaseServlet页面中service方法的设计原理
先来看兜底servlet 页面
BaseServlet
package web.servlet;
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.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@WebServlet("/baseServlet")
public class BaseServlet extends HttpServlet {
//重写一下sevice方法
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取资源请求路径
//getRequestURI
String uri = req.getRequestURI();
//获取路径中某个具体方法
//针对于这个项目的uri可能会返回/travel/user/add
//我们要的就是add这个方法名
String methodName = uri.substring(uri.lastIndexOf('/') + 1);
//获取方法对象的method
//之前就说了,比如访问UserServlet,调用service方法的就是UserServlet对象
//利用反射技术来做
try {
Method method = this.getClass().getDeclaredMethod(methodName,HttpServletRequest.class,HttpServletResponse.class);
//暴力反射
//method.setAccessible(true);
//执行方法
method.invoke(this,req,resp);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
再来看其他两个servlet页面
这里多说一点,一个servlet本质是一个Java开发的小程序,只有servlet页面的java文件才能识别,我们知道servlet里面有两个对象,一个request对象,一个response对象,这两个对象,可以接收和处理前端传过来的数据。这个对象也可以写到我们自己定义的方法里面去。
UserServlet
package web.servlet;
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;
@WebServlet("/user/*")//给一个路径信息
public class UserServlet extends BaseServlet {
protected void add(HttpServletRequest req, HttpServletResponse resp) {
System.out.println("这是UserServlet中的add()方法");
}
protected void minus(HttpServletRequest req, HttpServletResponse resp) {
System.out.println("这是userServlet中的minus()方法");
}
}
CategoryServlet
package web.servlet;
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;
@WebServlet("/category/*")
public class CategoryServlet extends BaseServlet {
protected void say(HttpServletRequest req, HttpServletResponse resp) {
System.out.println("这是category中的say()方法");
}
protected void talk(HttpServletRequest req, HttpServletResponse resp) {
System.out.println("这是userServlet中的minus()方法");
}
}
再来运行测试一下程序
我们还可以调佣category表的相关操作
上面这个兜底文件的代码还存在一定的问题
在servlet里面,有些方法是不想被比人访问的,如果采用getDeclaredMethod这样来做,所有的相关方法对象都能被获取,然后在暴力破解一下,就能访问
所以改动一下
获取方法对象的函数就设置成getMethod,只能获取public修饰的方法
然后在相关的servlet页面里面,我们把方法修饰符全部变成public
这里就不贴代码在这个地方了
下面我们利用上面的方法把项目的页面路径改写一下
怎么改也很简单,把之前做的servlet单独抽成一个方法放在UserServlet里面就行
UserServlet
package web.servlet;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import domain.ResultInfo;
import domain.User;
import org.apache.commons.beanutils.BeanUtils;
import service.UserService;
import service.impl.UserServiceImpl;
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.lang.reflect.InvocationTargetException;
import java.util.Map;
@WebServlet("/user/*")//给一个路径信息
public class UserServlet extends BaseServlet {
//每一个方法都需要用到UserService这个业务对象
private UserService service = new UserServiceImpl();
private ResultInfo info = new ResultInfo();
private ObjectMapper objectMapper = new ObjectMapper();
/**
*
* @param request
* @param response
*/
public void regist(HttpServletRequest request, HttpServletResponse response) throws IOException {
//验证校验
String check = request.getParameter("check");
//从session中获取验证码
//这个是做验证码的时候,就给我们放到服务器里面了
String checkcodeServer = (String)request.getSession().getAttribute("CHECKCODE_SERVER");
//这里判断一下验证码是否是正确的,如果不正确,直接return结束
if(checkcodeServer == null || !check.equalsIgnoreCase(checkcodeServer)) {
//这里验证码错误
//还是调用一个后端结果信息处理对象
ResultInfo info = new ResultInfo();
info.setFlag(false);
info.setErrorMsg("验证码错误");
//将resultInfo对象转变为json对象,响应给请求端
ObjectMapper objectMapper = new ObjectMapper();
String json = objectMapper.writeValueAsString(info);
//设置响应格式并且传送数据
response.setContentType("application/json;charset=utf-8");
response.getWriter().write(json);
//让程序在这个位置结束,不往下执行了
return;
}
//获取从前端传过来的数据
Map<String,String[]> map = request.getParameterMap();
//把这些集合数据封装成一个对象
//这里利用BeanUtils工具
User user = new User();//这个user类之前就已经做好了
try {
BeanUtils.populate(user,map);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
//内部我们先假定存在一个regist方法
boolean flag = service.regist(user);
//响应结果
//注册成功返回true,失败返回false
if(flag) {
//成功
//成功
info.setFlag(true);
} else {
info.setFlag(false);
info.setErrorMsg("注册失败了");
}
String json = objectMapper.writeValueAsString(info);
//将json数据写回给客户端
response.setContentType("application/json;charset=utf-8");
response.getWriter().write(json);
}
public void login(HttpServletRequest request, HttpServletResponse response) throws IOException {
//先来判断一下验证码是否正确,否则一切不用说了
//根据前端name属性来获取验证码
String checkCode = request.getParameter("check");
//从session中获取验证码
String checkCodeServer = (String)request.getSession().getAttribute("CHECKCODE_SERVER");
//需要一个处理信息的对象
//后面会把这个对象变成json数据格式返回给用户
response.setContentType("application/json;charset=utf-8");
//然后来判断一下验证码是否输入正确
if(checkCode == null || !checkCode.equalsIgnoreCase(checkCodeServer)) {
//验证码出错,直接在这个里面卡死程序
info.setFlag(false);
info.setErrorMsg("验证码错误");
//变为json数据格式传给客户端
String json = objectMapper.writeValueAsString(info);
//回写到客户端里面去
response.getWriter().write(json);
return;
}
//在把从前端拿到数据变成map集合,然后利用BeanUtils对象进行封装
Map<String,String[]> map = request.getParameterMap();
User user = new User();
try {
BeanUtils.populate(user,map);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
User u = service.login(user);//传入这个对象,然后从数据库中看看有没有这个用户
//如果查询不到用户
if(u == null) {
info.setFlag(false);
info.setErrorMsg("用户名或者密码错误");
}
//另外需要判断的就是用户是否被激活
if(u != null && !"Y".equals(u.getStatus())) {
info.setFlag(false);
info.setErrorMsg("您还没有被激活,请激活");
}
//考虑一下登录成功的情况下
if(u != null && "Y".equals(u.getStatus())) {
//登录成功,给一个session标志,好追踪
request.getSession().setAttribute("user",u);
//返回一个标志true
//然后返回login.html之后,会跳转到首页
info.setFlag(true);
}
//返回数据
objectMapper.writeValue(response.getOutputStream(),info);
}
public void exit(HttpServletRequest request, HttpServletResponse response) throws IOException {
//销毁session对象
request.getSession().invalidate();
//直接重定向页面,注意重定向的路径必须写全
//直接跳转到登录页面
response.sendRedirect(request.getContextPath()+"/login.html");
}
public void active(HttpServletRequest request, HttpServletResponse response) throws IOException {
//这里要拿到激活码
String codeString = request.getParameter("code");
if (codeString != null) {
//如果存在用户,然后才来激活
boolean flag = service.active(codeString);
String msg = null;
//根据结果集的结果进行处理
if (flag) {
//成功,就提示跳转到登录页面
msg = "激活成功,请<a href = 'login.html'>登录</a>";
} else {
//失败,就提示联系管理员
msg = "激活失败,请联系管理员";
}
//把数据响应给客户端
response.getWriter().write(msg);//向客户端回写数据
}
}
/**
* 通过session查询单个对象
* @param request
* @param response
* @throws IOException
*/
public void findOne(HttpServletRequest request, HttpServletResponse response) throws IOException {
//拿到存储在服务器的对象的session
Object user = request.getSession().getAttribute("user");
response.setContentType("application/json;charset=utf-8");
objectMapper.writeValue(response.getOutputStream(),user);
}
}
把前端一些页面路径也做一些相应的更改
register.html
header.html
login.html
上面路径写错了,/user/login最前面不要加/,我就不重新改动了,另外还需要修改的地方,邮件激活
下面测试运行一下
把这条数据插入到数据库里面
查询数据库发现已经插进去了,只是激活状态码还没有修改过来
现在去点击邮件激活
激活成功变成Y了
下面主要做旅游的一些主体功能
功能1:分类数据展示功能
换句话说,就是上面的的这些功能展示我们要从数据库中获取
这个功能就不是tab_user表的功能了,所以我们不在UserServlet中实现。
那这个功能,重点体现在什么表里
体现在这个叫tab_category表里面
所以,我们需要做一个 Category的servlet,然后里面写上与这张表相关的方法
那么来说一下,分类数据展示功能的设计原理
先来修改一下BaseServlet页面,这个servlet的兜底页面,里面我们需要添加几个方法进去,原因在于,我们之前在写程序的时候,遇到很多次我们需要把把当前的数据变成json对象,然后返回给前端来使用。也就是如下代码
这段代码在每一个方法中的复用率太高了,我把他写到BaseServlet里面去,以后所有的servlet都可以去调用这两个方法
所以,之前在UserServlet中的业务代码就可以进行修改了
这里我是把ObjectMapper对象拿出来了,既然在BaseServlet文件里面有方法了,这些都将可以省略不要了。
直接调用writeValue这个方法就回写了
修改之后的UserServlet.java页面代码
package web.servlet;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import domain.ResultInfo;
import domain.User;
import org.apache.commons.beanutils.BeanUtils;
import service.UserService;
import service.impl.UserServiceImpl;
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.lang.reflect.InvocationTargetException;
import java.util.Map;
@WebServlet("/user/*")//给一个路径信息
public class UserServlet extends BaseServlet {
//每一个方法都需要用到UserService这个业务对象
private UserService service = new UserServiceImpl();
private ResultInfo info = new ResultInfo();
/**
*
* @param request
* @param response
*/
public void regist(HttpServletRequest request, HttpServletResponse response) throws IOException {
//验证校验
String check = request.getParameter("check");
//从session中获取验证码
//这个是做验证码的时候,就给我们放到服务器里面了
String checkcodeServer = (String)request.getSession().getAttribute("CHECKCODE_SERVER");
//这里判断一下验证码是否是正确的,如果不正确,直接return结束
if(checkcodeServer == null || !check.equalsIgnoreCase(checkcodeServer)) {
//这里验证码错误
//还是调用一个后端结果信息处理对象
ResultInfo info = new ResultInfo();
info.setFlag(false);
info.setErrorMsg("验证码错误");
//向客户端回写数据
writeValue(info,response);
//让程序在这个位置结束,不往下执行了
return;
}
//获取从前端传过来的数据
Map<String,String[]> map = request.getParameterMap();
//把这些集合数据封装成一个对象
//这里利用BeanUtils工具
User user = new User();//这个user类之前就已经做好了
try {
BeanUtils.populate(user,map);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
//内部我们先假定存在一个regist方法
boolean flag = service.regist(user);
//响应结果
//注册成功返回true,失败返回false
if(flag) {
//成功
//成功
info.setFlag(true);
} else {
info.setFlag(false);
info.setErrorMsg("注册失败了");
}
String json = writeValueAsString(info);
//将json数据写回给客户端
response.setContentType("application/json;charset=utf-8");
response.getWriter().write(json);
}
public void login(HttpServletRequest request, HttpServletResponse response) throws IOException {
//先来判断一下验证码是否正确,否则一切不用说了
//根据前端name属性来获取验证码
String checkCode = request.getParameter("check");
//从session中获取验证码
String checkCodeServer = (String)request.getSession().getAttribute("CHECKCODE_SERVER");
//需要一个处理信息的对象
//后面会把这个对象变成json数据格式返回给用户
response.setContentType("application/json;charset=utf-8");
//然后来判断一下验证码是否输入正确
if(checkCode == null || !checkCode.equalsIgnoreCase(checkCodeServer)) {
//验证码出错,直接在这个里面卡死程序
info.setFlag(false);
info.setErrorMsg("验证码错误");
writeValue(info,response);
return;
}
//在把从前端拿到数据变成map集合,然后利用BeanUtils对象进行封装
Map<String,String[]> map = request.getParameterMap();
User user = new User();
try {
BeanUtils.populate(user,map);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
User u = service.login(user);//传入这个对象,然后从数据库中看看有没有这个用户
//如果查询不到用户
if(u == null) {
info.setFlag(false);
info.setErrorMsg("用户名或者密码错误");
}
//另外需要判断的就是用户是否被激活
if(u != null && !"Y".equals(u.getStatus())) {
info.setFlag(false);
info.setErrorMsg("您还没有被激活,请激活");
}
//考虑一下登录成功的情况下
if(u != null && "Y".equals(u.getStatus())) {
//登录成功,给一个session标志,好追踪
request.getSession().setAttribute("user",u);
//返回一个标志true
//然后返回login.html之后,会跳转到首页
info.setFlag(true);
}
//返回数据
writeValue(info,response);
}
public void exit(HttpServletRequest request, HttpServletResponse response) throws IOException {
//销毁session对象
request.getSession().invalidate();
//直接重定向页面,注意重定向的路径必须写全
//直接跳转到登录页面
response.sendRedirect(request.getContextPath()+"/login.html");
}
public void active(HttpServletRequest request, HttpServletResponse response) throws IOException {
//这里要拿到激活码
String codeString = request.getParameter("code");
if (codeString != null) {
//如果存在用户,然后才来激活
boolean flag = service.active(codeString);
String msg = null;
//根据结果集的结果进行处理
if (flag) {
//成功,就提示跳转到登录页面
msg = "激活成功,请<a href = 'login.html'>登录</a>";
} else {
//失败,就提示联系管理员
msg = "激活失败,请联系管理员";
}
//把数据响应给客户端
response.getWriter().write(msg);//向客户端回写数据
}
}
/**
* 通过session查询单个对象
* @param request
* @param response
* @throws IOException
*/
public void findOne(HttpServletRequest request, HttpServletResponse response) throws IOException {
//拿到存储在服务器的对象的session
Object user = request.getSession().getAttribute("user");
response.setContentType("application/json;charset=utf-8");
writeValue(user,response);
}
}
再来说回正题
先来写CategoryServlet页面、
然后看看CategoryService页面与CategoryServiceImpl页面
下面再去看dao层的CategoryDao页面与CategoryDaoImpl页面
然后去修改前台页面header.html
这个里面的li标签全部都要注释掉
然后在header.html顶部,页面加载完成后,调用ajax进行异步的请求处理
做好了之后,我们来测试一下
这里可以自行测试,页面只要只要正常显示,说明你的代码没问题
下面说一个问题,我们每一次去访问这个页面,她都会去dao层访问一个方法findAll
也就是说会不停的去select数据库,但是这部分的数据又不是那种会经常发生变化的,所以,我们在这里对分类数据进行一个缓存优化操作,那么我们这里想到的就是redis缓存数据库
原理也就是说,第一次从数据库拿到数据之后,然后就把数据存储到redis数据库里面
在CategoryServiceImpl中修改代码
package service.impl;
import dao.CategoryDao;
import dao.impl.CategoryDaoImpl;
import domain.Category;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Tuple;
import service.CategoryService;
import util.JedisUtil;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
public class CategoryServiceImpl implements CategoryService {
//会去调用dao层中具体的数据库方法
CategoryDao categoryDao = new CategoryDaoImpl();
@Override
public List<Category> findAll() {
//先从redis中查找数据
//需要一个redis的连接工具
Jedis jedis = JedisUtil.getJedis();
Set<Tuple> res = jedis.zrangeWithScores("category",0,-1);
List<Category> cs = null;
//然后来判断这个结果集是否存在
if(res == null && res.size() == 0) {
System.out.println("从数据库查询");
//这种情况数据没有,走数据库查询
//然后把数据添加到redis数据里面
cs = categoryDao.findAll();
//集合对象需要遍历拿出
for(int i = 0;i < cs.size();i++) {
//有几条对象插几条进来
jedis.zadd("category",cs.get(i).getCid(),cs.get(i).getCname());
}
} else {
System.out.println("从redis中查询");
cs = new ArrayList<Category>();
//把set集合中的数据插入到List集合里面,然后返回
for(Tuple data : res) {
//Tuple里面有id与name
Category category = new Category();
int score = (int)data.getScore();
String str = data.getElement();
category.setCid(score);
category.setCname(str);
cs.add(category);
}
}
return cs;
}
}
测试这个代码之前,必须把redis服务器给打开
刚开始redis里面还没有数据,后来运行一下就有了
并且第一次访问是从数据库查询的
在把这个页面运行一次
这样就极大减轻了数据库的压力
下面来做旅游线路的一个分页展示
这里涉及到两张表,一张是旅游线路表tab_route,另外一张是分类表tab_category表
利用sqlyog来看一下两张表之间的关系
把你想要有关系的表,直接拖进来就行了
直接给我们生成了一个一对多的关系
这个页面的语句大概处理方式就是,根据不同的cid来找不同的路线
select * from tab_route where cid = ?
这些li提交的位置都是route_list.html页面,那么他又是根据cid来区分页面的,所以,我们要子啊route_list.html页面里面获取一下cid这个东西
在js的location对象中有那么一个方法
获取一个url问号后面的部分
去访问一下上面这个route_list.html页面
下面来做根据id查询不同类别的旅游线路
分页展示旅游线路数据
我们需要用分页的效果来展示
1.创建一下PageBean这个对象
package domain;
import java.util.List;
/**
* 分页对象
*/
public class PageBean<T> {
private int totalCount;//总记录数
private int totalPage;//总页数
private int currentPage;//当前页码
private int pageSize;//每页显示的条数
private List<T> list;//每页显示的数据集合
public int getTotalCount() {
return totalCount;
}
public void setTotalCount(int totalCount) {
this.totalCount = totalCount;
}
public int getTotalPage() {
return totalPage;
}
public void setTotalPage(int totalPage) {
this.totalPage = totalPage;
}
public int getCurrentPage() {
return currentPage;
}
public void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public List<T> getList() {
return list;
}
public void setList(List<T> list) {
this.list = list;
}
}
下面开始进行代码编写
1.先来写服务器代码的编写
旅游路线展示的相关操作,是和route表相关的,所以,我们建立的servlet,service,dao都是与这张表相关联的
先来做一个RouteServlet页面
package web.servlet;
import domain.PageBean;
import domain.Route;
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;
@WebServlet("/route/*")
public class RouteServlet extends BaseServlet {
//这里需要调用service来chauxn
private RouteService routeService = new RouteServiceImpl();
/**
* 分页查询功能
* @param request
* @param response
* @throws ServletException
* @throws IOException
*/
public void pageQuery(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.接收参数
String currentPageStr = request.getParameter("currentPage");
String pageSizeStr = request.getParameter("pageSize");
String cidStr = request.getParameter("cid");
int cid = 0;
//参数处理
if(cidStr != null && cidStr.length() > 0) {
cid = Integer.parseInt(cidStr);
}
int currentPage = 1;//当前页面默认为第一页
if(currentPageStr != null && currentPageStr.length() > 0) {
currentPage = Integer.parseInt(currentPageStr);
}
int pageSize = 5;
if(pageSizeStr != null && pageSizeStr.length() > 0) {
pageSize = Integer.parseInt(pageSizeStr);
}
//3.调用service查询PageBean对象
//这个route封装的是一个数据库的查询信息
PageBean<Route> pb = routeService.pageQuery(cid,currentPage,pageSize);
//4.将pageBean对象序列化为json数据返回
writeValue(pb,response);
}
}
然后去把RouteService与RouteServiceImpl完成
RouteService
package web.servlet;
import domain.PageBean;
import domain.Route;
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;
@WebServlet("/route/*")
public class RouteServlet extends BaseServlet {
//这里需要调用service来chauxn
private RouteService routeService = new RouteServiceImpl();
/**
* 分页查询功能
* @param request
* @param response
* @throws ServletException
* @throws IOException
*/
public void pageQuery(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.接收参数
String currentPageStr = request.getParameter("currentPage");
String pageSizeStr = request.getParameter("pageSize");
String cidStr = request.getParameter("cid");
int cid = 0;
//参数处理
if(cidStr != null && cidStr.length() > 0) {
cid = Integer.parseInt(cidStr);
}
int currentPage = 1;//当前页面默认为第一页
if(currentPageStr != null && currentPageStr.length() > 0) {
currentPage = Integer.parseInt(currentPageStr);
}
int pageSize = 5;
if(pageSizeStr != null && pageSizeStr.length() > 0) {
pageSize = Integer.parseInt(pageSizeStr);
}
//3.调用service查询PageBean对象
//这个route封装的是一个数据库的查询信息
PageBean<Route> pb = routeService.pageQuery(cid,currentPage,pageSize);
//4.将pageBean对象序列化为json数据返回
writeValue(pb,response);
}
}
RouteServiceImpl
package service.impl;
import domain.PageBean;
import domain.Route;
import service.RouteService;
import java.util.List;
public class RouteServiceImpl implements RouteService {
//需要一个dao层对象去查找数据库
private RouteDao routeDao = new RouteDaoImpl();
@Override
public PageBean<Route> pageQuery(int cid, int currentPage, int pageSize) {
PageBean<Route> pb = new PageBean<Route>();
//考虑一下service层返回什么数据
//把所有数据集给封装到一个PageBean对象里面
//设置当前页码
pb.setCurrentPage(currentPage);
//设置每页显示条数
pb.setPageSize(pageSize);
//得到每个栏目的总记录数
int totalCount = routeDao.findTotalCount(cid);
pb.setTotalCount(totalCount);
//设置当前页面显示的数据集合
//也就是把一个数据库里面的一个route对象给封装进去
//这个currentPage是从前端页面传过来的
int start = (currentPage - 1) * pageSize;
List<Route> list = routeDao.findByPage(cid,start,pageSize) ;
//下面设置一下总页数
//总页数= 总记录数/每页显示的条数 如果除不尽加一页
int totalPage = totalCount % pageSize == 0 ? totalCount % pageSize : (totalCount / pageSize) + 1;
pb.setTotalPage(totalPage);
return pb;
}
}
上面针对于limit start,end中,start的某个细节进行Fenix
下面去实现一下dao层里面的东西
RouteDao
package dao;
import domain.Route;
import java.util.List;
public interface RouteDao {
int findTotalCount(int cid);
List<Route> findByPage(int cid, int start, int pageSize);
}
RouteDaoImpl
package dao.impl;
import dao.RouteDao;
import domain.Route;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import util.JDBCUtils;
import java.util.List;
public class RouteDaoImpl implements RouteDao {
private JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource());
//根据某一个分类来查看有多少个数据
@Override
public int findTotalCount(int cid) {
String sql = "select count(*) from tab_route where cid = ?";
return jdbcTemplate.queryForObject(sql,Integer.class,cid);
}
@Override
public List<Route> findByPage(int cid, int start, int pageSize) {
String sql = "select * from tab_route where cid = ? limit ?,?";
return jdbcTemplate.query(sql,new BeanPropertyRowMapper<Route>(Route.class),cid,start,pageSize);
}
}
上面就是后台代码的实现,下面来做前台代码
route_list.html页面
先来探讨几个问题:
第一个核心查询方法:
limit后面的第二个问号是要查询几条数据出来,也就是对应的变量是pageSize,那么就有一个问题就是,这个pageSize是从什么地方传进来的?
因为在进行Ajax请求的时候,我们回去访问/route/*,也就是一个pageQuery方法,这个方法内部会接收三个参数,如下
但是我们在对ajax请求的时候,只传递了两个参数,如下:
那么pageSize从哪里来,
在回到我们的RouteServlet里面,我们可以看到对于pageSize这个参数,会给我们设置一个默认值
所以,我们即使看不到pageSize被传递也是有默认值的
另外再来说一下分页的设计原理
下面再来解决数据传输回来data is null的问题
其实就是忘了给pb对象设置给list这个属性
目前来说,在数据库里面只有cid=5这个栏目有数据显示。其他栏目你点进去也是没有数据的