基于SSM框架的仿天猫在线商城系统(二)

三、新建分页功能

每一页记录开始位置 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 等文件上做的修改");
    }
}

版权声明:本文为weixin_44324036原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。