Spring Cloud学习day102:微服务架构的设计模式

一、微服务架构常用的六种设计模式

1.代理模式:

代理的职责:
(1)统一入口;
(2)鉴权校验;
(3)请求过滤;
典型案例:服务网关。

代理设计模式

2.聚合设计模式:

报表服务需求:查看当天的所有订单信息,订单内容包括:
(1)用户信息;
(2)商品信息;
(3)订单信息;
(4)交易支付信息;

示例

3.链条设计模式:

查看交易信息,交易信息一般包括:
(1)支付的信息;
(2)订单信息;
(3)商品信息;
(4)用户信息;

示例

4.聚合链条设计模式:

示例

5.数据共享设计模式:

后台管理系统一般的做法:
(1)可以直连多个数据库;
(2)操作的数据,涉及到缓存,必须调接口。

示例

6.异步消息设计模式:

示例

二、微服务设计模式案例:

1.需求:

示例

2.数据库设计:

数据库
  • User表:
CREATE TABLE `user` (
  `id` int(10) NOT NULL AUTO_INCREMENT COMMENT '自增主键',
  `user_name` varchar(50) DEFAULT NULL COMMENT '用户名',
  `password` varchar(50) NOT NULL COMMENT '密码',
  `email` varchar(50) NOT NULL COMMENT 'email',
  `deleted` tinyint(4) unsigned NOT NULL DEFAULT '0' COMMENT ' 删除标志,默认 0 不删除,1 删除',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更 新时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='用户表';
  • Product表:
CREATE TABLE `product` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `name` varchar(100) DEFAULT NULL COMMENT '产品名称',
  `status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '产品状态:0 待 审,1 上架,2 下架,3 停售,4 测试',
  `price` int(10) NOT NULL COMMENT '产品价格 单位分',
  `detail` text COMMENT '产品详情',
  `deleted` tinyint(4) unsigned NOT NULL DEFAULT '0' COMMENT ' 删除标志,默认 0 不删除,1 删除',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更 新时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COMMENT='产品信息';
  • Orders表:
CREATE TABLE `orders` (
  `id` int(10) NOT NULL,
  `product_id` int(10) NOT NULL DEFAULT '0' COMMENT '产品 ID',
  `price` int(10) DEFAULT '0' COMMENT '价格',
  `user_id` int(10) DEFAULT '0' COMMENT '用户账号 ID',
  `trade_id` int(10) DEFAULT '0' COMMENT '交易号 ID',
  `trade_status` tinyint(1) DEFAULT '0' COMMENT '支付状态 0=未支付 \r\n\r\n \r\n \r\n1=已支付',
  `deleted` tinyint(4) unsigned NOT NULL DEFAULT '0' COMMENT ' 删除标志,默认 0 不删除,1 删除',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更 新时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  • Trade表:
CREATE TABLE `trade` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'IID',
  `order_id` int(10) NOT NULL COMMENT '订单 ID',
  `user_id` int(10) NOT NULL COMMENT '用户 ID',
  `price` int(10) NOT NULL COMMENT '支付价',
  `pay_status` tinyint(4) NOT NULL COMMENT '1 未付款 2 付款中 3 付款失败 4 付款完成',
  `pay_type` tinyint(4) NOT NULL COMMENT '支付类型:1-支付宝支付, 2-网银在线,3-银联,4-微信支付',
  `gateway_pay_num` varchar(30) DEFAULT NULL COMMENT '网关支 付流水号',
  `gateway_pay_time` datetime NOT NULL COMMENT '网关支付 时间',
  `gateway_pay_price` int(10) NOT NULL DEFAULT '0' COMMENT '网关 实际支付金额',
  `deleted` tinyint(4) unsigned NOT NULL DEFAULT '0' COMMENT ' 删除标志,默认 0 不删除,1 删除',
  `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更 新时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COMMENT='交易';

3.MyBatis的generatorSqlmapCustom工具使用:

生成Mapper和实体类。需要创建好数据库。

示例
  • GeneratorSqlmap:
import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.internal.DefaultShellCallback;

public class GeneratorSqlmap {
    public void generator() throws Exception {
        List<String> warnings = new ArrayList<String>();
        boolean overwrite = true;
        // 指定 逆向工程配置文件
        File configFile = new File("generatorConfig.xml");
        ConfigurationParser cp = new ConfigurationParser(warnings);
        Configuration config = cp.parseConfiguration(configFile);
        DefaultShellCallback callback = new DefaultShellCallback(overwrite);
        MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
        myBatisGenerator.generate(null);

    }

    public static void main(String[] args) throws Exception {
        try {
            GeneratorSqlmap generatorSqlmap = new GeneratorSqlmap();
            generatorSqlmap.generator();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  • log4j.properties配置文件:
log4j.rootLogger=DEBUG, Console
#Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
log4j.logger.java.sql.ResultSet=INFO
log4j.logger.org.apache=INFO
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
  • generatorConfig.xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
  PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
  "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>
    <context id="testTables" targetRuntime="MyBatis3">
        <commentGenerator>
            <!-- 是否去除自动生成的注释 true:是 : false:否 -->
            <property name="suppressAllComments" value="true" />
        </commentGenerator>
        <!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
        <jdbcConnection driverClass="com.mysql.jdbc.Driver"
            connectionURL="jdbc:mysql://localhost:3306/book-trade" userId="root"
            password="root">
        </jdbcConnection>
        <!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL 
            和 NUMERIC 类型解析为java.math.BigDecimal -->
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false" />
        </javaTypeResolver>

        <!-- targetProject:生成PO类的位置 -->
        <javaModelGenerator
            targetPackage="com.book.trade.pojo" targetProject=".\src">
            <!-- enableSubPackages:是否让schema作为包的后缀 -->
            <property name="enableSubPackages" value="false" />
            <!-- 从数据库返回的值被清理前后的空格 -->
            <property name="trimStrings" value="true" />
        </javaModelGenerator>
        <!-- targetProject:mapper映射文件生成的位置 -->
        <sqlMapGenerator targetPackage="com.book.trade.mapper"
            targetProject=".\src">
            <!-- enableSubPackages:是否让schema作为包的后缀 -->
            <property name="enableSubPackages" value="false" />
        </sqlMapGenerator>
        <!-- targetPackage:mapper接口生成的位置 -->
        <javaClientGenerator type="XMLMAPPER"
            targetPackage="com.book.trade.mapper" targetProject=".\src">
            <!-- enableSubPackages:是否让schema作为包的后缀 -->
            <property name="enableSubPackages" value="false" />
        </javaClientGenerator>
        <!-- 指定数据库表 -->
        <table schema="" tableName="trade"></table>
    </context>
</generatorConfiguration>
  • 修改generatorConfig.xml配置文件:

需要修改的地方。

(1)数据库的连接:

示例

(2)实体的包名:


示例

(3)Mapper接口的包名:


示例

示例

(4)数据库表名:


示例
  • 实现的效果:


    执行main方法

4.创建User-Provider和User-Service:

  • User-Provider:
User-Product
  • 修改POM文件:
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.13.RELEASE</version>
    </parent>
    <groupId>com.zlw</groupId>
    <artifactId>e-book-user-provider</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Dalston.SR5</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    
    <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>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.0</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        
        <!-- 添加 product-service 坐标 -->
        <dependency>
            <groupId>com.zlw</groupId>
            <artifactId>e-book-user-service</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
    </dependencies>
  • 修改配置文件:
spring.application.name=e-book-user-provider
server.port=9002

#设置服务注册中心
eureka.client.serviceUrl.defaultZone=http://admin:123456@eureka1:8761/eureka/,http://admin:123456@eureka2:8761/eureka/
#----mysql-db-------
mybatis.type-aliases-package=com.book.user.pojo
#设置后不需要在POM添加打包插件
mybatis.mapper-locations==classpath:com/book/user/mapper/*.xml

spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/book-user?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull
spring.datasource.username=root
spring.datasource.password=root
  • 使用工具生成 Pojo、Mpper映射配置文件,添加到项目中:


    示例
  • 创建Service:
@Service
public class UserServiceImpl {

    @Autowired
    private UserMapper userMapper;
    
    //用户登录
    public User findUser(String userName,String password){
        UserExample userExample = new UserExample();
        Criteria createCriteria = userExample.createCriteria();
        createCriteria.andUserNameEqualTo(userName);
        createCriteria.andPasswordEqualTo(password);
        List<User> list = userMapper.selectByExample(userExample);
        if(list!=null&&list.size()>0) {
            return list.get(0);
        }else {
            return null;
        }
    }
}
  • 创建Controller实现UserService接口:
@RestController
public class UserController implements UserService {

    @Autowired
    private UserServiceImpl userServiceImpl;

    @Override
    public User login(String userName, String password) {
        
        return userServiceImpl.findUser(userName, password);
    }
}
  • 修改启动类:
@MapperScan("com.book.user.mapper")
@EnableEurekaClient
@SpringBootApplication
public class ProductApplication {

    public static void main(String[] args) {
        SpringApplication.run(ProductApplication.class, args);
    }
}
  • User-Service:
User-Service
  • 修改POM文件:
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Dalston.SR5</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
  • 将生成的实体类添加到项目中:
示例
  • 创建UserService接口:
/**
 * User服务接口
 * 
 * @author zhang
 */

@RequestMapping("/user")
public interface UserService {

    @RequestMapping(value = "/login",method = RequestMethod.GET)
    public User login(@RequestParam("userName") String userName, @RequestParam("password") String password);

}
  • 启动服务和注册中心测试:


    示例

5.创建Product-Provider和Product-Service项目:

  • Product-Service:


    Service
  • 修改POM文件:
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Dalston.SR5</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
  • 将生成的实体类添加到项目中:


    示例
  • 创建Service接口:
@RequestMapping("/product")
public interface ProductService {

    // 查询所有商品
    @RequestMapping(value = "/findAll", method = RequestMethod.GET)
    public List<Product> findAll();
}
  • 创建Product-Provider项目:


    Provider
  • 修改POM文件:
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Dalston.SR5</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <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>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.0</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!-- 添加 product-service 坐标 -->
        <dependency>
            <groupId>com.zlw</groupId>
            <artifactId>e-book-product-service</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>
  • 修该配置文件:
#设置服务注册中心
eureka.client.serviceUrl.defaultZone=http://admin:123456@eureka1:8761/eureka/,http://admin:123456@eureka2:8761/eureka/
#----mysql-db-------
mybatis.type-aliases-package=com.book.product.pojo
mybatis.mapper-locations==classpath:com/book/product/mapper/*.xml

spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/book-product?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull
spring.datasource.username=root
spring.datasource.password=root
  • 将生成的mapper接口和映射文件添加到项目:


    mapper
  • 创建Service类操作数据:
@Service
public class ProductServiceImpl {

    @Autowired
    private ProductMapper productMapper;

    // 查询所有商品
    public List<Product> findAllProduct() {
        ProductExample productExample = new ProductExample();
        // selectByExampleWithBLOBs包括text文本信息
        List<Product> list = productMapper.selectByExampleWithBLOBs(productExample);
        return list;
    }
}
  • 创建Controller实现ProductService接口:
@RestController
public class ProductServiceController implements ProductService {

    @Autowired
    private ProductServiceImpl productServiceImpl;

    @Override
    public List<Product> findAll() {
        return productServiceImpl.findAllProduct();
    }
}
  • 修改启动类:
/**
 * 启动类
 * @author zhang
 */
@MapperScan("com.book.product.mapper")
@EnableEurekaClient
@SpringBootApplication
public class ProductApplication {
    public static void main(String[] args) {
        SpringApplication.run(ProductApplication.class, args);
    }
}
  • 启动服务测试:


    示例

6.创建Order-Provider和Order-Service服务:

  • 创建Order-Service项目:

将生成的实体类添加到项目中。

示例
  • 修改POM文件:
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Dalston.SR5</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
  • 创建Service接口:
/**
 * 订单服务
 * 
 * @author zhang
 *
 */
@RequestMapping("/order")
public interface OrderService {

    // 查询所有订单
    @RequestMapping(value = "findAll", method = RequestMethod.GET)
    public List<Orders> findAll();

    // 添加订单
    @RequestMapping(value = "/create", method = RequestMethod.POST)
    public Integer addOrder(@RequestBody Orders orders);

    // 根据ID查询订单
    @RequestMapping(value = "/findById",method = RequestMethod.GET)
    public Orders findByIdOrder(@RequestParam("orderid") Integer orderid);
    
    //更新订单
    @RequestMapping(value = "/updateOrder",method = RequestMethod.POST,consumes =MediaType.APPLICATION_JSON_VALUE )
    public void updateOrder(@RequestBody Orders order);
}
  • 创建Order-Provider项目:

将生成的mapper接口和映射文件添加到项目中。

示例
  • 修改POM文件:
    <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>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.0</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!-- 添加 product-service 坐标 -->
        <dependency>
            <groupId>com.zlw</groupId>
            <artifactId>e-book-order-service</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
    </dependencies>
  • 修改配置文件:
spring.application.name=e-book-order-provider
server.port=9003

#设置服务注册中心
eureka.client.serviceUrl.defaultZone=http://admin:123456@eureka1:8761/eureka/,http://admin:123456@eureka2:8761/eureka/
#----mysql-db-------
mybatis.type-aliases-package=com.book.order.pojo
mybatis.mapper-locations==classpath:com/book/order/mapper/*.xml

spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/book-order?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull
spring.datasource.username=root
spring.datasource.password=root
  • 创建Service:
@Service
public class OrderServiceImpl {

    @Autowired
    private OrdersMapper ordersMapper;

    // 查询所有订单
    public List<Orders> findAllOrder() {
        OrdersExample ordersExample = new OrdersExample();
        return ordersMapper.selectByExample(ordersExample);
    }
    //添加订单
    public Integer createOrder(Orders order) {
        ordersMapper.insert(order);
        return order.getId();
    }
    //根据ID查询
    public Orders findById(Integer orderid) {
        return ordersMapper.selectByPrimaryKey(orderid);
    }
    //更新订单
    public void updateOrder(Orders order) {
        ordersMapper.updateByPrimaryKey(order);
    }
}
  • 创建Controller实现OrderService接口:
@RestController
public class OrderController implements OrderService {

    @Autowired
    private OrderServiceImpl orderServiceImpl;

    @Override
    public List<Orders> findAll() {
        return orderServiceImpl.findAllOrder();
    }

    @Override
    public Integer addOrder(@RequestBody Orders orders) {
        return orderServiceImpl.createOrder(orders);
    }

    @Override
    public Orders findByIdOrder(Integer orderid) {
        return orderServiceImpl.findById(orderid);
    }

    @Override
    public void updateOrder(Orders order) {
        orderServiceImpl.updateOrder(order);
    }
}
  • 修改启动类:
@MapperScan("com.book.order.mapper")
@EnableEurekaClient
@SpringBootApplication
public class OrderApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }
}
  • 测试:


    示例

7.创建Trade-Service和Trade-Provider项目:

  • 创建Trade-Service:

将生成的实体类添加到项目中。

示例
  • 修改POM文件:
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Dalston.SR5</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
  • 创建Service接口:
@RequestMapping("/trade")
public interface TradeService {

    // 查询所有交易
    @RequestMapping(value = "/findAll", method = RequestMethod.GET)
    public List<Trade> findAll();

    // 生成交易信息
    @RequestMapping(value = "/create", method = RequestMethod.POST)
    public void addTrade(@RequestBody Trade trade);
}

  • 创建Trade-Provider:

将生成的mapper接口和映射文件添加到项目中。

示例
  • 修改POM文件:
    <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>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.0</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!-- 添加 Feign 坐标 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-feign</artifactId>
        </dependency>
        <!-- 添加 product-service 坐标 -->
        <dependency>
            <groupId>com.zlw</groupId>
            <artifactId>e-book-trade-service</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
        <!-- 添加 e-book-order-service 坐标 -->
        <dependency>
            <groupId>com.zlw</groupId>
            <artifactId>e-book-order-service</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
    </dependencies>
  • 创建Service和调用OrderService服务的接口:
@Service
public class TradeServiceImpl {

    @Autowired
    private TradeMapper tradeMapper;

    // 查询所有交易
    public List<Trade> findAllTrade() {
        TradeExample tradeExample = new TradeExample();
        List<Trade> list = tradeMapper.selectByExample(tradeExample);
        return list;
    }
    
    //添加交易信息
    public void addTrade(Trade trade) {
        tradeMapper.insert(trade);
    }
}
@FeignClient("e-book-order-provider")
public interface ProviderOrderService extends OrderService {

}
  • 创建Controller:
@RestController
public class TradeController implements TradeService {

    @Autowired
    private TradeServiceImpl tradeServiceImpl;

    @Autowired
    private ProviderOrderService providerOrderService;

    @Override
    public List<Trade> findAll() {
        return tradeServiceImpl.findAllTrade();
    }

    @Override
    public void addTrade(@RequestBody Trade trade) {
        tradeServiceImpl.addTrade(trade);
        // 根据ID查询订单
        Orders order = providerOrderService.findByIdOrder(trade.getOrderId());
        // 更新订单
        providerOrderService.updateOrder(order);
    }
}
  • 修改启动类:
@MapperScan("com.book.trade.mapper")
@EnableFeignClients
@EnableEurekaClient
@SpringBootApplication
public class TradeApplication {
    public static void main(String[] args) {
        SpringApplication.run(TradeApplication.class, args);
    }
}
  • 测试:


    示例

8.创建Consumer项目:

  • 创建项目:


    示例
  • 修改POM文件,添加各服务的坐标:
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Dalston.SR5</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <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>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>   
        <!-- 添加 Feign 坐标 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-feign</artifactId>
        </dependency>
        <!-- 添加 e-book-user-service 坐标 -->
        <dependency>
            <groupId>com.zlw</groupId>
            <artifactId>e-book-user-service</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
        <!-- 添加 e-book-product-service 坐标 -->
        <dependency>
            <groupId>com.zlw</groupId>
            <artifactId>e-book-product-service</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
        <!-- 添加 e-book-trade-service 坐标 -->
        <dependency>
            <groupId>com.zlw</groupId>
            <artifactId>e-book-trade-service</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
        <!-- 添加 e-book-order-service 坐标 -->
        <dependency>
            <groupId>com.zlw</groupId>
            <artifactId>e-book-order-service</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>
  • 修改配置文件:
spring.application.name=e-book-consumer
server.port=9020

#设置服务注册中心
eureka.client.serviceUrl.defaultZone=http://admin:123456@eureka1:8761/eureka/,http://admin:123456@eureka2:8761/eureka/
  • 添加Service接口:
    (1)调用OrderService服务的接口:
/**
 * 调用Order服务
 * @author zhang
 */
@FeignClient("e-book-order-provider")
public interface ConsumerOrderService extends OrderService{
}

(2)调用UserService服务的接口:

/**
 * 调用User服务
 * @author zhang
 */
@FeignClient("e-book-user-provider")
public interface ConsumerUserService extends UserService {
}

(3)调用ProductService服务的接口:

/**
 * 调用Product服务
 * @author zhang
 *
 */
@FeignClient("e-book-product-provider")
public interface ConsumerProductService extends ProductService {
}

(4)调用TradeService服务的接口:

/**
 * 调用交易服务
 * @author zhang
 */
@FeignClient("e-book-trade-provider")
public interface ConsumerTradeService extends TradeService{
}
  • 创建Controller:

模拟内容:
(1)测试登录 账号 admin admin;
(2)查看所有产品列表 ;
(3)选第一款产品,下订单 ;
(4)实现订单交易支付 ;
(5)查看所有的订单信息 。

/**
 * 模拟内容: 登录 查看产品 下订单
 * 
 * @author zhang
 *
 */
@RestController
public class ConsumerController {

    @Autowired
    private ConsumerTradeService tradeService;
    @Autowired
    private ConsumerOrderService orderService;
    @Autowired
    private ConsumerProductService productService;
    @Autowired
    private ConsumerUserService userService;

    /**
     * 创建订单
     * 
     * @return
     */
    @RequestMapping(value = "/create", method = RequestMethod.GET)
    public List<Orders> createOrder() {
        // 测试用户登录
        Integer userid = this.login();
        System.out.println("userid:" + userid);

        // 查询所有商品
        List<Product> list = productService.findAll();
        for (Product product : list) {
            System.out.println(product.getName());
        }

        // 选择商品
        Product product = list.get(0);
        // 模拟创建订单
        Orders orders = new Orders();
        Integer orderId = 1002;
        orders.setId(orderId);
        orders.setUserId(userid);
        orders.setProductId(product.getId());
        orders.setPrice(product.getPrice());
        // 是否删除,0不删除,1删除
        orders.setDeleted((byte) 0);
        // 调用Order服务
        Integer orderid = orderService.addOrder(orders);
        System.out.println("创建成功!orderId:" + orderid);

        // 实现订单交易支付
        Trade trade = new Trade();
        trade.setUserId(userid);
        trade.setOrderId(orderid);
        trade.setPrice(orders.getPrice());
        // 付款的状态
        trade.setPayStatus((byte) 4);
        // 支付的类型
        trade.setPayType((byte) 4);
        // 支付的流水号
        trade.setGatewayPayNum(new Date().getTime() + "");
        trade.setGatewayPayPrice(orders.getPrice());
        trade.setGatewayPayTime(new Date());
        trade.setDeleted((byte) 0);
        // 调用Trade服务
        tradeService.addTrade(trade);

        // 查询所有订单
        List<Orders> li = orderService.findAll();
        return li;
    }

    /**
     * 用户登录
     */
    public Integer login() {
        // 假设从页面获取的数据
        String userName = "admin";
        String password = "admin";
        User user = userService.login(userName, password);
        if (user != null && user.getUserName().length() > 0) {
            System.out.println("登录成功!");
            return user.getId();
        }
        System.out.println("登录失败!");
        return null;
    }
}
  • 修改启动类:
@EnableEurekaClient
@EnableFeignClients
@SpringBootApplication
public class ConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class, args);
    }
}
  • 测试:


    登录测试

    查看商品

    创建订单
生成交易

示例
查看所有订单

示例
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,045评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,114评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,120评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,902评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,828评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,132评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,590评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,258评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,408评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,335评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,385评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,068评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,660评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,747评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,967评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,406评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,970评论 2 341

推荐阅读更多精彩内容