還在從零開始搭建項目?手寫了款快速開發腳手架

以前開源了一款項目骨架mall-tiny,完整繼承了mall項目的整個技術棧。總感受mall-tiny集成了太多中間件,過於複雜了。此次對其進行了簡化和升級,使它成爲了一款擁有完整權限管理功能的快速開發腳手架,但願對你們有所幫助!php

簡介

mall-tiny是一款基於SpringBoot+MyBatis-Plus的快速開發腳手架,擁有完整的權限管理功能,可對接Vue前端,開箱即用。css

項目演示

mall-tiny項目可無縫對接mall-admin-web前端項目,秒變權限管理系統。html

還在從零開始搭建項目?手擼了款快速開發腳手架


技術選型

還在從零開始搭建項目?手擼了款快速開發腳手架


數據庫表結構

還在從零開始搭建項目?手擼了款快速開發腳手架


  • 化繁爲簡,僅保留了權限管理功能相關的9張表,方便自由定製;前端

使用流程

環境搭建

簡化依賴服務,只需安裝最經常使用的MySql和Redis服務便可,數據庫中須要導入mall_tiny.sql腳本。java


開發規約

項目包結構

src
├── common -- 用於存放通用代碼|   ├── api -- 通用結果集封裝類
|   ├── config -- 通用配置類
|   ├── domain -- 通用封裝對象
|   ├── exception -- 全局異常處理相關類
|   └── service -- 通用業務類
├── config -- SpringBoot中的Java配置
├── domain -- 共用封裝對象
├── generator -- MyBatis-Plus代碼生成器
├── modules -- 存放業務代碼的基礎包
|   └── ums -- 權限管理模塊業務代碼
|       ├── controller -- 該模塊相關接口
|       ├── dto -- 該模塊數據傳輸封裝對象
|       ├── mapper -- 該模塊相關Mapper接口
|       ├── model -- 該模塊相關實體類
|       └── service -- 該模塊相關業務處理類
└── security -- SpringSecurity認證受權相關代碼
    ├── annotation -- 相關注解
    ├── aspect -- 相關切面
    ├── component -- 認證受權相關組件
    ├── config -- 相關配置
    └── util -- 相關工具類

資源文件說明

resources
├── mapper -- MyBatismapper.xml存放位置
├── application.yml -- SpringBoot通用配置文件
├── application-dev.yml -- SpringBoot開發環境配置文件
├── application-prod.yml -- SpringBoot生產環境配置文件
└── generator.properties -- MyBatis-Plus代碼生成器配置

接口定義規則

  • 建立表記錄:POST /{控制器路由名稱}/createweb

  • 修改表記錄:POST /{控制器路由名稱}/update/{id}sql

  • 刪除指定表記錄:POST /{控制器路由名稱}/delete/{id}數據庫

  • 分頁查詢表記錄:GET /{控制器路由名稱}/listapi

  • 獲取指定記錄詳情:GET /{控制器路由名稱}/{id}ruby

  • 具體參數及返回結果定義能夠運行代碼查看Swagger-UI的Api文檔:http://localhost:8080/swagger-ui.html

還在從零開始搭建項目?手擼了款快速開發腳手架


項目運行

直接運行啓動類MallTinyApplicationmain函數便可。

業務代碼開發流程

建立業務表

建立好pms模塊的全部表,須要注意的是必定要寫好表字段的註釋,這樣實體類和接口文檔中就會自動生成字段說明了。

還在從零開始搭建項目?手擼了款快速開發腳手架


使用代碼生成器

運行MyBatisPlusGenerator類的main方法來生成代碼,可直接生成controller、service、mapper、model、mapper.xml的代碼,無需手動建立。

  • 代碼生成器支持兩種模式,一種生成單表的代碼,好比只生成pms_brand表代碼能夠先輸入pms,後輸入pms_brand

還在從零開始搭建項目?手擼了款快速開發腳手架


  • 生成代碼結構一覽;

還在從零開始搭建項目?手擼了款快速開發腳手架


  • 另外一種直接生成整個模塊的代碼,好比生成pms模塊代碼能夠先輸入pms,後輸入pms_*

還在從零開始搭建項目?手擼了款快速開發腳手架


編寫業務代碼

單表查詢

因爲MyBatis-Plus提供的加強功能至關強大,單表查詢幾乎不用手寫SQL,直接使用ServiceImpl和BaseMapper中提供的方法便可。

好比咱們的菜單管理業務實現類UmsMenuServiceImpl中的方法都直接使用了這些方法。

/**
 * 後臺菜單管理Service實現類
 * Created by macro on 2020/2/2.
 */
