mall-tiny: A framework for single-application projects based on SpringBoot+MyBatis

Keywords: Java xml Database SpringBoot ElasticSearch

SpringBoot e-commerce project mall (20k+star) address: https://github.com/macrozheng/mall

abstract

mall-tiny is the project skeleton extracted from mall project, maintains the entire technology stack of mall project, simplifies the business logic, retains only permissions and commodity core tables, facilitates development and use, and allows free customization of business logic.

Technical Selection

technology Edition Explain
SpringBoot 2.1.3 Container+MVC Framework
SpringSecurity 5.1.4 Authentication and Authorization Framework
MyBatis 3.4.6 ORM Framework
MyBatisGenerator 1.3.3 Data Layer Code Generation
PageHelper 5.1.8 MyBatis Physical Paging Plugin
Swagger-UI 2.7.0 Document Production Tools
Elasticsearch 6.2.2 Search Engines
RabbitMq 3.7.14 Message Queue
Redis 3.2 Distributed Cache
MongoDb 3.2 NoSql Database
Docker 18.09.0 Apply Container Engine
Druid 1.1.10 Database Connection Pool
OSS 2.5.0 Object Storage
JWT 0.9.0 JWT login support
Lombok 1.18.6 Simplified Object Encapsulation Tool

Database table structure

Use process

Environment Setup

This project requires MySql, Elasticsearch, Redis, MongoDb, RabbitMq and other services to start. Please refer to the installation of dependent services Deployment of mall in Windows , the mall_tiny.sql script needs to be imported into the database.

Development Statute

Project Package Structure

src
├── common -- Used to store generic code and tool classes
|   ├── api -- Universal Result Set Encapsulation Class
|   └── utils -- Tool class
├── component -- Components defined in the project
├── config -- SpringBoot In Java To configure
├── controller -- Controller Layer Code
├── dao -- Data access layer code for our custom queries dao Interface to xxxDao name
├── dto -- Data Transfer Object Encapsulation
├── mbg -- MyBatisGenerator Generator related code
|   ├── mapper -- MyBatisGenerator Auto-generated mapper Interface (do not change)
|   └── model -- MyBatisGenerator Automatically generated entity classes and Example Object (do not change)
├── nosql -- nosql Classes related to database operations
|   ├── elasticsearch -- elasticsearch Data Operation Related Classes
|   |   ├── document -- elasticsearch Store document object encapsulation in
|   |   └── repository -- elasticsearch Data Operation Class
|   └── mongodb -- mongodb Data Operation Related Classes
|       ├── document -- mongodb Store document object encapsulation in
|       └── repository -- mongodb Data Operation Class
└── service -- Business layer interface code
    └── impl -- Business layer interface implementation class code

Resource File Description

res
├── com.macro.mall.tiny.mbg.mapper -- mbg Auto-generated mapper.xml Files (do not change)
├── mapper -- Customized mapper.xml File, corresponding dao The query interface in the package to xxxDao.xml name
├── application.yml -- SpringBoot Profile
├── generator.properties -- For configuration MyBatisGenerator Data source information when generating code
├── generatorConfig.xml -- MyBatisGenerator Generate Code Rule Configuration
└── logback-spring.xml -- integration ELK Configuration used to implement log collection

Interface Definition Rules

  • Create table records: POST /{Controller Route Name}/create
  • Modify table records: POST /{controller route name}/update/{id}
  • Delete specified table records: POST /{controller route name}/delete/{id}
  • Paged Query Table Records: GET /{Controller Route Name}/list
  • Get specific record details: GET /{Controller Route Name}/{id}

Specific parameters and return result definitions allow you to run code to view the Api documentation for the Swagger-UI:

Project Run

Start the main function of the com.macro.mall.tiny.MallTinyApplication class directly after installing the dependencies.

Business Code Development Process

Here is an example of the Brand Management function to illustrate the business code development process.

Create Table

To create a pms_brand table, it is important to note that the comments for the table fields are written so that when code is generated, there will be comments in the entity class, and there will be comments in the document generated by Swagger-UI, so that you do not have to repeat the comments.

