订单模块开发

相对于16.3节,这个章节不仅是重复的四种方式的请求方式的 Restful 接口,而且涉及应用模块服务之间的通信。举个例子,在下订单的时候,我们需要修改订单信息,同时需要在商品模块中修改商品列表,对其中库存减少数量,此时就会涉及服务之间的通信。本节依旧按照开发的先后顺序展开。

基本的准备工作

我们的准备工作有几个方面,包括添加依赖,添加配置项的引入,新建表以及添加数据的插入。

添加依赖,代码如下所示。

<!--Mybatis-->
<dependency>
   <groupId>org.mybatis.spring.boot</groupId>
   <artifactId>mybatis-spring-boot-starter</artifactId>
   <version>1.3.1</version>
</dependency>
<dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-feign</artifactId>
   <version>1.4.6.RELEASE</version>
</dependency>

通过查看依赖,可以发现除了添加与商品模块相同的 JDBC 需要的依赖之外,还多了一个依赖,这个依赖就是 Feign 的客户端。

添加配置项。在案例中,使用的是 Config 模块,所以,order 使用的配置项直接添加到 Config 中。因此,下面的配置项,MySQL 的连接信息、MyBatis 读取 SQL 的配置信息、以及数据库连接池的配置项都会放在远程 Git 中。

配置项放在 config-repository/orderService-dev.properties 中,下面是配置信息。

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3308/test?serverTimezo ne=UTC&useUnicode=true&characterEncoding=utf8&useSSL=false
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.maximum-pool-size=15
spring.datasource.hikari.auto-commit=true
spring.datasource.hikari.idle-timeout=30000
spring.datasource.hikari.pool-name=DatebookHikariCP
spring.datasource.hikari.max-lifetime=1800000
spring.datasource.hikari.connection-timeout=30000
spring.datasource.hikari.connection-test-query=SELECT 1
mybatis.mapper-locations=classpath:mapper/*.xml

新建表,以及添加数据。对于表,使用 SQL 可以重现,SQL 代码如下所示。

create table orderTable(
   order_id int(32) not null,
   order_number int(32) default null,
   product_id int(32) not null,
   primary key(product_id)
)engine=INNODB DEFAULT CHARSET=utf8;
insert into orderTable value(001,1,1);
insert into orderTable value(002,1,2);

在上面添加了两条数据,方便后续进行测试接口。

接口开发

关于需求的几个接口,将会在最后进行说明,因此这里还是按照项目的先后顺序展开,方便读者重现代码。

新建实体和新建 mapper 接口。首先,在项目下新建一个 entity 包,然后在包下新建 OrderTable 类,代码如下所示。

package com.exampleone.order.entity;
public class OrderTable {
   private int orderId;
   private int orderNumber;
   private int productId;
//SET和GET方法
}

然后,在项目下新建一个 mapper 包,在包下新建一个接口,代码如下所示。

package com.exampleone.order.mapper;
@Mapper
public interface OrderTableMapper {
   //根据orderId查询订单信息
   public List<OrderTable> queryOrderByOrderid(int orderId);
   //下订单
   public int insertOrder(OrderTable orderTable);
}

然后,写一层 service,使得服务层与数据库访问层分离。写 service 时,直接使用接口 OrderTableMapper 中的方法。先新建 service 包,再在包下新建 OrderTableService 类,代码如下所示。

package com.exampleone.order.service;
@Service
public class OrderTableService {
   @Autowired
   private OrderTableMapper orderTableMapper;
   //根据orderId查询订单信息
   public List<OrderTable> queryOrderByOrderid(int orderId){
      return orderTableMapper.queryOrderByOrderid(orderId);
   }
   //下订单
   public OrderTable insertOrder(OrderTable orderTable){
      orderTableMapper.insertOrder(orderTable);
      return orderTable;
   }
}

然后,新建 XML 的映射文件。在 Config 中,已经指定 XML 的读取路径是 mapper/**,所以,在 resources 下面新建一个 mapper 目录,然后新建 XML 文件,代码如下所示。

<?xml version = "1.0" encoding = "UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD com.example.Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.exampleone.order.mapper.OrderTableMapper">
   <resultMap id="result" type="com.exampleone.order.entity.OrderTable">
      <result property="orderId" column="order_id"/>
      <result property="orderNumber" column="order_number"/>
      <result property="productId" column="product_id"/>
   </resultMap>
   <select id="queryOrderByOrderid" resultMap="result">
      SELECT * FROM orderTable where order_id=#{orderId};
   </select>
   <insert id="insertOrder"
parameterType="com.exampleone.order.entity.OrderTable"
             keyProperty="orderId" useGeneratedKeys="true">
      INSERT INTO orderTable(order_id,order_number,product_id)
      VALUES (#{orderId},#{orderNumber},#{productId});
   </insert>
</mapper>

封装Restful接口

首先,对外提供的接口需要单独放在一个目录下。新建 controller 包,在包下新建一个 OrderTableController 类。根据条件查询某个订单的具体信息接口如下。

package com.exampleone.order.controller;
@RestController
@RequestMapping("/order")
public class OrderTableController {
   @Autowired
   private OrderTableService orderTableService;
   //根据orderId查询订单信息
   @RequestMapping("/queryOrderByOrderid")
   public List<OrderTable> queryOrderByOrderid(int orderId){
      return orderTableService.queryOrderByOrderid(orderId);
   }
}

Restful接口测试

对于16.4.3节中写的订单接口,都需要进行测试,确保对外提供的接口可以使用。根据条件查询某个订单的具体信息接口进行测试。这个接口使用的是 GET 请求方式,所以,我们直接使用浏览器进行测试。访问链接 http://localhost:8071/order/queryOrderByOrderid?orderId=001 ,执行效果如图16.20所示。

image 2024 04 01 15 52 47 125
Figure 1. 图16.20 执行效果