利用MVC(SpringMVC+Spring+MyBatis)实现购物车

利用MVC(SpringMVC+Spring+MyBatis)实现购物车

本试题使用Jsp+Spring+Mybatis+Mysql+Maven等技术实现购物车管理。

语言和环境

A、实现语言
Java
B、环境要求
JDK1.8、Eclipse、Tomcat7、SpringMVC、Spring、Mybatis、Mysql、Maven

功能要求

  1. 分页显示商品表中信息,如下图在这里插入图片描述
  2. 点击购买,显示购物车中的商品,如下图
    在这里插入图片描述

数据库设计

在这里插入图片描述

源码下载地址

https://download.csdn.net/download/pcbhyy/10765055

主要代码

数据库语句

use mydb;

create table tb_goods(
	id varchar(20) primary key,
    name varchar(20) not null,
    price double not null,
    company varchar(100) not null,
    leave_date timestamp not null,
    `desc` varchar(500)
)

insert into tb_goods values('12323434','桃李面包',6.0,'桃李食品公司','2018-06-09 12:00:05','桃李面包')

insert into tb_goods 
values
('9998734','桃李面包1',6.0,'桃李食品公司','2018-06-09 12:00:05','桃李面包'),
('34343434','桃李面包2',12.0,'桃李食品公司','2018-06-09 12:00:05','桃李面包'),
('494594594','桃李面包3',5.50,'桃李食品公司','2018-06-09 12:00:05','桃李面包'),
('458548548','桃李面包4',2.0,'桃李食品公司','2018-06-09 12:00:05','桃李面包')

select id,name,price,company,leave_date leaveDate,`desc` from tb_goods

实体类

package com.neu.entity;

import java.math.BigDecimal;
import java.util.Date;

public class Good {
	private String id;
	private String name;
	private BigDecimal price;
	private String company;
	private Date leaveDate;
	private String desc;
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Good other = (Good) obj;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		return true;
	}	
	public Good() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Good(String id, String name, BigDecimal price, String company, Date leaveDate, String desc) {
		super();
		this.id = id;
		this.name = name;
		this.price = price;
		this.company = company;
		this.leaveDate = leaveDate;
		this.desc = desc;
	}
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public BigDecimal getPrice() {
		return price;
	}
	public void setPrice(BigDecimal price) {
		this.price = price;
	}
	public String getCompany() {
		return company;
	}
	public void setCompany(String company) {
		this.company = company;
	}
	public Date getLeaveDate() {
		return leaveDate;
	}
	public void setLeaveDate(Date leaveDate) {
		this.leaveDate = leaveDate;
	}
	public String getDesc() {
		return desc;
	}
	public void setDesc(String desc) {
		this.desc = desc;
	}
}

mapper接口

package com.neu.mapper;

import java.util.List;

import org.apache.ibatis.annotations.Param;
import org.junit.runners.Parameterized.Parameters;

import com.neu.entity.Good;

public interface GoodMapper {
	public List<Good> getAll();
	//pageSize:每页最多有多少行,pageNum:第几页
	public List<Good> getPaged(@Param("pageSize") int pageSize,@Param("pageNum") int pageNum);
	//表中有多少行数据
	public int count();
	
	public Good getById(String id);
}

mapper

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.neu.mapper.GoodMapper">
	<select id="getAll" resultType="com.neu.entity.Good">
		select id,name,price,company,leave_date leaveDate,`desc` from tb_goods
	</select>
	
	<select id="getPaged" resultType="com.neu.entity.Good">
		select id,name,price,company,leave_date leaveDate,`desc` 
		from tb_goods
		limit ${(pageNum-1)*pageSize},${pageSize}
	</select>
	
	<select id="count" resultType="int">
		select count(*) from tb_goods
	</select>
	
	<select id="getById" resultType="com.neu.entity.Good">
		select id,name,price,company,leave_date leaveDate,`desc` 
		from tb_goods
		where id = #{id}
	</select>
</mapper>

业务逻辑层接口

package com.neu.service;

import java.util.List;

import org.apache.ibatis.annotations.Param;

import com.neu.entity.Good;

public interface GoodService {
	public List<Good> getAll();

	// pageSize:每页最多有多少行,pageNum:第几页
	public List<Good> getPaged(int pageSize,int pageNum);

