准备工作
参照之前的文章搭建好项目架构,接下来开始写订单模块的后端接口。接口文档在开源仓库上有,仓库地址在第一篇博客上有。
新建订单服务模块
1.创建新模块
模块继承主工程依赖依赖
2.导入相关依赖
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>common-service</artifactId>
<groupId>cuit.jiefang</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>order-service</artifactId>
<dependencies>
<!-- feign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.2.2.RELEASE</version>
</dependency>
<!-- RocketMQ -->
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-client</artifactId>
<version>4.7.0</version>
</dependency>
<!-- Common Service -->
<dependency>
<groupId>cuit.jiefang</groupId>
<artifactId>common-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- Repository Service -->
<dependency>
<groupId>cuit.jiefang</groupId>
<artifactId>repository-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<build>
<resources>
<resource>
<!--指定根目录 到java文件夹 一般如下-->
<directory>src/main/java</directory>
<includes>
<include>**/*.yml</include>
<include>**/*.yaml</include>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
</project>
3.基于MP 自动生成基本架构
新建一个代码生成类,自动生成代码,自动生成代码只需要修改自己的数据库用户名、用户密码、数据库表名(这个模块用 order、order-detail 表)
代码如下
package cuit.jiefang;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import java.util.Arrays;
import java.util.List;
/**
* @author :jiefang
* @description:代码生成模块
* @date :2022/4/10 11:44
*/
public class Code {
public static void main(String[] args) {
AutoGenerator autoGenerator = new AutoGenerator();
//数据源
DataSourceConfig dataSourceConfig = new DataSourceConfig();
dataSourceConfig.setDbType(DbType.MYSQL);
dataSourceConfig.setDriverName("com.mysql.cj.jdbc.Driver");
dataSourceConfig.setUrl("jdbc:mysql://localhost:3306/uushop?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai");
dataSourceConfig.setUsername("root");
dataSourceConfig.setPassword("123098");
autoGenerator.setDataSource(dataSourceConfig);
//全局配置
GlobalConfig globalConfig = new GlobalConfig();
globalConfig.setOutputDir(System.getProperty("user.dir")+"/order-service/src/main/java");
globalConfig.setAuthor("jiefang");
globalConfig.setOpen(false);
//去掉Service的I
globalConfig.setServiceName("%sService");
autoGenerator.setGlobalConfig(globalConfig);
//包配置
PackageConfig packageConfig = new PackageConfig();
packageConfig.setParent("cuit.jiefang");
packageConfig.setEntity("entity");
packageConfig.setMapper("mapper");
packageConfig.setService("service");
packageConfig.setServiceImpl("service.impl");
packageConfig.setController("controller");
autoGenerator.setPackageInfo(packageConfig);
//策略配置
StrategyConfig strategyConfig = new StrategyConfig();
strategyConfig.setInclude("order_detail","order_master");
strategyConfig.setNaming(NamingStrategy.underline_to_camel);
strategyConfig.setColumnNaming(NamingStrategy.underline_to_camel);
strategyConfig.setEntityLombokModel(true);
TableFill tableFill = new TableFill("create_time", FieldFill.INSERT);
TableFill tableFill2 = new TableFill("update_time", FieldFill.INSERT_UPDATE);
List<TableFill> list = Arrays.asList(tableFill,tableFill2);
strategyConfig.setTableFillList(list);
autoGenerator.setStrategy(strategyConfig);
//启动
autoGenerator.execute();
}
}
4创建启动类和配置文件
启动类:
注意启动类要放在项目的外层包里面。SpringBoot 启动时会去扫描当前包及其子包内的注解。当前包和子包外的注解是扫描不到的。
package cuit.jiefang;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
/**
* @author :jiefang
* @description:
* @date :2022/4/10 11:52
*/
@MapperScan("cuit.jiefang.mapper")
@SpringBootApplication
@EnableFeignClients
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class,args);
}
}
配置文件
server:
port: 8083
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/uushop?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
username: root
password: 123098
# 注册到微服务里面的服务明
# 使用nacos 注册服务很简单 引入依赖 启动nacos 然后配置一下就行
application:
name: order-service
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
mapper-locations: classpath:cuit/jiefang/mapper/xml/*.xml
#rocketmq:
# name-server: 192.168.108.140:9876
# producer:
# group: order
5 开始写后端代码
后端代码的实现主要参照接口文档,按照前端需求,将数据从数据库里面查出来,封装成前端需要的格式进行返回。这里主要介绍一下其中较为复杂的接口,分页查询,其他接口可以参照我gitee 上开源的项目。
分页查询配置类
配置类主要就是创建一个分页对象交给Spring 容器管理。
package cuit.jiefang.configuration;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
/**
* @author :jiefang
* @description:
* @date :2022/4/13 16:09
*/
@Component
public class PaginationConfiguration {
@Bean
public PaginationInterceptor paginationInterceptor(){
return new PaginationInterceptor();
}
}
配置数据库新增、修改数据的日期自动填充
package cuit.jiefang.handle;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
/**
* @author :jiefang
* @description:
* @date :2022/4/13 15:10
*/
@Component
public class FillHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
this.setFieldValByName("createTime", LocalDateTime.now(), metaObject);
this.setFieldValByName("updateTime", LocalDateTime.now(), metaObject);
}
@Override
public void updateFill(MetaObject metaObject) {
this.setFieldValByName("updateTime", LocalDateTime.now(), metaObject);
}
}
上面两个类可以放在reporsitory 模块里面,因为其他所有与数据库交互的模块都需要用到
分页查询接口实现
实现
@GetMapping("/list/{buyId}/{page}/{size}")
public ResultVo list(@PathVariable("buyId")Integer id, @PathVariable("page") Integer page, @PathVariable("size")Integer size){
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.eq("buyer_openid",id);
Page<OrderMaster> page1 = new Page<>(page,size);
Page<OrderMaster> resultPage = this.orderMasterService.page(page1,queryWrapper);
List<OrderMaster> records = resultPage.getRecords();
return ResultUtil.success(records);
}
6 基于Feign 进行接口调用
Feign 的调用过程是,根据服务名在nacos 中发现相关服务。然后像调用接口一样,调用相关服务。
1.导入依赖
<!-- feign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.2.2.RELEASE</version>
</dependency>
2.定义接口
package cuit.jiefang.feign;
import cuit.jiefang.vo.ProductInfoVO;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PutMapping;
import java.math.BigDecimal;
//声明调用的服务
@FeignClient("product-service")
public interface ProductServiceFeign {
String baseurl="/buyer/product";
//请求服务的地址
@GetMapping(baseurl+"/findPriceById/{id}")
public BigDecimal findPriceById(@PathVariable("id") Integer id);
@GetMapping(baseurl+"/findById/{id}")
public ProductInfoVO findById(@PathVariable("id") Integer id);
@PutMapping(baseurl+"/subStockById/{id}/{quantity}")
public boolean subStockById(@PathVariable("id") Integer id, @PathVariable("quantity") Integer quantity);
@PutMapping(baseurl+"/addStockById/{id}/{quantity}")
public boolean addStockById(@PathVariable("id") Integer id, @PathVariable("quantity") Integer quantity);
}
服务调用
1.像调用普通服务一样 注入
@Autowired
private ProductServiceFeign productServiceFeign;
2.调用
ProductInfoVO productInfoVO = productServiceFeign.findById(item.getProductId());
其他模块写
其他模块也是类似与这样 模块之前的调用采用Feign。搭建模块的时候基于MP 生成项目的基本框架。然后按照接口文档一个个的完成接口。前端部分的代码也在仓库里了
这里在放一下仓库地址:需要的小伙伴自取代码
https://gitee.com/jiefang666/uushop