[TOC]
## 步骤 1 : 目前的分页方式
目前的分页方式是自己写分页对应的limit SQL语句,并且提供一个获取总数的count(*) SQL。 不仅如此, mapper, service, service.impl 里都要提供两个方法:
list(Page page), count()
分类是这么做的,后续其他所有的实体类要做分页管理的时候都要这么做,所以为了提高开发效率,把目前的分页方式改为使用 pageHelper分页插件来实现。
对于pageHelper插件不熟悉的同学请参考: **SSM中使用PageHelper**
## 步骤 2 : CategoryMapper.xml
1. 去掉total SQL语句
2. 修改list SQL语句,去掉其中的limit
~~~
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.dodoke.tmall.mapper.CategoryMapper">
<select id="list" resultType="Category">
select * from t_category order by id desc
</select>
<insert id="add" keyProperty="id" useGeneratedKeys="true" parameterType="Category">
insert into t_category(name) values(#{name})
</insert>
<delete id="delete">
delete from t_category where id=#{id}
</delete>
<select id="get" resultType="Category">
select * from t_category where id=#{id}
</select>
<update id="update" parameterType="Category">
update t_category set name=#{name} where id=#{id}
</update>
</mapper>
~~~
## 步骤 3 : CategoryMapper
1. 去掉total()方法
2. 去掉list(Page page)方法
3. 新增list() 方法
~~~
package com.dodoke.tmall.mapper;
import java.util.List;
import com.dodoke.tmall.pojo.Category;
public interface CategoryMapper {
List<Category> list();
void add(Category category);
void delete(int id);
Category get(int id);
void update(Category category);
}
~~~
## 步骤 4 : CategoryService
1. 去掉total()方法
2. 去掉list(Page page)方法
3. 新增list() 方法
~~~
package com.dodoke.tmall.service;
import java.util.List;
import com.dodoke.tmall.pojo.Category;
public interface CategoryService {
List<Category> list();
void add(Category category);
void delete(int id);
Category get(int id);
void update(Category category);
}
~~~
## 步骤 5 : CategoryServiceImpl
1. 去掉total()方法
2. 去掉list(Page page)方法
3. 新增list() 方法
~~~
package com.dodoke.tmall.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.dodoke.tmall.mapper.CategoryMapper;
import com.dodoke.tmall.pojo.Category;
import com.dodoke.tmall.service.CategoryService;
@Service
public class CategoryServiceImpl implements CategoryService {
@Autowired
CategoryMapper categoryMapper;
@Override
public List<Category> list() {
return categoryMapper.list();
}
@Override
public void add(Category category) {
categoryMapper.add(category);
}
@Override
public void delete(int id) {
categoryMapper.delete(id);
}
@Override
public Category get(int id) {
return categoryMapper.get(id);
}
@Override
public void update(Category category) {
categoryMapper.update(category);
}
}
~~~
## 步骤 6 : CategoryController
修改list方法
1. 通过分页插件指定分页参数
PageHelper.offsetPage(page.getStart(),page.getCount());
2. 调用list() 获取对应分页的数据
categoryService.list();
3. 通过PageInfo获取总数
int total = (int) new PageInfo<>(cs).getTotal();
其余部分没有变化
~~~
package com.dodoke.tmall.controller;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import com.dodoke.tmall.pojo.Category;
import com.dodoke.tmall.service.CategoryService;
import com.dodoke.tmall.util.ImageUtil;
import com.dodoke.tmall.util.Page;
import com.dodoke.tmall.util.UploadedImageFile;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
@RequestMapping("")
@Controller
public class CategoryController {
@Autowired
CategoryService categoryService;
@RequestMapping("admin_category_list")
public String list(Model model,Page page) {
// 通过分页插件指定分页参数
PageHelper.offsetPage(page.getStart(),page.getCount());
// 调用list() 获取对应分页的数据
List<Category> cs = categoryService.list();
// 通过PageInfo获取总数
int total = (int) new PageInfo<>(cs).getTotal();
page.setTotal(total);
model.addAttribute("cs", cs);
model.addAttribute("page",page);
return "admin/listCategory";
}
/**
* 新增分类
* @param c 分类对象
* @param session 用于在后续获取当前应用的路径
* @param uploadedImageFile 用于接受上传的图片
* @return 页面路径
* @throws IOException
*/
@RequestMapping("admin_category_add")
public String add(Category c, HttpSession session, UploadedImageFile uploadedImageFile) throws IOException {
// 新增分类
categoryService.add(c);
// 通过session获取ControllerContext,再通过getRealPath定位存放分类图片的路径。
File imageFolder= new File(session.getServletContext().getRealPath("img/category"));
// 根据分类id创建文件名
File file = new File(imageFolder,c.getId() + ".jpg");
// 如果/img/category目录不存在,则创建该目录,否则后续保存浏览器传过来图片,会提示无法保存
if(!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
System.out.println(file);
// 通过UploadedImageFile 把浏览器传递过来的图片保存在上述指定的位置
uploadedImageFile.getImage().transferTo(file);
// 通过ImageUtil.change2jpg(file); 确保图片格式一定是jpg,而不仅仅是后缀名是jpg.
BufferedImage img = ImageUtil.change2jpg(file);
// 写入图片
ImageIO.write(img, "jpg", file);
// 客户端跳转到admin_category_list
return "redirect:/admin_category_list";
}
/**
* 删除分类
* @param id 分类id
* @param session 用于在后续获取当前应用的路径
* @return 页面路径
* @throws IOException
*/
@RequestMapping("admin_category_delete")
public String delete(int id,HttpSession session) throws IOException {
categoryService.delete(id);
File imageFolder= new File(session.getServletContext().getRealPath("img/category"));
File file = new File(imageFolder,id+".jpg");
file.delete();
return "redirect:/admin_category_list";
}
/**
* 根据id,查询分类信息
* @param id 分类id
* @param model 模型
* @return 页面路径
* @throws IOException
*/
@RequestMapping("admin_category_edit")
public String edit(int id,Model model) throws IOException {
Category c= categoryService.get(id);
model.addAttribute("c", c);
return "admin/editCategory";
}
/**
* 更新分类
* @param c 接受页面提交的分类名称
* @param session 用于在后续获取当前应用的路径
* @param uploadedImageFile 用于接受上传的图片
* @return 页面路径
* @throws IOException
*/
@RequestMapping("admin_category_update")
public String update(Category c, HttpSession session, UploadedImageFile uploadedImageFile) throws IOException {
// 更新分类
categoryService.update(c);
MultipartFile image = uploadedImageFile.getImage();
// 判断是否有图片上传
if(null!=image &&!image.isEmpty()){
File imageFolder= new File(session.getServletContext().getRealPath("img/category"));
// 根据分类id创建文件
File file = new File(imageFolder,c.getId()+".jpg");
// 把浏览器传递过来的图片保存在上述指定的位置
image.transferTo(file);
// 确保图片格式一定是jpg,而不仅仅是后缀名是jpg.
BufferedImage img = ImageUtil.change2jpg(file);
// 覆盖图片
ImageIO.write(img, "jpg", file);
}
// 客户端跳转到admin_category_list
return "redirect:/admin_category_list";
}
}
~~~
## 步骤 7 : 修改applicationContext.xml
applicationContext.xml中关于插件部分本来是被注释掉的,现在释放出来
~~~
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<context:annotation-config />
<context:component-scan base-package="com.dodoke.tmall.service" />
<!-- 导入数据库配置文件 -->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- 配置数据库连接池 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<!-- 基本属性 url、user、password -->
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<!-- 配置初始化大小、最小、最大 -->
<property name="initialSize" value="1" />
<property name="minIdle" value="1" />
<property name="maxActive" value="20" />
<!-- 配置获取连接等待超时的时间 -->
<property name="maxWait" value="60000" />
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000" />
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="300000" />
<property name="validationQuery" value="SELECT 1" />
<property name="testWhileIdle" value="true" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />
<!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->
<property name="poolPreparedStatements" value="true" />
<property name="maxPoolPreparedStatementPerConnectionSize"
value="20" />
</bean>
<!--Mybatis的SessionFactory配置-->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="typeAliasesPackage" value="com.dodoke.tmall.pojo" />
<property name="dataSource" ref="dataSource"/>
<property name="mapperLocations" value="classpath:mapper/*.xml"/>
<!--分页插件,目前先注释,后面重构的时候才会使用 -->
<property name="plugins">
<array>
<bean class="com.github.pagehelper.PageInterceptor">
<property name="properties">
<value>
</value>
</property>
</bean>
</array>
</property>
</bean>
<!--Mybatis的Mapper文件识别-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.dodoke.tmall.mapper"/>
</bean>
</beans>
~~~
## 步骤 8 : 重启tomcat,测试
重启Tomcat后访问如下地址,可以看到一样的分页查询效果
`http://localhost:8080/tmall_ssm/admin_category_list?start=5`
![](https://box.kancloud.cn/e5b00445180f63553655033a30cca359_1823x424.png)
> 注:重构不会影响功能性,所以重构之后的代码一样可以实现分页的功能。
- 项目简介
- 功能一览
- 前台
- 后台
- 开发流程
- 需求分析-展示
- 首页
- 产品页
- 分类页
- 搜索结果页
- 购物车查看页
- 结算页
- 确认支付页
- 支付成功页
- 我的订单页
- 确认收货页
- 确认收货成功页
- 评价页
- 需求分析-交互
- 分类页排序
- 立即购买
- 加入购物车
- 调整订单项数量
- 删除订单项
- 生成订单
- 订单页功能
- 确认付款
- 确认收货
- 提交评价信息
- 登录
- 注册
- 退出
- 搜索
- 前台需求列表
- 需求分析后台
- 分类管理
- 属性管理
- 产品管理
- 产品图片管理
- 产品属性设置
- 用户管理
- 订单管理
- 后台需求列表
- 表结构设计
- 数据建模
- 表与表之间的关系
- 后台-分类管理
- 可运行的项目
- 静态资源
- JSP包含关系
- 查询
- 分页
- 增加
- 删除
- 编辑
- 修改
- 做一遍
- 重构
- 分页方式
- 分类逆向工程
- 所有逆向工程
- 后台其他页面
- 属性管理实现
- 产品管理实现
- 产品图片管理实现
- 产品属性值设置
- 用户管理实现
- 订单管理实现
- 前端
- 前台-首页
- 可运行的项目
- 静态资源
- ForeController
- home方法
- home.jsp
- homePage.jsp
- 前台-无需登录
- 注册
- 登录
- 退出
- 产品页
- 模态登录
- 分类页
- 搜索
- 前台-需要登录
- 购物流程
- 立即购买
- 结算页面
- 加入购物车
- 查看购物车页面
- 登录状态拦截器
- 其他拦截器
- 购物车页面操作
- 订单状态图
- 生成订单
- 我的订单页
- 我的订单页操作
- 评价产品
- 总结