	// 表中有多少行数据
	public int count();
	
	public Good getById(String id);
}

业务逻辑实现类

package com.neu.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.neu.entity.Good;
import com.neu.mapper.GoodMapper;

@Service
public class GoodServiceImpl implements GoodService {
	@Autowired
	private GoodMapper goodMapper;

	@Override
	public List<Good> getAll() {
		
		return goodMapper.getAll();
	}

	@Override
	public List<Good> getPaged(int pageSize, int pageNum) {
		
		return goodMapper.getPaged(pageSize, pageNum);
	}

	@Override
	public int count() {
		
		return goodMapper.count();
	}

	@Override
	public Good getById(String id) {
		
		return goodMapper.getById(id);
	}

}

控制器

package com.neu.controller;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpSession;

import org.apache.ibatis.annotations.Param;
import org.hibernate.validator.internal.util.IgnoreJava6Requirement;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import com.neu.entity.Good;
import com.neu.service.GoodService;

@Controller
public class GoodController {
	@Autowired
	private GoodService goodService;
	
	@RequestMapping("getPaged")
	public String getAll(@RequestParam(defaultValue="1") int pageNum,Model model) {
		int pageSize = 3;
		List<Good> list = goodService.getPaged(pageSize, pageNum);
		model.addAttribute("list",list);
		
		int count = goodService.count();
		//计算一共有多少页
		int pageCount = count % pageSize == 0?count/pageSize:count/pageSize+1;
		model.addAttribute("pageCount", pageCount);
		
		model.addAttribute("pageNum", pageNum);
		
		return "getall";
	}
	@RequestMapping("addToCart")
	public String addToCart(Good good,HttpSession session,Model model) {
		Map<Good, Integer> cart = (Map<Good, Integer>)session.getAttribute("cart");
		
		if(cart == null) {
			cart = new HashMap<>();//创建购物车Map集合
			good = goodService.getById(good.getId());//从数据库中查询商品信息
			cart.put(good, 1);//向购物车map集合中添加商品
			session.setAttribute("cart", cart);//向session中添加购物车
		}else {
			Integer n = cart.get(good);
			if(n == null) {
				good = goodService.getById(good.getId());//从数据库中查询商品信息
				cart.put(good, 1);				
			}else {
				cart.put(good, 1+n);
			}
		}
		
		BigDecimal sum = new BigDecimal(0);
		for(Good g : cart.keySet()) {
			sum = sum.add(g.getPrice().multiply( new BigDecimal(cart.get(g))));
		}
		
		model.addAttribute("sum", sum);
		return "cart";
	}
}

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
  <display-name>good_demo</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <!-- 
  	启动两个容器,
  	父容器:业务逻辑层和数据访问层组件 ,通过监听器,在启动web容器的同时,启动
  	子容器:控制器组件,通过前端控制器(Servlet),启动
  	子容器组件可以访问父容器组件
  -->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
  </context-param>
  <listener>
    <listener-class>
  		org.springframework.web.context.ContextLoaderListener
  	</listener-class>
  </listener>
  <servlet>
  	<servlet-name>DispatcherServlet</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>
  
  <servlet-mapping>
  	<servlet-name>DispatcherServlet</servlet-name>
  	<url-pattern>/</url-pattern>
  </servlet-mapping>
  
  <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>
  </filter>
  <filter-mapping>
  	<filter-name>CharacterEncodingFilter</filter-name>
  	<url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>