@Service
public class UmsMenuServiceImpl extends ServiceImpl<UmsMenuMapper,UmsMenu>implements UmsMenuService {
    @Override
    public boolean create(UmsMenu umsMenu) {
        umsMenu.setCreateTime(new Date());
        updateLevel(umsMenu);        return save(umsMenu);
    }    @Override
    public boolean update(Long id, UmsMenu umsMenu) {
        umsMenu.setId(id);        updateLevel(umsMenu);        return updateById(umsMenu);
    }    @Override
    public Page<UmsMenu> list(Long parentId, Integer pageSize, Integer pageNum) {
        Page<UmsMenu> page = new Page<>(pageNum,pageSize);
        QueryWrapper<UmsMenu> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(UmsMenu::getParentId,parentId)                .orderByDesc(UmsMenu::getSort);        return page(page,wrapper);
    }    @Override
    public List<UmsMenuNode> treeList() {
        List<UmsMenu> menuList = list();        List<UmsMenuNode> result = menuList.stream()                .filter(menu -> menu.getParentId().equals(0L))
                .map(menu -> covertMenuNode(menu, menuList)).collect(Collectors.toList());        return result;
    }    @Override
    public boolean updateHidden(Long id, Integer hidden) {
        UmsMenu umsMenu = new UmsMenu();
        umsMenu.setId(id);        umsMenu.setHidden(hidden);        return updateById(umsMenu);
    }}

分頁查詢

對於分頁查詢MyBatis-Plus原生支持,不須要再整合其餘插件,直接構造Page對象,而後調用ServiceImpl中的page方法便可。

/**
 * 後臺菜單管理Service實現類
 * Created by macro on 2020/2/2.
 */
@Servicepublic class UmsMenuServiceImpl extends ServiceImpl<UmsMenuMapper,UmsMenu>implements UmsMenuService {
    @Override    public Page<UmsMenu> list(Long parentId, Integer pageSize, Integer pageNum) {
        Page<UmsMenu> page = new Page<>(pageNum,pageSize);
        QueryWrapper<UmsMenu> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(UmsMenu::getParentId,parentId)                .orderByDesc(UmsMenu::getSort);        return page(page,wrapper);
    }}

多表查詢

對於多表查詢,咱們須要手寫mapper.xml中的SQL實現,因爲以前咱們已經生成了mapper.xml文件,因此咱們直接在Mapper接口中定義好方法,而後在mapper.xml寫好SQL實現便可。

  • 好比說咱們須要寫一個根據用戶ID獲取其分配的菜單的方法,首先咱們在UmsMenuMapper接口中添加好getMenuList方法;

/**
 * <p>
 * 後臺菜單表 Mapper 接口
 * </p>
 *
 * @author macro
 * @since 2020-08-21
 */
public interface UmsMenuMapper extends BaseMapper<UmsMenu{
    /**
     * 根據後臺用戶ID獲取菜單
     */
    List<UmsMenu> getMenuList(@Param("adminId") Long adminId);
}
  • 而後在UmsMenuMapper.xml添加該方法的對應SQL實現便可。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.macro.mall.tiny.modules.ums.mapper.UmsMenuMapper">
    <select id="getMenuList" resultType="com.macro.mall.tiny.modules.ums.model.UmsMenu">
        SELECT            m.id id,            m.parent_id parentId,            m.create_time createTime,            m.title title,            m.level level,            m.sort sort,            m.name name,            m.icon icon,            m.hidden hidden        FROM            ums_admin_role_relation arr                LEFT JOIN ums_role r ON arr.role_id = r.id                LEFT JOIN ums_role_menu_relation rmr ON r.id = rmr.role_id                LEFT JOIN ums_menu m ON rmr.menu_id = m.id        WHERE            arr.admin_id = #{adminId}          AND m.id IS NOT NULL        GROUP BY            m.id    </select>
    </mapper>

項目部署

mall-tiny已經集成了Docker插件,能夠打包成Docker鏡像來部署

其餘說明

SpringSecurity相關

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

  • 訪問Swagger-UI接口文檔

  • 調用登陸接口獲取token;

還在從零開始搭建項目?手擼了款快速開發腳手架


點擊右上角Authorize按鈕輸入token,而後訪問相關接口便可。

還在從零開始搭建項目?手擼了款快速開發腳手架


請求參數校驗

默認集成了Jakarta Bean Validation參數校驗框架,只需在參數對象屬性中添加javax.validation.constraints包中的註解註解便可實現校驗功能,這裏以登陸參數校驗爲例。

  • 首先在登陸請求參數中添加@NotEmpty註解;

/**
 * 用戶登陸參數
 * Created by macro on 2018/4/26.
 */
@Data
@EqualsAndHashCode(callSuper = false)
public class UmsAdminLoginParam {    @NotEmpty
    @ApiModelProperty(value = "用戶名",required = true)
    private String username;    @NotEmpty
    @ApiModelProperty(value = "密碼",required = true)
    private String password;}
  • 而後在登陸接口中添加@Validated註解開啓參數校驗功能便可。

/**
 * 後臺用戶管理
 * Created by macro on 2018/4/26.
 */
@Controller
@Api(tags = "UmsAdminController", description = "後臺用戶管理")
@RequestMapping("/admin")
public class UmsAdminController {
    @ApiOperation(value = "登陸之後返回token")
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult login(@Validated @RequestBody UmsAdminLoginParam umsAdminLoginParam) {
        String token = adminService.login(umsAdminLoginParam.getUsername(), umsAdminLoginParam.getPassword());        if (token == null) {
            return CommonResult.validateFailed("用戶名或密碼錯誤");
        }        Map<String, String> tokenMap = new HashMap<>();        tokenMap.put("token", token);
        tokenMap.put("tokenHead", tokenHead);
        return CommonResult.success(tokenMap);    }}
相關文章
相關標籤/搜索