還在從零開始搭建項目粉寞?手擼了款快速開發(fā)腳手架

之前開源了一款項目骨架mall-tiny尼荆,完整繼承了mall項目的整個技術(shù)棧∵罂眩總感覺mall-tiny集成了太多中間件捅儒,過于復雜了。這次對其進行了簡化和升級振亮,使它成為了一款擁有完整權(quán)限管理功能的快速開發(fā)腳手架巧还,希望對大家有所幫助!

簡介

mall-tiny是一款基于SpringBoot+MyBatis-Plus的快速開發(fā)腳手架坊秸,擁有完整的權(quán)限管理功能麸祷,可對接Vue前端,開箱即用褒搔。

項目演示

mall-tiny項目可無縫對接mall-admin-web前端項目阶牍,秒變權(quán)限管理系統(tǒng)喷面。

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

技術(shù)選型

還在從零開始搭建項目走孽?手擼了款快速開發(fā)腳手架

數(shù)據(jù)庫表結(jié)構(gòu)

還在從零開始搭建項目惧辈?手擼了款快速開發(fā)腳手架
  • 化繁為簡,僅保留了權(quán)限管理功能相關(guān)的9張表磕瓷,方便自由定制咬像;

使用流程

環(huán)境搭建

簡化依賴服務,只需安裝最常用的MySql和Redis服務即可生宛,數(shù)據(jù)庫中需要導入mall_tiny.sql腳本。

開發(fā)規(guī)約

項目包結(jié)構(gòu)

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

資源文件說明

resources
├── mapper -- MyBatis中mapper.xml存放位置
├── application.yml -- SpringBoot通用配置文件
├── application-dev.yml -- SpringBoot開發(fā)環(huán)境配置文件
├── application-prod.yml -- SpringBoot生產(chǎn)環(huán)境配置文件
└── generator.properties -- MyBatis-Plus代碼生成器配置

接口定義規(guī)則

  • 創(chuàng)建表記錄:POST /{控制器路由名稱}/create
  • 修改表記錄:POST /{控制器路由名稱}/update/{id}
  • 刪除指定表記錄:POST /{控制器路由名稱}/delete/{id}
  • 分頁查詢表記錄:GET /{控制器路由名稱}/list
  • 獲取指定記錄詳情:GET /{控制器路由名稱}/{id}
  • 具體參數(shù)及返回結(jié)果定義可以運行代碼查看Swagger-UI的Api文檔:http://localhost:8080/swagger-ui.html
還在從零開始搭建項目肮柜?手擼了款快速開發(fā)腳手架

項目運行

直接運行啟動類MallTinyApplication的main函數(shù)即可陷舅。

業(yè)務代碼開發(fā)流程

創(chuàng)建業(yè)務表

創(chuàng)建好pms模塊的所有表,需要注意的是一定要寫好表字段的注釋审洞,這樣實體類和接口文檔中就會自動生成字段說明了莱睁。

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

使用代碼生成器

運行MyBatisPlusGenerator類的main方法來生成代碼芒澜,可直接生成controller仰剿、service、mapper痴晦、model南吮、mapper.xml的代碼,無需手動創(chuàng)建誊酌。

  • 代碼生成器支持兩種模式部凑,一種生成單表的代碼,比如只生成pms_brand表代碼可以先輸入pms碧浊,后輸入pms_brand涂邀;
還在從零開始搭建項目?手擼了款快速開發(fā)腳手架
  • 生成代碼結(jié)構(gòu)一覽箱锐;
還在從零開始搭建項目比勉?手擼了款快速開發(fā)腳手架
  • 另一種直接生成整個模塊的代碼,比如生成pms模塊代碼可以先輸入pms驹止,后輸入pms_*浩聋。
還在從零開始搭建項目?手擼了款快速開發(fā)腳手架

編寫業(yè)務代碼

單表查詢

由于MyBatis-Plus提供的增強功能相當強大臊恋,單表查詢幾乎不用手寫SQL赡勘,直接使用ServiceImpl和BaseMapper中提供的方法即可。

比如我們的菜單管理業(yè)務實現(xiàn)類UmsMenuServiceImpl中的方法都直接使用了這些方法捞镰。

