Gateway 订单服务

在正式搭建 Gateway 服务之前,我们先搭建两个微服务,分别是:订单微服务、用户微服务,调用关系如下图:

Gateway 订单服务

上图中,用户发送请求获取订单信息,然后订单又调用用户服务获取订单的用户信息,然后将订单和用户信息统一返回给用户。

订单服务

数据库

创建 cloud_order 数据库,执行如下 SQL:

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for t_order
-- ----------------------------
DROP TABLE IF EXISTS `t_order`;
CREATE TABLE `t_order`  (
 `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '订单ID',
 `title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '订单标题',
 `num` int(11) NULL DEFAULT NULL COMMENT '商品数量',
 `price` decimal(10, 2) NULL DEFAULT NULL COMMENT '订单总价格',
 `user_id` int(11) NOT NULL COMMENT '用户ID',
 PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of t_order
-- ----------------------------
INSERT INTO `t_order` VALUES (1, '海尔冰箱335升 法式多门四开门冰箱 一级能效 风冷无霜 双变频省电 节能净味 家用大容量超薄变温 多门推荐 BCD-335WLHFD9DS9', 1, 2598.00, 1);
INSERT INTO `t_order` VALUES (2, '施耐德(Schneider)开关插座面板错位开关五孔插座10a86型二三插皓呈薄雾灰全屋套餐 斜五孔插座10A十只装', 1, 313.38, 1);
INSERT INTO `t_order` VALUES (3, 'JRINKTEEA日本品牌高档焖茶杯保温杯闷泡杯陶瓷喷陶纯钛茶隔办公车载保暖杯 Toyama冰裂银480ml(陶瓷喷陶)', 2, 316.00, 2);
INSERT INTO `t_order` VALUES (4, '倍哆氛 【同价双11】无线蓝牙耳机空气传导不入耳挂耳式超长续航运动跑步游戏音乐苹果华为oppo手机通用 黑色 全新蓝牙5.2 听歌12小时', 1, 59.90, 3);
INSERT INTO `t_order` VALUES (5, '坚果(JMGO)N1 Ultra 4K超高清白天三色激光云台投影 投影仪家用投墙卧室家庭影院 游戏投影 240HZ高刷', 1, 8799.00, 4);

SET FOREIGN_KEY_CHECKS = 1;

运行 SQL 后,数据库只存在 t_order 数据表,如下图:

Gateway 订单服务

数据表内容如下:

Gateway 订单服务

Maven依赖

项目依赖如下,从父项目继承依赖:

<?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.hxstrive.springcloud</groupId>
       <artifactId>springcloud_learn</artifactId>
       <version>0.0.1-SNAPSHOT</version>
       <relativePath/> <!-- lookup parent from repository -->
   </parent>
   <artifactId>service_order</artifactId>
   <name>service_order</name>
   <description>service_order</description>

   <dependencies>
       <!-- 从父项目继承版本信息 -->
       <dependency>
           <groupId>com.alibaba.cloud</groupId>
           <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
       </dependency>

       <dependency>
           <groupId>com.alibaba.cloud</groupId>
           <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
       </dependency>

       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-web</artifactId>
       </dependency>

       <dependency>
           <groupId>org.mybatis.spring.boot</groupId>
           <artifactId>mybatis-spring-boot-starter</artifactId>
       </dependency>

       <dependency>
           <groupId>com.mysql</groupId>
           <artifactId>mysql-connector-java</artifactId>
       </dependency>

       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-devtools</artifactId>
           <scope>runtime</scope>
           <optional>true</optional>
       </dependency>
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-test</artifactId>
           <scope>test</scope>
       </dependency>
   </dependencies>

</project>

服务配置

下面 bootstrap.yml 配置文件内容(注意配置文件名称):

server:
 port: 8081

spring:
 application:
   name: service-order
 # datasource
 datasource:
   driver-class-name: com.mysql.jdbc.Driver
   url: jdbc:mysql://localhost:3306/cloud_order?useUnicode=true&characterEncoding=utf-8
   username: root
   password: aaaaaa
 cloud:
   # nacos 配置
   nacos:
     # nacos 服务发现
     discovery:
       server-addr: localhost:8848
       username: nacos
       password: nacos
     # nacos 服务配置
     config:
       server-addr: localhost:8848
       username: nacos
       password: nacos
       refresh-enabled: true
       file-extension: yaml
       group: DEFAULT_GROUP

logging:
 level:
   root: warn

服务代码

AppConfig.java 配置类

package com.hxstrive.springcloud.order.config;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

/**
* 配置类
* @author hxstrive.com
*/
@Configuration
public class AppConfig {

   @LoadBalanced // 开启负载均衡
   @Bean
   public RestTemplate restTemplate() {
       return new RestTemplate();
   }

}

OrderEntity.java 实体类

package com.hxstrive.springcloud.order.entity;

/**
* 订单实体
* @author hxstrive.com
*/
public class OrderEntity {
   /** 订单ID */
   private int id;
   /** 标题 */
   private String title;
   /** 数量 */
   private int num;
   /** 价格 */
   private float price;
   /** 用户ID */
   private int userId;

   /** 订单所属用户信息 */
   private UserEntity user;

   // getter 和 setter
}

UserEntity.java 实体类

package com.hxstrive.springcloud.order.entity;

/**
* 用户实体
* @author hxstrive.com
*/
public class UserEntity {
   /** 用户ID */
   private int id;
   /** 姓名 */
   private String name;
   /** 年龄 */
   private int age;
   /** 电子邮件地址 */
   private String email;
   // getter 和 setter
}

OrderMapper.java 接口

package com.hxstrive.springcloud.order.mapper;

import com.hxstrive.springcloud.order.entity.OrderEntity;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;

/**
* 订单 Mapper
* @author hxstrive.com
*/
@Mapper
public interface OrderMapper {

   /** 获取指定订单信息 */
   @Select("select * from t_order where id=#{orderId}")
   @Results({
           @Result(column = "id", property = "id"),
           @Result(column = "title", property = "title"),
           @Result(column = "num", property = "num"),
           @Result(column = "price", property = "price"),
           @Result(column = "user_id", property = "userId")
   })
   OrderEntity getOrder(int orderId);

}

OrderService.java 服务类

package com.hxstrive.springcloud.order.service;

import com.hxstrive.springcloud.order.entity.OrderEntity;
import com.hxstrive.springcloud.order.entity.UserEntity;
import com.hxstrive.springcloud.order.mapper.OrderMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

/**
* 订单服务
* @author hxstrive.com
*/
@Service
public class OrderService {

   @Autowired
   private OrderMapper orderMapper;

   @Autowired
   private RestTemplate restTemplate;

   public OrderEntity getOrder(int orderId) {
       // 1.查询订单信息
       OrderEntity order = orderMapper.getOrder(orderId);
       if(null == order) {
           return null;
       }

       // 2.根据订单中的用户id,调用用户服务查询用户信息
       // 问题:
       // (1)如果用户服务部署了多个,我们该怎么调用?
       // (2)如果用户服务地址变动了,我们是不是每次都要来修改改地址,非常麻烦!
       // (3)如果调用用户服务的地址参数较多,拼接 URL 地址同样非常麻烦!
       String url = "http://service-user/user/" + order.getUserId();
       UserEntity user = restTemplate.getForObject(url, UserEntity.class);
       order.setUser(user);

       // 3.返回订单对象
       return order;
   }

}

OrderController.java 控制器

package com.hxstrive.springcloud.order.controller;

import com.hxstrive.springcloud.order.entity.OrderEntity;
import com.hxstrive.springcloud.order.service.OrderService;
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.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
* 订单 Controller
* @author hxstrive.com
*/
@RestController
@RequestMapping("/order")
public class OrderController {

   @Autowired
   private OrderService orderService;

   @GetMapping("/{id}")
   public OrderEntity getOrder(@PathVariable("id") int id) {
       System.out.println("## OrderController.getOrder() id=" + id);
       return orderService.getOrder(id);
   }

}

OrderApplication.java 启动类

package com.hxstrive.springcloud.order;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class OrderApplication {

   public static void main(String[] args) {
       SpringApplication.run(OrderApplication.class, args);
   }

}

到这里订单服务编写完成,继续查看下一章,编写用户服务。

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号