mall-tiny:基於SpringBoot+MyBatis的單應用項目骨架

SpringBoot實戰電商項目mall(18k+star)地址:github.com/macrozheng/…html

摘要

mall-tiny是從mall項目中抽取出來的項目骨架,保留了mall項目的整個技術棧,對業務邏輯進行了精簡,只保留了權限及商品核心表,方便開發使用,能夠自由定製業務邏輯。java

技術選型

技術 版本 說明
SpringBoot 2.1.3 容器+MVC框架
SpringSecurity 5.1.4 認證和受權框架
MyBatis 3.4.6 ORM框架
MyBatisGenerator 1.3.3 數據層代碼生成
PageHelper 5.1.8 MyBatis物理分頁插件
Swagger-UI 2.7.0 文檔生產工具
Elasticsearch 6.2.2 搜索引擎
RabbitMq 3.7.14 消息隊列
Redis 3.2 分佈式緩存
MongoDb 3.2 NoSql數據庫
Docker 18.09.0 應用容器引擎
Druid 1.1.10 數據庫鏈接池
OSS 2.5.0 對象存儲
JWT 0.9.0 JWT登陸支持
Lombok 1.18.6 簡化對象封裝工具

數據庫表結構

展現圖片

  • 只保留了商品及權限相關核心表,僅12張表,業務邏輯簡單;
  • 數據庫源文件地址:github.com/macrozheng/…

使用流程

環境搭建

本項目啓動須要依賴MySql、Elasticsearch、Redis、MongoDb、RabbitMq等服務,安裝依賴服務請參考mall在Windows環境下的部署,數據庫中須要導入mall_tiny.sql腳本。git

開發規約

項目包結構

src
├── common -- 用於存儲通用代碼及工具類
|   ├── api -- 通用結果集封裝類
|   └── utils -- 工具類
├── component -- 項目中定義的各種組件
├── config -- SpringBoot中的Java配置
├── controller -- 控制器層代碼
├── dao -- 數據訪問層代碼,存放咱們自定義查詢的dao接口,以xxxDao命名
├── dto -- 數據傳輸對象封裝
├── mbg -- MyBatisGenerator生成器相關代碼
|   ├── mapper -- MyBatisGenerator自動生成的mapper接口(請勿改動)
|   └── model -- MyBatisGenerator自動生成的實體類及Example對象(請勿改動)
├── nosql -- nosql數據庫操做相關類
|   ├── elasticsearch -- elasticsearch數據操做相關類
|   |   ├── document -- elasticsearch中存儲文檔對象封裝
|   |   └── repository -- elasticsearch數據操做類
|   └── mongodb -- mongodb數據操做相關類
|       ├── document -- mongodb中存儲文檔對象封裝
|       └── repository -- mongodb數據操做類
└── service -- 業務層接口代碼
    └── impl -- 業務層接口實現類代碼
複製代碼

資源文件說明

res
├── com.macro.mall.tiny.mbg.mapper -- mbg自動生成的mapper.xml文件(請勿改動)
├── mapper -- 自定義的mapper.xml文件,對應dao包中的查詢接口,以xxxDao.xml命名
├── application.yml -- SpringBoot的配置文件
├── generator.properties -- 用於配置MyBatisGenerator生成代碼時的數據源信息
├── generatorConfig.xml -- MyBatisGenerator生成代碼規則配置
└── logback-spring.xml -- 整合ELK實現日誌收集時使用的配置
複製代碼

接口定義規則

  • 建立表記錄:POST /{控制器路由名稱}/create
  • 修改表記錄:POST /{控制器路由名稱}/update/{id}
  • 刪除指定表記錄:POST /{控制器路由名稱}/delete/{id}
  • 分頁查詢表記錄:GET /{控制器路由名稱}/list
  • 獲取指定記錄詳情:GET /{控制器路由名稱}/{id}

具體參數及返回結果定義能夠運行代碼查看Swagger-UI的Api文檔:github

展現圖片

項目運行

安裝完相關依賴之後直接啓動com.macro.mall.tiny.MallTinyApplication類的main函數便可。spring

業務代碼開發流程

這裏以品牌管理功能爲例來講明業務代碼開發流程。sql

建立表

建立一張pms_brand表,須要注意的是必定要寫好表字段的註釋,這樣在生成代碼時,實體類中就會有註釋了,並且Swagger-UI生成的文檔中也會有註釋,不用再重複寫註釋。mongodb

CREATE TABLE `pms_brand` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(64) DEFAULT NULL,
  `first_letter` varchar(8) DEFAULT NULL COMMENT '首字母',
  `sort` int(11) DEFAULT NULL,
  `factory_status` int(1) DEFAULT NULL COMMENT '是否爲品牌製造商:0->不是;1->是',
  `show_status` int(1) DEFAULT NULL,
  `product_count` int(11) DEFAULT NULL COMMENT '產品數量',
  `product_comment_count` int(11) DEFAULT NULL COMMENT '產品評論數量',
  `logo` varchar(255) DEFAULT NULL COMMENT '品牌logo',
  `big_pic` varchar(255) DEFAULT NULL COMMENT '專區大圖',
  `brand_story` text COMMENT '品牌故事',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=59 DEFAULT CHARSET=utf8 COMMENT='品牌表';