CREATE TABLE `pms_brand` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(64) DEFAULT NULL,
  `first_letter` varchar(8) DEFAULT NULL COMMENT 'Initials',
  `sort` int(11) DEFAULT NULL,
  `factory_status` int(1) DEFAULT NULL COMMENT 'Is it a brand manufacturer:0->No; 1->yes',
  `show_status` int(1) DEFAULT NULL,
  `product_count` int(11) DEFAULT NULL COMMENT 'Product Quantity',
  `product_comment_count` int(11) DEFAULT NULL COMMENT 'Number of product reviews',
  `logo` varchar(255) DEFAULT NULL COMMENT 'brand logo',
  `big_pic` varchar(255) DEFAULT NULL COMMENT 'District Map',
  `brand_story` text COMMENT 'Brand Story',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=59 DEFAULT CHARSET=utf8 COMMENT='Brand Table';

Generate code using MyBatisGenerator

Run the main method of the com.macro.mall.tiny.mbg.Generator class to generate the code, which will have the following files.

PmsBrandMapper interface

Common interfaces containing form queries

public interface PmsBrandMapper {
    long countByExample(PmsBrandExample example);

    int deleteByExample(PmsBrandExample example);

    int deleteByPrimaryKey(Long id);

    int insert(PmsBrand record);

    int insertSelective(PmsBrand record);

    List<PmsBrand> selectByExampleWithBLOBs(PmsBrandExample example);

    List<PmsBrand> selectByExample(PmsBrandExample example);

    PmsBrand selectByPrimaryKey(Long id);

    int updateByExampleSelective(@Param("record") PmsBrand record, @Param("example") PmsBrandExample example);

    int updateByExampleWithBLOBs(@Param("record") PmsBrand record, @Param("example") PmsBrandExample example);

    int updateByExample(@Param("record") PmsBrand record, @Param("example") PmsBrandExample example);

    int updateByPrimaryKeySelective(PmsBrand record);

    int updateByPrimaryKeyWithBLOBs(PmsBrand record);

    int updateByPrimaryKey(PmsBrand record);
}
PmsBrand Entity Class

An annotation for Swagger-UI has been added to the entity class generated from the database table.

package com.macro.mall.tiny.mbg.model;

import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;

public class PmsBrand implements Serializable {
    private Long id;

    private String name;

    @ApiModelProperty(value = "Initials")
    private String firstLetter;

    private Integer sort;

    @ApiModelProperty(value = "Is it a brand manufacturer:0->No; 1->yes")
    private Integer factoryStatus;

    private Integer showStatus;

    @ApiModelProperty(value = "Product Quantity")
    private Integer productCount;

    @ApiModelProperty(value = "Number of product reviews")
    private Integer productCommentCount;

    @ApiModelProperty(value = "brand logo")
    private String logo;

    @ApiModelProperty(value = "District Map")
    private String bigPic;

    @ApiModelProperty(value = "Brand Story")
    private String brandStory;

    private static final long serialVersionUID = 1L;
    //Omit getter, setter, toString methods
}
PmsBrandExample Query Constructor

Used to construct query conditions when complex queries occur.

PmsBrandMapper.xml file

For the mapper.xml implementation in the PmsBrandMapper interface, the specific query implementation of the methods in the PmsBrandMapper interface is here.

Write data access layer code

Form Query

Form queries recommend query constructors instead of handwritten sql statements, such as the following fuzzy queries by brand name.

@Override
public List<PmsBrand> list(int pageNum, int pageSize, String name) {
    PageHelper.startPage(pageNum, pageSize);
    PmsBrandExample example = new PmsBrandExample();
    if(StrUtil.isNotEmpty(name)){
        example.createCriteria().andNameLike("%"+name+"%");
    }
    return brandMapper.selectByExample(example);
}
Paging Query

Paging queries are implemented using the PageHelper Paging Plugin by adding the following code before the query statement.

 PageHelper.startPage(pageNum, pageSize);
multi-table query

