IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> SSM 项目 ---------小米商城后台管理系统 -> 正文阅读

[Java知识库]SSM 项目 ---------小米商城后台管理系统


一、项目名称

  • 名称 :小米商城后台管理系统

本项目主要目的是使学员更深层的了解IT企业的文化和岗位需求、模拟企业的工作场景,分享研制成果,增加学员对今后工作岗位及计算机应用开发对客观世界影响的感性认识,使学员对技术有更深入的理解,在今后工作中能有更明确的目标和方向。并能为日后职业规划提供很好的指导作用。

二、使用技术

  • 服务端:Spring+SpringMVC+MyBatis框架整合
  • 数据库:MySql8.0
  • web服务器:Tomcat
  • 项目管理:Maven
  • 前端:jQuery + BootStrap + JavaScript
  • 开发工具:idea2021

三、开发步骤

  • 介绍项目实现功能,使用到的技术点,使用到的框架,演示最终效果。
  • 创建数据库和表,添加idea可视化。
  • 完成SSM框架的搭建。
  • 添加字符编码过滤器,实现中文编码解析。
  • 使用数据库连接池技术,使用mybatis框架完成底层实体类的创建和数据访问层的实现。
  • 实现登录功能。
  • 实现登录成功后全部商品分页显示。
  • 实现Ajax的翻页功能。
  • 添加监听器,实现获取全部商品类型功能。
  • 实现商品增加功能。
  • 实现Ajax商品删除功能。
  • 实现Ajax商品批量删除功能。
  • 实现商品修改的回显功能。
  • 实现商品修改功能。
  • 实现按商品名称条件查询并分页功能,翻页使用Ajax技术。
  • 实现按商品类型查询并分页功能,翻页使用Ajax技术。
  • 实现按商品价格查询并分页功能,翻页使用Ajax技术。
  • 实现按商品名称、商品类型、商品价格多条件查询并分页,翻页使用Ajax技术。
  • 实现退出功能。

四、具体实现

1、创建数据库表

DROP DATABASE IF EXISTS xiaomissm;
CREATE DATABASE xiaomissm DEFAULT CHARSET utf8;

/*打开DB*/
USE xiaomissm;
DROP TABLE IF EXISTS `orderdetail`;
DROP TABLE IF EXISTS `xmorder`;
DROP TABLE IF EXISTS `carshop`;
DROP TABLE IF EXISTS `address`;
DROP TABLE IF EXISTS `users`;
drop table if exists product_info;
drop table if exists product_type;
drop table if exists admin;


#DROP TABLE xiaomi_admin;
#管理员表
CREATE TABLE admin(
	a_id INT AUTO_INCREMENT PRIMARY KEY,
	a_name VARCHAR(20),
	a_pass VARCHAR(20)
);
INSERT INTO admin(a_id,a_name,a_pass) VALUES(1,'admin','000000');

#商品类型表
CREATE TABLE product_type
(
	type_id int auto_increment PRIMARY KEY,
	type_name varchar(20)
);

#添加数据
insert into product_type(type_name) values('手机');
insert into product_type(type_name) values('电脑');
insert into product_type(type_name) values('电视');


#创建商品表
create table product_info
(
	p_id int auto_increment primary key,
	p_name varchar(20),
	p_content varchar(200), ##############33商品规格/简介
	p_price int, ###############价格
	p_image varchar(200), #############图片
	p_number int, ########数量
	type_id int,
	p_date date,
	FOREIGN KEY(type_id) REFERENCES product_type(type_id)
);

#添加商品
insert into product_info(p_name,p_content,p_price,p_image,p_number,type_id,p_date) values('小米Note2','双曲面 黑色 6GB内存 64GB闪存',2899,'xmNote2.jpg',500,1,'2018-01-04');
insert into product_info(p_name,p_content,p_price,p_image,p_number,type_id,p_date) values('红米Note5A','5.5英寸 粉色 2GB内存 16GB闪存',699,'hmNote5A.jpg',500,1,'2018-01-05');
insert into product_info(p_name,p_content,p_price,p_image,p_number,type_id,p_date) values('红米Note4X','5.5英寸 绿色 4GB内存 64GB闪存',1299,'hmNote4X.jpg',500,1,'2018-01-06');
insert into product_info(p_name,p_content,p_price,p_image,p_number,type_id,p_date) values('红米4','5英寸 金色 3GB内存 32GB闪存',999,'hm4.jpg',500,1,'2018-01-07');
insert into product_info(p_name,p_content,p_price,p_image,p_number,type_id,p_date) values('红米4X','5英寸 黑色 3GB内存 32GB闪存',899,'hm4X.jpg',500,1,'2018-01-08');

insert into product_info(p_name,p_content,p_price,p_image,p_number,type_id,p_date) values('小米平板3','7.9英寸 金色 4GB内存 64GB闪存',1499,'xmPad3.jpg',500,2,'2018-01-09');
insert into product_info(p_name,p_content,p_price,p_image,p_number,type_id,p_date) values('小米Air12','12.5英寸 银色 4GB内存 128GB闪存',3599,'xmAir12.jpg',500,2,'2018-01-18');
insert into product_info(p_name,p_content,p_price,p_image,p_number,type_id,p_date) values('小米Air13','13.3英寸 银色 8GB内存 256GB闪存',4999,'xmAir13.jpg',500,2,'2018-01-17');
insert into product_info(p_name,p_content,p_price,p_image,p_number,type_id,p_date) values('小米Pro','15.6英寸 灰色 16GB内存 256GB闪存',6999,'xmPro.jpg',500,2,'2018-01-16');