getall.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	<div style="text-align:center">
		<h1>商品信息浏览</h1>
		<table border="1" width="800" align="center">
			<tr>
				<th>编号</th><th>名称</th><th>价格</th><th>出厂日期</th><th>生产厂家</th><th>描述</th><th>操作</th>
			</tr>
			<c:forEach items="${ list }" var="good">
				<tr>
					<td>${ good.id }</td>
					<td>${ good.name }</td>
					<td>${ good.price }</td>
					<td><fmt:formatDate value="${ good.leaveDate }" pattern="yyyy-MM-dd HH:mm:ss"/> </td>
					<td>${ good.company }</td>
					<td>${ good.desc }</td>
					<td>
						<a href="${ pageContext.request.contextPath }/addToCart?id=${ good.id }">点击购买</a>
					</td>
				</tr>				
			</c:forEach>
			<tr>
				<td colspan="7">
					<c:forEach begin="1" end="${ pageCount }" var="pageNum">
						<c:if test="${ pageNum == requestScope.pageNum }">
							${ pageNum }
						</c:if>
						<c:if test="${ pageNum != requestScope.pageNum }">
							[<a href="${ pageContext.request.contextPath }/getPaged?pageNum=${ pageNum }">${ pageNum }</a>]
						</c:if>						
					</c:forEach>
				</td>
			</tr>
			
			<tr>
				<td colspan="7">
					<c:if test="${ pageNum == 1 }">
						首页&nbsp;上一页
					</c:if>
					<c:if test="${ pageNum > 1 }">
						<a href="${ pageContext.request.contextPath }/getPaged?pageNum=1">首页</a>
						<a href="${ pageContext.request.contextPath }/getPaged?pageNum=${ pageNum - 1 }">上一页</a>
					</c:if>
					<c:if test="${ pageNum == pageCount }">
						下一页&nbsp;末页
					</c:if>
					<c:if test="${ pageNum < pageCount }">
						<a href="${ pageContext.request.contextPath }/getPaged?pageNum=${ pageNum + 1 }">下一页</a>
						<a href="${ pageContext.request.contextPath }/getPaged?pageNum=${ pageCount }">末页</a>
					</c:if>
				</td>
			</tr>
		</table>
	</div>
</body>
</html>

cart.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	<div style="text-align:center;">
		<h1>我的购物车</h1>
		<table border="1" width="700" align="center">
			<tr>
				<th>编号</th>
				<th>名称</th>
				<th>单价</th>
				<th>数量</th>
				<th>小计</th>
			</tr>			
			<c:forEach items="${ cart }" var="entry">
				<tr>
					<td>${ entry.key.id }</td>
					<td>${ entry.key.name }</td>
					<td>${ entry.key.price }</td>
					<td>${ entry.value }</td>
					<td>${ entry.key.price*entry.value }</td>
				</tr>
			</c:forEach>
				<tr>
					<td colspan="5">
						总计:${ sum }
					</td>
				</tr>
				<tr>
					<td colspan="5">
						<a href="javascript:history.go(-1)">返回商品信息页面</a>
					</td>
				</tr>
		</table>
	</div>
</body>
</html>

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
	<!-- 组件扫描 -->
	<context:component-scan base-package="com.neu.service,com.neu.mapper"></context:component-scan>
	
	<!-- 读取属性文件 -->
	<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="locations">
			<list>
				<value>classpath:db.properties</value>
			</list>
		</property>
	</bean>
	
	<!-- jdbcTemplate,封装了数据库的常用操作的工具类 -->
	<!-- <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
		<property name="dataSource" ref="dataSource"></property>
	</bean> -->
	
	<!-- 数据源,可以支持连接池 -->
	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
		<property name="url" value="${jdbc.url}"></property>
		<property name="driverClassName" value="${jdbc.driverClassName}"></property>
		<property name="username" value="${jdbc.username}"></property>
		<property name="password" value="${jdbc.password}"></property>
		
		<!-- 最大激活数 -->
		<property name="maxActive" value="20"></property>
		<!-- 最大闲置数 -->
		<property name="maxIdle" value="5"></property>
		<!-- 最大等待时间,单位为毫秒,超过这个时间,就抛出异常 -->
		<property name="maxWait" value="1000"></property>
	</bean>
	
	<bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="dataSource"></property>
		<property name="configLocation" value="classpath:SqlMapConfig.xml"></property>
	</bean>
	
	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<property name="basePackage" value="com.neu.mapper"></property>
		<property name="sqlSessionFactoryBeanName" value="sqlSessionFactoryBean"></property>
	</bean>