Multi-table queries require you to write your own mapper interface and implementation of mapper.xml, which is consistent with the usage in MyBatis. Here is an example of querying goods that contain attributes.

  • First, you need to customize a Dao interface. To distinguish it from the mapper interface generated by mbg, the mapper interfaces customized in mall-tiny are named xxDao.
public interface EsProductDao {
    List<EsProduct> getAllEsProductList(@Param("id") Long id);
}
  • Then write an XML query implementation of the interface, named xxxDao.xml in mall-tiny.
<select id="getAllEsProductList" resultMap="esProductListMap">
    select
        p.id id,
        p.product_sn productSn,
        p.brand_id brandId,
        p.brand_name brandName,
        p.product_category_id productCategoryId,
        p.product_category_name productCategoryName,
        p.pic pic,
        p.name name,
        p.sub_title subTitle,
        p.price price,
        p.sale sale,
        p.new_status newStatus,
        p.recommand_status recommandStatus,
        p.stock stock,
        p.promotion_type promotionType,
        p.keywords keywords,
        p.sort sort,
        pav.id attr_id,
        pav.value attr_value,
        pav.product_attribute_id attr_product_attribute_id,
        pa.type attr_type,
        pa.name attr_name
    from pms_product p
    left join pms_product_attribute_value pav on p.id = pav.product_id
    left join pms_product_attribute pa on pav.product_attribute_id= pa.id
    where delete_status = 0 and publish_status = 1
    <if test="id!=null">
        and p.id=#{id}
    </if>
</select>

Write business-tier code

  • First add the PmsBrandService interface to the com.macro.mall.tiny.service package;
  • Add its implementation class to com.macro.mall.tiny.serviceImpl.

Write controller layer code

Add the PmsBrandController class to the com.macro.mall.tiny.controller package.

Project Deployment

mall-tiny has integrated a docker plug-in that can be packaged into a docker image and deployed using the docker for reference: Building Docker Mirrors for SpringBoot Applications Using Maven Plugins

Other Instructions

SpringSecurity correlation

Since SpringSecurity is used to implement authentication and authorization, some interfaces require login to be accessible. The process for accessing the login interface is as follows.



  • Click the Authorize button in the upper right corner to enter the actual token:

About Log Collection

This project has logged all interface access logs using AOP facets and has integrated ELK for log collection.ELK log collection environment can be set up for reference: SpringBoot application integrates ELK for log collection.

oss file upload related

When uploading oss files, you need to modify your own configuration, which is as follows:

# OSS-related configuration information
aliyun:
  oss:
    endpoint: oss-cn-shenzhen.aliyuncs.com # Access domain name of oss external service
    accessKeyId: test # User identity used in access authentication
    accessKeySecret: test # User used to encrypt signature strings and key used by oss to verify signature strings
    bucketName: macro-oss # Storage space of oss
    policy:
      expire: 300 # Signature validity period (S)
    maxSize: 10 # Upload file size (M)
    callback: http://localhost:8080/aliyun/oss/callback #Callback address after successful file upload (must be accessible from the public network)
    dir:
      prefix: mall/images/ # Upload Folder Path Prefix

On Cross-domain Issues

A global filter has been configured to allow cross-domain access, and SpringSecurity has released cross-domain preview OPTIONS requests.

/**
 * Global Cross-Domain Configuration
 * Created by macro on 2019/7/27.
 */
@Configuration
public class GlobalCorsConfig {

    /**
     * Filters that allow cross-domain calls
     */
    @Bean
    public CorsFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        //Allow cross-domain calls for all domain names
        config.addAllowedOrigin("*");
        //Allow cookie s to be sent across
        config.setAllowCredentials(true);
        //Release all original header information
        config.addAllowedHeader("*");
        //Allow all request methods to be called across domains
        config.addAllowedMethod("*");
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }
}
//The configure method of SecurityConfig has been added
.antMatchers(HttpMethod.OPTIONS)//Cross-domain requests start with an options request
.permitAll()

Project Source Address

https://github.com/macrozheng/mall-tiny

Public Number

mall project In the full series of learning tutorials, focus on the first time public number is available.

Posted by knashash on Mon, 23 Sep 2019 19:07:54 -0700