insert into product_info(p_name,p_content,p_price,p_image,p_number,type_id,p_date) values('小米电视4','49英寸 原装LG屏 3840×2160 真4K',3299,'xmTV4-49.jpg',500,3,'2018-01-15');
insert into product_info(p_name,p_content,p_price,p_image,p_number,type_id,p_date) values('小米电视4','55英寸 原装三星屏 3840×2160 真4K',3999,'xmTV4-55.jpg',500,3,'2018-01-13');
insert into product_info(p_name,p_content,p_price,p_image,p_number,type_id,p_date) values('小米电视4','65英寸 原装三星屏 3840×2160 真4K',8999,'xmTV4-65.jpg',500,3,'2018-01-22');
insert into product_info(p_name,p_content,p_price,p_image,p_number,type_id,p_date) values('小米电视4A','43英寸 FHD全高清屏 1920*1080',1999,'xmTV4A-43.jpg',500,3,'2018-01-11');
insert into product_info(p_name,p_content,p_price,p_image,p_number,type_id,p_date) values('小米电视4A','49英寸 FHD全高清屏 1920*1080',2299,'xmTV4A-49.jpg',500,3,'2018-01-21');
insert into product_info(p_name,p_content,p_price,p_image,p_number,type_id,p_date) values('小米MIX2','全陶瓷 黑色 8GB内存 128GB闪存',4699,'xmMIX2.jpg',500,1,'2018-04-01');
insert into product_info(p_name,p_content,p_price,p_image,p_number,type_id,p_date) values('小米Note3','全网通 蓝色 6GB内存 64GB闪存',2499,'xmNote3.jpg',500,1,'2018-03-01');
insert into product_info(p_name,p_content,p_price,p_image,p_number,type_id,p_date) values('小米6','玻璃金属 白色 6GB内存 128GB闪存',2899,'xm6.jpg',500,1,'2018-02-01');
insert into product_info(p_name,p_content,p_price,p_image,p_number,type_id,p_date) values('小米MAX2','全金属 金色 4GB内存 64GB闪存',1599,'xmMAX2.jpg',500,1,'2018-01-02');
insert into product_info(p_name,p_content,p_price,p_image,p_number,type_id,p_date) values('小米5X','全金属 金色 4GB内存 64GB闪存',1499,'xm5X.jpg',500,1,'2018-01-03');