</beans>

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-4.3.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
		http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd">
	<!-- 组件扫描 -->
	<context:component-scan base-package="com.neu.controller"></context:component-scan>
	
	<!-- 日期进行转换的格式设置 -->
	<bean id="formattingConversionServiceFactoryBean"
		class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
		<property name="converters">
			<list>
				<!-- <bean class="com.neu.controller.DateConverter"></bean> -->
			</list>
		</property>
	</bean>
	<!-- 使用springmvc的注解 -->
	<mvc:annotation-driven validator="validator" conversion-service="formattingConversionServiceFactoryBean" ></mvc:annotation-driven>
	<!-- 视图解析器,通过前缀和后缀来得到视图的物理路径 -->
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/jsp/"></property>
		<property name="suffix" value=".jsp"></property>
	</bean>
	<!-- 配置校验错误信息文件,主要用于国际化 -->
	<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
		<property name="basenames">
			<list>
				<value>classpath:CustomValidationMessages</value>
			</list>
		</property>
		<property name="fileEncodings" value="utf-8"></property>
		<property name="cacheSeconds" value="120"></property>
	</bean>
	
	<!-- 配置验证器 -->
	<bean 
		id="validator" 
		class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
		<property name="providerClass" value="org.hibernate.validator.HibernateValidator"></property>
		<property name="validationMessageSource" ref="messageSource"></property>
	</bean>
	
	<!-- <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
		默认的异常处理页面视图
		<property name="defaultErrorView" value="error/err"></property>
		默认异常名为:exception,但是可以通过该属性修改异常的名称
		<property name="exceptionAttribute" value="ex"></property>
		
		<property name="exceptionMappings">
			<props>
				<prop key="ArithmeticException">error/ArithmeticException</prop>
				<prop key="IOException">error/IOException</prop>
				<prop key="java.sql.SQLException">error/SQLException</prop>
			</props>
		</property>
	</bean> -->
	
	<!-- 用于文件上传 -->
	<!-- <bean id="multipartResolver"
		class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		配置上传文件的总大小,单位为:字节
		<property name="maxUploadSize" value="5242880"></property>
		设置文本编码
		<property name="defaultEncoding" value="utf-8"></property>
	</bean> -->
	<!-- 配置静态资源的解析方法 -->
	<mvc:resources location="/js/" mapping="/js/**"></mvc:resources>
	<mvc:resources location="/css/" mapping="/css/**"></mvc:resources>
	<mvc:resources location="/images/" mapping="/images/**"></mvc:resources>
	
	<!-- 登录检查的拦截器 -->
	<!-- <mvc:interceptors>
		<mvc:interceptor>
			<mvc:mapping path="/**"/>
			需要排除的请求
			<mvc:exclude-mapping path="/user/login.action"/>
			<bean class="com.neu.controller.LoginCheckInterceptor"></bean>
		</mvc:interceptor>
	</mvc:interceptors> -->
</beans>

SqlMapConfig.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>
	<!-- <environments default="mysql">
		<environment id="mysql">
			事物管理器
			<transactionManager type="jdbc"></transactionManager>
			type="pooled"表示使用连接池
			<dataSource type="pooled">
				<property name="url" value="jdbc:mysql://localhost:3306/mydb?serverTimezone=UTC&amp;allowMultiQueries=true"/>
				<property name="driver" value="com.mysql.jdbc.Driver"/>
				<property name="username" value="root"/>
				<property name="password" value="root"/>
			</dataSource>
		</environment>
	</environments> -->
	
	<!-- <mappers>
		添加映射文件配置
		<mapper resource="com/neu/dao/DeptMapper.xml" />
		<mapper resource="com/neu/dao/EmpMapper.xml" />
	</mappers> -->
</configuration>

db.properties

jdbc.url=jdbc:mysql://localhost:3306/mydb?serverTimezone=UTC
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.username=root
jdbc.password=root

#jdbc.url=jdbc:oracle:thin:@localhost:1521:ORCL
#jdbc.driverClassName=oracle.jdbc.driver.OracleDriver
#jdbc.username=scott
#jdbc.password=tiger

log4j.properties

# Global logging configuration
#\u751F\u4EA7\u73AF\u5883\u914D\u7F6Einfo   ERROR
log4j.rootLogger=DEBUG,stdout
# MyBatis logging configuration...
log4j.logger.org.mybatis.example.BlogMapper=TRACE
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

CustomValidationMessages.properties

user.username.notblank=\u7528\u6237\u540D\u4E0D\u80FD\u4E3A\u7A7A
user.password.notblank=\u5BC6\u7801\u4E0D\u80FD\u4E3A\u7A7A

猜你喜欢

转载自blog.csdn.net/pcbhyy/article/details/83746023