/**
 * 后臺菜單管理Service實現(xiàn)類
 * 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原生支持闸与,不需要再整合其他插件毙替,直接構(gòu)造Page對象,然后調(diào)用ServiceImpl中的page方法即可践樱。

/**
 * 后臺菜單管理Service實現(xiàn)類
 * 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實現(xiàn),由于之前我們已經(jīng)生成了mapper.xml文件拷邢,所以我們直接在Mapper接口中定義好方法袱院,然后在mapper.xml寫好SQL實現(xiàn)即可。

  • 比如說我們需要寫一個根據(jù)用戶ID獲取其分配的菜單的方法瞭稼,首先我們在UmsMenuMapper接口中添加好getMenuList方法忽洛;
/**
 * <p>
 * 后臺菜單表 Mapper 接口
 * </p>
 *
 * @author macro
 * @since 2020-08-21
 */
public interface UmsMenuMapper extends BaseMapper<UmsMenu> {
    /**
     * 根據(jù)后臺用戶ID獲取菜單
     */
    List<UmsMenu> getMenuList(@Param("adminId") Long adminId);
}
  • 然后在UmsMenuMapper.xml添加該方法的對應SQL實現(xiàn)即可。
<?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已經(jīng)集成了Docker插件环肘,可以打包成Docker鏡像來部署

其他說明

SpringSecurity相關(guān)

由于使用了SpringSecurity來實現(xiàn)認證和授權(quán)欲虚,部分接口需要token才可以訪問,訪問需要認證授權(quán)接口流程如下悔雹。

  • 訪問Swagger-UI接口文檔
  • 調(diào)用登錄接口獲取token复哆;
還在從零開始搭建項目?手擼了款快速開發(fā)腳手架

點擊右上角Authorize按鈕輸入token腌零,然后訪問相關(guān)接口即可梯找。

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

請求參數(shù)校驗

默認集成了Jakarta Bean Validation參數(shù)校驗框架益涧,只需在參數(shù)對象屬性中添加javax.validation.constraints包中的注解注解即可實現(xiàn)校驗功能锈锤,這里以登錄參數(shù)校驗為例。

  • 首先在登錄請求參數(shù)中添加@NotEmpty注解闲询;
/**
 * 用戶登錄參數(shù)
 * 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注解開啟參數(shù)校驗功能即可牙咏。
/**
 * 后臺用戶管理
 * 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);
    }}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市嘹裂,隨后出現(xiàn)的幾起案子妄壶,更是在濱河造成了極大的恐慌,老刑警劉巖寄狼,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件丁寄,死亡現(xiàn)場離奇詭異,居然都是意外死亡泊愧,警方通過查閱死者的電腦和手機伊磺,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來删咱,“玉大人屑埋,你說我怎么就攤上這事√底蹋” “怎么了摘能?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵续崖,是天一觀的道長。 經(jīng)常有香客問我团搞,道長严望,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任逻恐,我火速辦了婚禮像吻,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘复隆。我一直安慰自己拨匆,他們只是感情好,可當我...
    茶點故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布挽拂。 她就那樣靜靜地躺著惭每,像睡著了一般。 火紅的嫁衣襯著肌膚如雪轻局。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天样刷,我揣著相機與錄音仑扑,去河邊找鬼。 笑死置鼻,一個胖子當著我的面吹牛镇饮,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播箕母,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼储藐,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了嘶是?” 一聲冷哼從身側(cè)響起钙勃,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎聂喇,沒想到半個月后辖源,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡希太,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年克饶,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片誊辉。...
    茶點故事閱讀 38,724評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡矾湃,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出堕澄,到底是詐尸還是另有隱情邀跃,我是刑警寧澤霉咨,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站坞嘀,受9級特大地震影響躯护,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜丽涩,卻給世界環(huán)境...
    茶點故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一棺滞、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧矢渊,春花似錦继准、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至毡鉴,卻和暖如春崔泵,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背猪瞬。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工憎瘸, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人陈瘦。 一個月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓幌甘,卻偏偏與公主長得像,于是被迫代替她去往敵國和親痊项。 傳聞我的和親對象是個殘疾皇子锅风,可洞房花燭夜當晚...
    茶點故事閱讀 43,627評論 2 350