複製代碼

使用MyBatisGenerator生成代碼

運行com.macro.mall.tiny.mbg.Generator類的main方法來生成代碼,生成完後會有如下幾個文件。docker

PmsBrandMapper接口

包含了單表查詢的經常使用接口數據庫

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實體類

根據數據庫表生成的實體類,已添加Swagger-UI的註解。api

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 = "首字母")
    private String firstLetter;

    private Integer sort;

    @ApiModelProperty(value = "是否爲品牌製造商:0->不是;1->是")
    private Integer factoryStatus;

    private Integer showStatus;

    @ApiModelProperty(value = "產品數量")
    private Integer productCount;

    @ApiModelProperty(value = "產品評論數量")
    private Integer productCommentCount;

    @ApiModelProperty(value = "品牌logo")
    private String logo;

    @ApiModelProperty(value = "專區大圖")
    private String bigPic;

    @ApiModelProperty(value = "品牌故事")
    private String brandStory;

    private static final long serialVersionUID = 1L;
    //省略getter、setter、toString方法
}
複製代碼
PmsBrandExample查詢構造器

用於在複雜查詢時構造查詢條件。

PmsBrandMapper.xml文件

對應PmsBrandMapper接口中的mapper.xml實現,PmsBrandMapper接口中方法的具體查詢實現都在此處。

編寫數據訪問層代碼

單表查詢

單表查詢推薦使用查詢構造器來進行查詢,不用手寫sql語句,好比如下的按品牌名稱進行模糊查詢。

@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);
}
複製代碼
分頁查詢

分頁查詢使用PageHelper分頁插件實現,只需在查詢語句前添加如下代碼便可。

PageHelper.startPage(pageNum, pageSize);
複製代碼
多表查詢

多表查詢須要本身編寫mapper接口和mapper.xml實現,和MyBatis中用法一致,這裏以查詢包含屬性的商品爲例。

  • 首先須要須要自定義一個Dao接口,爲了和mbg生成的mapper接口進行區分,mall-tiny中自定義的mapper接口都以xxxDao來命名。
public interface EsProductDao {
    List<EsProduct> getAllEsProductList(@Param("id") Long id);
}
複製代碼
  • 而後編寫接口的xml查詢實現,在mall-tiny中以xxxDao.xml來命名。
<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>
複製代碼

編寫業務層代碼

  • 先在com.macro.mall.tiny.service包中添加PmsBrandService接口;
  • 再在com.macro.mall.tiny.serviceImpl中添加其實現類。

編寫控制器層代碼

在com.macro.mall.tiny.controller包中添加PmsBrandController類。

項目部署

mall-tiny已經集成了docker插件,能夠打包成docker鏡像後使用docker來部署,具體參考:使用Maven插件爲SpringBoot應用構建Docker鏡像

其餘說明

SpringSecurity相關

因爲使用了SpringSecurity來實現認證和受權,部分接口須要登陸才能夠訪問,訪問登陸接口流程以下。

關於日誌收集

本項目已使用AOP切面記錄了全部接口訪問日誌,同時整合了ELK實現了日誌收集。ELK日誌收集環境搭建能夠參考:SpringBoot應用整合ELK實現日誌收集

oss文件上傳相關

oss文件上傳使用時須要修改爲你本身的配置,須要修改配置以下:

# OSS相關配置信息
aliyun:
 oss:
 endpoint: oss-cn-shenzhen.aliyuncs.com # oss對外服務的訪問域名
 accessKeyId: test # 訪問身份驗證中用到用戶標識
 accessKeySecret: test # 用戶用於加密簽名字符串和oss用來驗證簽名字符串的密鑰
 bucketName: macro-oss # oss的存儲空間
 policy:
 expire: 300 # 簽名有效期(S)
 maxSize: 10 # 上傳文件大小(M)
 callback: http://localhost:8080/aliyun/oss/callback # 文件上傳成功後的回調地址(必須公網能夠訪問)
 dir:
 prefix: mall/images/ # 上傳文件夾路徑前綴
複製代碼

關於跨域問題

已經配置了全局的過濾器,容許跨越訪問,同時SpringSecurity也放行了跨域的預檢OPTIONS請求。

/** * 全局跨域配置 * Created by macro on 2019/7/27. */
@Configuration
public class GlobalCorsConfig {

    /** * 容許跨域調用的過濾器 */
    @Bean
    public CorsFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        //容許全部域名進行跨域調用
        config.addAllowedOrigin("*");
        //容許跨愈加送cookie
        config.setAllowCredentials(true);
        //放行所有原始頭信息
        config.addAllowedHeader("*");
        //容許全部請求方法跨域調用
        config.addAllowedMethod("*");
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }
}
複製代碼
//SecurityConfig的configure方法中已經添加
.antMatchers(HttpMethod.OPTIONS)//跨域請求會先進行一次options請求
.permitAll()
複製代碼

項目源碼地址

github.com/macrozheng/…

公衆號

mall項目全套學習教程連載中,關注公衆號第一時間獲取。

公衆號圖片
相關文章
相關標籤/搜索