🎉🎉欢迎来到我的CSDN主页!🎉🎉
🏅我是Java方文山,一个在CSDN分享笔记的博主。📚📚
🌟推荐给大家我的专栏《电商项目实战》。🎯🎯
👉点击这里,就可以查看我的主页啦!👇👇
Java方文山的个人主页
🎁如果感觉还不错的话请给我点赞吧!🎁🎁
💖期待你的加入,一起学习,一起进步!💖💖
前言
项目介绍
前面讲解了这么多的知识点,现在我们将这些知识点串起来,并且在这个基础上追加新的技术。 电商系统主要包括用户登录、第三方授权、首页展示、商品详情、购买商品、购物车、订单、订单详情、沙箱支付等。
开发技术
此项目开发我用到的技术有:springboot、mybatis puls、freemarker、redis、oauth2
一、环境搭建
1.配置pom文件
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.csdn</groupId>
<artifactId>shop</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>shop</name>
<description>shop</description>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.7.6</spring-boot.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<!-- 模板引擎 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 这个依赖提供了使用Spring Boot构建Web应用程序的支持。 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.3.0</version>
</dependency>
<!-- 这个依赖提供了MyBatis和Spring Boot之间的集成,允许你在应用程序中使用MyBatis。 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!-- 这个依赖提供了用于增强Spring Boot应用程序开发效率的开发工具。 -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<!-- 这个依赖提供了连接到MySQL数据库的JDBC驱动程序。 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- 这个依赖将Lombok集成到项目中,有助于减少Java类中的样板代码。 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 这个依赖提供了在Spring Boot应用程序中编写测试的支持。 -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 这个依赖提供了Spring Security的测试工具。 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.2</version>
</dependency>
<!-- 这个依赖提供了对MyBatis的增强支持,包括额外的功能和实用工具。 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.2</version>
</dependency>
<!-- 这个依赖提供了MyBatis Plus的代码生成功能,允许你生成MyBatis的mapper接口、XML映射和实体类。 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.15</version>
</dependency>
<!--druid连接池-->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.0.1-jre</version>
</dependency>
<!-- 集合分片 -->
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<configuration>
<mainClass>com.csdn.shop.ShopApplication</mainClass>
<skip>true</skip>
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
2.配置yml文件
#日志配置
logging:
level:
com.csdn.boot.mapper: debug
#server配置
server:
# 配置端口
port: 8080
# 项目名
servlet:
context-path: /
#数据库配置
spring:
freemarker:
# 设置模板后缀名
suffix: .html
# 设置文档类型
content-type: text/html
# 设置页面编码格式
charset: UTF-8
# 设置页面缓存
cache: false
# 设置ftl文件路径
template-loader-path: classpath:/templates
# 设置静态文件路径,js,css等
mvc:
static-path-pattern: /static/**
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/goodsshop?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
username: root
password: 123456
druid:
#2.连接池配置
#初始化连接池的连接数量 大小,最小,最大
initial-size: 5
min-idle: 5
max-active: 20
#配置获取连接等待超时的时间
max-wait: 60000
#配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
time-between-eviction-runs-millis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
min-evictable-idle-time-millis: 30000
validation-query: SELECT 1 FROM DUAL
test-while-idle: true
test-on-borrow: true
test-on-return: false
# 是否缓存preparedStatement,也就是PSCache 官方建议MySQL下建议关闭 个人建议如果想用SQL防火墙 建议打开
pool-prepared-statements: true
max-pool-prepared-statement-per-connection-size: 20
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
filter:
stat:
merge-sql: true
slow-sql-millis: 5000
#3.基础监控配置
web-stat-filter:
enabled: true
url-pattern: /*
#设置不统计哪些URL
exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"
session-stat-enable: true
session-stat-max-count: 100
stat-view-servlet:
enabled: true
url-pattern: /druid/*
reset-enable: true
#设置监控页面的登录名和密码
login-username: admin
login-password: admin
allow: 127.0.0.1
#deny: 192.168.1.100
#mybatis配置
mybatis:
#配置SQL映射文件路径
mapper-locations: classpath:mapper/*.xml
#配置别名
type-aliases-package: com.csdn.shop.pojo
#pagehelper分页插件配置
pagehelper:
#sql“方言”
helperDialect: mysql
#开启分页合理化
reasonable: true
#mapper方法上的参数
supportMethodsArguments: true
#查询数量
params: count=countSql
weblog:
enable: false
#乐观锁配置
mybatis-plus:
# Mybatis Mapper所对应的XML位置
mapper-locations: classpath:mapper/*.xml
# 别名包扫描路径
type-aliases-package: com.csdn.shop.pojo
# 是否开启自动驼峰命名规则(camel case)映射
configuration:
map-underscore-to-camel-case: true
global-config:
db-config:
logic-delete-field: flag # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
3.编写电商首页
这个其他页面的源码我会上传CSDN的方便大家下载实践
<!DOCTYPE html>
<html>
<head lang="en">
<#include "common/head.html">
<link rel="stylesheet" type="text/css" href="css/public.css"/>
<link rel="stylesheet" type="text/css" href="css/index.css" />
</head>
<body>
<!------------------------------head------------------------------>
<#include "common/top.html">
<!-------------------------banner--------------------------->
<div class="block_home_slider">
<div id="home_slider" class="flexslider">
<ul class="slides">
<li>
<div class="slide">
<img src="img/banner2.jpg"/>
</div>
</li>
<li>
<div class="slide">
<img src="img/banner1.jpg"/>
</div>
</li>
</ul>
</div>
</div>
<!------------------------------thImg------------------------------>
<div class="thImg">
<div class="clearfix">
<a href="${ctx}/page/vase_proList.html"><img src="img/i1.jpg"/></a>
<a href="${ctx}/page/proList.html"><img src="img/i2.jpg"/></a>
<a href="#2"><img src="img/i3.jpg"/></a>
</div>
</div>
<!------------------------------news------------------------------>
<div class="news">
<div class="wrapper">
<h2><img src="img/ih1.jpg"/></h2>
<div class="top clearfix">
<a href="${ctx}/page/proDetail.html"><img src="img/n1.jpg"/><p></p></a>
<a href="${ctx}/page/proDetail.html"><img src="img/n2.jpg"/><p></p></a>
<a href="${ctx}/page/proDetail.html"><img src="img/n3.jpg"/><p></p></a>
</div>
<div class="bott clearfix">
<a href="${ctx}/page/proDetail.html"><img src="img/n4.jpg"/><p></p></a>
<a href="${ctx}/page/proDetail.html"><img src="img/n5.jpg"/><p></p></a>
<a href="${ctx}/page/proDetail.html"><img src="img/n6.jpg"/><p></p></a>
</div>
<h2><img src="img/ih2.jpg"/></h2>
<div class="flower clearfix tran">
<a href="proDetail.html" class="clearfix">
<dl>
<dt>
<span class="abl"></span>
<img src="img/flo1.jpg"/>
<span class="abr"></span>
</dt>
<dd>【花艺】七头美丽玫瑰仿真花束</dd>
<dd><span>¥ 79.00</span></dd>
</dl>
</a>
<a href="proDetail.html">
<dl>
<dt>
<span class="abl"></span>
<img src="img/flo2.jpg"/>
<span class="abr"></span>
</dt>
<dd>【花艺】七头美丽玫瑰仿真花束</dd>
<dd><span>¥ 79.00</span></dd>
</dl>
</a>
<a href="proDetail.html">
<dl>
<dt>
<span class="abl"></span>
<img src="img/flo3.jpg"/>
<span class="abr"></span>
</dt>
<dd>【花艺】七头美丽玫瑰仿真花束</dd>
<dd><span>¥ 79.00</span></dd>
</dl>
</a>
</div>
<div class="flower clearfix tran">
<a href="proDetail.html">
<dl>
<dt>
<span class="abl"></span>
<img src="img/flo4.jpg"/>
<span class="abr"></span>
</dt>
<dd>【花艺】七头美丽玫瑰仿真花束</dd>
<dd><span>¥ 79.00</span></dd>
</dl>
</a>
<a href="proDetail.html">
<dl>
<dt>
<span class="abl"></span>
<img src="img/flo5.jpg"/>
<span class="abr"></span>
</dt>
<dd>【花艺】七头美丽玫瑰仿真花束</dd>
<dd><span>¥ 79.00</span></dd>
</dl>
</a>
<a href="proDetail.html">
<dl>
<dt>
<span class="abl"></span>
<img src="img/flo6.jpg"/>
<span class="abr"></span>
</dt>
<dd>【花艺】七头美丽玫瑰仿真花束</dd>
<dd><span>¥ 79.00</span></dd>
</dl>
</a>
</div>
</div>
</div>
<!------------------------------ad------------------------------>
<a href="#" class="ad"><img src="img/ib1.jpg"/></a>
<!------------------------------people------------------------------>
<div class="people">
<div class="wrapper">
<h2><img src="img/ih3.jpg"/></h2>
<div class="pList clearfix tran">
<a href="proDetail.html">
<dl>
<dt>
<span class="abl"></span>
<img src="img/s7.jpg"/>
<span class="abr"></span>
</dt>
<dd>【最家】不锈钢壁饰墙饰软装</dd>
<dd><span>¥688.00</span></dd>
</dl>
</a>
<a href="proDetail.html">
<dl>
<dt>
<span class="abl"></span>
<img src="img/s10.jpg"/>
<span class="abr"></span>
</dt>
<dd>【最家】小城动物木板画壁挂北欧</dd>
<dd><span>¥188.00</span></dd>
</dl>
</a>
<a href="proDetail.html">
<dl>
<dt>
<span class="abl"></span>
<img src="img/s4.jpg"/>
<span class="abr"></span>
</dt>
<dd>【最家】玄关假山水壁饰背景墙饰挂件创意</dd>
<dd><span>¥599.00</span></dd>
</dl>
</a>
<a href="proDetail.html">
<dl>
<dt>
<span class="abl"></span>
<img src="img/s9.jpg"/>
<span class="abr"></span>
</dt>
<dd>【最家】金属树枝壁饰铜鸟装饰品</dd>
<dd><span>¥928.00</span></dd>
</dl>
</a>
</div>
<div class="pList clearfix tran">
<a href="proDetail.html">
<dl>
<dt>
<span class="abl"></span>
<img src="img/s6.jpg"/>
<span class="abr"></span>
</dt>
<dd>【最家】金属壁饰创意背景墙面挂件创意</dd>
<dd><span>¥228.00</span></dd>
</dl>
</a>
<a href="proDetail.html">
<dl>
<dt>
<span class="abl"></span>
<img src="img/s8.jpg"/>
<span class="abr"></span>
</dt>
<dd>【最家】小城动物木板画壁挂北欧</dd>
<dd><span>¥199.00</span></dd>
</dl>
</a>
<a href="proDetail.html">
<dl>
<dt>
<span class="abl"></span>
<img src="img/s12.jpg"/>
<span class="abr"></span>
</dt>
<dd>【最家】欧式复古挂钟创意餐厅钟表家居挂件</dd>
<dd><span>¥666.00</span></dd>
</dl>
</a>
<a href="proDetail.html">
<dl>
<dt>
<span class="abl"></span>
<img src="img/s1.jpg"/>
<span class="abr"></span>
</dt>
<dd>【最家】客厅地中海欧式现代相片墙创意</dd>
<dd><span>¥59.80</span></dd>
</dl>
</a>
</div>
<div class="pList clearfix tran">
<a href="proDetail.html">
<dl>
<dt>
<span class="abl"></span>
<img src="img/s5.jpg"/>
<span class="abr"></span>
</dt>
<dd>【最家】铁艺荷叶壁挂软装背景墙上装饰品</dd>
<dd><span>¥800.00</span></dd>
</dl>
</a>
<a href="proDetail.html">
<dl>
<dt>
<span class="abl"></span>
<img src="img/s3.jpg"/>
<span class="abr"></span>
</dt>
<dd>【最家】欧式照片墙 创意组合结婚礼物</dd>
<dd><span>¥189.00</span></dd>
</dl>
</a>
<a href="proDetail.html">
<dl>
<dt>
<span class="abl"></span>
<img src="img/s2.jpg"/>
<span class="abr"></span>
</dt>
<dd>【最家】欧式钟表相框墙挂墙创意组合</dd>
<dd><span>¥148.00</span></dd>
</dl>
</a>
<a href="proDetail.html">
<dl>
<dt>
<span class="abl"></span>
<img src="img/s11.jpg"/>
<span class="abr"></span>
</dt>
<dd>【最家】小城动物木板画壁挂北欧</dd>
<dd><span>¥188.00</span></dd>
</dl>
</a>
</div>
</div>
</div>
<#include "common/footer.html"/>
<script src="js/public.js" type="text/javascript" charset="utf-8"></script>
<script src="js/nav.js" type="text/javascript" charset="utf-8"></script>
<script src="js/jquery.flexslider-min.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
$(function() {
$('#home_slider').flexslider({
animation: 'slide',
controlNav: true,
directionNav: true,
animationLoop: true,
slideshow: true,
slideshowSpeed:2000,
useCSS: false
});
});
</script>
</body>
</html>
4.编写controller层代码
package com.csdn.shop.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class PageController {
@RequestMapping("/page/{page}")
public String to(@PathVariable("page") String page) {
return page.replace(".html", "");
}
}
这里如果不去掉.html,我们点击的路径就会是http://localhost:8080/page/index.html.html
二、表设计
我们这个电商项目目前是有这几张表,分别是t_dict_data、t_dict_type、t_goods、t_order、t_order_item、t_user。这根据我所给出的图片创建表。
t_dict_data
t_dict_type
t_goods
t_order
t_order_item
**t_user **
三、功能实现
1.首页商品显示
首先根据我们的页面分析同样的商品在摆件挂件需要展示六条,而在壁挂北欧需要展示十二条所以商品类别和数量是可变的其他都是不变的,得出以下sql语句。
select * from t_dict_data a,t_goods b where
a.dict_label='?' and a.dict_value=b.goods_type limit ?
知道sql语句后根据我们的sql语句编写mapper层和service层代码
mapper.xml代码
<select id="BydictlabelSelect" resultType="goods">
select *
from t_dict_data a,
t_goods b
where a.dict_label = #{type}
and a.dict_value = b.goods_type limit #{num}
</select>
mapper代码
@Repository
public interface GoodsMapper extends BaseMapper<Goods> {
List<Goods> BydictlabelSelect(@Param("type") String type , @Param("num") Integer num);
}
** service接口类**
public interface IGoodsService extends IService<Goods> {
List<Goods> BydictlabelSelect( String type , Integer num);
}
** service实现类**
@Service
public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements IGoodsService {
@Autowired
private GoodsMapper goodsMapper;
@Override
public List<Goods> BydictlabelSelect(String type, Integer num) {
return goodsMapper.BydictlabelSelect(type,num);
}
}
** controller层**
@Controller
public class PageController {
@Autowired
private IGoodsService goodsService;
@RequestMapping("/")
public String index(Model model) {
List<Goods> gs1 = goodsService.BydictlabelSelect("装饰摆件", 6);
List<List<Goods>> ps1 = Lists.partition(gs1, 3);
List<Goods> gs2 = goodsService.BydictlabelSelect("墙式壁挂", 12);
List<List<Goods>> ps2 = Lists.partition(gs2, 4);
model.addAttribute("ps1", ps1);
model.addAttribute("ps2", ps2);
return "index";
}
@RequestMapping("/page/{page}")
public String to(@PathVariable("page") String page) {
return page.replace(".html", "");
}
}
这里用到了Google Guava库的 Lists 工具类,将 gs1 列表按照每组最多3个元素进行分割,得到一个二维列表 ps1,将 gs2 列表按照每组最多4个元素进行分割,得到一个二维列表 ps4。这样的好处是为了方便我们前端进行数据遍历。
装饰插件
<#list ps1 as p1>
<div class="flower clearfix tran">
<#list p1 as g1>
<a href="proDetail.html" class="clearfix">
<dl>
<dt>
<span class="abl"></span>
<img src="${g1.goodsImg}"/>
<span class="abr"></span>
</dt>
<dd>${g1.goodsName}</dd>
<dd><span>¥ ${g1.goodsPrice}</span></dd>
</dl>
</a>
</#list>
</div>
</#list>
** 壁挂北欧**
<#list ps2 as p2>
<div class="pList clearfix tran">
<#list p2 as g2>
<a href="proDetail.html" class="clearfix">
<dl>
<dt>
<span class="abl"></span>
<img src="${g2.goodsImg}"/>
<span class="abr"></span>
</dt>
<dd>${g2.goodsName}</dd>
<dd><span>¥ ${g2.goodsPrice}</span></dd>
</dl>
</a>
</#list>
</div>
</#list>
2.商品分类显示
像我们的首页有一个商品类别的数据,这个数据肯定也是来自于数据库
mapper.xml代码
<select id="Selecttype" resultType="dictData">
select dict_label,dict_value from t_dict_data
</select>
后面的代码都和上面差不多,我就直接跳到controller做讲解了
@RequestMapping("/")
public String index(Model model) {
//首页商品数据
List<Goods> gs1 = goodsService.BydictlabelSelect("装饰摆件", 6);
List<List<Goods>> ps1 = Lists.partition(gs1, 3);
List<Goods> gs2 = goodsService.BydictlabelSelect("墙式壁挂", 12);
List<List<Goods>> ps2 = Lists.partition(gs2, 4);
model.addAttribute("ps1", ps1);
model.addAttribute("ps2", ps2);
//首页分类
List<DictData> selecttype = dictDataService.Selecttype();
model.addAttribute("type", selecttype);
return "index";
}
** 首页商品类别展示**
<ul class="clearfix" id="bott">
<li><a href="${ctx}/">首页</a></li>
<#list type as t>
<li>
<a href="${ctx}/page/flowerDer.html">${t.dictLabel}</a>
<div class="sList">
<div class="wrapper clearfix">
<a href="${ctx}/page/paint.html">
<dl>
<dt><img src="img/nav1.jpg"/></dt>
<dd>浓情欧式</dd>
</dl>
</a>
<a href="${ctx}/page/paint.html">
<dl>
<dt><img src="img/nav2.jpg"/></dt>
<dd>浪漫美式</dd>
</dl>
</a>
<a href="${ctx}/page/paint.html">
<dl>
<dt><img src="img/nav3.jpg"/></dt>
<dd>雅致中式</dd>
</dl>
</a>
<a href="${ctx}/page/paint.html">
<dl>
<dt><img src="img/nav6.jpg"/></dt>
<dd>简约现代</dd>
</dl>
</a>
<a href="${ctx}/page/paint.html">
<dl>
<dt><img src="img/nav7.jpg"/></dt>
<dd>创意装饰</dd>
</dl>
</a>
</div>
</div>
</li>
</#list>
</ul>
到这里我的分享就结束了,欢迎到评论区探讨交流!!
💖如果觉得有用的话还请点个赞吧 💖
版权归原作者 Java方文山 所有, 如有侵权,请联系我们删除。