1 逆向工程设计
1.1 xml文件配置(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="testTables" targetRuntime="MyBatis3">
<commentGenerator>
<!-- 是否去除自动生成的注释 true:是 : false:否 -->
<property name="suppressAllComments" value="true" />
</commentGenerator>
<!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/xiaomissm?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true" userId="root"
password="123456">
</jdbcConnection>
<!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL 和
NUMERIC 类型解析为java.math.BigDecimal -->
<javaTypeResolver>
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
<!-- targetProject:生成PO类的位置 -->
<javaModelGenerator targetPackage="com.bjpowernode.pojo"
targetProject=".\src">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
<!-- 从数据库返回的值被清理前后的空格 -->
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!-- targetProject:mapper映射文件生成的位置 -->
<sqlMapGenerator targetPackage="com.bjpowernode.mapper"
targetProject=".\src">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
</sqlMapGenerator>
<!-- targetPackage:mapper接口生成的位置 -->
<javaClientGenerator type="XMLMAPPER"
targetPackage="com.bjpowernode.mapper"
targetProject=".\src">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
</javaClientGenerator>
<!-- 指定数据库表 -->
<table schema="" tableName="admin"></table>
<table schema="" tableName="product_info"></table>
<table schema="" tableName="product_type"></table>
</context>
</generatorConfiguration>
1.2 工具类
public class GeneratorSqlmap {
public GeneratorSqlmap() {
}
public void generator() throws Exception {
List<String> warnings = new ArrayList();
boolean overwrite = true;
File configFile = new File("generatorConfig.xml");
ConfigurationParser cp = new ConfigurationParser(warnings);
Configuration config = cp.parseConfiguration(configFile);
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
myBatisGenerator.generate((ProgressCallback)null);
}
public static void main(String[] args) throws Exception {
try {
GeneratorSqlmap generatorSqlmap = new GeneratorSqlmap();
generatorSqlmap.generator();
} catch (Exception var2) {
var2.printStackTrace();
}
}
}
1.3 结果展示
2 配置文件的设置
首先先建立一个maven 项目
2.1 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.zcl</groupId>
<artifactId>mimissm</artifactId>
<version>1.0</version>
<packaging>war</packaging>
<!-- 集中定义依赖版本号 -->
<properties>
<junit.version>4.12</junit.version>
<spring.version>5.3.9</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>org.json</groupId>
<artifactId>json</artifactId>
<version>20140107</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>
<!--log4j 日志文件-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.2</version>
</dependency>
</dependencies>
<!-- 插件配置 -->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
<!--识别所有的配置文件-->
<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>
</build>
</project>
2.2 数据库连接配置文件
2.2.1 jdbc.properties
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/zclshop?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
jdbc.username=root
jdbc.password=123456
2.2.2 mybatisConfig.xml
<?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>
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<!-- 分页插件的配置-->
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor"/>
</plugins>
</configuration>
2.2.3 applicationContext_dao.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/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!--读取jdbc.properties-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- 创建数据源-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!-- 创建SqlSessionFactoryBean-->
<bean class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 配置数据源-->
<property name="dataSource" ref="dataSource"/>
<!-- 配置Mybatis的核心配置文件-->
<property name="configLocation" value="classpath:mybatisConfig.xml"/>
<!-- 配置实体类-->
<property name="typeAliasesPackage" value="com.zcl.pojo"/>
</bean>
<!-- 创建mapper文件扫描-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.zcl.mapper"/>
</bean>
</beans>
2.2 事务配置文件
<?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>-->
<!-- 设置业务逻辑层的包扫描器,目的是在指定的路径下,使用@Service注解的类,Spring负责创建对象,并添加依赖-->
<context:component-scan base-package="com.zcl.service"></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="*find*" read-only="true"/>
<tx:method name="*get*" read-only="true"/>
<tx:method name="*search*" read-only="true"/>
<tx:method name="*insert*" propagation="REQUIRED"/>
<tx:method name="*save*" propagation="REQUIRED"/>
<tx:method name="*add*" propagation="REQUIRED"/>
<tx:method name="*delete*" propagation="REQUIRED"/>
<tx:method name="*remove*" propagation="REQUIRED"/>
<tx:method name="*clear*" propagation="REQUIRED"/>
<tx:method name="*update*" propagation="REQUIRED"/>
<tx:method name="*modify*" propagation="REQUIRED"/>
<tx:method name="*change*" propagation="REQUIRED"/>
<tx:method name="*set*" propagation="REQUIRED"/>
<tx:method name="*" propagation="SUPPORTS"/>
</tx:attributes>
</tx:advice>
<!-- 完成切面和切入点的织入-->
<aop:config>
<aop:pointcut id="mypointcut" expression="execution(* com.zcl.service.*.*(..))"/>
<aop:advisor advice-ref="myadvice" pointcut-ref="mypointcut"></aop:advisor>
</aop:config>
</beans>
2.3 springmvc.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"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 设置包扫描器-->
<context:component-scan base-package="com.zcl.controller"/>
<!-- 设置视图解析器 /admin/ main .jsp-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!-- 设置文件上传核心组件-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
</bean>
<!-- 设置注解驱动-->
<mvc:annotation-driven></mvc:annotation-driven>
</beans>
2.4 前端控制器:web.xml
<?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>encode</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>
</filter>
<filter-mapping>
<filter-name>encode</filter-name>
<url-pattern>*.action</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>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- 拦截配置:拦截以.action 结尾的请求-->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!-- <url-pattern>*.action</url-pattern>-->
<url-pattern>*.action</url-pattern>
</servlet-mapping>
<!--spring框架注册-->
<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>
<!-- 自动跳转到登录界面-->
<welcome-file-list>
<welcome-file>/WEB-INF/pages/admin/login.jsp</welcome-file>
</welcome-file-list>
</web-app>
2.5 工具类
FileNameUtil.java
package com.zcl.utils;
import java.util.UUID;
public class FileNameUtil {
//根据UUID生成文件名
public static String getUUIDFileName() {
UUID uuid = UUID.randomUUID();
return uuid.toString().replace("-", "");
}
//从请求头中提取文件名和类型
public static String getRealFileName(String context) {
// Content-Disposition: form-data; name="myfile"; filename="a_left.jpg"
int index = context.lastIndexOf("=");
String filename = context.substring(index + 2, context.length() - 1);
return filename;
}
//根据给定的文件名和后缀截取文件名
public static String getFileType(String fileName){
//9527s.jpg
int index = fileName.lastIndexOf(".");
return fileName.substring(index);
}
}
MD5Util.java
package com.zcl.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;
}
}
3 登录注册模块设计
3.1 登录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" value="admin" 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" value="123456" 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>
3.2 service层
adminService.java
//完成登录
Admin login(String name,String pwd);
adminServiceImpl.java
public Admin login(String name, String pwd) {
//根据用户名查询
//创建封装条件
AdminExample adminExample = new AdminExample();
//添加用户名a_name条件
adminExample.createCriteria().andANameEqualTo(name);
List<Admin> adminList = adminMapper.selectByExample(adminExample);
if (adminList.size() > 0) {
Admin admin = adminList.get(0);
//进行密码比对,数据密码是用md5加密的
String miPwd= MD5Util.getMD5(pwd);
if(miPwd.equals(admin.getaPass())){
return admin;
}
}
return null;
}
3.3 controller
adminAction.java
@RequestMapping("/login.action")
public String login(String name, String pwd, HttpServletRequest request){
Admin admin=adminService.login(name,pwd);
System.out.println(admin);
if(admin!=null){
//登录成功
request.setAttribute("admin",admin);
return "admin/main";
}else{
//登录失败
request.setAttribute("errmsg","用户名或密码错误");
return "admin/login";
}
}
4 商品模块设计
4.1 商品分页展示
4.1.1 分页查询类–PageInfo
这里面有三个属性:
pageNum:当前页码
pageSize:页面显示记录数
total:总记录
4.1.2 service层
ProductInfoService.java
//分页功能实现
PageInfo splitPage(int pageNum,int pageSize);
ProductInfoServiceImpl.java
@Override
public PageInfo splitPage(int pageNum, int pageSize) {
//分页插件PageHelper工具类进行实现
PageHelper.startPage(pageNum,pageSize);
//进行PageInfo的数据封装
//进行有条件的查询操作,创建ProductInfoExample对象
ProductInfoExample example = new ProductInfoExample();
//设置排序,按照id降序
example.setOrderByClause("p_id desc");
List<ProductInfo>list=productInfoMapper.selectByExample(example);
PageInfo<ProductInfo> pageInfo = new PageInfo<>(list);
return pageInfo;
}
4.1.3 controller层
//分页显示商品
@RequestMapping("/splitPage.action")
public String viewGoodsByPage(HttpServletRequest request) {
PageInfo info = null;
//根据条件进行查询
//得到第一页是数据
info = productInfoService.splitPage(1, PAGE_SIZE);
request.setAttribute("info", info);
return "product/product";
}
4.2 图片上传功能
4.2.1 ajaxfileupload.js 文件
jQuery.extend({
createUploadIframe: function(id, uri)
{
//create frame
var frameId = 'jUploadFrame' + id;
if(window.ActiveXObject) {
var io = document.createElement('<iframe id="' + frameId + '" name="' + frameId + '" />');
if(typeof uri== 'boolean'){
io.src = 'javascript:false';
}
else if(typeof uri== 'string'){
io.src = uri;
}
}
else {
var io = document.createElement('iframe');
io.id = frameId;
io.name = frameId;
}
io.style.position = 'absolute';
io.style.top = '-1000px';
io.style.left = '-1000px';
document.body.appendChild(io);
return io
},
createUploadForm: function(id, fileElementId)
{
//create form
var formId = 'jUploadForm' + id;
var fileId = 'jUploadFile' + id;
var form = $('<form action="" method="POST" name="' + formId + '" id="' + formId + '" enctype="multipart/form-data"></form>');
var oldElement = $('#' + fileElementId);
var newElement = $(oldElement).clone();
$(oldElement).attr('id', fileId);
$(oldElement).before(newElement);
$(oldElement).appendTo(form);
//set attributes
$(form).css('position', 'absolute');
$(form).css('top', '-1200px');
$(form).css('left', '-1200px');
$(form).appendTo('body');
return form;
},
ajaxFileUpload: function(s) {
// TODO introduce global settings, allowing the client to modify them for all requests, not only timeout
s = jQuery.extend({}, jQuery.ajaxSettings, s);
var id = s.fileElementId;
var form = jQuery.createUploadForm(id, s.fileElementId);
var io = jQuery.createUploadIframe(id, s.secureuri);
var frameId = 'jUploadFrame' + id;
var formId = 'jUploadForm' + id;
// Watch for a new set of requests
if ( s.global && ! jQuery.active++ )
{
jQuery.event.trigger( "ajaxStart" );
}
var requestDone = false;
// Create the request object
var xml = {}
if ( s.global )
jQuery.event.trigger("ajaxSend", [xml, s]);
// Wait for a response to come back
var uploadCallback = function(isTimeout)
{
var io = document.getElementById(frameId);
try
{
if(io.contentWindow)
{
xml.responseText = io.contentWindow.document.body?io.contentWindow.document.body.innerHTML:null;
xml.responseXML = io.contentWindow.document.XMLDocument?io.contentWindow.document.XMLDocument:io.contentWindow.document;
}else if(io.contentDocument)
{
xml.responseText = io.contentDocument.document.body?io.contentDocument.document.body.innerHTML:null;
xml.responseXML = io.contentDocument.document.XMLDocument?io.contentDocument.document.XMLDocument:io.contentDocument.document;
}
}catch(e)
{
jQuery.handleError(s, xml, null, e);
}
if ( xml || isTimeout == "timeout")
{
requestDone = true;
var status;
try {
status = isTimeout != "timeout" ? "success" : "error";
// Make sure that the request was successful or notmodified
if ( status != "error" )
{
// process the data (runs the xml through httpData regardless of callback)
var data = jQuery.uploadHttpData( xml, s.dataType );
// If a local callback was specified, fire it and pass it the data
if ( s.success )
s.success( data, status );
// Fire the global callback
if( s.global )
jQuery.event.trigger( "ajaxSuccess", [xml, s] );
} else
jQuery.handleError(s, xml, status);
} catch(e)
{
status = "error";
jQuery.handleError(s, xml, status, e);
}
// The request was completed
if( s.global )
jQuery.event.trigger( "ajaxComplete", [xml, s] );
// Handle the global AJAX counter
if ( s.global && ! --jQuery.active )
jQuery.event.trigger( "ajaxStop" );
// Process result
if ( s.complete )
s.complete(xml, status);
jQuery(io).unbind()
setTimeout(function()
{ try
{
$(io).remove();
$(form).remove();
} catch(e)
{
jQuery.handleError(s, xml, null, e);
}
}, 100)
xml = null
}
}
// Timeout checker
if ( s.timeout > 0 )
{
setTimeout(function(){
// Check to see if the request is still happening
if( !requestDone ) uploadCallback( "timeout" );
}, s.timeout);
}
try
{
// var io = $('#' + frameId);
var form = $('#' + formId);
$(form).attr('action', s.url);
$(form).attr('method', 'POST');
$(form).attr('target', frameId);
if(form.encoding)
{
form.encoding = 'multipart/form-data';
}
else
{
form.enctype = 'multipart/form-data';
}
$(form).submit();
} catch(e)
{
jQuery.handleError(s, xml, null, e);
}
if(window.attachEvent){
document.getElementById(frameId).attachEvent('onload', uploadCallback);
}
else{
document.getElementById(frameId).addEventListener('load', uploadCallback, false);
}
return {abort: function () {}};
},
uploadHttpData: function( r, type ) {
var data = !type;
data = type == "xml" || data ? r.responseXML : r.responseText;
// If the type is "script", eval it in global context
if ( type == "script" )
jQuery.globalEval( data );
// Get the JavaScript object, if JSON is used.
if ( type == "json" )
eval( "data = " + data );
// evaluate scripts within html
if ( type == "html" )
jQuery("<div>").html(data).evalScripts();
//alert($('param', data).each(function(){alert($(this).attr('value'));}));
return data;
}
})
4.2.2 前端请求(jQuery引用ajaxfileupload.js)
<script type="text/javascript">
function fileChange(){
$.ajaxFileUpload({
url:"${pageContext.request.contextPath}/prod/ajaxImg.action",
secureuri: false,//是否遵循安全协议
fileElementId: 'pimage',
dataType:"json",
success:function(res){
//创建一个图片标签
var imgObj=$("<img>");
//图片在服务器中的相对位置
imgObj.attr("src","/mimissm/image_big/"+res.imgurl);
imgObj.attr("width","100px");
imgObj.attr("height","100px");
//将图片追加到imgDiv
$("#imgDiv").append(imgObj);
},
error: function (e)//服务器响应失败处理函数
{
alert(e.message);
}
})
}
</script>
4.2.3 springMVC
<!-- 设置文件上传核心组件-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
</bean>
4.2.4 controller
//异步ajax文件上传
@ResponseBody
@RequestMapping("/ajaxImg.action")
public Object ajaxImg(MultipartFile pimage, HttpServletRequest request) {
//提取生成文件名UUID+上传图片后缀
saveFileName = FileNameUtil.getUUIDFileName() + FileNameUtil.getFileType(pimage.getOriginalFilename());
//得到项目中图片存储的路径
String path = request.getServletContext().getRealPath("/image_big");
//转存
try {
pimage.transferTo(new File(path + File.separator + saveFileName));
} catch (IOException e) {
e.printStackTrace();
}
//返回客户端JSON对象,封装图片路径
JSONObject jsonObject = new JSONObject();
jsonObject.put("imgurl", saveFileName);
return jsonObject.toString();
}
4.2 商品新增
4.2.1 service
ProductInfoService.java
//添加功能
int save(ProductInfo info);
ProductInfoServiceImpl.java
//添加功能
@Override
public int save(ProductInfo info) {
return productInfoMapper.insert(info);
}
4.2.2 controller
@RequestMapping("/save.action")
public String save(ProductInfo info, HttpServletRequest request) {
info.setpDate(new Date());
info.setpImage(saveFileName);
//info有表单提交上来的五个数据,有异步Ajax上来的图片名称数据,还有上架时间数据
int num = -1;
try {
num = productInfoService.save(info);
} catch (Exception e) {
e.printStackTrace();
}
if (num > 0) {
//增加成功
request.setAttribute("msg", "增加成功");
} else {
//增加失败
request.setAttribute("msg", "增加失败");
}
//清空saveFileName
saveFileName = "";
//增加成功后应该重新访问数据库,跳转到分页查询的action
return "forward:/prod/splitPage.action";
}
4.3 商品更新
4.3.1 商品的回显
4.3.1.1 service
ProductInfo.java
//按主键id查询
ProductInfo getById(int pid);
ProductInfoImpl.java
@Override
public ProductInfo getById(int pid) {
return productInfoMapper.selectByPrimaryKey(pid);
}
4.3.1.2 controller
@RequestMapping("/one.action")
public String one(int pid, ProductInfoVo vo, Model model, HttpSession session) {
ProductInfo info = productInfoService.getById(pid);
model.addAttribute("prod", info);
//将多条件及页码放到session中
session.setAttribute("prodvo", vo);
return "product/updateProduct";
}
4.3.2 商品的更新
4.3.2.1 service
ProductInfo.java
//更新商品
int update(ProductInfo info);
ProductInfoImpl.java
@Override
public int update(ProductInfo info) {
return productInfoMapper.updateByPrimaryKey(info);
}
4.3.2.2 controller
@RequestMapping("/update.action")
public String update(ProductInfo info, HttpServletRequest request) {
//图片上传处理
if (!saveFileName.equals("")) {
info.setpImage(saveFileName);
}
//完成更新操作
int num = -1;
try {
num = productInfoService.update(info);
} catch (Exception e) {
e.printStackTrace();
}
if (num > 0) {
//更新成功
request.setAttribute("msg", "更新成功");
} else {
//更新失败
request.setAttribute("msg", "更新失败");
}
//更新savaFileName
saveFileName = "";
return "forward:/prod/splitPage.action";
}
4.4 商品删除
4.4.1 service
ProductInfo.java
//单个商品删除
int delete(int pid);
ProductInfoImpl.java
@Override
public int delete(int pid) {
return productInfoMapper.deleteByPrimaryKey(pid);
}
4.4.2 controller
@RequestMapping("/delete.action")
public String delete(int pid, HttpServletRequest request) {
int num = -1;
try {
num = productInfoService.delete(pid);
} catch (Exception e) {
e.printStackTrace();
}
if (num > 0) {
//删除成功
request.setAttribute("msg", "删除成功");
} else {
//删除失败
request.setAttribute("msg", "删除失败");
}
//跳转到分页
return "forward:/prod/deleteAjaxSplit.action";
}
4.5 批量删除
4.5.1 dao
ProductInfoMapper.java
int deleteBath(String []ids);
ProductInfoMapper.xml
<!-- 批量删除-->
<delete id="deleteBath">
delete from product_info where p_id in
<foreach collection="array" item="pid" separator="," open="(" close=")">
#{pid}
</foreach>
</delete>
4.5.2 service
ProductInfo.java
//批量删除
int deleteBatch(String[] ids);
ProductInfoImpl.java
@Override
public int deleteBatch(String[] ids) {
return productInfoMapper.deleteBath(ids);
}
4.5.3 controller
//批量删除商品
@RequestMapping("/deleteBatch.action")
public String deleteBatch(String pids, HttpServletRequest request) {
//将上传上来的字符串截开,形成商品id的字符数组
String[] ps = pids.split(",");
int num = productInfoService.deleteBatch(ps);
try {
if (num > 0) {
request.setAttribute("msg", "批量删除成功!");
} else {
request.setAttribute("msg", "批量删除失败!");
}
} catch (Exception e) {
request.setAttribute("msg", "商品不可删除!");
}
return "forward:/prod/deleteAjaxSplit.action";
}
4.6 多条件查询
4.6.1 封装条件查询类:ProductInfoVo.java
package com.zcl.pojo.vo;
/**
* @author ZCL
* @Description
* @date 2022/12/14 15:00
*/
public class ProductInfoVo {
//商品名称
private String pname;
//商品类型
private Integer typeid;
//最低价格
private Integer lprice;
//最高价格
private Integer hprice;
//设置页码
private Integer page=1;
public ProductInfoVo(String pname, Integer typeid, Integer lprice, Integer hprice, Integer page) {
this.pname = pname;
this.typeid = typeid;
this.lprice = lprice;
this.hprice = hprice;
this.page = page;
}
public ProductInfoVo() {
}
public String getPname() {
return pname;
}
public void setPname(String pname) {
this.pname = pname;
}
public Integer getTypeid() {
return typeid;
}
public void setTypeid(Integer typeid) {
this.typeid = typeid;
}
public Integer getLprice() {
return lprice;
}
public void setLprice(Integer lprice) {
this.lprice = lprice;
}
public Integer getHprice() {
return hprice;
}
public void setHprice(Integer hprice) {
this.hprice = hprice;
}
public Integer getPage() {
return page;
}
public void setPage(Integer page) {
this.page = page;
}
@Override
public String toString() {
return "ProductInfoVo{" +
"pname='" + pname + '\'' +
", typeid=" + typeid +
", lprice=" + lprice +
", hprice=" + hprice +
", page=" + page +
'}';
}
}
4.6.2 dao
ProductInfoMapper.java
//多条件查询
List<ProductInfo> selectCondition(ProductInfoVo vo);
ProductInfoMapper.xml
<!-- 多条件查询-->
<select id="selectCondition" resultMap="BaseResultMap" parameterType="com.zcl.pojo.vo.ProductInfoVo">
select
<include refid="Base_Column_List"></include>
from product_info
<where>
<if test="pname !=null and pname != '' ">
and p_name like '%${pname}%'
</if>
<if test="typeid !=null and typeid != '' ">
and type_id like '%${typeid}%'
</if>
<if test="(lprice!=null and lprice!='') and (hprice==null or hprice=='')">
and p_price >= #{lprice}
</if>
<if test="(lprice==null or lprice=='') and (hprice!=null and hprice!='')">
and p_price <= #{hprice}
</if>
<if test="(lprice!=null and lprice!='') and (hprice!=null and hprice!='')">
and p_price between #{lprice} and #{hprice}
</if>
</where>
</select>
4.6.3 service
ProductInfo.java
//多条件查询
List<ProductInfo> selectCondition(ProductInfoVo vo);
ProductInfoImpl.java
@Override
public List<ProductInfo> selectCondition(ProductInfoVo vo) {
return productInfoMapper.selectCondition(vo);
}
4.6.4 controller
@ResponseBody
@RequestMapping("/condition.action")
public void searchCondition(ProductInfoVo vo, HttpSession session) {
List<ProductInfo> list = productInfoService.selectCondition(vo);
session.setAttribute("list", list);
}
4.7 模块优化
4.7.1 多条件分页查询
ProductInfoService.java
//多条件查询分页
PageInfo splitPageVo(ProductInfoVo vo,int pageSize);
ProductInfoServiceImpl.java
@Override
public PageInfo splitPageVo(ProductInfoVo vo, int pageSize) {
//设置PageHelper
PageHelper.startPage(vo.getPage(),pageSize);
List<ProductInfo> list = productInfoMapper.selectCondition(vo);
return new PageInfo<>(list);
}
4.7.2 分页查询优化
//分页显示商品
@RequestMapping("/splitPage.action")
public String viewGoodsByPage(HttpServletRequest request) {
PageInfo info = null;
Object vo = request.getSession().getAttribute("prodvo");
if (vo != null) {
//根据条件进行查询
info = productInfoService.splitPageVo((ProductInfoVo) vo, PAGE_SIZE);
request.getSession().removeAttribute("prodvo");
} else {
//得到第一页是数据
info = productInfoService.splitPage(1, PAGE_SIZE);
}
request.setAttribute("info", info);
return "product/product";
}
4.7.3 删除优化
@RequestMapping("/delete.action")
public String delete(int pid,ProductInfoVo vo, HttpServletRequest request) {
int num = -1;
try {
num = productInfoService.delete(pid);
} catch (Exception e) {
e.printStackTrace();
}
if (num > 0) {
//删除成功
request.setAttribute("msg", "删除成功");
request.getSession().setAttribute("deleteProdvo",vo);
} else {
//删除失败
request.setAttribute("msg", "删除失败");
}
//跳转到分页
return "forward:/prod/deleteAjaxSplit.action";
}
@ResponseBody
@RequestMapping(value = "/deleteAjaxSplit.action", produces = "text/html;charset=UTF-8")
public Object deleteAjaxSplit(HttpServletRequest request) {
PageInfo info=null;
Object vo=request.getSession().getAttribute("deleteProdvo");
if (vo!=null){
info=productInfoService.splitPageVo((ProductInfoVo) vo,PAGE_SIZE);
}else{
//显示第一页数据
info = productInfoService.splitPage(1, PAGE_SIZE);
}
request.getSession().setAttribute("info", info);
return request.getAttribute("msg");
}
4.7.4 更新优化
@RequestMapping("/one.action")
public String one(int pid, ProductInfoVo vo, Model model, HttpSession session) {
ProductInfo info = productInfoService.getById(pid);
model.addAttribute("prod", info);
//将多条件及页码放到session中
session.setAttribute("prodvo", vo);
return "product/updateProduct";
}
@RequestMapping("/update.action")
public String update(ProductInfo info, HttpServletRequest request) {
//图片上传处理
if (!saveFileName.equals("")) {
info.setpImage(saveFileName);
}
//完成更新操作
int num = -1;
try {
num = productInfoService.update(info);
} catch (Exception e) {
e.printStackTrace();
}
if (num > 0) {
//更新成功
request.setAttribute("msg", "更新成功");
} else {
//更新失败
request.setAttribute("msg", "更新失败");
}
//更新savaFileName
saveFileName = "";
return "forward:/prod/splitPage.action";
}
4.7.5 翻页优化
//ajax翻页处理
@ResponseBody
@RequestMapping("/ajaxSplit.action")
public void ajaxSplit(ProductInfoVo vo, HttpSession session) {
PageInfo info = productInfoService.splitPageVo(vo, PAGE_SIZE);
session.setAttribute("info", info);
}
4.8 前端页面开发
main.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/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>欢迎您,${admin.aName}</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/splitPage.action" target="myright" >
<li class="two"><span class="glyphicon glyphicon-book" style="color: white;"></span> 商品管理 <span class="glyphicon glyphicon-play" style="color: white;"></span> </li>
</a>
<a href="${pageContext.request.contextPath}/WEB-INF/pages/admin/err.jsp" target="myright">
<li class="one"><span class="glyphicon glyphicon-sort" style="color: white;"></span> 订单管理 <span class="glyphicon glyphicon-play" style="color: white;"></span> </li>
</a>
<a href="${pageContext.request.contextPath}/WEB-INF/pages/admin/err.jsp" target="myright">
<li class="one"><span class="glyphicon glyphicon-user" style="color: white;"></span> 用户管理 <span class="glyphicon glyphicon-play" style="color: white;"></span> </li>
</a>
<a href="${pageContext.request.contextPath}/WEB-INF/pages/admin/err.jsp" target="myright">
<li class="one"><span class="glyphicon glyphicon-bullhorn" style="color: white"></span> 通知公告 <span class="glyphicon glyphicon-play" style="color: white;"></span> </li>
</a>
</ul>
</div>
</div>
<!--下部分右边-->
<div id="bright">
<iframe frameborder="0" scrolling="yes" name="myright" width="1235px" height="700px" ></iframe>
</div>
</div>
</div>
</body>
</html>
product.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@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>
<script type="text/javascript">
//全选复选框功能实现
function allClick() {
//获得当前点击后全选按钮的状态
var flag = $("#all").prop("checked");
//将此状态赋值给下面五个复选框
$("input[name='ck']").each(function () {
this.checked = flag;
});
}
//单个复选框点击改变全选复选框功能实现
function ckClick() {
//得到下面五个复选框的个数
var fiveLength = $("input[name='ck']").length;
//得到下面五个复选框被选中的个数
var checkedLength = $("input[name='ck']:checked").length;
//进行对比,改变全选复选框的状态
if (fiveLength == checkedLength) {
$("#all").prop("checked", true);
} else {
$("#all").prop("checked", false);
}
}
</script>
<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">
商品类型:<select name="typeid" id="typeid">
<option value="0">请选择</option>
<c:forEach items="${typeList}" var="pt">
<option value="${pt.typeId}">${pt.typeName}</option>
</c:forEach>
</select>
价格:<input name="lprice" id="lprice">-<input name="hprice" id="hprice">
<input type="button" value="查询" onclick="condition()">
</form>
</div>
<br>
<div id="table">
<c:choose>
<c:when test="${info.list.size()!=0}">
<div id="top">
<input type="checkbox" id="all" onclick="allClick()" style="margin-left: 50px"> 全选
<a onclick="toAdd(${info.pageNum})">
<input type="button" class="btn btn-warning" id="btn1" value="新增商品">
</a>
<input type="button" class="btn btn-warning" id="btn1" value="批量删除" onclick="deleteBatch()">
</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="${info.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>
<c:if test="${p.pImage!='' and p.pImage!=null}">
<img width="55px" height="45px"
src="${pageContext.request.contextPath}/image_big/${p.pImage}">
</c:if>
</td>
<td>${p.pNumber}</td>
<%--<td><a href="${pageContext.request.contextPath}/admin/product?flag=delete&pid=${p.pId}" onclick="return confirm('确定删除吗?')">删除</a>--%>
<%-- <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},${info.pageNum})">编辑
</button>
<button type="button" class="btn btn-warning" id="mydel"
onclick="del(${p.pId},${info.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=${info.prePage}" aria-label="Previous">--%>
<a href="javascript:ajaxsplit(${info.prePage})" aria-label="Previous">
<span aria-hidden="true">«</span></a>
</li>
<c:forEach begin="1" end="${info.pages}" var="i">
<c:if test="${info.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="${info.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(${info.nextPage})" aria-label="Next">
<span aria-hidden="true">»</span></a>
</li>
<li style=" margin-left:150px;color: #0e90d2;height: 35px; line-height: 35px;">总共 <font
style="color:orange;">${info.pages}</font> 页
<c:if test="${info.pageNum!=0}">
当前 <font
style="color:orange;">${info.pageNum}</font> 页
</c:if>
<c:if test="${info.pageNum==0}">
当前 <font
style="color:orange;">1</font> 页
</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>
</body>
<script type="text/javascript">
function toAdd(page) {
//取出查询条件
var pname = $("#pname").val();
var typeid = $("#typeid").val();
var lprice = $("#lprice").val();
var hprice = $("#hprice").val();
//向服务器提交请求,传递商品id
var str = "?page=" + page + "&pname=" + pname + "&typeid=" + typeid + "&lprice=" + lprice + "&hprice=" + hprice;
location.href = "${pageContext.request.contextPath}/prod/toAdd.action" + str;
}
function mysubmit() {
$("#myform").submit();
}
//批量删除
function deleteBatch() {
//得到所有选中复选框的对象,根据其长度判断是否有选中商品
var cks = $("input[name='ck']:checked"); //1,4,5
//如果有选中的商品,获取其value的值,进行字符串拼接
if (cks.length == 0) {
alert("请选择将要删除的商品");
} else {
var str = "";
var id = "";
if (confirm("你确定要删除" + cks.length + "条商品")) {
// alert("可以进行删除!")
//进行提交商品id的字符串的拼接
$.each(cks, function () {
pid = $(this).val(); //每一个被选中商品的id
//进行非空判断,避免出错
if (pid != null) {
str += pid + ",";
}
});
//发送ajax请求,进行批量删除的提交
$.ajax({
url: "${pageContext.request.contextPath}/prod/deleteBatch.action",
data: {"pids": str},
type: "post",
dataType: "text",
success: function (msg) {
alert(msg);//批量删除提示信息
//将页面上显示商品数据的容器重新加载
$("#table").load("http://localhost:8080/mimissm/prod/toProduct.action #table")
}
})
}
}
}
//单个删除
function del(pid, page) {
//弹框提示
if (confirm("你确定删除吗?")) {
//取出查询条件
var pname = $("#pname").val();
var typeid = $("#typeid").val();
var lprice = $("#lprice").val();
var hprice = $("#hprice").val();
//ajax请求
$.ajax({
url: "${pageContext.request.contextPath}/prod/delete.action",
data: {"pid": pid, "page": page, "pname": pname, "typeid": typeid, "lprice": lprice, "hprice": hprice},
type: "post",
dataType: "text",
success: function (msg) {
alert(msg);
$("#table").load("http://localhost:8080/mimissm/prod/toProduct.action #table")
}
})
}
}
function one(pid, page) {
//取出查询条件
var pname = $("#pname").val();
var typeid = $("#typeid").val();
var lprice = $("#lprice").val();
var hprice = $("#hprice").val();
//向服务器提交请求,传递商品id
var str = "?pid=" + pid + "&page=" + page + "&pname=" + pname + "&typeid=" + typeid + "&lprice=" + lprice + "&hprice=" + hprice;
location.href = "${pageContext.request.contextPath}/prod/one.action" + str;
}
</script>
<!--分页的AJAX实现-->
<script type="text/javascript">
function ajaxsplit(page) {
//取出查询条件
var pname = $("#pname").val();
var typeid = $("#typeid").val();
var lprice = $("#lprice").val();
var hprice = $("#hprice").val();
//向服务发出ajax请求,请示page页中的所有数据,在当前页面上局部刷新显示
$.ajax({
url: "${pageContext.request.contextPath}/prod/ajaxSplit.action",
data: {"page": page, "pname": pname, "typeid": typeid, "lprice": lprice, "hprice": hprice},
type: "post",
success: function () {
//重新加载显示分页数据
$("#table").load("http://localhost:8080/mimissm/prod/toProduct.action #table")
}
});
}
function condition() {
//取出查询条件
var pname = $("#pname").val();
var typeid = $("#typeid").val();
var lprice = $("#lprice").val();
var hprice = $("#hprice").val();
$.ajax({
type: "post",
url: "${pageContext.request.contextPath}/prod/ajaxSplit.action",
data: {"pname": pname, "typeid": typeid, "lprice": lprice, "hprice": hprice},
success: function () {
//重新加载显示分页数据
$("#table").load("http://localhost:8080/mimissm/prod/toProduct.action #table")
}
})
}
</script>
</html>
addProduct.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/css/bootstrap.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>
<script type="text/javascript" src="${pageContext.request.contextPath }/js/jquery.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath }/js/ajaxfileupload.js"></script>
</head>
<script type="text/javascript">
function fileChange(){
$.ajaxFileUpload({
url:"${pageContext.request.contextPath}/prod/ajaxImg.action",
secureuri: false,//是否遵循安全协议
fileElementId: 'pimage',
dataType:"json",
success:function(res){
//创建一个图片标签
var imgObj=$("<img>");
imgObj.attr("src","/mimissm/image_big/"+res.imgurl);
imgObj.attr("width","100px");
imgObj.attr("height","100px");
//将图片追加到imgDiv
$("#imgDiv").append(imgObj);
},
error: function (e)//服务器响应失败处理函数
{
alert(e.message);
}
})
}
</script>
<body>
<!--取出上一个页面上带来的page的值-->
<div id="addAll">
<div id="nav">
<p>商品管理>新增商品</p>
</div>
<div id="table">
<form id="myform" action="${pageContext.request.contextPath}/prod/save.action">
<table>
<tr>
<td class="one">商品名称</td>
<td><input type="text" name="pName" class="two"></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"></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"></td>
</tr>
<!--错误提示-->
<tr class="three">
<td class="four"></td>
<td><span id="priceerr"></span></td>
</tr>
<tr>
<td class="three">图片介绍</td>
<td> <br><div id="imgDiv" style="display:block; width: 40px; height: 50px;"></div><br><br><br><br>
<input type="file" id="pimage" name="pimage" onchange="fileChange()" >
<span id="imgName" ></span><br>
</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"></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" >
<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" value="提交" class="btn btn-success">
</td>
<td>
<input type="reset" value="取消" class="btn btn-default" onclick="myclose()">
<script type="text/javascript">
function myclose() {
location.href = "${pageContext.request.contextPath}/prod/splitPage.action";
}
</script>
</td>
</tr>
</table>
</form>
</div>
</div>
</body>
</html>
update.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/css/bootstrap.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>
<script type="text/javascript" src="${pageContext.request.contextPath }/js/ajaxfileupload.js"></script>
</head>
<body>
<div id="addAll">
<div id="nav">
<p>商品管理>更新商品</p>
</div>
<script type="text/javascript">
function fileChange(){//注意:此处不能使用jQuery中的change事件,因此仅触发一次,因此使用标签的:onchange属性
$.ajaxFileUpload({
url: '${pageContext.request.contextPath}/prod/ajaxImg.action',//用于文件上传的服务器端请求地址
secureuri: false,//一般设置为false
fileElementId: 'pimage',//文件上传控件的id属性 <input type="file" id="pimage" name="pimage" />
dataType: 'json',//返回值类型 一般设置为json
success: function(obj) //服务器成功响应处理函数
{
$("#imgDiv").empty(); //清空原有数据
//创建img 标签对象
var imgObj = $("<img>");
//给img标签对象追加属性
imgObj.attr("src","/mimissm/image_big/"+obj.imgurl);
imgObj.attr("width","100px");
imgObj.attr("height","100px");
//将图片img标签追加到imgDiv末尾
$("#imgDiv").append(imgObj);
//将图片的名称(从服务端返回的JSON中取得)赋值给文件本框
//$("#imgName").html(data.imgName);
},
error: function (e)//服务器响应失败处理函数
{
alert(e.message);
}
});
}
</script>
<script type="text/javascript">
function myclose() {
location.href = "${pageContext.request.contextPath}/prod/splitPage.action";
}
</script>
<div id="table">
<form action="${pageContext.request.contextPath}/prod/update.action" enctype="multipart/form-data" method="post" id="myform">
<input type="hidden" value="${prod.pId}" name="pId">
<input type="hidden" value="${prod.pImage}" name="pImage">
<table>
<tr>
<td class="one">商品名称</td>
<td><input type="text" name="pName" class="two" value="${prod.pName}"></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" value="${prod.pContent}"></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" value="${prod.pPrice}"></td>
</tr>
<!--错误提示-->
<tr class="three">
<td class="four"></td>
<td><span id="priceerr"></span></td>
</tr>
<tr>
<td class="one">图片介绍</td>
<td> <br><div id="imgDiv" style="display:block; width: 40px; height: 50px;"><img src="/mimissm/image_big/${prod.pImage}" width="100px" height="100px" ></div><br><br><br><br>
<input type="file" id="pimage" name="pimage" onchange="fileChange()">
<span id="imgName"></span><br>
</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" value="${prod.pNumber}"></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">
<c:forEach items="${typeList}" var="type">
<option value="${type.typeId}"
<c:if test="${type.typeId==prod.typeId}">
selected="selected"
</c:if>
>${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" value="提交" class="btn btn-success">
</td>
<td>
<input type="reset" value="取消" class="btn btn-default" onclick="myclose()">
</td>
</tr>
</table>
</form>
</div>
</div>
</body>
</html>