三、新建分页功能
每一页记录开始位置 start
总记录 total
每页显示记录数 count
其他参数 param
修改mapper.xml:添加用于分页的SQL语句(limit #(start),#(count))
添加获取总记录数:select count(*) from category
1、先查出总记录数,然后再根据js判断分页
2、判断是否有前一页/后一页
3、计算总页数和最后一页
页面组成:« ‹ 页码 › »
1、若当前位置有上一页,则可以点击 « ‹ ,用JSTL中c:if标签控制
2、若当前位置有下一页,则可以点击 › » ,用JSTL中c:if标签控制
分别对应:
<a href="?start=${page.start-page.count}${page.param}" aria-label="Previous">
① http://localhost:8080/tmall_ssm/admin_category_list?start=-5
<a href="?start=${page.start+page.count}${page.param}" aria-label="Next">
② http://localhost:8080/tmall_ssm/admin_category_list?start=10
导入JSP页面:<%@ include file="" %>
若显示500错误但只是页面显示不全,可以先将JSP放在页面最开始导入【重新运行显示错误位置】
四、新建增加功能
1、在CategoryMapper.xml文件中添加insert语句
2、在CategoryMapper接口文件中添加新增功能实现代码
3、在CategoryService接口文件中添加新增实现
4、在CategoryServiceImpl接口实现类中实现Service中的新增方法(自动注入到mapper中)
5、由于可能需要上传图片,因此需要实现上传图片的代码功能UploadImageFile,同时确保上传的图片为二进制的jpg格式和设置图片大小,添加ImageUtil工具类
6、在Controller类中实现新增分类方法,同时在项目中添加上传的图片,成功之后重定向到查询列表
五、新建删除功能
主要步骤同上: 根据删除图标设置的地址,进行访问操作
注意点:
1、需要在删除前使用js设置确认操作,防止误删除
$(function(){
$("a").click(function(){
var deleteLink = $(this).attr("deleteLink");
console.log(deleteLink);
if("true"==deleteLink){
var confirmDelete = confirm("确认要删除");
if(confirmDelete)
return true;
return false;
}
});
})
// 先找到控件,然后再来判断事件
2、在删除分类的时候,还需要把在项目里的图片删除
@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去查找的功能,然后再执行delete语句,同时需要添加一个编辑的jsp页面
具体思路: 用户点击编辑图标,进入到edit页面,也就是编辑的jsp页面,此时页面的数据由前面根据id查找的功能实现并展示,当执行修改操作后,点击提交之后,跳转到列表。但是,此时的修改操作包括一整套步骤(从mapper、service到controller层,一级一级的实现,完成之后重定向到列表) 这里还包括是否修改了图片,下面是图片的判断
@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"));
File file = new File(imageFolder,c.getId()+".jpg");
image.transferTo(file);
BufferedImage img = ImageUtil.change2jpg(file);
ImageIO.write(img, "jpg", file);
}
return "redirect:/admin_category_list";
}
七、修改分页
1、原先
在mapper.xml文件中通过limit管理分页,同时添加查询总记录数的SQL
<select id="list" resultType="Category">
select * from category order by id asc
<!-- 用于分页 -->
<if test="start!=null and count!=null">
limit #{start},#{count}
</if>
</select>
<!-- 获取总数 -->
<select id="total" resultType="int">
select count(*) from category
</select>
在mapper接口中添加查询总记录数的方法,并依次添加service和serviceImpl的查询方法
// 支持分页查询分类
List<Category> list(Page page);
int total();
在controller层中查询分类信息和总记录数,将page和category存入model中
// 查询
@RequestMapping("admin_category_list")
public String list(Model model, Page page){
List<Category> cs = categoryService.list(page);
int total = categoryService.total();
page.setTotal(total);
model.addAttribute("cs", cs);
model.addAttribute("page", page);
return "admin/listCategory";
}
2、修改
不使用limit语句,同时不添加总记录数的SQL,使用PageHelper插件
<select id="list" resultType="Category">
select * from category order by id asc
</select>
依次实现方法,同时在applicationContext.xml中添加PageHelper插件的使用
<!--Mybatis的SessionFactory配置-->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="typeAliasesPackage" value="com.how2java.tmall.pojo" />
<property name="dataSource" ref="dataSource"/>
<property name="mapperLocations" value="classpath:mapper/*.xml"/>
<!-- PageHelper -->
<property name="plugins">
<array>
<bean class="com.github.pagehelper.PageInterceptor">
<property name="properties">
<value>
</value>
</property>
</bean>
</array>
</property>
</bean>
在controller中实现查询并分页功能
// 查询
@RequestMapping("admin_category_list")
public String list(Model model, Page page){
PageHelper.offsetPage(page.getStart(), page.getCount());
List<Category> cs = categoryService.list();
int total = (int) new PageInfo<>(cs).getTotal();
page.setTotal(total);
model.addAttribute("cs", cs);
model.addAttribute("page", page);
return "admin/listCategory";
}
八、重构
为了解决手动编写SQL语句效率低的问题,使用逆向工程进行重构
1、编写小插件类 OverIsMergeablePlugin
package com.linjie.tmall.util;
import org.mybatis.generator.api.GeneratedXmlFile;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import java.lang.reflect.Field;
import java.util.List;
/**
* @Title:OverlsMergeablePlugin
* @Package:com.linjie.tmall.util
* @Description:解决逆向工程多次运行 MybatisGenerator造成重复内容
* @author:done
* @date:2021/12/24 14:29
*/
public class OverlsMergeablePlugin extends PluginAdapter {
@Override
public boolean validate(List<String> list) {
return true;
}
@Override
public boolean sqlMapGenerated(GeneratedXmlFile sqlMap, IntrospectedTable introspectedTable) {
try{
Field field = sqlMap.getClass().getDeclaredField("isMergeable");
field.setAccessible(true);
field.setBoolean(sqlMap, false);
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
}
2、创建generatorConfig.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<context id="DB2Tables" targetRuntime="MyBatis3">
<!-- 避免生成重复代码 -->
<plugin type="com.linjie.tmall.util.OverlsMergeablePlugin"></plugin>
<!-- 是否在代码中显示注解 -->
<commentGenerator>
<property name="suppressDate" value="true"/>
<property name="suppressAllComments" value="true"/>
</commentGenerator>
<!-- 数据库连接 -->
<jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://localhost:3307/tmall_ssm" userId="root" password="123456"></jdbcConnection>
<!-- 不知道要干嘛的,好像是大小写问题 -->
<javaTypeResolver>
<property name="forceBigDecimals" value="false"/>
</javaTypeResolver>
<!-- 生成pojo类存放位置 -->
<javaModelGenerator targetPackage="com.linjie.tmall.pojo" targetProject="src/main/java">
<property name="enableSubPackages" value="true"/>
<property name="trimStrings" value="true"/>
</javaModelGenerator>
<!-- 生成映射文件的位置 -->
<sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources">
<property name="enableSubPackages" value="true"/>
</sqlMapGenerator>
<!-- 生成mapper存放位置 -->
<javaClientGenerator type="XMLMAPPER" targetPackage="com.linjie.tmall.mapper" targetProject="src/main/java">
<property name="enableSubPackages" value="true"/>
</javaClientGenerator>
<!-- 生成对应表及类名 ** Category -->
<table tableName="category" domainObjectName="Category" enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="true" selectByExampleQueryId="false">
<property name="my.isgen.usekeys" value="true"/>
<property name="useActualColumnNames" value="true"/>
<generatedKey column="id" sqlStatement="JDBC"></generatedKey>
</table>
<!-- OrderItem -->
<table tableName="orderitem" domainObjectName="OrderItem" enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="true" selectByExampleQueryId="false">
<property name="my.isgen.usekeys" value="true"/>
<property name="useActualColumnNames" value="true"/>
<generatedKey column="id" sqlStatement="JDBC"></generatedKey>
</table>
<!-- Orders -->
<table tableName="orders" domainObjectName="Orders" enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="true" selectByExampleQueryId="false">
<property name="my.isgen.usekeys" value="true"/>
<property name="useActualColumnNames" value="true"/>
<generatedKey column="id" sqlStatement="JDBC"></generatedKey>
</table>
<!-- Product -->
<table tableName="product" domainObjectName="Product" enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="true" selectByExampleQueryId="false">
<property name="my.isgen.usekeys" value="true"/>
<property name="useActualColumnNames" value="true"/>
<generatedKey column="id" sqlStatement="JDBC"></generatedKey>
</table>
<!-- ProductImage -->
<table tableName="productimage" domainObjectName="ProductImage" enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="true" selectByExampleQueryId="false">
<property name="my.isgen.usekeys" value="true"/>
<property name="useActualColumnNames" value="true"/>
<generatedKey column="id" sqlStatement="JDBC"></generatedKey>
</table>
<!-- Property -->
<table tableName="property" domainObjectName="Property" enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="true" selectByExampleQueryId="false">
<property name="my.isgen.usekeys" value="true"/>
<property name="useActualColumnNames" value="true"/>
<generatedKey column="id" sqlStatement="JDBC"></generatedKey>
</table>
<!-- PropertyValue -->
<table tableName="propertyvalue" domainObjectName="PropertyValue" enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="true" selectByExampleQueryId="false">
<property name="my.isgen.usekeys" value="true"/>
<property name="useActualColumnNames" value="true"/>
<generatedKey column="id" sqlStatement="JDBC"></generatedKey>
</table>
<!-- Review -->
<table tableName="review" domainObjectName="Review" enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="true" selectByExampleQueryId="false">
<property name="my.isgen.usekeys" value="true"/>
<property name="useActualColumnNames" value="true"/>
<generatedKey column="id" sqlStatement="JDBC"></generatedKey>
</table>
<!-- User -->
<table tableName="user" domainObjectName="User" enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="true" selectByExampleQueryId="false">
<property name="my.isgen.usekeys" value="true"/>
<property name="useActualColumnNames" value="true"/>
<generatedKey column="id" sqlStatement="JDBC"></generatedKey>
</table>
</context>
</generatorConfiguration>
3、创建MybatisGenerator进行pojo、mapper、xml文件的生成
package com.linjie.tmall.util;
import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.internal.DefaultShellCallback;
import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* @Title:MybatisGenerator
* @Package:com.linjie.tmall.util
* @Description:逆向工程生成代码
* @author:done
* @date:2021/12/24 14:49
*/
public class MybatisGenerator {
public static void main(String[] args) throws Exception {
String today = "2021-12-24";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
Date now = simpleDateFormat.parse(today);
Date date = new Date();
if (date.getTime() > now.getTime() + 1000*60*60*24){
System.out.println("-----------未成功运行------------");
System.err.println("本程序具有破坏作用,应该只运行一次,如果必须要再运行,需要修改today变量为今天,如:" + simpleDateFormat.format(new Date()));
return;
}
if (false){
return;
}
List<String> warnings = new ArrayList<>();
boolean overwrite = true;
InputStream is = MybatisGenerator.class.getClassLoader().getResource("generatorConfig.xml").openStream();
ConfigurationParser cp = new ConfigurationParser(warnings);
Configuration configuration = cp.parseConfiguration(is);
is.close();
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(configuration, callback, warnings);
myBatisGenerator.generate(null);
System.out.println("生成代码成功,只能执行一次,以后执行会覆盖掉mapper,pojo,xml 等文件上做的修改");
}
}