项目简要说明:使用微服务(SpringCloud)搭建的一个简易外卖订单系统。
本项目技术栈:SpringCloud、SpringBoot、MyBatis、LayUI、thymeleaf等
写在前面:springcloud及其五大核心组件?点击下方链接。
SpringCloud学习:https://blog.csdn.net/qq_41822345/article/details/104585350
项目详细说明:首先来了解项目需求。本项目分为客户端和后台管理系统两个界面,客户端针对普通用户,功能包括用户登陆、用户退出、菜品订购、我的订单。后台管理系统针对管理员,功能包括管理员登陆、管理员退出、添加菜品、查询菜品、修改菜品、删除菜品、订单处理、添加用户、查询用户、删除用户。
设计系统架构设计:
①首先分配出4个服务提供者,account、menu、order、user。
account 提供账户服务:用户和管理员登陆。
menu 提供菜品服务:添加菜品、查询菜品、修改菜品、删除菜品。
order 提供订单服务:添加订单、查询订单、删除订单、处理订单。
user 提供用户服务:添加用户、查询用户、删除用户。
②接下来分配出1个服务消费者,包括客户端的前端页面和后台接口、后台管理系统的前端页面和后台接口,用户/管理员直接访问的资源都保存在服务消费者中,然后服务消费者调用4个服务提供者对应的接口完成业务逻辑,并通过 feign 完成负载均衡。
4个服务提供者和1个服务消费者都需要在注册中心完成注册,同时注册配置中心,提供远程配置信息读取,服务提供者和服务消费者的配置信息保存在 Git 远程仓库,由配置中心负责拉取,关系如下图所示。
本系统共有7个模块组成,包括注册中心,配置中心(本地 / Git 仓库配置信息),服务消费者,4个服务提供者。最终的代码结构如下:
项目构成:(七个微服务: EurekaServer ConfigServer Menu User Account Order Client)
注册中心 → 服务配置中心 → 服务提供者:菜单服务、用户服务、登录服务、订单服务 → 服务消费者:客户端服务
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.7.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.SR2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
server:
port: 8761
eureka:
client:
register-with-eureka: false
fetch-registry: false
service-url:
defaultZone: http://localhost:8761/eureka/
package com.liuwen;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer // 标注这是微服务注册中心启动类
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class,args);
}
}
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
</dependencies>
server:
port: 8762
spring:
application:
name: nativeconfigserver
profiles:
active: native
cloud:
config:
server:
native:
search-locations: classpath:/shared //配置文件存放路径
1、order-dev.yml
server:
port: 8010
spring:
application:
name: order
datasource:
name: orderingsystem
url: jdbc:mysql://localhost:3306/orderingsystem?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8
username: root
password: root
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
instance:
prefer-ip-address: true
mybatis:
mapper-locations: classpath:/mapping/*.xml
type-aliases-package: com.liuwen.entity
2、menu-dev.yml
server:
port: 8020
spring:
application:
name: menu
datasource:
name: orderingsystem
url: jdbc:mysql://localhost:3306/orderingsystem?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8
username: root
password: root
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
instance:
prefer-ip-address: true
mybatis:
type-aliases-package: com.liuwen.entity
mapper-locations: classpath:/mapping/*.xml
3、client-dev.yml
server:
port: 8030
spring:
application:
name: client
thymeleaf:
prefix: classpath:/static/
suffix: .html
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
instance:
prefer-ip-address: true
4、user-dev.yml
server:
port: 8040
spring:
application:
name: user
datasource:
name: orderingsystem
url: jdbc:mysql://localhost:3306/orderingsystem?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8
username: root
password: root
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
instance:
prefer-ip-address: true
mybatis:
mapper-locations: classpath:/mapping/*.xml
type-aliases-package: com.liuwen.entity
5、account-dev.yml
server:
port: 8050
spring:
application:
name: account
datasource:
name: orderingsystem
url: jdbc:mysql://localhost:3306/orderingsystem?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8
username: root
password: root
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
instance:
prefer-ip-address: true
mybatis:
mapper-locations: classpath:/mapping/*.xml
type-aliases-package: com.liuwen.entity
package com.liuwen;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
@SpringBootApplication
@EnableConfigServer //标注这是配置中心启动类
public class ConfigServerApplication {
public static void main(String[] args){
SpringApplication.run(ConfigServerApplication.class,args);
}
}
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>2.0.0.RELEASE</version>
</dependency>
<!-- MyBatis驱动 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.1</version>
</dependency>
<!-- MySQL驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency>
<!-- 配置中心 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
spring:
application:
name: order
profiles:
active: dev
cloud:
config:
uri: http://localhost:8762
fail-fast: true
package com.liuwen;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.liuwen.repository")
public class OrderApplication {
public static void main(String[] args){
SpringApplication.run(OrderApplication.class,args);
}
}
package com.liuwen.entity;
import lombok.Data;
import java.util.Date;
@Data
public class Order {
private long id;
private User user;
private Menu menu;
private Admin admin;
private Date date;
private int state;
}
package com.liuwen.repository;
import com.liuwen.entity.Order;
import java.util.List;
public interface OrderRepository {
public List<Order> findAllByUid(long uid,int index,int limit);
public void save(Order order);
public int countByUid(long uid);
public void deleteByMid(long mid);
public void deleteByUid(long uid);
public List<Order> findAllByState(int state,int index,int limit);
public int countByState(int state);
public void updateState(long id,long aid,int state);
}
<?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.liuwen.repository.OrderRepository">
<resultMap id="orderMap" type="Order">
<id property="id" column="oid"/>
<result property="date" column="date"/>
<result property="state" column="state"/>
<!-- 映射menu -->
<association property="menu" javaType="Menu">
<id property="id" column="mid"/>
<result property="name" column="name"/>
<result property="price" column="price"/>
<result property="flavor" column="flavor"/>
</association>
</resultMap>
<resultMap id="orderMap2" type="Order">
<id property="id" column="oid"/>
<result property="date" column="date"/>
<!-- 映射menu -->
<association property="menu" javaType="Menu">
<id property="id" column="mid"/>
<result property="name" column="name"/>
<result property="price" column="price"/>
<result property="flavor" column="flavor"/>
</association>
<!-- 映射user -->
<association property="user" javaType="User">
<id property="id" column="uid"/>
<result property="nickname" column="nickname"/>
<result property="telephone" column="telephone"/>
<result property="address" column="address"/>
</association>
</resultMap>
<insert id="save" parameterType="Order">
insert into t_order(uid,mid,aid,date,state) values(#{user.id},#{menu.id},#{admin.id},#{date},0)
</insert>
<select id="findAllByUid" resultMap="orderMap">
select m.id mid,m.name,m.price,m.flavor,o.id oid,o.date,o.state from t_order o,t_menu m where o.mid = m.id and o.uid = #{param1} order by oid limit #{param2},#{param3}
</select>
<select id="countByUid" parameterType="long" resultType="int">
select count(*) from t_order where uid = #{uid}
</select>
<delete id="deleteByMid" parameterType="long">
delete from t_order where mid = #{mid}
</delete>
<delete id="deleteByUid" parameterType="long">
delete from t_order where uid = #{uid}
</delete>
<select id="findAllByState" resultMap="orderMap2">
select m.id mid,m.name,m.price,m.flavor,o.id oid,o.date,u.id uid,u.nickname,u.telephone,u.address from t_order o,t_menu m,t_user u where o.mid = m.id and o.uid = u.id and o.state = #{param1} order by oid limit #{param2},#{param3}
</select>
<select id="countByState" parameterType="int" resultType="int">
select count(*) from t_order where state = #{state}
</select>
<update id="updateState">
update t_order set aid = #{param2},state = #{param3} where id = #{param1}
</update>
</mapper>
package com.liuwen.controller;
import com.liuwen.entity.Order;
import com.liuwen.entity.OrderVO;
import com.liuwen.repository.OrderRepository;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@RestController
@RequestMapping("/order")
public class OrderHandler {
//test
@Value("${server.port}")
private String port;
@GetMapping("/index")
public String index(){
return "order的端口:"+this.port;
}
@Resource
private OrderRepository orderRepository;
@PostMapping("/save")
public void save(@RequestBody Order order){
orderRepository.save(order);
}
//Layui需要的数据格式
@GetMapping("/findAllByUid/{uid}/{page}/{limit}")
public OrderVO findAllByUid(@PathVariable("uid") long uid, @PathVariable("page") int page, @PathVariable("limit") int limit){
OrderVO orderVO = new OrderVO();
orderVO.setCode(0);
orderVO.setMsg("");
orderVO.setCount(orderRepository.countByUid(uid));
orderVO.setData(orderRepository.findAllByUid(uid,(page-1)*limit,limit));
return orderVO;
}
@GetMapping("/countByUid/{uid}")
public int countByUid(@PathVariable("uid") long uid){
return orderRepository.countByUid(uid);
}
@DeleteMapping("/deleteByMid/{mid}")
public void deleteByMid(@PathVariable("mid") long mid){
orderRepository.deleteByMid(mid);
}
@DeleteMapping("/deleteByUid/{uid}")
public void deleteByUid(@PathVariable("uid") long uid){
orderRepository.deleteByUid(uid);
}
@GetMapping("/findAllByState/{state}/{page}/{limit}")
public OrderVO findAllByState(@PathVariable("state") int state, @PathVariable("page") int page, @PathVariable("limit") int limit){
OrderVO orderVO = new OrderVO();
orderVO.setCode(0);
orderVO.setMsg("");
orderVO.setCount(orderRepository.countByState(0));
orderVO.setData(orderRepository.findAllByState(0,(page-1)*limit,limit));
return orderVO;
}
@PutMapping("/updateState/{id}/{state}/{aid}")
public void updateState(@PathVariable("id") long id, @PathVariable("state") int state, @PathVariable("aid") long aid){
orderRepository.updateState(id,aid,state);
}
}
-- MySQL dump 10.13 Distrib 8.0.11, for macos10.13 (x86_64)
--
-- Host: 127.0.0.1 Database: orderingsystem【自己手动创建数据库orderingsystem】
-- ------------------------------------------------------
-- Server version 8.0.11
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
SET NAMES utf8mb4 ;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `t_admin`
--
DROP TABLE IF EXISTS `t_admin`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
SET character_set_client = utf8mb4 ;
CREATE TABLE `t_admin` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(11) DEFAULT NULL,
`password` varchar(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `t_admin`
--
LOCK TABLES `t_admin` WRITE;
/*!40000 ALTER TABLE `t_admin` DISABLE KEYS */;
INSERT INTO `t_admin` VALUES (1,'admin1','123123');
/*!40000 ALTER TABLE `t_admin` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `t_menu`
--
DROP TABLE IF EXISTS `t_menu`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
SET character_set_client = utf8mb4 ;
CREATE TABLE `t_menu` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(11) DEFAULT NULL,
`price` double DEFAULT NULL,
`flavor` varchar(11) DEFAULT NULL,
`tid` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `tid` (`tid`),
CONSTRAINT `t_menu_ibfk_1` FOREIGN KEY (`tid`) REFERENCES `t_type` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `t_menu`
--
LOCK TABLES `t_menu` WRITE;
/*!40000 ALTER TABLE `t_menu` DISABLE KEYS */;
INSERT INTO `t_menu` VALUES (1,'香酥鸡',39,'五香',1),(2,'烧椒扣肉',46,'微辣',1),(3,'栗子三杯鸡',56,'五香',1),(4,'毛血旺',50,'麻辣',1),(5,'菠菜拌粉丝',22,'五香',2),(6,'凉拌豆腐皮',19,'微辣',2),(7,'酱牛肉',36,'麻辣',2),(8,'鱼头豆腐汤',32,'五香',3),(9,'瘦肉鸡蛋白菜汤',30,'五香',3),(10,'西葫芦虾仁蒸饺',26,'五香',4),(11,'蛋炒饭',18,'五香',4),(12,'酥粒椰蓉面包',12,'香甜',5);
/*!40000 ALTER TABLE `t_menu` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `t_order`
--
DROP TABLE IF EXISTS `t_order`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
SET character_set_client = utf8mb4 ;
CREATE TABLE `t_order` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`uid` int(11) DEFAULT NULL,
`mid` int(11) DEFAULT NULL,
`aid` int(11) DEFAULT NULL,
`date` date DEFAULT NULL,
`state` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `uid` (`uid`),
KEY `mid` (`mid`),
KEY `aid` (`aid`),
CONSTRAINT `t_order_ibfk_1` FOREIGN KEY (`uid`) REFERENCES `t_user` (`id`),
CONSTRAINT `t_order_ibfk_2` FOREIGN KEY (`mid`) REFERENCES `t_menu` (`id`),
CONSTRAINT `t_order_ibfk_3` FOREIGN KEY (`aid`) REFERENCES `t_admin` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `t_order`
--
LOCK TABLES `t_order` WRITE;
/*!40000 ALTER TABLE `t_order` DISABLE KEYS */;
INSERT INTO `t_order` VALUES (1,1,7,1,'2019-02-06',1),(2,1,2,1,'2019-02-06',1),(5,1,5,1,'2019-02-06',1),(6,1,9,1,'2019-02-06',1),(10,1,10,1,'2019-02-06',1),(11,1,10,NULL,'2019-02-06',0),(12,1,10,1,'2019-02-06',1),(14,1,6,1,'2019-02-06',1),(16,1,10,1,'2019-02-06',1),(19,1,7,1,'2019-02-07',1),(26,2,8,NULL,'2019-02-08',0),(27,2,12,NULL,'2019-02-08',0);
/*!40000 ALTER TABLE `t_order` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `t_type`
--
DROP TABLE IF EXISTS `t_type`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
SET character_set_client = utf8mb4 ;
CREATE TABLE `t_type` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `t_type`
--
LOCK TABLES `t_type` WRITE;
/*!40000 ALTER TABLE `t_type` DISABLE KEYS */;
INSERT INTO `t_type` VALUES (1,'热菜'),(2,'凉菜'),(3,'汤羹'),(4,'主食'),(5,'烘焙');
/*!40000 ALTER TABLE `t_type` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `t_user`
--
DROP TABLE IF EXISTS `t_user`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
SET character_set_client = utf8mb4 ;
CREATE TABLE `t_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(11) DEFAULT NULL,
`password` varchar(11) DEFAULT NULL,
`nickname` varchar(11) DEFAULT NULL,
`gender` varchar(2) DEFAULT NULL,
`telephone` varchar(20) DEFAULT NULL,
`registerdate` date DEFAULT NULL,
`address` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `t_user`
--
LOCK TABLES `t_user` WRITE;
/*!40000 ALTER TABLE `t_user` DISABLE KEYS */;
INSERT INTO `t_user` VALUES (1,'zhangsan','123123','张三','男','13576765678','2019-02-03','科技路'),(2,'lisi','123123','李四','女','18678987676','2019-02-03','科技路');
/*!40000 ALTER TABLE `t_user` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2019-02-12 16:02:37
本项目源码:https://github.com/liuwen766/OrderSystem.git