精品专题:
01.《C语言从不挂科到高绩点》课程详细笔记
https://blog.csdn.net/yueyehuguang/category_12753294.html?spm=1001.2014.3001.5482
02. 《SpringBoot详细教程》课程详细笔记
https://blog.csdn.net/yueyehuguang/category_12789841.html?spm=1001.2014.3001.5482
03.《SpringBoot电脑商城项目》课程详细笔记
https://blog.csdn.net/yueyehuguang/category_12752883.html?spm=1001.2014.3001.5482
04.《VUE3.0 核心教程》课程详细笔记
https://blog.csdn.net/yueyehuguang/category_12769996.html?spm=1001.2014.3001.5482
05. 《SSM详细教程》课程详细笔记
https://blog.csdn.net/yueyehuguang/category_12806942.html?spm=1001.2014.3001.5482
================================
|| 持续分享系列教程,关注一下不迷路 ||
|| 视频教程:墨轩大楼 ||
================================
在上一章节中我们已经大体了解了微服务以及微服务的实现技术,本教程主要讲解SpringCloud Alibaba的技术栈。
🌲 2.1 案例准备
🌿 2.1.1 技术选型
maven:3.6.3
数据库:mysql 8.0
持久层框架:mybatis 2.3.1、mybatisPlus
SpringBoot版本:2.7.17
cloud:SpringCloud Alibaba 技术栈 3.4.1
🌿 2.1.2 模块设计
父工程:spring-cloud
公共模块:shop-common 【工具类、实体类】
用户微服务:shop-user 【端口:801x】
商品微服务:shop-product 【端口:802x】
订单微服务:shop-order 【端口:803x】
🌿 2.1.3 微服务调用
在微服务架构中,最常见的场景就是微服务之间的相互调用。我们以电商系统中常见的用户下单为例来演示微服务的调用:客户向订单微服务发起一个下单的请求,在进行保存订单之前需要调用商品微服务查询商品的信息。
我们一般把服务的主动调用方称为服务消费者,把服务的被调用方称为服务提供者。
在这种场景下,订单微服务就是一个服务消费者, 商品微服务就是一个服务提供者。
🌲 2.2 创建父工程
创建一个SpringBoot2.7.17版本项目,添加相关依赖
<?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><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.17</version><relativePath/> <!-- lookup parent from repository --></parent><packaging>pom</packaging><groupId>com.moxuan</groupId><artifactId>spring_cloud</artifactId><version>0.0.1-SNAPSHOT</version><name>spring_cloud</name><description>Demo project for Spring Boot</description><properties><java.version>17</java.version><spring-cloud.version>2021.0.3</spring-cloud.version><spring-cloud-alibaba.version>2021.0.4.0</spring-cloud-alibaba.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><type>pom</type><version>${spring-cloud-alibaba.version}</version><scope>import</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter-test</artifactId><version>2.3.1</version><scope>test</scope></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.1</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.2.16</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.8.1</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.56</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
🌲 2.3 创建公共模块
创建公共模块shop-common,在pom.xml中将父模块设置为前面创建的spring-cloud模块。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 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.moxuan</groupId><artifactId>spring_cloud</artifactId><version>0.0.1-SNAPSHOT</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.moxuan</groupId><artifactId>shop-common</artifactId><version>0.0.1-SNAPSHOT</version><name>shop-common</name><description>Demo project for Spring Boot</description><properties><java.version>17</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
创建实体类,将项目中所需要的实体类都创建到这个模块里面
package com.moxuan.shopcommon.entity;import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;@Data
@TableName("t_user")
public class User {private Integer uid;private String email;private String password;private String nickname;
}
package com.moxuan.shopcommon.entity;import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@NoArgsConstructor
@TableName("t_product")
public class Product {@TableId(type= IdType.AUTO)private Integer pid;private String pname;// 商品名称private Double pprice; // 商品价格private Integer stock; // 库存public Product(String pname, Double pprice, Integer stock) {this.pname = pname;this.pprice = pprice;this.stock = stock;}
}
package com.moxuan.shopcommon.entity;import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;@Data
@TableName("t_order")
public class Order {// 订单id@TableId(type = IdType.AUTO)private Long oid;private Integer uid; // 用户idprivate String username;// 用户名private Integer pid;// 商品idprivate String pname; // 商品名称private Double pprice; // 商品价格private Integer num;// 购买数量
}
创建向前端统一返回数据的工具类
package com.moxuan.shopcommon.util;import java.util.HashMap;
import java.util.Map;/**** 返回码*/
public enum ReturnCode {/*********************************************全局ReturnCode(请勿改动)*********************************************/SUCCESS("0000", "成功完成操作"),BUSSINESS_EXCEPTION("10000", "业务系统异常"),NO_RESULT("10001", "查询无结果"),MULTI_RESULT("10002", "查询结果不唯一"),EXPORT_EXCEL_ERROR("10004", "导出Excel异常"),USER_NOT_LOGIN("90000", "用户未登录"),ACCESS_FORBIDDEN("90001","无访问权限"), AUTHENTICATION_FAILURE("90002","认证失败"), TOKEN_FORBIDDEN("90003","无访问口令,请先登陆后获取"), TOKEN_EXPIRE("90004","Token失效,需要重新登陆"), TOKEN_ERROR("90005","Token创建出错,请联系管理员"),USER_LOGIN_ERROR("90006","账号或者密码错误"),SYSTEM_ERROR("99999", "系统繁忙,请稍后再试.");/*** 返回码*/private String code;/*** 返回信息*/private String msg;ReturnCode(String code, String msg) {this.code = code;this.msg = msg;}public String code() {return this.code;}public String msg() {return this.msg;}public Map<String, String> toMap() {Map<String, String> map = new HashMap<>();map.put("msg", this.msg);map.put("code", this.code);return map;}
}
package com.moxuan.shopcommon.util;import com.alibaba.fastjson.JSON;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;/*** 封装结果的工具类*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Result {private String Code;private Object data;// 数据源private String msg;public static Result sendResult(ReturnCode returnCode) {Result result = new Result();result.setCode(returnCode.code());result.setMsg(returnCode.msg());return result;}public static Result sendResult(ReturnCode returnCode,Object data){Result result = sendResult(returnCode);String jsonData = JSON.toJSONString(data);result.setData(jsonData);return result;}
}
🌲 2.4 创建用户微服务
新建一个 shop-user 模块,然后进行下面操作
- 导入依赖,需要引入父模块以及公共模块
<?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><parent><groupId>com.moxuan</groupId><artifactId>spring_cloud</artifactId><version>0.0.1-SNAPSHOT</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.moxuan</groupId><artifactId>shop-user</artifactId><version>0.0.1-SNAPSHOT</version><name>shop-user</name><description>Demo project for Spring Boot</description><properties><java.version>17</java.version></properties><dependencies><dependency><groupId>com.moxuan</groupId><artifactId>shop-common</artifactId><version>0.0.1-SNAPSHOT</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
- 添加配置文件
server.port=8011
spring.application.name=service-user
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/cloud
spring.datasource.username=root
spring.datasource.password=123456
🌲 2.5 创建商品微服务
创建一个名为 shop_product 的模块,并添加springboot依赖、父模块、公共模块
<?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><parent><groupId>com.moxuan</groupId><artifactId>spring_cloud</artifactId><version>0.0.1-SNAPSHOT</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.moxuan</groupId><artifactId>shop-product</artifactId><version>0.0.1-SNAPSHOT</version><name>shop-product</name><description>Demo project for Spring Boot</description><properties><java.version>17</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>com.moxuan</groupId><artifactId>shop-common</artifactId><version>0.0.1-SNAPSHOT</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
添加配置文件
server.port=8021
spring.application.name=service-product
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/cloud
spring.datasource.username=root
spring.datasource.password=123456
创建ProductMapper
package com.moxuan.shopproduct.dao;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.moxuan.shopcommon.entity.Product;public interface ProductMapper extends BaseMapper<Product> {
}
在启动类中开启MP接口扫描
package com.moxuan.shopproduct;import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
@MapperScan("com.moxuan.shopproduct.dao")
public class ShopProductApplication {public static void main(String[] args) {SpringApplication.run(ShopProductApplication.class, args);}}
创建ProductService以及实现类
package com.moxuan.shopproduct.service;import com.moxuan.shopcommon.util.Result;public interface ProductService {Result getProductById(int pid);Result saveProductBeach();
}
package com.moxuan.shopproduct.service.impl;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.moxuan.shopcommon.entity.Product;
import com.moxuan.shopcommon.util.Result;
import com.moxuan.shopcommon.util.ReturnCode;
import com.moxuan.shopproduct.dao.ProductMapper;
import com.moxuan.shopproduct.service.ProductService;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.ArrayList;
import java.util.List;@Service
public class ProductServiceImpl extends ServiceImpl<ProductMapper,Product> implements ProductService {@Autowiredprivate ProductMapper productMapper;public Result getProductById(int pid) {QueryWrapper<Product> qw = new QueryWrapper<>();qw.lambda().eq(Product::getPid,pid);Product product = productMapper.selectOne(qw);if(product==null){return Result.sendResult(ReturnCode.NO_RESULT);}return Result.sendResult(ReturnCode.SUCCESS,product);}/*** 批量插入数据* @return*/public Result saveProductBeach() {List<Product> productList = new ArrayList<>();productList.add(new Product("小米",1000.0,5000));productList.add(new Product("华为",2000.0,5000));productList.add(new Product("苹果",3000.0,5000));productList.add(new Product("OPPO",2000.0,5000));boolean flag = saveBatch(productList);if(!flag){return Result.sendResult(ReturnCode.BUSSINESS_EXCEPTION);}return Result.sendResult(ReturnCode.SUCCESS);}
}
创建控制器类Controller
package com.moxuan.shopproduct.controller;import com.moxuan.shopcommon.entity.Product;
import com.moxuan.shopcommon.util.Result;
import com.moxuan.shopproduct.service.ProductService;
import com.moxuan.shopproduct.service.impl.ProductServiceImpl;import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.ArrayList;
import java.util.List;@RestController
@Slf4j
public class ProductController {@Autowiredprivate ProductService productService;@GetMapping("/product/{pid}")public Result product(@PathVariable("pid") int pid){Result result = productService.getProductById(pid);log.info("查询到商品:"+result);return result;}@PostMapping("/product/sa")public Result saveProductBeach(){Result result = productService.saveProductBeach();return result;}}
启动项目,先访问http://localhost:8021/product/sa 批量添加数据
然后再访问: http://localhost:8021/product/1 看能否查询到数据
🌲 2.6 创建订单微服务
创建一个名为 shop-order 的模块,并添加springboot依赖、父模块、公共模块
<?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><parent><groupId>com.moxuan</groupId><artifactId>spring_cloud</artifactId><version>0.0.1-SNAPSHOT</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.moxuan</groupId><artifactId>shop-order</artifactId><version>0.0.1-SNAPSHOT</version><name>shop-order</name><description>Demo project for Spring Boot</description><properties><java.version>17</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>com.moxuan</groupId><artifactId>shop-common</artifactId><version>0.0.1-SNAPSHOT</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
添加配置文件
server.port=8031spring.application.name=service-productspring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/cloud
spring.datasource.username=root
spring.datasource.password=123456
创建OrderMapper接口
package com.moxuan.shoporder.dao;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.moxuan.shopcommon.entity.Order;
import org.apache.ibatis.annotations.Mapper;@Mapper
public interface OrderMapper extends BaseMapper<Order> {}
在启动类中开启mp注解扫描,并添加RestTemplateBean,方便后续微服务之间的数据通信
package com.moxuan.shoporder;import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;@SpringBootApplication
@MapperScan("com.moxuan.shoporder.dao")
public class ShopOrderApplication {public static void main(String[] args) {SpringApplication.run(ShopOrderApplication.class, args);}/*** org.springframework.web.client.RestTemplate;* 可以用来调用其他微服务* @return*/@Beanpublic RestTemplate getRestTemplate(){return new RestTemplate();}
}
创建OrderService以及实现类
package com.moxuan.shoporder.service;import com.moxuan.shopcommon.entity.Order;
import com.moxuan.shopcommon.util.Result;public interface OrderService {Result saveOrder(Order order);
}
package com.moxuan.shoporder.service.impl;import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.moxuan.shopcommon.entity.Order;
import com.moxuan.shopcommon.util.Result;
import com.moxuan.shopcommon.util.ReturnCode;
import com.moxuan.shoporder.dao.OrderMapper;
import com.moxuan.shoporder.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {@Autowiredprivate OrderMapper orderMapper;@Overridepublic Result saveOrder(Order order) {int num = orderMapper.insert(order);if(num==0){return Result.sendResult(ReturnCode.BUSSINESS_EXCEPTION);}return Result.sendResult(ReturnCode.SUCCESS);}
}
创建OrderController
package com.moxuan.shoporder.controller;import com.alibaba.fastjson.JSON;
import com.moxuan.shopcommon.entity.Order;
import com.moxuan.shopcommon.entity.Product;
import com.moxuan.shopcommon.util.Result;
import com.moxuan.shoporder.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;import java.util.HashMap;
import java.util.Map;@RestController
@Slf4j
public class OrderController {@Autowiredprivate OrderService orderService;@Autowiredprivate RestTemplate restTemplate;@GetMapping("/order/prod/{pid}")public Result order(@PathVariable("pid")Integer pid){log.info(">> 客户下单,这时候要调用商品微服务查询商品信息");// 通过restTemplate调用商品微服务Result result = restTemplate.getForObject("http://localhost:8021/product/"+pid,Result.class);log.info("商品信息>> 查询结果"+result.getData());// Map<String,Object> pro =
// (HashMap<String, Object>) result.getData();
//
// Order order = new Order();
// order.setUid(1);
// order.setUsername("墨轩");
// order.setPid((Integer)pro.get("pid"));
// order.setPname((String)pro.get("pname"));
// order.setPprice((Double)pro.get("pprice"));
// order.setNumber(1);Product pro = JSON.parseObject(result.getData().toString(),Product.class);System.out.println(pro);Order order = new Order();order.setUid(1);order.setUsername("墨轩");order.setPid(pro.getPid());order.setPname(pro.getPname());order.setPprice(pro.getPprice());order.setNum(1);result = orderService.saveOrder(order);return result;}}
启动项目,测试生成订单