人之所以痛苦,那是因为你在成长。--------magic_guo

在分布式系统中,数据库的设计尤为重要,关系着系统性能;在高可用的概念中,数据库的设计和优化被单独划分为一个模块来叙述,由此可见其重要性;
其中有分库分表、字段设计、索引选择、数据库引擎、主键策略、表之间的关联等,都属于这一范畴;

商品模块数据库搭建:
阐述:
商品的基本信息:id、价格、描述、类型、商品图片等;
在一些真实业务场景中,商品图片是一个表(一般商品图片都存放于分布式文件存储系统中,如fastFDS和OSS)、商品描述是一个表;三个表之间是根据商品id来维护关系,而不是通过主键强关联的方式来维护关系(因为这样,做增删改查的时候容易),而且主键策略一般是根据一些算法(如雪花算法等)来生成id,而不是直接主键自增等;

本文只是做一个案列,只是将商品图片做了一个分表;图片存放fastFDS中;后续优化在后文中会写出来;

商品表创建:

java 电商架构 java电商项目模块介绍_数据


商品图片创建:

java 电商架构 java电商项目模块介绍_spring_02


创建商品模块:

还是老步骤:整理pom文件,写mapper、sevice、controller层,配置文件,启动类;

目录结构:

java 电商架构 java电商项目模块介绍_数据库_03


pom文件(shop-common模块在下面叙述):

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <dependency>
            <groupId>com.guo</groupId>
            <artifactId>shop-common</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

其他层都不再说了,跟前面的shop-user模块一样,不同的是controller层:
说一下多条件查询,这里使用一个mapo来传递参数,因为后面要使用feign来调用此模块,在feign的接口中,多参数出传递或者list传递很不方便;
大多数条件查询都是以下几个步骤:
1.接收参数;2.创建page对象;3.创建EntityWrapper对象;4.查询

@Slf4j
@RestController
@RequestMapping("/goods")
public class GoodsController {

    @Autowired
    IGoodsService goodsService;

    @Autowired
    IGoodsPngService goodsPngService;

    @RequestMapping("/addGoods")
    public ResultEntity addGoods(@RequestBody Goods goods) {
        return ResultEntity.responseClient(goodsService.insert(goods));
    }

    @RequestMapping("/getGoodsPage")
    public ResultEntity getGoodsPage(@RequestBody Map<String, Object> map) {

        // 1.获取请求的数据
        Object current = map.get("current");
        Object size = map.get("size");
        Object gname = map.get("gname");
        Object gtype = map.get("gtype");
        Object gprice = map.get("gprice");

        // 2.创建分页对象
        Page<Goods> page = new Page<>();
        if (!StringUtils.isEmpty(current.toString())) {
            page.setCurrent(Integer.parseInt(current.toString()));
        }

        if (!StringUtils.isEmpty(size.toString())) {
            page.setSize(Integer.parseInt(size.toString()));
        }

        // 3.创建EntityWrapper
        EntityWrapper<Goods> entityWrapper = new EntityWrapper<>();
        if (!StringUtils.isEmpty(gname.toString())) {
            entityWrapper.like("gname", gname.toString());
        }

        if (!StringUtils.isEmpty(gtype.toString())) {
            entityWrapper.like("gtype", gtype.toString());
        }

        if (!StringUtils.isEmpty(gprice.toString())) {
            entityWrapper.like("gprice", gprice.toString());
        }

        // 4.查询
        return ResultEntity.success(goodsService.selectPage(page, entityWrapper));
    }
}

启动此模块,查看端口和注册中心,访问接口:

java 电商架构 java电商项目模块介绍_java 电商架构_04


数据库:

java 电商架构 java电商项目模块介绍_java 电商架构_05


这里说一下@RequestBody注解:

@RequestBody主要用来接收前端传递给后端的json字符串中的数据的(请求体中的数据的);GET方式无请求体,所以使用@RequestBody接收数据时,前端不能使用GET方式提交数据,而是用POST方式进行提交;

一个请求,只有一个RequestBody;一个请求,可以有多个RequestParam

后台模块以feign的方式调用商品模块和调用user模块是一样的,上一篇已经写过,不再作重复描述;

公共模块shop-common搭建:
此模块以maven工程的形式来构建,用于存放各个模块共同用到的资源:如全局异常类、工具类等

全局异常:异常处理分为两类,一种是非IO型异常,则可直接抛出做处理;另一种是IO型异常,要直接在代码里作资源关闭的处理,不能单靠此全局异常来处理;

@ControllerAdvice 是一个增强的 Controller。使用这个 Controller ,可以实现三个方面的功能:
1.全局异常处理(最常用)
2.全局数据绑定
3.全局数据预处理

// @ControllerAdvice 表明这是一个全局异常
// @ExceptionHandler 注解用来指明异常的处理类型
@ControllerAdvice
@Slf4j
public class ShopExceptionHandler {

    // 处理系统异常
    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public ResultEntity systemException(Exception e) {
        log.error("系统异常", e);

        return ResultEntity.error("系统正在维护,请联系管理员.........");
    }


    // 处理业务异常
    @ExceptionHandler(value = ShopException.class)
    @ResponseBody
    public ResultEntity businessException(ShopException e) {
        log.error("业务异常", e);

        return ResultEntity.error(e.getMsg());
    }
}

ShopException实例:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class ShopException extends RuntimeException{

    private String msg;

    private Integer code;

}

今天就到这儿吧。。。。。