#创建前台用户表
CREATE TABLE `users` (
    `uid` int(11) NOT NULL auto_increment,
    `uname` varchar(50) default NULL,
    `upass` varbinary(50) default NULL,
    `ustatus` int(11) default NULL,
    `ulevel` int(11) default NULL,
    `score` int(11) default NULL,
    PRIMARY KEY  (`uid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

#增加用户数据
INSERT INTO `users` VALUES ('1', 'zar', 0x313233343536, '0', '0', '0');
INSERT INTO `users` VALUES ('2', 'zhangsan', 0x313233343536, '1', '0', '0');

#创建地址表
CREATE TABLE `address` (
    `addressId` int(11) NOT NULL auto_increment,
    `uid` int(11) default NULL,
    `cnee` varchar(50) default NULL,
    `phone` varchar(11) default NULL,
    `address` varchar(100) default NULL,
    PRIMARY KEY  (`addressId`),
    KEY `FK_Reference_1` (`uid`),
    CONSTRAINT `FK_Reference_1` FOREIGN KEY (`uid`) REFERENCES `users` (`uid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

#增加地址表数据
INSERT INTO `address` VALUES ('1', '1', 'zar', '15266676667', '北京海淀甲骨文');
INSERT INTO `address` VALUES ('2', '1', 'oracle', '15266678888', '北京朝阳科技文化一条街');
INSERT INTO `address` VALUES ('3', '2', '张三', '15290888162', '北京大兴西红门');

#创建购物车表
CREATE TABLE `carshop` (
     `cid` int(11) NOT NULL auto_increment,
     `uid` int(11) default NULL,
     `pid` int(11) default NULL,
     `numbers` int(11) default NULL,
     PRIMARY KEY  (`cid`),
     KEY `FK_Reference_3` (`uid`),
     KEY `FK_Reference_4` (`pid`),
     CONSTRAINT `FK_Reference_4` FOREIGN KEY (`pid`) REFERENCES `product_info` (`p_id`),
     CONSTRAINT `FK_Reference_3` FOREIGN KEY (`uid`) REFERENCES `users` (`uid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

#增加购物车数据
insert into carshop (uid,pid,numbers) values (1,1,2);

#创建订单表
CREATE TABLE `xmorder` (
   `oid` char(32) NOT NULL ,
   `uid` int(11) default NULL,
   `addressId` int(11) default NULL,
   `totalprice` double(10,2) default NULL,
   `remarks` varchar(200) default NULL,
   `status` varchar(6) default NULL,
   `odate` TIMESTAMP  DEFAULT CURRENT_TIMESTAMP ,
    PRIMARY KEY  (`oid`),
    KEY `FK_Reference_5` (`uid`),
    KEY `FK_Reference_6` (`addressId`),
    CONSTRAINT `FK_Reference_6` FOREIGN KEY (`addressId`) REFERENCES `address` (`addressId`),
    CONSTRAINT `FK_Reference_5` FOREIGN KEY (`uid`) REFERENCES `users` (`uid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

#订单表增加数据
insert into xmorder(oid,uid,addressid,totalprice,remarks,status,odate) values('abcd111222333444777888999000wwww',1,1,9996,'尽快送到','待发货',default);

#创建订单明细表
CREATE TABLE `orderdetail` (
    `odid` int(11) NOT NULL auto_increment,
    `oid` char(32) default NULL,
    `pid` int(11) default NULL,
    `pnumber` int(11) default NULL,
    `ptotal` double(10,2) default NULL,
    PRIMARY KEY  (`odid`),
    KEY `FK_Reference_7` (`oid`),
    KEY `FK_Reference_8` (`pid`),
    CONSTRAINT `FK_Reference_8` FOREIGN KEY (`pid`) REFERENCES `product_info` (`p_id`),
    CONSTRAINT `FK_Reference_9` FOREIGN KEY (`oid`) REFERENCES `xmorder` (`oid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

insert into orderdetail(oid,pid,pnumber,ptotal) values ('abcd111222333444777888999000wwww',1,2,9996);

select * from admin;
select * from users;
select * from product_type;
select * from product_info ;
select * from orderdetail;
select * from xmorder;
select * from carshop;
select * from address;

用 Navicat 执行此 SQL文件 即可

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2、项目结构

在这里插入图片描述

SSM 项目分层参考 : SSM框架下各个层的解释说明

3、配置文件

pom.xml

与之前不同整合项目不同的是,在此版本号进行集中管理,便于后续进行更改

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.fancy</groupId>
  <artifactId>xiaomissm</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>xiaomissm Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
    <!-- 集中定义依赖版本号 -->
    <junit.version>4.12</junit.version>
    <spring.version>5.2.5.RELEASE</spring.version>
    <mybatis.version>3.5.1</mybatis.version>
    <mybatis.spring.version>1.3.1</mybatis.spring.version>
    <mybatis.paginator.version>1.2.15</mybatis.paginator.version>
    <mysql.version>8.0.22</mysql.version>
    <slf4j.version>1.6.4</slf4j.version>
    <druid.version>1.1.12</druid.version>
    <pagehelper.version>5.1.2</pagehelper.version>
    <jstl.version>1.2</jstl.version>
    <servlet-api.version>3.0.1</servlet-api.version>
    <jsp-api.version>2.0</jsp-api.version>
    <jackson.version>2.9.6</jackson.version>
  </properties>

  <dependencies>
      <!-- spring -->
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
      </dependency>
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>${spring.version}</version>
      </dependency>
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${spring.version}</version>
      </dependency>
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>${spring.version}</version>
      </dependency>
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
        <version>${spring.version}</version>
      </dependency>
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jms</artifactId>
        <version>${spring.version}</version>
      </dependency>
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>${spring.version}</version>
      </dependency>
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>${spring.version}</version>
      </dependency>
      <!-- Mybatis -->
      <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>${mybatis.version}</version>
      </dependency>
      <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>${mybatis.spring.version}</version>
      </dependency>
      <dependency>
        <groupId>com.github.miemiedev</groupId>
        <artifactId>mybatis-paginator</artifactId>
        <version>${mybatis.paginator.version}</version>
      </dependency>
      <dependency>
        <groupId>com.github.pagehelper</groupId>
        <artifactId>pagehelper</artifactId>
        <version>${pagehelper.version}</version>
      </dependency>
      <!-- MySql -->
      <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>${mysql.version}</version>
      </dependency>
      <!-- 连接池 -->
      <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>${druid.version}</version>
      </dependency>

      <!-- junit -->
      <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>${junit.version}</version>
        <scope>test</scope>
      </dependency>


      <!-- JSP相关 -->
      <dependency>
        <groupId>jstl</groupId>
        <artifactId>jstl</artifactId>
        <version>${jstl.version}</version>
      </dependency>
      <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.0.1</version>
        <scope>provided</scope>
      </dependency>
      <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jsp-api</artifactId>
        <scope>provided</scope>
        <version>${jsp-api.version}</version>
      </dependency>
      <!-- Jackson Json处理工具包 -->
      <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>${jackson.version}</version>
      </dependency>
      <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.4</version>
      </dependency>
      <dependency>
        <groupId>commons-fileupload</groupId>
        <artifactId>commons-fileupload</artifactId>
        <version>1.3.1</version>
      </dependency>

  </dependencies>

  <build>
      <!--识别所有的配置文件-->
      <resources>
          <resource>
              <directory>src/main/java</directory>
              <includes>
                  <include>**/*.properties</include>
                  <include>**/*.xml</include>
              </includes>
              <filtering>false</filtering>
          </resource>
          <resource>
              <directory>src/main/resources</directory>
              <includes>
                  <include>**/*.properties</include>
                  <include>**/*.xml</include>
              </includes>
              <filtering>false</filtering>
          </resource>
      </resources>
    <finalName>xiaomissm</finalName>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.22.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-war-plugin</artifactId>
          <version>3.2.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

db.properties

在此需要在 password、username等前加上前缀 jdbc. ,以防与登录界面中的username、password的相冲突

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/xiaomissm?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
jdbc.username=root
jdbc.password=123456

application-services.xml 配置文件中的 ${ } 可以取到全局域所有的username与password#

applicationContext-dao.xml

此文件主要完成 Spring 在 dao 包(持久层)相关配置,主要分为以下四步

(1) 配置属性文件 :读取数据库配置文件 db.properties ,引入连接数据库的相关属性

(2) 配置数据源 :数据库连接池用到阿里旗下 druid 连接池,读取数据库属性,完成数据库的连接

(3) 配置 MyBatis 工厂 : 需要用到数据源与mybatis核心配置文件

(4) 创建动态代理对象 :代码中有解释

<?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/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
      <!-- 配置属性文件  -->
      <context:property-placeholder location="classpath:db.properties"></context:property-placeholder>
      <!-- 配置数据源 -->
      <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
          <property name="driverClassName" value="${jdbc.driver}"></property>
          <property name="url" value="${jdbc.url}"></property>
          <property name="username" value="${jdbc.username}"></property>
          <property name="password" value="${jdbc.password}"></property>
      </bean>
      <!-- 配置MyBatis工厂  -->
      <bean  id="SqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
          <!-- 配置数据源    -->
          <property name="dataSource" ref="dataSource"></property>
          <!-- 配置mybatis的核心配置文件   -->
          <property name="configLocation" value="classpath:SqlMapConfig.xml"></property>
      </bean>

    <!--
         MapperScannerConfigurer作用:
         循环basePackage所表示的包,把包中的每个接口都找到,调用SqlSession.getMapper(XXXDao.class)
         把每个dao接口都创建出对应的dao代理对象,将dao代理对象放在容器中
         就不需要我们去为每个映射接口去声明一个bean了, 大大缩减了开发的效率
         对于StudentDao接口,其代理对象为 studentDao
    -->
      <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
          <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
          <property name="basePackage" value="com.fancy.dao"></property>
      </bean>
</beans>

applicationContext-services.xml

此文件主要完成 Spring 在 services 包 (业务层) 相关配置,主要分为以下几步操作

(1) 配置组件扫描器,完成对于 services 包的扫描,使注解生效

(2) 设置事务管理器

(3) 添加事务切面

(4) 完成切面和切入点的织入

至于为什么要在 services 包而不是 dao 包下添加事务,可以参考此文章:
https://blog.csdn.net/m0_51111980/article/details/123140072?spm=1001.2014.3001.5501

<?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" xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
    
    <import resource="classpath:applicationContext-dao.xml"></import>
    <!-- 配置业务逻辑层,给spring扫描识别该包下的所有类,使用注解方式 -->
    <context:component-scan base-package="com.fancy.services"></context:component-scan>

    <!-- 设置事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    
    <!-- 添加事务切面 -->
    <tx:advice id="myAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="select*" read-only="true"/>
            <tx:method name="insert*" propagation="REQUIRED"></tx:method>
            <tx:method name="delete*" propagation="REQUIRED"></tx:method>
            <tx:method name="update*" propagation="REQUIRED"></tx:method>
            <tx:method name="*" propagation="SUPPORTS"></tx:method>
        </tx:attributes>
    </tx:advice>
    
    <!-- 完成切面和切入点的织入 -->
    <aop:config>
        <aop:pointcut id="myPointcut" expression="execution(* com.fancy.services.*.*(..))"/>
        <aop:advisor advice-ref="myAdvice" pointcut-ref="myPointcut"></aop:advisor>
    </aop:config>
</beans>

springmvc.xml

springmvc.xml 配置文件主要完成 Spring 在 controllers 包(控制层) 需要的相关配置,分为以下四步

(1) 注册组件扫描器:使 controllers 包下注解生效

(2) 指定视图解析器:简化视图路径,便于开发

(3) 设置文件上传核心组件:使用MultipartFile这个类主要是来实现以表单的形式进行多文件上传功能

(4) 注册注解驱动:<mvc:annotation-driven>后,默认会帮我们注册默认处理请求,参数和返回值的类。其会自动注册DefaultAnnotationHandlerMapping与AnnotationMethodHandlerAdapter 两个bean,是spring MVC为 @Controller 分发请求所必须的。

<?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" xmlns:mvc="http://www.alibaba.com/schema/stat"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.alibaba.com/schema/stat http://www.alibaba.com/schema/stat.xsd">

    <!-- 注册组件扫描器
         base-package : 指定 @Controller 注解所在包
    -->
    <context:component-scan base-package="com.fancy.controllers"></context:component-scan>

    <!--  指定视图解析器   -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- 前缀与后缀   -->
        <property name="prefix" value="/WEB-INF/view"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>

    <!--设置文件上传核心组件   -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean>

    <!-- 注册注解驱动  -->
    <mvc:annotation-driven/>
</beans>

SqlMapConfig.xml

SqlMapConfig.xml 作为 MyBatis 全局配置文件,一般完成两个设置别名、指定 sql 映射文件。由于我们要在项目中用到分页功能,在此我们要注册分页插件。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!-- 配置别名 -->
    <typeAliases>
        <package name="com.fancy.pojo"/>
    </typeAliases>

    <!-- 注册分页插件 -->
    <plugins>
        <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
    </plugins>
    
    <!-- 指定sql映射文件 -->
    <mappers>
        <package name="com.fancy.dao"/>
    </mappers>
</configuration>

web.xml

我们需要在 web.xml 配置文件中完成注册字符编码过滤器、注册Spring框架、注册 SpringMVC 框架的代码,以便在web项目启动时框架可以正常使用。

注册Spring框架主要完成 注册监听器和加载applicationContext.xml配置文件 两个部分

注册SpringMVC框架主要完成注册中央调度器和拦截匹配的请求两部分,Servlet拦截匹配规则要自已定义,把拦截下来的请求,依据某某规则分发到目标Controller(我们写的Action)来处理。

<?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">
    <!-- 字符编码过滤器   -->
    <filter>
        <filter-name>characterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceRequsetEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
        <init-param>
            <param-name>forceResponseEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>characterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!--  注册springmvc框架  -->
    <servlet>
        <servlet-name>SpringMVC</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>SpringMVC</servlet-name>
        <url-pattern>*.action</url-pattern>
    </servlet-mapping>

    <!-- spring 框架注册 -->
    <!-- 监听器作用 : 在启动 Web 容器时,自动装配Spring applicationContext.xml 的配置信息  -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
</web-app>

4、使用 MyBatis 逆向工程生成 pojo 类 和 dao 类

在 maven 中添加依赖

分别是mybatis-generator-maven-plugin插件,log4j、mybatis、mysql、mybatis-generator的依赖

依赖:

<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
	<version>8.0.22</version>
</dependency>
<dependency>
	<groupId>org.mybatis.generator</groupId>
	<artifactId>mybatis-generator-core</artifactId>
	<version>1.3.6</version>
</dependency>
<dependency>
	<groupId>log4j</groupId>
	<artifactId>log4j</artifactId>
	<version>1.2.17</version>
</dependency>
<dependency>
	<groupId>org.mybatis</groupId>
	<artifactId>mybatis</artifactId>
	<version>3.5.1</version>
</dependency>

插件:

<plugins>
<!-- mybatis-generator自动生成代码插件 -->
<plugin>
    <groupId>org.mybatis.generator</groupId>
    <artifactId>mybatis-generator-maven-plugin</artifactId>
    <version>1.3.6</version>
    <dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.22</version>
        </dependency>
    </dependencies>
    <configuration>
        <verbose>true</verbose>
        <overwrite>true</overwrite>
    </configuration>
</plugin>

插件无法显示怎么办? 参考文章 https://blog.csdn.net/chenyao1994/article/details/85916642

同时需要在插件中再次加入 mysq-connector-java 依赖,否则在运行时会出现以下错误
在这里插入图片描述
配置成功后出现以下插件
在这里插入图片描述

配置逆向工程核心配置文件 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>

    <!-- classPathEntry:数据库的 JDBC驱动的jar 包地址
     这里需要一个mysql的驱动包,去随便找一个驱动包就可以,指定路径
     -->
    <!-- 
       <classPathEntry location="C:\\Program Files\\mysql-connector-java-8.0.25" /> 
     -->
    <context id="tables" targetRuntime="MyBatis3">
        <commentGenerator>
            <!-- 是否去除自动生成的注释 true:是 : false:否 -->
            <!-- 这里选择的是去掉注释,因为mybatis生成的注释非常繁琐 -->
            <property name="suppressAllComments" value="true" />
        </commentGenerator>

        <!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->

        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/xiaomissm?useSSL=false&amp;serverTimezone=Asia/Shanghai&amp;allowPublicKeyRetrieval=true"
                        userId="root"
                        password="aszhuo123">
            <!-- 解决出现重复resultMap id值的情况          -->
            <property name="nullCatalogMeansCurrent" value="true" />
        </jdbcConnection>
        <!-- orcal数据库 注意这里使用orcal数据库 上面驱动包也必须指定为 orcal的驱动-->

        <!-- <jdbcConnection driverClass="oracle.jdbc.OracleDriver"
        connectionURL="jdbc:oracle:thin:@127.0.0.1:1521:yycg"
        userId="yycg"
        password="yycg">
        </jdbcConnection> -->

        <!-- 默认 false,把 JDBC DECIMAL 和 NUMERIC 类型解析为 Integer true,把 JDBC DECIMAL 和
        NUMERIC 类型解析为java.math.BigDecimal -->
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false" />
        </javaTypeResolver>

        <!-- targetProject:生成 POJO 类的位置 src/main/java/com.pyg.pojo -->
        <javaModelGenerator targetPackage="com.fancy.pojo"	targetProject="src/main/java">
            <!-- enableSubPackages:是否让schema 作为包的后缀 -->
            <property name="enableSubPackages" value="true" />
            <!-- 从数据库返回的值被清理前后的空格 -->
            <property name="trimStrings" value="true" />
        </javaModelGenerator>


        <!-- 生成 XML文件  ./src/main/resources/com.facny.mapper -->
        <sqlMapGenerator targetPackage="com.fancy.dao"  	 targetProject="./src/main/java">
            <property name="enableSubPackages" value="false" />
        </sqlMapGenerator>

        <!--生成接口-->
        <javaClientGenerator type="XMLMAPPER"
                             targetPackage="com.fancy.dao"  targetProject="./src/main/java">
            <property name="enableSubPackages" value="false" />
        </javaClientGenerator>

        <!-- 你要生成逆向工程的表名,这里必须和数据库中的表名保持一致 -->
        <table tableName="address"
               enableCountByExample="false" enableUpdateByExample="false"
               enableDeleteByExample="false" enableSelectByExample="false"
               selectByExampleQueryId="false"></table>
        <table tableName="admin"
               enableCountByExample="false" enableUpdateByExample="false"
               enableDeleteByExample="false" enableSelectByExample="false"
               selectByExampleQueryId="false"></table>
        <table tableName="carshop"
               enableCountByExample="false" enableUpdateByExample="false"
               enableDeleteByExample="false" enableSelectByExample="false"
               selectByExampleQueryId="false"></table>
        <table tableName="orderdetail"
               enableCountByExample="false" enableUpdateByExample="false"
               enableDeleteByExample="false" enableSelectByExample="false"
               selectByExampleQueryId="false"></table>
        <table tableName="product_info"
               enableCountByExample="false" enableUpdateByExample="false"
               enableDeleteByExample="false" enableSelectByExample="false"
               selectByExampleQueryId="false"></table>
        <table tableName="product_type"
               enableCountByExample="false" enableUpdateByExample="false"
               enableDeleteByExample="false" enableSelectByExample="false"
               selectByExampleQueryId="false"></table>
        <table tableName="users"
               enableCountByExample="false" enableUpdateByExample="false"
               enableDeleteByExample="false" enableSelectByExample="false"
               selectByExampleQueryId="false"></table>
        <table tableName="xmorder"
               enableCountByExample="false" enableUpdateByExample="false"
               enableDeleteByExample="false" enableSelectByExample="false"
               selectByExampleQueryId="false"></table>
    </context>
</generatorConfiguration>

运行并生成 pojo类 和 dao类

鼠标移到插件,右键 Run Maven Build
在这里插入图片描述
生成代码如图
在这里插入图片描述
在这里插入图片描述

5、utils 包下添加 MD5 加密算法工具类

此算法主要在注册登录页面的表单提交数据时使用

package com.fancy.utils;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MD5Util {
    /**
     * 1.MD5(message-digest algorithm 5)信息摘要算法,
     *   它的长度一般是32位的16进制数字符串(如81dc9bdb52d04dc20036dbd8313ed055)
     * 2.由于系统密码明文存储容易被黑客盗取
     * 3.应用:注册时,将密码进行md5加密,存到数据库中,防止可以看到数据库数据的人恶意篡改。
     *       登录时,将密码进行md5加密,与存储在数据库中加密过的密码进行比对
     * 4.md5不可逆,即没有对应的算法,从产生的md5值逆向得到原始数据。
     *   但是可以使用暴力破解,这里的破解并非把摘要还原成原始数据,如暴力枚举法。
     *
     */
    public final static String getMD5(String str){
        try {
            MessageDigest md = MessageDigest.getInstance("SHA");//创建具有指定算法名称的摘要
            md.update(str.getBytes());                    //使用指定的字节数组更新摘要
            byte mdBytes[] = md.digest();                 //进行哈希计算并返回一个字节数组

            String hash = "";
            for(int i= 0;i<mdBytes.length;i++){           //循环字节数组
                int temp;
                if(mdBytes[i]<0)                          //如果有小于0的字节,则转换为正数
                    temp =256+mdBytes[i];
                else
                    temp=mdBytes[i];
                if(temp<16)
                    hash+= "0";
                hash+=Integer.toString(temp,16);         //将字节转换为16进制后,转换为字符串
            }
            return hash;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }
}

6、登录功能

我们先编写登录界面 login.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>

<!DOCTYPE html>
<html>

	<head>
		<meta charset="UTF-8">
		<link rel="stylesheet" href="${pageContext.request.contextPath}/css/bootstrap.css" />
		<link rel="stylesheet" href="${pageContext.request.contextPath}/css/login.css" />
		<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-3.3.1.js"></script>
		<script type="text/javascript" src="${pageContext.request.contextPath}/js/bootstrap.js"></script>
		<title></title>
		
	</head>

	<body>
		<div id="login">
			<div id="top">
				<img src="${pageContext.request.contextPath}/images/cloud.jpg" /><span>LOGIN</span>
			</div>
			<div id="bottom">
				<form  action="${pageContext.request.contextPath}/admin/login.action" method="post">
					<table border="0px" id="table">
						<tr>
							<td class="td1">用户名:</td>
							<td><input type="text" placeholder="Username" class="td2" name="name"></td>
						</tr>
						<tr>
							<td></td>
							<td><span id="nameerr"></span></td>
						</tr>
						<tr>
							<td class="td1">密码:</td>
							<td><input type="password"  placeholder="Password" class="td2" name="pwd"></td>
						</tr>
						<tr>
							<td></td>
							<td><span id="pwderr"></span></td>
						</tr>
						<tr>
							<td></td>
							<td><input type="submit" value="登录" class="td3">
								<a href="${pageContext.request.contextPath}/regist.jsp"><input type="button" value="注册" class="td3	"></a>
							</td>
						</tr>
					</table>
				</form>
				${errmsg}
			</div>
		</div>
	</body>
</html>

如图所示
在这里插入图片描述
接下来是做登录判断,如果表单提交数据与数据库表中数据相符,则登录成功;反之,则登录失败。

做登录判断的功能函数属于业务层范围,我们在services包下定义 AdminService 接口及其实现类 AdminServiceImpl,其内部封装 login() 作为登录判断的函数。

做业务层开发时,我们知道业务层函数是基于持久层操作数据库方法的,所以业务层实现类一定会有持久层的对象

既然要判断表中是否存在该数据,我们需要到 MyBatis 逆向工程生成的 AdminMapper 接口中寻找 根据用户名称查询 的方法。

在这里插入图片描述

我们发现其中只有根据主键查询数据的方法,而 admin 表中 aName属性不是主键,在此我们需要额外再创建方法

Admin selectByName(String aName) 来根据用户提交的username来查询

在这里插入图片描述

mapper 映射文件中同时定义

<select id="selectByName" parameterType="java.lang.String" resultType="BaseResultMap">
  select
  <include refid="Base_Column_List"></include>
  from admin
  where a_name = #{aName, jdbcType=VARCHAR}
</select>

仿照原有的方法 selectByPrimaryKey 进行定义
在这里插入图片描述

AdminService.java

package com.fancy.services;

import com.fancy.pojo.Admin;

public interface AdminService {
    // 完成登录判断
    Admin login(String name, String pwd);

}

AdminServiceImpl.java

package com.fancy.services;

import com.fancy.dao.AdminMapper;
import com.fancy.pojo.Admin;
import com.fancy.utils.MD5Util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class AdminSeriviceImpl implements AdminService{
    //在业务层中, 一定有持久层对象
    @Autowired
    AdminMapper adminMapper;


    @Override
    public Admin login(String name, String pwd) {

        //根据传入的用户或到DB中查询相应用户对象
        Admin admin = adminMapper.selectByName(name);

        if(admin != null) {
           //如果查询到用户对象, 在进行密码比对, 注意密码是密文
            String mPwd = MD5Util.getMD5(pwd);
            //在进行密码对比时,要将传入的pwd进行md5加密,再与数据库中查到的对象的密码进行对比
            if (mPwd.equals(admin.getaPass())) {
                return admin;
            }
        }
        return  null;
    }
}

从数据库中取出数据后,我们需要与前端提交的数据进行比对。接收浏览器数据属于控制层范畴,此时比对的操作需要在控制层完成,然而我们也需要刚刚从数据库中获取的数据对象,所以我们又可以得到一个结论:控制层中一定有业务层对象。 AdminService 实现类 AdminServiceImpl 我们通过注解 @Service 已经创建好了对象 adminServiceImpl
我们在控制层AdminAction类中定义 AdminService adminService,上方加上 @Autowired 注解进行扫描,当扫描到adminServiceImpl 这个对象由于是其实现类对象,会自动进行注入。这种写法起到了解耦合的作用。

如不理解可以参考一下文章:https://blog.csdn.net/qq_32224047/article/details/107082167

package com.fancy.controllers;

import com.fancy.pojo.Admin;
import com.fancy.services.AdminService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;

@Controller
@RequestMapping("/admin")
public class AdminAction {
    //在所有控制层中一定有业务层对象
    @Autowired
    AdminService adminService;

    @RequestMapping("/login.action")
    public String login(String name, String pwd, HttpServletRequest request) {
        Admin admin = adminService.login(name, pwd);
        if (admin != null) {
            request.setAttribute("admin", admin);
            return "main";
        } else {
            request.setAttribute("errmsg", "用户名或密码不正确");
            return "login";
        }
    }
}

登录测试:

登录成功:
在这里插入图片描述
在这里插入图片描述
登录失败:
在这里插入图片描述

7、分页与翻页

步骤: 将全部商品不分页显示出来 -----> 分页显示 ------> 翻页功能

首先我们给出商品管理总界面

<%@ page language="java" contentType="text/html; charset=UTF-8"
		 pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>

	<head>
		<meta charset="UTF-8">
		<link rel="stylesheet" href="${pageContext.request.contextPath}/css/bootstrap.css" />
		<link rel="stylesheet" href="${pageContext.request.contextPath}/css/index.css" />
		<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-3.3.1.js"></script>
		<script type="text/javascript" src="${pageContext.request.contextPath}/js/bootstrap.js"></script>
		<title></title>
		<%--<link href="${pageContext.request.contextPath}/css/main.css" rel="stylesheet" >--%>
		<style type="text/css">
		
		</style>
	</head>

	<body>
		<!--整体部分-->
		<div id="all">
			<!--上部分-->
			<div id="top">
				<div id="top1">
					<span>商品管理系统</span>
				</div>
				<div id="top2"></div>
				<div id="top3">
					<span>欢迎您,${name}</span>
				</div>
			</div>
			<!--下部分-->
			<div id="bottom">
				<!--下部分左边-->
				<div id="bleft">
					<div id="ltop">
						<div id="lts">
							<img src="${pageContext.request.contextPath}/images/logo.jpg" /><br />
							<p style="text-align: center;">随机访客</p>
						</div>
					</div>
					<div id="lbottom">
						<ul>
							<a href="${pageContext.request.contextPath}/prod/split.action" target="myright" >
								<li class="two"><span class="glyphicon glyphicon-book" style="color: white;"></span>&nbsp;&nbsp;&nbsp;&nbsp;商品管理&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="glyphicon glyphicon-play" style="color: white;"></span> </li>
							</a>
							<a href="${pageContext.request.contextPath}/admin/err.jsp" target="myright">
								<li class="one"><span class="glyphicon glyphicon-sort" style="color: white;"></span>&nbsp;&nbsp;&nbsp;&nbsp;订单管理&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="glyphicon glyphicon-play" style="color: white;"></span> </li>
							</a>
							<a href="${pageContext.request.contextPath}/admin/err.jsp" target="myright">
								<li class="one"><span class="glyphicon glyphicon-user" style="color: white;"></span>&nbsp;&nbsp;&nbsp;&nbsp;用户管理&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="glyphicon glyphicon-play" style="color: white;"></span> </li>
							</a>
							<a href="${pageContext.request.contextPath}/admin/err.jsp" target="myright">
								<li class="one"><span class="glyphicon glyphicon-bullhorn" style="color: white"></span>&nbsp;&nbsp;&nbsp;&nbsp;通知公告&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="glyphicon glyphicon-play" style="color: white;"></span> </li>
							</a>
						</ul>
					</div>
				</div>
				<!--下部分右边-->
				<div id="bright">
					<iframe frameborder="0" scrolling="no" name="myright" width="1235px" height="700px" ></iframe>
				</div>
			</div>
		</div>
	</body>
</html>

在这里插入图片描述

同上一个实现登录的步骤,我们先开发 service 接口及其实现类,先编写 getAll() 方法以获取所有商品数据

在这里插入图片描述

然后我们在实现类 ProductInfoServiceImpl 中将 getAll() 方法进行实现,实际上是调用 mapper 类中 selectAll()方法,如没有请自行定义。

在这里插入图片描述
getAll() 方法的实现。
在这里插入图片描述
在控制层中,我们接受到浏览器的请求之后,调用通过业务层对象调用getAll()方法从数据库中获取所有商品的数据,添加到 request 作用域中,并提交给 Product.jsp 界面,在 Product.jsp 中所有商品的数据显现出来。

Product.jsp 界面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@page import="com.oracle.xiaomi.pojo.*" %>
<%@page import="java.util.*" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <script type="text/javascript">
        if ("${msg}" != "") {
            alert("${msg}");
        }
    </script>
    <c:remove var="msg"></c:remove>
    <link rel="stylesheet" href="${pageContext.request.contextPath}/css/bootstrap.css"/>
    <link rel="stylesheet" href="${pageContext.request.contextPath}/css/bright.css"/>
    <link rel="stylesheet" href="${pageContext.request.contextPath}/css/addBook.css"/>
    <script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-3.3.1.js"></script>
    <script type="text/javascript" src="${pageContext.request.contextPath}/js/bootstrap.js"></script>
    <title></title>
</head>
<body>
<div id="brall">
    <div id="nav">
        <p>商品管理>商品列表</p>
    </div>
    <div id="condition" style="text-align: center">
        <form id="myform">
            商品名称:<input name="pname" id="pname">&nbsp;&nbsp;&nbsp;
            商品类型:<select name="typeid" id="typeid">
            <option value="-1">请选择</option>
            <c:forEach items="${ptlist}" var="pt">
                <option value="${pt.typeId}">${pt.typeName}</option>
            </c:forEach>
        </select>&nbsp;&nbsp;&nbsp;
            价格:<input name="lprice" id="lprice">-<input name="hprice" id="hprice">
            <input type="button" value="查询" onclick="ajaxsplit(${pb.pageNum})">
        </form>
    </div>
    <br>
    <div id="table">

        <c:choose>
            <c:when test="${pb.list.size()!=0}">

                <div id="top">
                    <input type="checkbox" id="all" onclick="allClick()" style="margin-left: 50px">&nbsp;&nbsp;全选
                    <a href="${pageContext.request.contextPath}/admin/addproduct.jsp">

                        <input type="button" class="btn btn-warning" id="btn1"
                               value="新增商品">
                    </a>
                    <input type="button" class="btn btn-warning" id="btn1"
                           value="批量删除" onclick="deleteBatch(${pb.pageNum})">
                </div>
                <!--显示分页后的商品-->
                <div id="middle">
                    <table class="table table-bordered table-striped">
                        <tr>
                            <th></th>
                            <th>商品名</th>
                            <th>商品介绍</th>
                            <th>定价(元)</th>
                            <th>商品图片</th>
                            <th>商品数量</th>
                            <th>操作</th>
                        </tr>
                        <c:forEach items="${list}" var="p">
                            <tr>
                                <td valign="center" align="center"><input type="checkbox" name="ck" id="ck" value="${p.pId}" onclick="ckClick()"></td>
                                <td>${p.pName}</td>
                                <td>${p.pContent}</td>
                                <td>${p.pPrice}</td>
                                <td><img width="55px" height="45px"
                                         src="${pageContext.request.contextPath}/image_big/${p.pImage}"></td>
                                <td>${p.pNumber}</td>
                                    <%--<td><a href="${pageContext.request.contextPath}/admin/product?flag=delete&pid=${p.pId}" onclick="return confirm('确定删除吗?')">删除</a>--%>
                                    <%--&nbsp;&nbsp;&nbsp;<a href="${pageContext.request.contextPath}/admin/product?flag=one&pid=${p.pId}">修改</a></td>--%>
                                <td>
                                    <button type="button" class="btn btn-info "
                                            onclick="one(${p.pId},${pb.pageNum})">编辑
                                    </button>
                                    <button type="button" class="btn btn-warning" id="mydel"
                                            onclick="del(${p.pId},${pb.pageNum})">删除
                                    </button>
                                </td>
                            </tr>
                        </c:forEach>
                    </table>
                    <!--分页栏-->
                    <div id="bottom">
                        <div>
                            <nav aria-label="..." style="text-align:center;">
                                <ul class="pagination">
                                    <li>
                                            <%--                                        <a href="${pageContext.request.contextPath}/prod/split.action?page=${pb.prePage}" aria-label="Previous">--%>
                                        <a href="javascript:ajaxsplit(${pb.prePage})" aria-label="Previous">

                                            <span aria-hidden="true">?</span></a>
                                    </li>
                                    <c:forEach begin="1" end="${pb.pages}" var="i">
                                        <c:if test="${pb.pageNum==i}">
                                            <li>
                                                    <%--                                                <a href="${pageContext.request.contextPath}/prod/split.action?page=${i}" style="background-color: grey">${i}</a>--%>
                                                <a href="javascript:ajaxsplit(${i})"
                                                   style="background-color: grey">${i}</a>
                                            </li>
                                        </c:if>
                                        <c:if test="${pb.pageNum!=i}">
                                            <li>
                                                    <%--                                                <a href="${pageContext.request.contextPath}/prod/split.action?page=${i}">${i}</a>--%>
                                                <a href="javascript:ajaxsplit(${i})">${i}</a>
                                            </li>
                                        </c:if>
                                    </c:forEach>
                                    <li>
                                        <%--  <a href="${pageContext.request.contextPath}/prod/split.action?page=1" aria-label="Next">--%>
                                        <a href="javascript:ajaxsplit(${pb.nextPage})" aria-label="Next">
                                            <span aria-hidden="true">?</span></a>
                                    </li>
                                    <li style=" margin-left:150px;color: #0e90d2;height: 35px; line-height: 35px;">总共&nbsp;&nbsp;&nbsp;<font
                                            style="color:orange;">${pb.pages}</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                                        <c:if test="${pb.pageNum!=0}">
                                            当前&nbsp;&nbsp;&nbsp;<font
                                            style="color:orange;">${pb.pageNum}</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                                        </c:if>
                                        <c:if test="${pb.pageNum==0}">
                                            当前&nbsp;&nbsp;&nbsp;<font
                                            style="color:orange;">1</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                                        </c:if>
                                    </li>
                                </ul>
                            </nav>
                        </div>
                    </div>
                </div>
            </c:when>
            <c:otherwise>
                <div>
                    <h2 style="width:1200px; text-align: center;color: orangered;margin-top: 100px">暂时没有符合条件的商品!</h2>
                </div>
            </c:otherwise>
        </c:choose>
    </div>
</div>
<!--编辑的模式对话框-->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
                <h4 class="modal-title" id="myModalLabel">新增商品</h4>
            </div>
            <div class="modal-body" id="addTD">
                <form action="${pageContext.request.contextPath}/admin/product?flag=save" enctype="multipart/form-data"
                      method="post" id="myform">
                    <table>
                        <tr>
                            <td class="one">商品名称</td>
                            <td><input type="text" name="pname" class="two" class="form-control"></td>
                        </tr>
                        <!--错误提示-->
                        <tr class="three">
                            <td class="four"></td>
                            <td><span id="pnameerr"></span></td>
                        </tr>
                        <tr>
                            <td class="one">商品介绍</td>
                            <td><input type="text" name="pcontent" class="two" class="form-control"></td>
                        </tr>
                        <!--错误提示-->
                        <tr class="three">
                            <td class="four"></td>
                            <td><span id="pcontenterr"></span></td>
                        </tr>
                        <tr>
                            <td class="one">定价</td>
                            <td><input type="number" name="pprice" class="two" class="form-control"></td>
                        </tr>
                        <!--错误提示-->
                        <tr class="three">
                            <td class="four"></td>
                            <td><span id="priceerr"></span></td>
                        </tr>

                        <tr>
                            <td class="one">图片介绍</td>
                            <td><input type="file" name="pimage" class="form-control"></td>
                        </tr>
                        <tr class="three">
                            <td class="four"></td>
                            <td><span></span></td>
                        </tr>

                        <tr>
                            <td class="one">总数量</td>
                            <td><input type="number" name="pnumber" class="two" class="form-control"></td>
                        </tr>
                        <!--错误提示-->
                        <tr class="three">
                            <td class="four"></td>
                            <td><span id="numerr"></span></td>
                        </tr>


                        <tr>
                            <td class="one">类别</td>
                            <td>
                                <select name="typeid" class="form-control">
                                    <c:forEach items="${typeList}" var="type">
                                        <option value="${type.typeId}">${type.typeName}</option>
                                    </c:forEach>
                                </select>
                            </td>
                        </tr>
                        <!--错误提示-->
                        <tr class="three">
                            <td class="four"></td>
                            <td><span></span></td>
                        </tr>

                        <tr>
                            <td>
                                <input type="submit" class="btn btn-success" value="提交" class="btn btn-success">
                            </td>
                            <td>
                                <button type="button" class="btn btn-info" data-dismiss="modal">取消</button>
                            </td>
                        </tr>
                    </table>
                </form>

            </div>

        </div>
        <!-- /.modal-content -->
    </div>
    <!-- /.modal -->
</div>
</body>

</html>

结果如图:

在这里插入图片描述
所有商品显示在一页中。

接下来,我们需要完成的是分页操作。分页操作实际上就是要在函数中实现 select * from product_info limit 10,5查询,在此我们使用 PageHelper 插件来辅助完成分页操作。

在 ProductService 接口中添加 splitPage 方法并在 ProductServiceImpl 进行实现

@Override
public PageInfo splitPage(int pageNum, int pageSize) {
    //使用分页插件 PageHelper 工具类完成分页设置
    PageHelper.startPage(pageNum, pageSize);
    
    List<ProductInfo> list = productInfoMapper.selectAll();
    
    //将查询到的集合封装进 PageInfo 对象中
    PageInfo<ProductInfo> pageInfo = new PageInfo<>(list);
    
    return pageInfo;
}

在控制层中,我们只需要将 splitPage() 方法执行即可,并将结果提交到 product.jsp 页面中
在这里插入图片描述
结果如图,第一页的数据就显现出来了

在这里插入图片描述
不过,此方法只能得到第一页的数据,要想得到第2、3、4等页的数据,我们需要定义 ajax 进行翻页操作

翻页事实上是修改 PageHelper.startPage(pageNum, pageSize) 的 pageNum 属性,在定义 ajax 请求时我们要特别地将页数 page 进行传入。

在这里插入图片描述
每次将 page 传入 ajaxSplit(page) 函数中,并将数据提交控制器给 ajaxSplit.action 中,新的page数据存入到session中,EL表达式${}的原理是每次刷新页面都重新从session中取出数据

ajax请求:

<script type="text/javascript">
    function ajaxsplit(page) {
        //向服务发出ajax请求,请示page页中的所有数据,在当前页面上局部刷新显示
        $.ajax({
            url: "${pageContext.request.contextPath}/prod/ajaxSplit.action",
            data: {"page": page},
            type: "post",
            success: function () {
                //重新加载显示分页数据的容器
                $("#table").load("http://localhost:8080/MyWeb/admin/product.jsp #table");
            }
        });
    }
</script>

控制器方法:

@RequestMapping("/ajaxSplit.action")
@ResponseBody
public void ajaxSplit(int page, HttpSession session) {
         PageInfo info = productInfoService.splitPage(page, 5);
         session.setAttribute("info", info);
}

结果:
在这里插入图片描述


未完待续

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-02-28 15:14:49  更:2022-02-28 15:14:59 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 11:52:15-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码