项目简介:基于Java开发的完整电商网站系统,实现了书籍浏览、搜索、购买及后台管理的全流程功能。
技术栈:Spring 5.1.6 + SpringMVC + MyBatis 3.2.2框架,MySQL 8.0.27数据库,JSP+JSTL前端技术,Maven构建管理。
核心功能:
- 用户模块:注册登录、个人信息管理、权限控制
- 书籍模块:分类展示、搜索、详情查看、热门推荐
- 购物车与订单:商品管理、订单提交、订单查询
- 后台管理:用户管理、书籍管理、订单状态跟踪
架构特色:采用MVC三层架构设计,代码结构清晰,实现了前后台分离,具备良好的扩展性和维护性。通过该项目熟练掌握了Java Web开发全流程及主流框架应用。

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.vilicode.group</groupId>
<artifactId>BookShop</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>BookShop 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>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.2.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.1.6.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.6.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-dbcp/commons-dbcp -->
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.27</version>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.6.RELEASE</version>
</dependency>
<!--<dependency>-->
<!--<groupId>com.vili.encryption</groupId>-->
<!--<artifactId>encryption</artifactId>-->
<!--<version>1.0.0</version>-->
<!--</dependency>-->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
</dependencies>
<build>
<finalName>BookShop</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>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/java</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
</build>
</project>
bean下实体类
Book – 书籍实体
- 作用:表示系统中的书籍信息,包含书籍的基本属性和推荐状态
- 核心属性:书籍ID、ISBN、名称、作者、出版社、价格、库存、分类、封面图片等
- 特色功能:包含是否为轮播书籍、热门书籍、新书的标识属性
- 在项目架构中的作用
- 数据传输:作为数据传输对象(DTO)在不同层之间传递数据
- 持久化映射:作为持久化对象(PO)与数据库表进行映射
- 业务逻辑支持:封装业务数据和相关操作,如订单实体中包含购物车逻辑
- 前端展示:将后端数据结构化后传递给前端JSP页面进行渲染展示
- 这些实体类构成了整个项目的数据模型基础,通过它们实现了系统各层之间的数据流转和业务逻辑的实现。
package com.vilicode.bean;
public class Book {
private Integer bid;
private String bisbn;
private String bname;
private String bauthor;
private String bpublisher;
private String bcover;
private String bimage1;
private String bimage2;
private Double bprice;
private Integer btid;
private String btname;
private Integer bstock;
private String bmark;
private boolean isScroll;
private boolean isHot;
private boolean isNew;
public boolean getIsScroll() {
return isScroll;
}
public void setScroll(boolean isScroll) {
this.isScroll = isScroll;
}
public boolean getIsHot() {
return isHot;
}
public void setHot(boolean isHot) {
this.isHot = isHot;
}
public boolean getIsNew() {
return isNew;
}
public void setNew(boolean isNew) {
this.isNew = isNew;
}
public String getBtname() {
return btname;
}
public void setBtname(String btname) {
this.btname = btname;
}
public Integer getBid() {
return bid;
}
public void setBid(Integer bid) {
this.bid = bid;
}
public String getBisbn() {
return bisbn;
}
public void setBisbn(String bisbn) {
this.bisbn = bisbn;
}
public String getBname() {
return bname;
}
public void setBname(String bname) {
this.bname = bname;
}
public String getBauthor() {
return bauthor;
}
public void setBauthor(String bauthor) {
this.bauthor = bauthor;
}
public String getBpublisher() {
return bpublisher;
}
public void setBpublisher(String bpublisher) {
this.bpublisher = bpublisher;
}
public String getBcover() {
return bcover;
}
public void setBcover(String bcover) {
this.bcover = bcover;
}
public String getBimage1() {
return bimage1;
}
public void setBimage1(String bimage1) {
this.bimage1 = bimage1;
}
public String getBimage2() {
return bimage2;
}
public void setBimage2(String bimage2) {
this.bimage2 = bimage2;
}
public Double getBprice() {
return bprice;
}
public void setBprice(Double bprice) {
this.bprice = bprice;
}
public Integer getBtid() {
return btid;
}
public void setBtid(Integer btid) {
this.btid = btid;
}
public Integer getBstock() {
return bstock;
}
public void setBstock(Integer bstock) {
this.bstock = bstock;
}
public String getBmark() {
return bmark;
}
public void setBmark(String bmark) {
this.bmark = bmark;
}
@Override
public String toString() {
return "Book{" +
"bid=" + bid +
", bisbn='" + bisbn + '\'' +
", bname='" + bname + '\'' +
", bauthor='" + bauthor + '\'' +
", bpublisher='" + bpublisher + '\'' +
", bcover='" + bcover + '\'' +
", bimage1='" + bimage1 + '\'' +
", bimage2='" + bimage2 + '\'' +
", bprice=" + bprice +
", btid=" + btid +
", btname='" + btname + '\'' +
", bstock=" + bstock +
", bmark='" + bmark + '\'' +
'}';
}
}
User – 用户实体
- 作用:表示系统中的用户信息,区分普通用户和管理员
- 核心属性:用户ID、用户名、密码、真实姓名、角色、手机号、地址等
- 特色功能:内置权限判断逻辑,通过urole字段区分管理员和普通用户
package com.vilicode.bean;
public class User {
private Integer uid;
private String uname;
private String upwd;
private String urealname;
private Integer urole;
private String umark;
private String uphone;
private String uaddress;
private boolean isadmin=false;
public Integer getUid() {
return uid;
}
public void setUid(Integer uid) {
this.uid = uid;
}
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
public String getUpwd() {
return upwd;
}
public void setUpwd(String upwd) {
this.upwd = upwd;
}
public String getUrealname() {
return urealname;
}
public void setUrealname(String urealname) {
this.urealname = urealname;
}
public boolean isIsadmin() {
return isadmin;
}
public void setIsadmin(boolean isadmin) {
this.isadmin = isadmin;
}
public Integer getUrole() {
return urole;
}
public void setUrole(Integer urole) {
this.urole = urole;
isadmin=urole==0?true:false;
}
public String getUmark() {
return umark;
}
public void setUmark(String umark) {
this.umark = umark;
}
public String getUphone() {
return uphone;
}
public void setUphone(String uphone) {
this.uphone = uphone;
}
public String getUaddress() {
return uaddress;
}
public void setUaddress(String uaddress) {
this.uaddress = uaddress;
}
public boolean isAdmin()
{
return urole==0;
}
@Override
public String toString() {
return "User{" +
"uid=" + uid +
", uname='" + uname + '\'' +
", upwd='" + upwd + '\'' +
", urealname='" + urealname + '\'' +
", urole=" + urole +
", umark='" + umark + '\'' +
", uphone='" + uphone + '\'' +
", uaddress='" + uaddress + '\'' +
'}';
}
}
Order – 订单实体
- 作用:表示用户的订单信息,包含订单的整体信息
- 核心属性:订单ID、总金额、商品数量、状态、支付方式、用户ID、收货信息等
- 特色功能:内部集成购物车功能,包含添加、减少、删除商品的方法
package com.vilicode.bean;
import com.vilicode.Utils.PriceUtil;
import org.springframework.web.bind.annotation.RequestMapping;
import java.time.DateTimeException;
import java.util.*;
public class Order {
private String oid;
private Double ototal;
private Integer oamount;
private Integer ostatus;
private Integer opaytype;
private Integer uid;
private String orealname;
private String ophone;
private String oaddress;
private String odatetime;
private Map<Integer,OrderItem> itemMap = new HashMap<Integer,OrderItem>();
private List<OrderItem> itemList = new ArrayList<OrderItem>();
public String getOid() {
return oid;
}
public void setOid(String oid) {
this.oid = oid;
}
public Double getOtotal() {
return ototal;
}
public void setOtotal(Double ototal) {
this.ototal = ototal;
}
public String getOdatetime() {
return odatetime;
}
public void setOdatetime(String odatetime) {
this.odatetime = odatetime;
}
public Integer getOamount() {
return oamount;
}
public void setOamount(Integer oamount) {
this.oamount = oamount;
}
public Integer getOstatus() {
return ostatus;
}
public void setOstatus(Integer ostatus) {
this.ostatus = ostatus;
}
public Integer getOpaytype() {
return opaytype;
}
public void setOpaytype(Integer opaytype) {
this.opaytype = opaytype;
}
public Integer getUid() {
return uid;
}
public void setUid(Integer uid) {
this.uid = uid;
}
public String getOrealname() {
return orealname;
}
public void setOrealname(String orealname) {
this.orealname = orealname;
}
public String getOphone() {
return ophone;
}
public void setOphone(String ophone) {
this.ophone = ophone;
}
public String getOaddress() {
return oaddress;
}
public void setOaddress(String oaddress) {
this.oaddress = oaddress;
}
public List<OrderItem> getItemList() {
return itemList;
}
public void setItemList(List<OrderItem> itemList) {
this.itemList = itemList;
}
public Map<Integer, OrderItem> getItemMap() {
return itemMap;
}
public void setItemMap(Map<Integer, OrderItem> itemMap) {
this.itemMap = itemMap;
}
public void addGoods(Book book) {
if(itemMap.containsKey(book.getBid())) {
OrderItem item = itemMap.get(book.getBid());
item.setOiamount(item.getOiamount()+1);
}else {
OrderItem item = new OrderItem();
item.setOiprice(book.getBprice());
item.setOiamount(1);
item.setBook(book);
item.setOrder(this);
item.setBid(book.getBid());
itemMap.put(book.getBid(), item);
}
oamount++;
ototal = PriceUtil.add(ototal,book.getBprice());
}
public void lessen(int bid) {
if(itemMap.containsKey(bid)) {
OrderItem item = itemMap.get(bid);
item.setOiamount(item.getOiamount()-1);
oamount--;
ototal = PriceUtil.subtract(ototal,item.getOiprice());
if(item.getOiamount()<=0) {
itemMap.remove(bid);
}
}
}
public void delete(int bid)
{
if(itemMap.containsKey(bid)) {
OrderItem item = itemMap.get(bid);
ototal = PriceUtil.subtract(ototal,item.getOiamount()*item.getOiprice());
oamount-=item.getOiamount();
itemMap.remove(bid);
}
}
}
OrderItem – 订单项实体
- 作用:表示订单中的具体商品项,连接订单和书籍
- 核心属性:订单项ID、单价、数量、书籍ID、订单ID等
- 关联关系:与Book和Order实体建立关联
package com.vilicode.bean;
public class OrderItem {
private Integer oiid;
private Double oiprice;
private Integer oiamount;
private Integer bid;
private String oid;
private Book book;
private Order order;
public Integer getOiid() {
return oiid;
}
public void setOiid(Integer oiid) {
this.oiid = oiid;
}
public Double getOiprice() {
return oiprice;
}
public void setOiprice(Double oiprice) {
this.oiprice = oiprice;
}
public Integer getOiamount() {
return oiamount;
}
public void setOiamount(Integer oiamount) {
this.oiamount = oiamount;
}
public Integer getBid() {
return bid;
}
public void setBid(Integer bid) {
this.bid = bid;
}
public String getOid() {
return oid;
}
public void setOid(String oid) {
this.oid = oid;
}
public Book getBook() {
return book;
}
public void setBook(Book book) {
this.book = book;
}
public Order getOrder() {
return order;
}
public void setOrder(Order order) {
this.order = order;
}
}
BookType – 书籍分类实体
- 作用:表示书籍的分类信息
- 核心属性:分类ID、分类名称
package com.vilicode.bean;
public class BookType {
private Integer btid;
private String btname;
public Integer getBtid() {
return btid;
}
public void setBtid(Integer btid) {
this.btid = btid;
}
public String getBtname() {
return btname;
}
public void setBtname(String btname) {
this.btname = btname;
}
}
Recommend – 推荐关系实体
- 作用:表示书籍的推荐关系,管理书籍的推荐类型
- 核心属性:推荐ID、推荐类型、书籍ID
package com.vilicode.bean;
public class Recommend {
private Integer rid;
private Integer rtype;
private Integer bid;
public Integer getRid() {
return rid;
}
public void setRid(Integer rid) {
this.rid = rid;
}
public Integer getRtype() {
return rtype;
}
public void setRtype(Integer rtype) {
this.rtype = rtype;
}
public Integer getBid() {
return bid;
}
public void setBid(Integer bid) {
this.bid = bid;
}
}
Page – 分页实体
- 作用:用于系统中所有列表数据的分页展示
- 核心属性:当前页码、每页大小、总记录数、总页数、数据列表
- 特色功能:提供计算总页数的方法
package com.vilicode.bean;
import java.util.List;
public class Page {
private int pageNumber;
private int pageSize;
private int totalCount;
private int totalPage;
private List<Object> list;
public void SetPageSizeAndTotalCount(int pageSize,int totalCount)
{
this.pageSize=pageSize;
this.totalCount=totalCount;
totalPage= (int)Math.ceil((double)totalCount/pageSize);
}
public int getPageNumber() {
return pageNumber;
}
public void setPageNumber(int pageNumber) {
this.pageNumber = pageNumber;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getTotalCount() {
return totalCount;
}
public void setTotalCount(int totalCount) {
this.totalCount = totalCount;
}
public int getTotalPage() {
return totalPage;
}
public void setTotalPage(int totalPage) {
this.totalPage = totalPage;
}
public List<Object> getList() {
return list;
}
public void setList(List<Object> list) {
this.list = list;
}
}
Address
类用于表示用户收货地址的数据模型
- 数据存储与映射:作为MyBatis ORM框架的映射对象,与数据库中存储用户地址的表结构对应
- 业务流程支持:在订单提交、用户中心地址管理等功能中,用于传递和处理地址信息
- 用户体验优化:支持用户管理多个收货地址,提高购物流程的便捷性
- 关联设计体现:通过
uid
属性与User
实体类建立关联,体现了系统的关系型数据设计思想 - 分层架构支撑:通过配置文件明确划分了数据访问层(Mapper)、业务逻辑层(Service)和表现层(Controller)的边界和交互方式
- 框架集成:实现了Spring、SpringMVC和MyBatis三大框架的无缝集成
- 可配置性:将可变的配置信息(如数据库连接)与代码分离,提高了系统的可维护性和灵活性
- 自动化管理:大量使用包扫描和自动注入机制,减少了手动配置的工作量
- 该配置包是整个项目的骨架,确保了各个组件能够按照预定的方式协同工作,是项目正常运行的基础保障。
该类是一个典型的POJO(Plain Old Java Object),专注于数据的存储和访问,符合项目MVC架构中数据模型层的设计理念。
package com.vilicode.bean;
public class Address {
private Integer aid;
private Integer uid;
private String aphone;
private String aaddr;
public Integer getAid() {
return aid;
}
public void setAid(Integer aid) {
this.aid = aid;
}
public Integer getUid() {
return uid;
}
public void setUid(Integer uid) {
this.uid = uid;
}
public String getAphone() {
return aphone;
}
public void setAphone(String aphone) {
this.aphone = aphone;
}
public String getAaddr() {
return aaddr;
}
public void setAaddr(String aaddr) {
this.aaddr = aaddr;
}
}
com.vilicode.config
核心配置包
负责配置整个项目的基础架构和运行环境。该包包含4个关键配置文件,共同实现了SSM(Spring+SpringMVC+MyBatis)框架的集成与配置。
jdbc.properties
- 数据库连接配置文件,存储数据库访问的基础信息
- 包含MySQL驱动类、连接URL(指定数据库名、编码、时区等参数)、用户名和密码
- 采用外部化配置方式,便于环境切换和安全管理
className=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/bookshop?autoReconnect=true&useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
user=root
password=123456
mybatis-config.xml
- MyBatis框架的核心配置文件
- 通过
<typeAliases>
配置实体类包扫描,简化映射文件中的类型引用 - 通过
<mappers>
注册所有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.vilicode.bean"/>
</typeAliases>
<mappers>
<mapper resource="com/vilicode/mapper/UserMapper.xml"/>
<mapper resource="com/vilicode/mapper/BookMapper.xml"/>
<mapper resource="com/vilicode/mapper/RecommendMapper.xml"/>
<mapper resource="com/vilicode/mapper/BookTypeMapper.xml"/>
<mapper resource="com/vilicode/mapper/OrderMapper.xml"/>
</mappers>
</configuration>
spring.xml
- Spring框架的核心配置文件
- 导入数据库配置资源,配置DBCP数据库连接池
- 配置
SqlSessionFactoryBean
,整合MyBatis与Spring - 通过
MapperScannerConfigurer
自动扫描并注册Mapper接口 - 扫描
service.impl
包,管理业务层Bean
<?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"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
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
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 导入连接数据库的资源文件 -->
<context:property-placeholder location="classpath:com/vilicode/config/jdbc.properties"/>
<!-- 配置数据源 dbcp=database connection pool数据库连接池 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${className}"></property>
<property name="url" value="${url}"></property>
<property name="username" value="${user}"></property>
<property name="password" value="${password}"></property>
</bean>
<!-- 配置SqlSessionFactoryBean,注入数据源和mybatis配置文件 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:com/vilicode/config/mybatis-config.xml"></property>
<!-- 如果mybatis配置文件未扫描类的包,则在此处扫描,
如果mybatis未指定mapper接口的映射实现文件,则在此处配置,为了增加程序的可读性通常
在mybaits配置前两项 -->
</bean>
<!-- 通过MapperScannerConfigurer类自动完成基础包的扫描和Mapper接口的实现
自动关联sqlSessionFactory -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.vilicode.mapper"></property>
</bean>
<!-- 扫描service -->
<context:component-scan base-package="com.vilicode.service.impl"></context:component-scan>
</beans>
springMVC.xml
- SpringMVC框架的配置文件
- 扫描
controller
包,注册控制器Bean - 配置
InternalResourceViewResolver
视图解析器,设置JSP视图的前缀和后缀
<?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"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
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
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<context:component-scan base-package="com.vilicode.controller"></context:component-scan>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
com.vilicode.controller包
com.vilicode.controller
包是BookShop项目的控制器层,负责处理所有HTTP请求,实现前后端交互,是MVC架构中的控制器(Controller)组件。该包包含4个核心控制器类,共同构成了系统的请求处理中心。
求分发与处理:接收用户请求,调用相应的Service层方法处理业务逻辑
参数传递与校验:接收和验证请求参数,传递给业务层
视图渲染与响应:根据业务处理结果,选择合适的视图进行渲染或返回重定向
用户会话管理:管理用户登录状态、购物车信息等会话数据
权限控制:部分控制器方法实现了基于用户角色的权限控制
前后端交互桥梁:连接前端页面和后端业务逻辑,是系统与用户交互的主要入口
该包严格遵循了SpringMVC的设计理念,通过注解(如@RequestMapping、@Autowired)实现了请求映射和依赖注入,使代码结构清晰、职责分明。控制器层的设计确保了前端请求能够被正确路由和处理,同时也为系统提供了良好的扩展性
IndexController
- 系统首页控制器,处理根路径和首页请求
- 负责查询和展示推荐图书(滚动图书、热门图书、新书)
- 加载图书分类信息到应用上下文,供全局使用
- 实现首页数据的初始化和展示逻辑
package com.vilicode.controller;
import com.vilicode.bean.Book;
import com.vilicode.bean.BookType;
import com.vilicode.service.BookService;
import com.vilicode.service.BookTypeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
@Controller
public class IndexController {
@Autowired
public BookService bookService;
@Autowired
public BookTypeService bookTypeService;
@RequestMapping("/index")
public String Init(HttpServletRequest request)
{
List<Book> books=bookService.queryBookByRecommendType(1,1,6);
if(books.size()>0)
request.setAttribute("scrollBook",books.get(0));
books=bookService.queryBookByRecommendType(2,1,6);
request.setAttribute("hotList",books);
books=bookService.queryBookByRecommendType(3,1,8);
request.setAttribute("newList",books);
List<BookType> bookTypes=bookTypeService.queryBookTypes();
request.getServletContext().setAttribute("bookTypes",bookTypes);
return "index";
}
}
BookController
- 图书管理控制器,功能最丰富的控制器之一
- 处理图书浏览、搜索、详情查看等用户操作
- 支持按推荐类型、分类、关键词等多种方式查询图书
- 提供管理员功能,包括图书分类管理、图书推荐设置、图书信息CRUD
- 实现图书数据的分页展示
package com.vilicode.controller;
import com.vilicode.bean.Book;
import com.vilicode.bean.Page;
import com.vilicode.bean.User;
import com.vilicode.mapper.RecommendMapper;
import com.vilicode.service.BookService;
import com.vilicode.service.BookTypeService;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.URLEncoder;
import java.util.Date;
import java.util.List;
@Controller
public class BookController {
@Autowired
public BookService bookService;
@Autowired
public BookTypeService bookTypeService;
@RequestMapping("/recommend_books")
public String showRecommendBook(int rtype, int pageNumber, HttpServletRequest request)
{
if(pageNumber<=0)
pageNumber=1;
Page p= bookService.queryBookByRecommendType(rtype,pageNumber);
if(p.getTotalPage()==0)
{
p.setTotalPage(1);
p.setPageNumber(1);
}
else {
if(pageNumber>=p.getTotalPage()+1)
{
p = bookService.queryBookByRecommendType(rtype,p.getTotalPage());
}
}
request.setAttribute("p", p);
request.setAttribute("t", rtype);
return "recommend_list";
}
@RequestMapping("/booktypes_list")
public String showBooksByBookTypeID(int pageNumber, int btid,HttpServletRequest request)
{
String btname="";
if(btid!=0)
{
btname=bookTypeService.queryBookTypeNameByBookTypeID(btid);
}
request.setAttribute("t",btname);
//List<Goods> list=gService.selectGoodsByTypeID(id,1,8);
//request.setAttribute("goodsList",list);
if(pageNumber<=0)
pageNumber=1;
Page p=bookTypeService.queryBookByBookTypeID(btid,pageNumber);
if(p.getTotalPage()==0)
{
p.setTotalPage(1);
p.setPageNumber(1);
}
else {
if(pageNumber>=p.getTotalPage()+1)
{
p=bookTypeService.queryBookByBookTypeID(btid,p.getTotalPage());
}
}
request.setAttribute("p",p);
request.setAttribute("btid",btid);
return "booktypes_list";
}
@RequestMapping("/book_detail")
public String showBookByID(int bid,HttpServletRequest request)
{
Book book= bookService.queryBookByID(bid);
request.setAttribute("book",book);
return "book_detail";
}
@RequestMapping("/search_books")
public String SearchBooksByKeyword(int pageNumber,String keyword,HttpServletRequest request) throws UnsupportedEncodingException {
if(pageNumber<=0)
{
pageNumber=1;
}
Page p =bookService.searchBooksByKeyword(keyword,pageNumber);
if(p.getTotalPage()==0)
{
p.setTotalPage(1);
p.setPageNumber(1);
}
else {
if(pageNumber>=p.getTotalPage()+1)
{
p =bookService.searchBooksByKeyword(keyword,p.getTotalPage());
}
}
request.setAttribute("p", p);
request.setAttribute("keyword", URLEncoder.encode(keyword,"utf-8"));
return "book_search";
}
@RequestMapping("/admin/type_list")
public String ShowBookTypes(HttpServletRequest request)
{
request.setAttribute("list",bookTypeService.queryBookTypes());
return "admin/type_list";
}
@RequestMapping("/admin/type_add")
public String CreateBookType(String btname,HttpServletRequest request)
{
boolean result= bookTypeService.addBookType(btname);
UpdateBookType(request);
return "redirect:type_list.action";
}
@RequestMapping("/admin/type_delete")
public String RemoveBookType(int btid,HttpServletRequest request)
{
boolean result= bookTypeService.removeBookType(btid);
UpdateBookType(request);
return "redirect:type_list.action";
}
@RequestMapping("/admin/type_update")
public String ModifyBookType(int btid,String btname,HttpServletRequest request)
{
boolean result= bookTypeService.modifyBookType(btid,btname);
UpdateBookType(request);
return "redirect:type_list.action";
}
public void UpdateBookType(HttpServletRequest request)
{
if(request.getServletContext().getAttribute("bookTypes")==null)
{
request.getServletContext().setAttribute("bookTypes",bookTypeService.queryBookTypes());
}
else
{
request.getServletContext().removeAttribute("bookTypes");
request.getServletContext().setAttribute("bookTypes",bookTypeService.queryBookTypes());
}
}
@RequestMapping("/admin/book_list")
public String ShowBookByRecommend(int pageNumber,int rtype,HttpServletRequest request)
{
if(pageNumber<=0)
pageNumber=1;
Page p = bookService.queryBookByRecommendType(rtype, pageNumber);
if(p.getTotalPage()==0)
{
p.setTotalPage(1);
p.setPageNumber(1);
}
else {
if(pageNumber>=p.getTotalPage()+1)
{
p = bookService.queryBookByRecommendType(rtype, p.getTotalPage());
}
}
request.setAttribute("p", p);
request.setAttribute("rtype", rtype);
return "/admin/book_list";
}
@RequestMapping("/admin/book_change")
public String ChangeBookRecommend(int bid,int rtype,String method,int page)
{
boolean result=false;
if(method.equals("add")) {
result=bookService.addRecommend(bid,rtype);
}else {
result=bookService.remoteRecommend(bid,rtype);
}
return "redirect:book_list.action?pageNumber=1&rtype="+page;
}
@RequestMapping("/admin/book_delete")
public String DeleteBook(int bid,int rtype)
{
boolean result=bookService.removeBookByBid(bid);
//
return "redirect:book_list.action?pageNumber=1&rtype="+rtype;
}
@RequestMapping("/admin/book_add")
public String uploadimg(HttpServletRequest request) throws Exception{
DiskFileItemFactory factory=new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
try {
List<FileItem> list = upload.parseRequest(request);
Book b = new Book();
for(FileItem item:list) {
if(item.isFormField()) {
switch(item.getFieldName()) {
case "bname":
b.setBname(item.getString("utf-8"));
break;
case "bprice":
b.setBprice(Double.parseDouble(item.getString("utf-8")));
break;
case "bmark":
b.setBmark(item.getString("utf-8"));
break;
case "bstock":
b.setBstock(Integer.parseInt(item.getString("utf-8")));
break;
case "btid":
b.setBtid(Integer.parseInt(item.getString("utf-8")));
break;
case "bisbn":
b.setBisbn(item.getString("utf-8"));
break;
case "bauthor":
b.setBauthor(item.getString("utf-8"));
break;
case "bpublisher":
b.setBpublisher(item.getString("utf-8"));
break;
}
}else {
if(item.getInputStream().available()<=0)continue;
String fileName = item.getName();
fileName = fileName.substring(fileName.lastIndexOf("."));
fileName = "/"+new Date().getTime()+fileName;
String path = request.getServletContext().getRealPath("/images")+fileName;
InputStream in = item.getInputStream();
FileOutputStream out = new FileOutputStream(path);
byte[] buffer = new byte[1024];
int len=0;
while( (len=in.read(buffer))>0 ) {
out.write(buffer);
}
in.close();
out.close();
item.delete();
switch(item.getFieldName()) {
case "bcover":
b.setBcover("images"+fileName);
break;
case "bimage1":
b.setBimage1("images"+fileName);
break;
case "bimage2":
b.setBimage2("images"+fileName);
break;
}
}
}
bookService.addBook(b);
} catch (FileUploadException e) {
System.out.println(e.getMessage());
}
return "redirect:book_list.action?pageNumber=1&rtype=0";
}
@RequestMapping("/admin/book_edit_show")
public String ShowBookByBid(int bid,HttpServletRequest request)
{
Book b = bookService.queryBookByID(bid);
request.setAttribute("g", b);
return "admin/book_edit";
}
@RequestMapping("/admin/book_update")
public String ModifyBook(HttpServletRequest request) throws Exception {
DiskFileItemFactory factory=new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
try {
List<FileItem> list = upload.parseRequest(request);
Book b=new Book();
for(FileItem item:list) {
if(item.isFormField()) {
switch(item.getFieldName()) {
case "bid":
b.setBid(Integer.parseInt(item.getString("utf-8")));
break;
case "bname":
b.setBname(item.getString("utf-8"));
break;
case "bprice":
b.setBprice(Double.parseDouble(item.getString("utf-8")));
break;
case "bmark":
b.setBmark(item.getString("utf-8"));
break;
case "bstock":
b.setBstock(Integer.parseInt(item.getString("utf-8")));
break;
case "btid":
b.setBtid(Integer.parseInt(item.getString("utf-8")));
break;
case "bisbn":
b.setBisbn(item.getString("utf-8"));
break;
case "bauthor":
b.setBauthor(item.getString("utf-8"));
break;
case "bpublisher":
b.setBpublisher(item.getString("utf-8"));
break;
case "bcover":
b.setBcover(item.getString("utf-8"));
break;
case "bimage1":
b.setBimage1(item.getString("utf-8"));
break;
case "bimage2":
b.setBimage2(item.getString("utf-8"));
break;
}
}else {
if(item.getInputStream().available()<=0)continue;
String fileName = item.getName();
fileName = fileName.substring(fileName.lastIndexOf("."));
fileName = "/"+new Date().getTime()+fileName;
String path = request.getServletContext().getRealPath("/images")+fileName;
InputStream in = item.getInputStream();
FileOutputStream out = new FileOutputStream(path);
byte[] buffer = new byte[1024];
int len=0;
while( (len=in.read(buffer))>0 ) {
out.write(buffer);
}
in.close();
out.close();
item.delete();
switch(item.getFieldName()) {
case "bcover":
b.setBcover("images"+fileName);
break;
case "bimage1":
b.setBimage1("images"+fileName);
break;
case "bimage2":
b.setBimage2("images"+fileName);
break;
}
}
}
bookService.modifyBook(b);
//Service.update(g);
//request.getRequestDispatcher("/admin/goods_list?pageNumber="+pageNumber+"&type="+type).forward(request, response);
} catch (FileUploadException e) {
System.out.println(e.getMessage());
}
return "redirect:book_list.action?pageNumber=1&rtype=0";
}
}
UserController
- 用户管理控制器,处理所有用户相关操作
- 实现用户注册、登录、登出功能
- 管理用户个人信息(修改手机号、地址、密码等)
- 提供管理员用户管理功能(添加、修改、删除、列表查询)
- 负责用户会话管理和权限控制
package com.vilicode.controller;
import com.vilicode.Utils.MyCipher;
import com.vilicode.bean.Page;
import com.vilicode.bean.User;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import com.vilicode.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/login")
public String login(User tempUser, HttpServletRequest request, HttpSession session)
{
String path="";
User user=userService.login(tempUser.getUname());
if(user==null)
{
request.setAttribute("failMsg","用户名不存在!");
return "user_login";
}
if(tempUser.getUpwd().equals(user.getUpwd()))
{
session.setAttribute("user", user);
request.setAttribute("msg","登录成功!");
return "redirect:/index.action";
}else{
request.setAttribute("failMsg","密码错误!");
return "user_login";
}
}
@RequestMapping("/register")
public String register(User user, HttpServletRequest request)
{
String path="";
user.setUrole(1);
user.setUmark("普通用户");
if(userService.register(user))
{
path="redirect:user_login.jsp";
}else{
request.setAttribute("msg","用户名重复!");
path="user_register";
}
return path;
}
@RequestMapping("/admin/user_add")
public String AddUser(User user, HttpServletRequest request)
{
user.setUrole(1);
user.setUmark("普通用户");
if(userService.register(user))
{
return "redirect:user_list.action?pageNumber=1";
}else{
request.setAttribute("msg","用户名重复!");
return "admin/user_add";
}
}
@RequestMapping("/logout")
public String logout(HttpServletRequest request)
{
request.getSession().removeAttribute("user");
return "redirect:index.action";
}
@RequestMapping("/admin/logout")
public String adminLogout(HttpServletRequest request)
{
request.getSession().removeAttribute("user");
return "redirect:index.action";
}
@RequestMapping("/change_phone_and_address")
public String updateUphoneAndUaddress(int uid,String uphone,String uaddress,HttpServletRequest request)
{
boolean result=userService.UpdatePhoneAndAddress(uid,uphone,uaddress);
if(result)
{
request.setAttribute("msg","修改成功!");
User u=(User)request.getSession().getAttribute("user");
u.setUaddress(uaddress);
u.setUphone(uphone);
request.getSession().removeAttribute("user");
request.getSession().setAttribute("user",u);
return "user_center";
}
else
{
request.setAttribute("failMsg","修改密码时出现错误,请确认原密码是否正确或联系管理员!");
return "user_center";
}
}
@RequestMapping("/change_password")
public String updatePassword(int uid,String oldupwd,String upwd,HttpServletRequest request)
{
boolean result=userService.UpdatePassword(uid,upwd,oldupwd);
if(result)
{
request.setAttribute("msg","修改成功!");
MyCipher myCipher=new MyCipher();
User u=(User)request.getSession().getAttribute("user");
u.setUpwd(myCipher.encrypt(upwd,"!"));
request.getSession().removeAttribute("user");
request.getSession().setAttribute("user",u);
return "user_center";
}
else
{
request.setAttribute("failMsg","修改密码时出现错误,请确认原密码是否正确或联系管理员!");
return "user_center";
}
}
@RequestMapping("admin/change_password")
public String updatePassword(int uid,String upwd,HttpServletRequest request)
{
boolean result=userService.UpdatePassword(uid,upwd);
if(result)
{
MyCipher myCipher=new MyCipher();
request.setAttribute("msg","修改成功!");
User u=(User)request.getSession().getAttribute("user");
u.setUpwd(myCipher.encrypt(upwd,"!"));
request.getSession().removeAttribute("user");
request.getSession().setAttribute("user",u);
return "redirect:user_list.action?pageNumber=1";
}
else
{
request.setAttribute("failMsg","修改失败");
return "redirect:user_list.action?pageNumber=1";
}
}
@RequestMapping("admin/user_list")
public String ShowUserList(int pageNumber,HttpServletRequest request)
{
if(pageNumber<=0)
pageNumber=1;
Page p = userService.queryUser(pageNumber);
if(p.getTotalPage()==0)
{
p.setTotalPage(1);
p.setPageNumber(1);
}
else {
if(pageNumber>=p.getTotalPage()+1)
{
p = userService.queryUser(p.getTotalPage());
}
}
request.setAttribute("p", p);
return "admin/user_list";
}
@RequestMapping("admin/user_delete")
public String DeleteUser(int uid)
{
boolean result= userService.deleteUser(uid);
return "redirect:user_list.action?pageNumber=1";
}
@RequestMapping("/admin/user_edit_show")
public String ChangeUser(int uid,HttpServletRequest request)
{
User user=userService.queryUserByUid(uid);
if(user==null)
return "redirect:user_list.action?pageNumber=1";
else
{
request.setAttribute("u",user);
return "admin/user_edit";
}
}
@RequestMapping("/admin/user_update")
public String updateUser(int uid,String uphone,String uaddress,HttpServletRequest request)
{
boolean result=userService.UpdatePhoneAndAddress(uid,uphone,uaddress);
if(result)
{
User user=(User)request.getSession().getAttribute("user");
if(user.getUid()==uid)
{
user.setUaddress(uaddress);
user.setUphone(uphone);
request.getSession().removeAttribute("user");
request.getSession().setAttribute("user",user);
}
}
return "redirect:user_list.action?pageNumber=1";
}
}
OrderController
- 订单管理控制器,处理购物车和订单流程
- 实现购物车商品的添加、修改、删除
- 负责订单的确认和提交
- 管理用户的订单列表和订单状态
- 提供管理员订单管理功能(订单列表、状态修改、删除)
- 处理订单支付相关逻辑
package com.vilicode.controller;
import com.vilicode.bean.Book;
import com.vilicode.bean.Order;
import com.vilicode.bean.Page;
import com.vilicode.bean.User;
import com.vilicode.service.BookService;
import com.vilicode.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.List;
@Controller
public class OrderController {
@Autowired
public BookService bookService;
@Autowired
public OrderService orderService;
@RequestMapping(value = "/books_buy")
public void AddBookToCart(@RequestParam("bid") int bid, HttpServletRequest request, HttpServletResponse response) throws IOException {
Order o = null;
if(request.getSession().getAttribute("order") != null) {
o = (Order) request.getSession().getAttribute("order");
}else {
o = new Order();
o.setOamount(0);
o.setOtotal(0.0);
request.getSession().setAttribute("order", o);
}
Book book = bookService.queryBookByID(bid);
if(book.getBstock()>0) {
o.addGoods(book);
response.getWriter().print("ok");
}else {
response.getWriter().print("fail");
}
}
@RequestMapping(value = "/books_lessen")
public void LessenBookToCart(@RequestParam("bid") int bid, HttpServletRequest request, HttpServletResponse response) throws IOException {
Order o = (Order) request.getSession().getAttribute("order");
o.lessen(bid);
response.getWriter().print("ok");
}
@RequestMapping(value = "/books_delete")
public void DeleteBookToCart(@RequestParam("bid") int bid, HttpServletRequest request, HttpServletResponse response) throws IOException {
Order o = (Order) request.getSession().getAttribute("order");
o.delete(bid);
response.getWriter().print("ok");
}
@RequestMapping(value = "/order_confirm")
public String OrderConfirm( int opaytype,HttpServletRequest request)
{
Order o = (Order) request.getSession().getAttribute("order");
o.setOstatus(2);
o.setOpaytype(opaytype);
User user=(User)request.getSession().getAttribute("user");
o.setUid(user.getUid());
o.setOrealname(user.getUrealname());
o.setOphone(user.getUphone());
o.setOaddress(user.getUaddress());
boolean result=orderService.addOrder(o);
if(result)
{
request.getSession().removeAttribute("order");
request.setAttribute("msg", "订单支付成功!");
return "order_result";
}
else
{
request.setAttribute("failmsg", "订单支付失败!");
return "order_result";
}
}
@RequestMapping("/order_submit")
public String OrderSubmit(HttpServletRequest request)
{
if(request.getSession().getAttribute("user")!=null) {
return "order_submit";
}else {
request.setAttribute("failMsg", "请登录后,再提交订单!");
return "redirect:user_login.jsp";
}
}
@RequestMapping("order_list")
public String ShowOrderByUid(HttpServletRequest request)
{
User user=(User)request.getSession().getAttribute("user");
if(user==null)
{
return "redirect:/index.action";
}
List<Order> orderList=orderService.queryOrderByUid(user.getUid());
request.setAttribute("orderList", orderList);
return "order_list";
}
@RequestMapping("/admin/order_list")
public String ShowOrderList(int pageNumber,int ostatus,HttpServletRequest request)
{
request.setAttribute("ostatus", ostatus);
if(pageNumber<=0)
pageNumber=1;
Page p = orderService.queryOrdersByOstatus(ostatus,pageNumber);
if(p.getTotalPage()==0)
{
p.setTotalPage(1);
p.setPageNumber(1);
}
else {
if(pageNumber>=p.getTotalPage()+1)
{
p = orderService.queryOrdersByOstatus(ostatus,p.getTotalPage());
}
}
request.setAttribute("p", p);
return "admin/order_list";
}
@RequestMapping("/admin/order_status_change")
public String ChangeOrderStatusByOid(String oid,int ostatus,HttpServletRequest request)
{
boolean result= orderService.updateOrderStatus(oid,ostatus);
return "redirect:order_list.action?pageNumber=1&ostatus="+ostatus;
}
@RequestMapping("/admin/order_delete")
public String DeleteOrderByOid(String oid,int ostatus,HttpServletRequest request)
{
boolean result= orderService.deleteOrderByOid(oid);
return "redirect:order_list.action?pageNumber=1&ostatus="+ostatus;
}
}
com.vilicode.filter;
com.vilicode.filter
包是BookShop项目的过滤器包,负责实现Web应用中的请求过滤功能,用于在请求到达控制器之前进行预处理或后处理。目前该包仅包含一个核心过滤器类:AdminFilter
AdminFilter过滤器
- 拦截范围:通过
@WebFilter
注解配置,拦截所有访问/admin/*
路径下的请求 - 权限验证逻辑:
- 从HTTP会话(
HttpSession
)中获取当前登录用户对象(user
) - 检查用户对象是否存在(即用户是否已登录)
- 检查用户是否具有管理员权限(通过
isAdmin()
方法判断) - 如果用户未登录或不是管理员,则重定向到网站首页(
../index.action
) - 如果用户是管理员,则允许请求继续传递到后续处理组件(调用
chain.doFilter()
) - 在项目安全架构中的作用
- 权限控制:作为系统的安全屏障,防止未授权用户访问管理后台
- 请求预处理:在请求到达控制器之前进行权限验证,是AOP(面向切面编程)思想的一种具体实现
- 集中式安全管理:将管理后台的权限验证逻辑集中到一处,便于维护和扩展
- 用户体验保护:对未授权访问提供友好的重定向处理
- 这个过滤器是项目安全机制的重要组成部分,通过URL级别的拦截和会话级别的权限验证,确保了管理功能的安全性。虽然目前包中只有一个过滤器,但这种结构设计允许系统根据需要轻松添加更多过滤器,如字符编码过滤器、日志记录过滤器等。
- 从HTTP会话(
技术细节
- 实现了
javax.servlet.Filter
接口,重写了三个核心方法:init()
:过滤器初始化方法(此处为空实现)doFilter()
:核心过滤逻辑实现destroy()
:过滤器销毁方法(此处为空实现)
- 使用了
ServletRequest
和ServletResponse
的HTTP特定实现类进行类型转换,以便访问HTTP特定功能
package com.vilicode.filter;
import com.vilicode.bean.User;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebFilter(filterName = "AdminFilter",urlPatterns = "/admin/*")
public class AdminFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse requestp = (HttpServletResponse)resp;
User u = (User) request.getSession().getAttribute("user");
if(u==null || u.isAdmin()==false) {
requestp.sendRedirect("../index.action");
}else {
// pass the request along the filter chain
chain.doFilter(req, resp);
}
}
public void init(FilterConfig config) throws ServletException {
}
}
com.vilicode.mapper包
1. 包结构与组成
该包包含两类文件:
Java接口文件:定义数据操作方法(如BookMapper.java)
XML映射文件:实现具体SQL语句(如BookMapper.xml)
目前包含5组核心映射器:
BookMapper:图书数据操作
BookTypeMapper:图书分类数据操作
OrderMapper:订单数据操作
RecommendMapper:推荐关系数据操作
UserMapper:用户数据操作
3. 在项目架构中的作用
数据访问抽象:通过接口方式抽象数据库操作,实现业务逻辑与数据访问分离
SQL与代码分离:将SQL语句集中管理在XML文件中,便于维护和优化
对象关系映射:自动完成Java对象与数据库表之间的转换(ORM)
框架集成支持:通过Spring配置(MapperScannerConfigurer)实现自动扫描和装配
参数映射与结果映射:支持复杂参数传递和结果集映射,包括集合、分页等
4. 工作流程
服务层(Service)通过依赖注入调用Mapper接口方法
MyBatis框架根据接口方法名匹配XML中的SQL语句
执行SQL并将结果自动映射为Java对象返回给服务层
总结来说,com.vilicode.mapper包是项目的数据访问核心,它借助MyBatis框架实现了高效、灵活的数据库交互,是连接业务逻辑层与底层数据库的重要桥梁。
总结:Mapper接口与XML的协作模式
接口定义契约:每个Mapper接口定义了数据操作的契约(方法签名)
XML实现具体逻辑:对应的XML文件提供具体的SQL实现
自动映射:MyBatis框架自动将Java对象与数据库表进行映射转换
依赖注入:Spring框架通过自动扫描将Mapper接口实例注入到Service层
这种设计实现了业务逻辑与数据访问的解耦,使SQL语句集中管理便于维护,同时提供了灵活的参数传递和结果映射机制。
BookMapper接口
BookMapper接口是一个Java接口,主要负责定义图书数据操作的契约,它规定了可以对图书数据执行哪些操作,但不包含具体的实现逻辑。
- 抽象数据操作:将图书的各种数据操作抽象为方法,形成统一的API
- 约定方法签名:规定了方法名称、参数类型和返回值类型
- 支持依赖注入:Spring框架可以通过接口自动注入实现类
- 解耦业务逻辑与数据访问:Service层只需调用接口方法,无需关心具体实现
package com.vilicode.mapper;
import com.vilicode.bean.Book;
import java.util.List;
public interface BookMapper {
public void addBook(Book book); //添加一本书籍
public void removeBook(int bid); //删除一本书籍
public void modifyBook(Book book); //修改一本书籍
public List<Book> queryBooks(int pageIndex,int pageSize); //查询全部书籍
public int queryCountOfBooks();
public List<Book> queryBooksByKeyword(String keyword, int pageIndex,int pageSize); //查询全部书籍
public int queryCountOfBooksByKeyword(String keyword);
public Book queryBookById(int bid); //按bid查询一本书籍
public Book queryBookByIsbn(String bisbn); //按bisbn查询一本书籍
public void deleteBookByBtid(int btid);
}
BookMapper.xml
BookMapper.xml是一个XML配置文件,主要负责为BookMapper接口中的方法提供具体的SQL实现,并定义数据映射规则。
数据映射功能
参数映射:通过#{参数名}
语法将Java对象的属性映射到SQL语句中
结果映射:通过resultType="Book"
将查询结果自动映射为Book对象
列名别名映射:使用bt_id btid
这样的别名映射数据库列名到Java对象属性名
动态SQL支持
<set>
标签:智能生成UPDATE语句中的SET部分,自动处理逗号
<where>
标签:智能生成WHERE条件,自动处理AND/OR三、BookMapper接口与XML的协同工作机制
- 绑定关系:通过XML中的
namespace="com.vilicode.mapper.BookMapper"
将XML与接口绑定 - 方法匹配:XML中的SQL语句ID必须与接口中的方法名完全对应
- 参数传递:MyBatis自动将接口方法的参数传递给XML中对应的SQL语句
- 结果转换:MyBatis自动将SQL执行结果转换为接口方法指定的返回类型
四、在项目中的应用场景
- 图书管理:后台管理员添加、编辑、删除图书
- 图书展示:前台展示图书列表、图书详情
- 图书搜索:根据关键词搜索图书
- 图书分类:根据分类查询图书
- 分页功能:实现图书列表的分页展示
五、技术优势
- SQL集中管理:所有SQL语句集中在XML文件中,便于维护和优化
- 代码与SQL分离:Java代码专注于业务逻辑,SQL专注于数据操作
- 灵活的映射:支持复杂的参数映射和结果映射
- 动态SQL:支持条件判断、循环等动态SQL功能
- 性能优化:可以针对特定查询进行SQL优化
总结来说,BookMapper接口与BookMapper.xml共同构成了项目中图书数据访问的核心,它们通过MyBatis框架实现了高效、灵活的数据库交互,为整个系统提供了基础的数据支持。
<?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.vilicode.mapper.BookMapper">
<insert id="addBook" parameterType="Book">
insert into book(b_isbn,b_name,b_author,b_publisher,b_cover,b_image1,b_image2,b_price,bt_id,
b_stock,b_mark) values(#{bisbn},#{bname},#{bauthor},#{bpublisher},#{bcover},#{bimage1},#{bimage2},
#{bprice},#{btid},#{bstock},#{bmark})
</insert>
<update id="modifyBook" parameterType="Book">
update book
<set>
b_isbn=#{bisbn},b_name=#{bname},b_author=#{bauthor},b_publisher=#{bpublisher},
b_cover=#{bcover},b_image1=#{bimage1},b_image2=#{bimage2},b_price=#{bprice},bt_id=#{btid},
b_stock=#{bstock},b_mark=#{bmark},b_mark=#{bmark}
</set>
<where>
b_id=#{bid}
</where>
</update>
<delete id="removeBook" parameterType="int">
delete from book
<where>
b_id=#{value}
</where>
</delete>
<select id="queryBooks" resultType="Book">
select t.bt_id btid,bt_name btname,b_id bid,b_isbn bisbn,b_name bname,b_author bauthor,b_publisher bpublisher,
b_cover bcover,b_image1 bimage1,b_image2 bimage2,b_price bprice,b_stock bstock,b_mark bmark from booktype t,book b
where t.bt_id=b.bt_id order by b_id limit #{0},#{1}
</select>
<select id="queryBookById" resultType="Book" parameterType="int">
select t.bt_id btid,bt_name btname,b_id bid,b_isbn bisbn,b_name bname,b_author bauthor,b_publisher bpublisher,
b_cover bcover,b_image1 bimage1,b_image2 bimage2,b_price bprice,b_stock bstock,b_mark bmark from booktype t,book b
where t.bt_id=b.bt_id and b.b_id=#{value}
</select>
<select id="queryBookByIsbn" resultType="Book" parameterType="String">
select t.bt_id btid,bt_name btname,b_id bid,b_isbn bisbn,b_name bname,b_author bauthor,b_publisher bpublisher,
b_cover bcover,b_image1 bimage1,b_image2 bimage2,b_price bprice,b_stock bstock,b_mark bmark from booktype t,book b
where t.bt_id=b.bt_id and b.b_isbn=#{value}
</select>
<select id="queryCountOfBooks" resultType="int">
select count(*) from book;
</select>
<select id="queryCountOfBooksByKeyword" resultType="int" parameterType="String">
select count(*) from book where b_name like "%"#{value}"%"
</select>
<select id="queryBooksByKeyword" resultType="Book">
select t.bt_id btid,bt_name btname,b_id bid,b_isbn bisbn,b_name bname,b_author bauthor,b_publisher bpublisher,
b_cover bcover,b_image1 bimage1,b_image2 bimage2,b_price bprice,b_stock bstock,b_mark bmark from booktype t,book b
where t.bt_id=b.bt_id and b_name like "%"#{0}"%" limit #{1},#{2}
</select>
<delete id="deleteBookByBtid" parameterType="int">
delete from book where b_id=#{value}
</delete>
</mapper>
OrderMapper接口与OrderMapper.xml
作用:负责订单相关的数据操作,主要功能包括:
- 订单管理:创建订单、更新订单状态、取消订单
- 订单查询:查询用户订单列表、查询订单详情
- 订单统计:可能包含订单金额统计、订单状态统计等功能
- 订单项管理:处理订单与图书之间的多对多关系
应用场景:用户下单流程、订单历史查询、订单状态跟踪、后台订单管理等
package com.vilicode.mapper;
import com.vilicode.bean.Order;
import com.vilicode.bean.OrderItem;
import java.util.List;
public interface OrderMapper {
public void addOrder(Order order);
public void addOrderItem(OrderItem orderItem);
public void deleteOrder(String oid);
public void deleteOrderItem(String oid);
public List<Order> queryOrderByUid(int uid);
public List<OrderItem> queryOrderItemByUidAndOid(String oid);
public List<Order> queryOrder(int pageIndex,int pageSize);
public int queryCountOfOrder();
public List<Order> queryOrderByOstatus(int ostatus,int pageIndex,int pageSize);
public int queryCountOfOrderByOstatus(int ostatus);
public void updateOrderStatus(String oid,int ostatus);
}
<?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.vilicode.mapper.OrderMapper">
<insert id="addOrder" parameterType="Order">
insert into `Order`(o_id,o_total,o_amount,o_status,o_paytype,u_id,o_realname,o_phone,o_address)
values(#{oid},#{ototal},#{oamount},#{ostatus},#{opaytype},#{uid},#{orealname},#{ophone},#{oaddress})
</insert>
<insert id="addOrderItem" parameterType="OrderItem">
insert into OrderItem(oi_price,oi_amount,b_id,o_id)
values(#{oiprice},#{oiamount},#{bid},#{oid})
</insert>
<delete id="deleteOrder" parameterType="String">
delete from `order` where o_id=#{value}
</delete>
<delete id="deleteOrderItem" parameterType="String">
delete from orderitem where o_id=#{value}
</delete>
<select id="queryOrderByUid" parameterType="int" resultType="Order">
select o_id oid,o_total ototal,o_amount oamount,o_status ostatus,o_paytype opaytype,u_id uid,
o_realname orealname,o_phone ophone,o_address oaddress,o_datetime odatetime from `order`
where u_id=#{value}
</select>
<select id="queryOrderItemByUidAndOid" resultType="OrderItem" parameterType="String">
select oi_id oiid,oi_price oiprice,oi_amount oiamount,b_id bid,o_id oid
from orderitem where o_id=#{0}
</select>
<select id="queryOrder" resultType="Order">
select o_id oid,o_total ototal,o_amount oamount,o_status ostatus,o_paytype opaytype,u_id uid,
o_realname orealname,o_phone ophone,o_address oaddress,o_datetime odatetime from `order`
limit #{0},#{1}
</select>
<select id="queryCountOfOrder" resultType="int">
select count(*) from `order`
</select>
<select id="queryOrderByOstatus" resultType="Order" parameterType="int">
select o_id oid,o_total ototal,o_amount oamount,o_status ostatus,o_paytype opaytype,u_id uid,
o_realname orealname,o_phone ophone,o_address oaddress,o_datetime odatetime from `order`
where o_status=#{0} limit #{1},#{2}
</select>
<select id="queryCountOfOrderByOstatus" resultType="int" parameterType="int">
select count(*) from `order` where o_status=#{value}
</select>
<update id="updateOrderStatus">
update `order`
<set>
o_status=#{1}
</set>
<where>
o_id=#{0}
</where>
</update>
</mapper>
RecommendMapper接口与RecommendMapper.xml
作用:负责图书推荐关系的数据操作,主要功能包括:
- 推荐关系管理:添加、删除图书推荐关系
- 推荐列表查询:根据用户ID或图书ID查询推荐内容
- 推荐算法支持:为推荐系统提供数据基础
应用场景:首页推荐图书展示、图书详情页的相关推荐、个性化推荐功能等
package com.vilicode.mapper;
import com.vilicode.bean.Book;
import java.util.List;
public interface RecommendMapper {
public List<Book> queryBookByRecommendType(int rtype,int pageIndex,int pageSize); //按推荐类型查询图书
public int queryRecommendCountOfBooksByTypeID(int rtype);//根据推荐类型查询总数
public int queryBookByRtypeAndBid(int rtype,int bid);
public void addRecommendBook(int bid,int rtype);//添加推荐书籍
public void removeRecommendBook(int bid,int rtype);//删除推荐书籍
public void removeRecommend(int bid);
}
<?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.vilicode.mapper.RecommendMapper">
<select id="queryBookByRecommendType" resultType="Book">
select t.bt_id btid,bt_name btname,b.b_id bid,b_isbn bisbn,b_name bname,b_author bauthor,b_publisher bpublisher,
b_cover bcover,b_image1 bimage1,b_image2 bimage2,b_price bprice,b_stock bstock,b_mark bmark from booktype t,book b,recommend r
where t.bt_id=b.bt_id and b.b_id=r.b_id and r_type=#{0} order by b.b_id limit #{1},#{2}
</select>
<select id="queryRecommendCountOfBooksByTypeID" resultType="int" parameterType="int">
select count(*) from recommend where r_type=#{0};
</select>
<select id="queryBookByRtypeAndBid" resultType="int">
select count(*) from recommend where r_type=#{0} and b_id =#{1};
</select>
<insert id="addRecommendBook">
insert into recommend(r_type,b_id) values(#{1},#{0});
</insert>
<delete id="removeRecommendBook">
delete from recommend where r_type=#{1} and b_id=#{0};
</delete>
<delete id="removeRecommend" parameterType="int">
delete from recommend where b_id=#{0};
</delete>
</mapper>
UserMapper接口与UserMapper.xml
作用:负责用户相关的数据操作,主要功能包括:
- 用户管理:注册新用户、更新用户信息、删除用户
- 用户认证:验证用户登录信息
- 用户查询:根据ID查询用户、查询所有用户(后台管理)
- 权限管理:可能包含查询用户权限信息的功能
应用场景:用户注册、用户登录、个人中心信息管理、后台用户管理等
package com.vilicode.mapper;
import com.vilicode.bean.User;
import java.util.List;
public interface UserMapper {
public void addUser(User user);
public int identify(String uname);
public void UpdatePhoneAndAddress(int uid,String uphone,String uaddress);
public void UpdatePassword(int uid,String upwd);
public int getUidByUname(String uname);
public User login(String uname );
public String queryUpwd(int uid);
public List<User> queryUser(int pageIndex,int pageSize);
public int queryCountOfUser();
public void deleteUser(int uid);
public User queryUserByUid(int uid);
}
<?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.vilicode.mapper.UserMapper">
<select id="login" resultType="User" parameterType="String">
select u_id uid,u_name uname,u_pwd upwd,u_realname urealname,u_role urole,u_mark umark,
u_phone uphone,u_address uaddress
from `user` where u_name=#{value}
</select>
<select id="identify" resultType="int" parameterType="String">
select count(*) from `user` where u_name=#{value}
</select>
<select id="getUidByUname" resultType="int" parameterType="String">
select u_id from `user` where u_name=#{value}
</select>
<select id="queryUpwd" resultType="String" parameterType="int">
select u_pwd from `user` where u_id=#{value}
</select>
<insert id="addUser" parameterType="User">
insert into `user`(u_name,u_pwd,u_realname,u_role,u_mark,u_phone,u_address)
values(#{uname},#{upwd},#{urealname},#{urole},#{umark},#{uphone},#{uaddress})
</insert>
<update id="UpdatePhoneAndAddress">
update `user`
<set>
u_phone=#{1},
u_address=#{2}
</set>
<where>
u_id=#{0}
</where>
</update>
<update id="UpdatePassword" >
update `user`
<set>
u_pwd=#{1}
</set>
<where>
u_id=#{0}
</where>
</update>
<select id="queryUser" resultType="User" >
select u_id uid,u_name uname,u_pwd upwd,u_realname urealname,u_role urole,u_mark umark,
u_phone uphone,u_address uaddress from `user` limit #{0},#{1}
</select>
<select id="queryCountOfUser" resultType="int">
select count(*) from `user`
</select>
<delete id="deleteUser" parameterType="int">
delete from `user` where u_id = #{value}
</delete>
<select id="queryUserByUid" resultType="User" parameterType="int">
select u_id uid,u_name uname,u_pwd upwd,u_realname urealname,u_role urole,u_mark umark,
u_phone uphone,u_address uaddress
from `user` where u_id=#{value}
</select>
</mapper>
com.vilicode.service
com.vilicode.service包是叮当书城项目中的业务逻辑层,负责实现系统的核心业务功能,是连接数据访问层(Mapper)和表示层(Controller/JSP)的重要桥梁。以下是其详细作用分析: 1. 包结构与组成 该包采用接口与实现分离的设计模式,包含: 接口文件:定义业务方法规范(如BookService.java) impl子包:包含接口的具体实现类(如BookServiceImpl.java) 目前包含4组核心服务: BookService:图书相关业务逻辑 BookTypeService:图书分类相关业务逻辑 OrderService:订单相关业务逻辑 UserService:用户相关业务逻辑 3. 在项目架构中的作用 业务逻辑封装:将复杂的业务逻辑封装在Service层,实现业务规则和流程控制 事务管理:作为事务的边界,确保业务操作的原子性、一致性、隔离性和持久性 数据访问协调:协调多个Mapper接口的调用,实现复杂业务场景下的数据操作 业务规则校验:实现数据校验、业务规则检查等逻辑 解耦表现层与数据层:使Controller层只需调用Service层方法,无需直接访问数据库 4. 服务层的核心功能 图书服务:图书查询、搜索、推荐管理、图书CRUD操作 分类服务:图书分类管理、分类下图书查询 订单服务:订单创建、查询、状态更新、订单统计 用户服务:用户注册、登录、信息管理、权限验证 5. 工作流程 表现层(Controller/JSP)调用Service层方法 Service层执行业务逻辑,可能涉及多个Mapper的调用 Service层将处理结果返回给表现层 整个过程中,Spring框架提供事务管理、依赖注入等支持 6. 技术特点 依赖注入:通过@Autowired注解自动注入Mapper接口和其他Service AOP支持:支持面向切面编程,实现事务管理、日志记录等横切关注点 接口与实现分离:便于单元测试和实现切换 异常处理:捕获并处理业务异常,向上层提供友好的错误信息 总结来说,com.vilicode.service包是项目的业务逻辑核心,它通过封装复杂的业务规则和流程,协调数据访问操作,为整个系统提供了稳定、可靠的业务功能支持。
BookService接口与BookServiceImpl实现类
BookService接口 BookService.java 定义了图书管理的核心业务操作契约: 图书查询功能:按推荐类型查询、按ID查询、关键词搜索图书 推荐管理功能:添加/移除图书推荐 图书维护功能:添加/修改/删除图书 BookServiceImpl实现类 BookServiceImpl.java 是具体业务逻辑的实现: 使用@Service注解标记为Spring服务组件 通过@Autowired注入BookMapper和RecommendMapper实现数据访问 实现分页查询逻辑,处理推荐图书的特殊状态(滚动/热门/新书) 包含异常捕获和处理机制
package com.vilicode.service;
import com.vilicode.bean.Book;
import com.vilicode.bean.Page;
import java.util.ArrayList;
import java.util.List;
public interface BookService {
public List<Book> queryBookByRecommendType(int rtype,int pageNumber,int pageSize);
public Page queryBookByRecommendType(int rtype,int pageNumber);
public Book queryBookByID(int bid);
public Page searchBooksByKeyword(String keyword, int pageNumber);
public boolean addRecommend(int bid,int rtype);
public boolean remoteRecommend(int bid,int rtype);
public boolean removeBookByBid(int bid);
public boolean addBook(Book book);
public boolean modifyBook(Book book);
}
package com.vilicode.service.impl;
import com.vilicode.bean.Book;
import com.vilicode.bean.Page;
import com.vilicode.mapper.BookMapper;
import com.vilicode.mapper.RecommendMapper;
import com.vilicode.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class BookServiceImpl implements BookService {
@Autowired
public BookMapper bookMapper;
@Autowired
public RecommendMapper recommendMapper;
@Override
public List<Book> queryBookByRecommendType(int rtype,int pageNumber,int pageSize)
{
return recommendMapper.queryBookByRecommendType(rtype,(pageNumber-1)*pageSize,pageSize);
}
@Override
public Page queryBookByRecommendType(int rtype, int pageNumber) {
Page p = new Page();
p.setPageNumber(pageNumber);
int totalCount = 0;
try {
if(rtype==0)
totalCount =bookMapper.queryCountOfBooks();
else
totalCount = recommendMapper.queryRecommendCountOfBooksByTypeID(rtype);
} catch (Exception e) {
System.out.println(e.getMessage());
}
p.SetPageSizeAndTotalCount(8, totalCount);
List<Book> list=null;
try {
if(rtype==0)
list=bookMapper.queryBooks((pageNumber-1)*8,8);
else
list = recommendMapper.queryBookByRecommendType(rtype,(pageNumber-1)*8,8);
for(int i=0;i<list.size();i++)
{
Book book=list.get(i);
book.setScroll(recommendMapper.queryBookByRtypeAndBid(1,book.getBid())>=1);
book.setHot(recommendMapper.queryBookByRtypeAndBid(2,book.getBid())>=1);
book.setNew(recommendMapper.queryBookByRtypeAndBid(3,book.getBid())>=1);
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
p.setList((List) list);
return p;
}
public Book queryBookByID(int bid)
{
return bookMapper.queryBookById(bid);
}
public Page searchBooksByKeyword(String keyword,int pageNumber) {
Page p = new Page();
p.setPageNumber(pageNumber);
int totalCount = 0;
try {
totalCount = bookMapper.queryCountOfBooksByKeyword(keyword);
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
p.SetPageSizeAndTotalCount(8, totalCount);
List list=null;
try {
list = bookMapper.queryBooksByKeyword(keyword,(pageNumber-1)*8,8);
} catch (Exception e) {
System.out.println(e.getMessage());
}
p.setList(list);
return p;
}
@Override
public boolean addRecommend(int bid, int rtype) {
try {
recommendMapper.addRecommendBook(bid,rtype);
return true;
}catch (Exception e)
{
System.out.println(e.getMessage());
return false;
}
}
@Override
public boolean remoteRecommend(int bid, int rtype) {
try {
recommendMapper.removeRecommendBook(bid,rtype);
return true;
}catch (Exception e)
{
System.out.println(e.getMessage());
return false;
}
}
@Override
public boolean removeBookByBid(int bid) {
try {
recommendMapper.removeRecommend(bid);
bookMapper.deleteBookByBtid(bid);
return true;
}catch (Exception e)
{
System.out.println(e.getMessage());
return false;
}
}
@Override
public boolean addBook(Book book) {
try {
bookMapper.addBook(book);
return true;
}catch (Exception e)
{
System.out.println(e.getMessage());
return false;
}
}
public boolean modifyBook(Book book) {
try {
bookMapper.modifyBook(book);
return true;
}catch (Exception e)
{
System.out.println(e.getMessage());
return false;
}
}
}
BookTypeService接口
BookTypeService接口 BookTypeService.java
定义了图书分类管理的业务操作:
- 查询所有图书分类
- 按分类ID查询图书(分页)
- 查询分类名称
- 添加/删除/修改图书分类
package com.vilicode.service;
import com.vilicode.bean.BookType;
import com.vilicode.bean.Page;
import java.util.List;
public interface BookTypeService {
public List<BookType> queryBookTypes();
public Page queryBookByBookTypeID(int btid, int pageNumber);
public String queryBookTypeNameByBookTypeID(int btid);
public boolean addBookType(String btname);
public boolean removeBookType(int btid);
public boolean modifyBookType(int btid,String btname);
}
BookTypeServiceImpl实现类
BookTypeServiceImpl.java
实现了分类管理的具体逻辑:
- 使用
@Service
注解标记 - 注入
BookMapper
和BookTypeMapper
- 实现分类名称重复性检查
- 在删除分类时级联删除相关图书
package com.vilicode.service.impl;
import com.vilicode.bean.BookType;
import com.vilicode.bean.Page;
import com.vilicode.mapper.BookMapper;
import com.vilicode.mapper.BookTypeMapper;
import com.vilicode.service.BookService;
import com.vilicode.service.BookTypeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class BookTypeServiceImpl implements BookTypeService {
@Autowired
public BookMapper bookMapper;
@Autowired
public BookTypeMapper bookTypeMapper;
@Override
public List<BookType> queryBookTypes() {
return bookTypeMapper.queryBookTypes();
}
@Override
public Page queryBookByBookTypeID(int btid, int pageNumber) {
Page p = new Page();
p.setPageNumber(pageNumber);
int totalCount = 0;
try {
if(btid==-1)
totalCount=bookMapper.queryCountOfBooks();
else
totalCount = bookTypeMapper.queryCountOfBooksByTypeID(btid);
} catch (Exception e) {
System.out.println(e.getMessage());
}
p.SetPageSizeAndTotalCount(8, totalCount);
List list=null;
try {
if(btid==-1)
list=bookMapper.queryBooks((pageNumber-1)*8,8);
else
list = bookTypeMapper.queryBooksByBtid(btid,(pageNumber-1)*8,8);
} catch (Exception e) {
System.out.println(e.getMessage());
}
p.setList(list);
return p;
}
@Override
public String queryBookTypeNameByBookTypeID(int btid) {
return bookTypeMapper.queryBookTypeNameByBookTypeID(btid);
}
@Override
public boolean addBookType(String btname) {
try {
int result=bookTypeMapper.identifyBtname(btname);
if(result>=1)
return false;
bookTypeMapper.addBookType(btname);
return true;
}catch (Exception e)
{
System.out.println(e.getMessage());
return false;
}
}
@Override
public boolean removeBookType(int btid) {
try {
bookMapper.deleteBookByBtid(btid);
bookTypeMapper.deleteBookType(btid);
return true;
}catch (Exception e)
{
System.out.println(e.getMessage());
return false;
}
}
@Override
public boolean modifyBookType(int btid, String btname) {
try {
bookTypeMapper.updateBookType(btid,btname);
return true;
}catch (Exception e)
{
System.out.println(e.getMessage());
return false;
}
}
}
OrderService接口
OrderService接口 OrderService.java
定义了订单管理的业务操作:
- 添加订单
- 按用户ID查询订单
- 按订单状态查询订单(分页)
- 更新订单状态
- 删除订单
package com.vilicode.service;
import com.vilicode.bean.Book;
import com.vilicode.bean.Order;
import com.vilicode.bean.OrderItem;
import com.vilicode.bean.Page;
import java.util.List;
public interface OrderService {
public boolean addOrder(Order order);
public List<Order> queryOrderByUid(int uid);
public Page queryOrdersByOstatus(int status,int pageNumber);
public boolean updateOrderStatus(String oid,int ostatus);
public boolean deleteOrderByOid(String oid);
}
OrderServiceImpl实现类
OrderServiceImpl.java
实现了订单处理的具体逻辑:
- 使用
@Service
注解标记 - 注入
OrderMapper
和BookMapper
- 生成唯一订单ID(基于时间戳)
- 实现订单与订单项的级联操作
- 包含事务回滚机制(失败时删除已添加的订单和订单项)
- 为查询结果中的订单项关联图书信息
package com.vilicode.service.impl;
import com.vilicode.bean.Book;
import com.vilicode.bean.Order;
import com.vilicode.bean.OrderItem;
import com.vilicode.bean.Page;
import com.vilicode.mapper.BookMapper;
import com.vilicode.mapper.OrderMapper;
import com.vilicode.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
public OrderMapper orderMapper;
@Autowired
public BookMapper bookMapper;
@Override
public boolean addOrder(Order order) {
String oid=new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date());
order.setOid(oid);
try {
orderMapper.addOrder(order);
order.getItemMap().forEach((key, value) -> {
value.setOid(oid);
orderMapper.addOrderItem(value);
});
return true;
}catch (Exception e)
{
orderMapper.deleteOrder(oid);
orderMapper.deleteOrderItem(oid);
System.out.println(e.getMessage());
return false;
}
}
@Override
public List<Order> queryOrderByUid(int uid) {
List<Order> orders=new ArrayList<>();
try {
orders=orderMapper.queryOrderByUid(uid);
for(int i=0;i<orders.size();i++)
{
orders.get(i).setItemList(orderMapper.queryOrderItemByUidAndOid(orders.get(i).getOid()));
for(int j=0;j<orders.get(i).getItemList().size();j++)
{
orders.get(i).getItemList().get(j).setBook(bookMapper.queryBookById(orders.get(i).getItemList().get(j).getBid()));
}
}
}catch (Exception e)
{
System.out.println(e.getMessage());
}
return orders;
}
@Override
public Page queryOrdersByOstatus(int ostatus,int pageNumber) {
Page p = new Page();
p.setPageNumber(pageNumber);
int pageSize = 4;
int totalCount = 0;
try {
if(ostatus!=1)
totalCount=orderMapper.queryCountOfOrderByOstatus(ostatus);
else
totalCount=orderMapper.queryCountOfOrder();
} catch (Exception e) {
System.out.println(e.getMessage());
}
p.SetPageSizeAndTotalCount(pageSize, totalCount);
List<Order> list=null;
try {
if(ostatus!=1)
list=orderMapper.queryOrderByOstatus(ostatus,(pageNumber-1)*pageSize,pageSize);
else
list=orderMapper.queryOrder((pageNumber-1)*pageSize,pageSize);
for(int i=0;i<list.size();i++)
{
list.get(i).setItemList(orderMapper.queryOrderItemByUidAndOid(list.get(i).getOid()));
for(int j=0;j<list.get(i).getItemList().size();j++)
{
list.get(i).getItemList().get(j).setBook(bookMapper.queryBookById(list.get(i).getItemList().get(j).getBid()));
}
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
p.setList((List)list);
return p;
}
@Override
public boolean updateOrderStatus(String oid, int ostatus) {
try {
orderMapper.updateOrderStatus(oid,ostatus);
return true;
}catch (Exception e)
{
System.out.println(e.getMessage());
return false;
}
}
@Override
public boolean deleteOrderByOid(String oid) {
try {
orderMapper.deleteOrderItem(oid);
orderMapper.deleteOrder(oid);
return true;
}catch (Exception e)
{
System.out.println(e.getMessage());
return false;
}
}
}
UserService接口
UserService.java
定义了用户管理的业务操作:
- 用户注册
- 用户登录
- 更新联系方式
- 修改密码(带原密码验证和不带验证两种方式)
- 查询用户(分页)
- 删除用户
- 按ID查询用户
package com.vilicode.service;
import com.vilicode.bean.Page;
import com.vilicode.bean.User;
import java.util.List;
public interface UserService {
public Boolean register(User user);
public User login(String uname);
public boolean UpdatePhoneAndAddress(int uid,String uphone,String uaddress);
public boolean UpdatePassword(int uid,String upwd,String oldupwd);
public boolean UpdatePassword(int uid,String upwd);
public Page queryUser(int pageNumber);
public boolean deleteUser(int uid);
public User queryUserByUid(int uid);
}
UserServiceImpl实现类
UserServiceImpl.java
实现了用户管理的具体逻辑:
- 使用
@Service
注解标记 - 注入
UserMapper
- 实现密码加密和解密功能(使用MyCipher工具类)
- 进行用户名重复性检查
- 实现密码修改时的原密码验证
package com.vilicode.service.impl;
import com.vilicode.Utils.MyCipher;
import com.vilicode.bean.Page;
import com.vilicode.bean.User;
import com.vilicode.mapper.UserMapper;
import com.vilicode.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public Boolean register(User user) {
boolean flag=false;
//密码加密
MyCipher mc=new MyCipher();
user.setUpwd(mc.encrypt(user.getUpwd(), "!"));
try {
int result=userMapper.identify(user.getUname());
if(result>=1)
return false;
userMapper.addUser(user);
flag=true;
} catch (Exception e) {
System.out.println(e.getMessage());
}
return flag;
}
@Override
public User login(String uname) {
String pwd="";
//密码解密
MyCipher mc=new MyCipher();
User user=userMapper.login(uname);
if(user!=null)
user.setUpwd(mc.decrypt(user.getUpwd(),"!"));
return user;
}
public boolean UpdatePhoneAndAddress(int uid,String uphone,String uaddress)
{
try {
userMapper.UpdatePhoneAndAddress(uid,uphone,uaddress);
return true;
}catch (Exception e)
{
System.out.println(e.getMessage());
return false;
}
}
@Override
public boolean UpdatePassword(int uid, String upwd,String oldupwd) {
MyCipher myCipher=new MyCipher();
try {
String temp=userMapper.queryUpwd(uid);
if(temp.equals(myCipher.encrypt(oldupwd,"!")))
{
userMapper.UpdatePassword(uid,myCipher.encrypt(upwd,"!"));
return true;
}
else
{
return false;
}
}catch (Exception e)
{
System.out.println(e.getMessage());
return false;
}
}
@Override
public boolean UpdatePassword(int uid, String upwd) {
MyCipher myCipher=new MyCipher();
try {
userMapper.UpdatePassword(uid,myCipher.encrypt(upwd,"!"));
return true;
}catch (Exception e)
{
System.out.println(e.getMessage());
return false;
}
}
@Override
public Page queryUser(int pageNumber) {
Page p = new Page();
p.setPageNumber(pageNumber);
int pageSize = 7;
int totalCount = 0;
try {
totalCount = userMapper.queryCountOfUser();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
p.SetPageSizeAndTotalCount(pageSize, totalCount);
List list=null;
try {
list = userMapper.queryUser( (pageNumber-1)*pageSize, pageSize);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
p.setList(list);
return p;
}
@Override
public boolean deleteUser(int uid) {
try {
userMapper.deleteUser(uid);
return true;
}catch (Exception e)
{
System.out.println(e.getMessage());
return false;
}
}
@Override
public User queryUserByUid(int uid) {
return userMapper.queryUserByUid(uid);
}
}