懒人方案–半天搞定一个SpringBoot单体项目

前言

好久木有冒个泡了,来活跃一下,顺便再水一篇博文~。那么最近也是在构建咱们这个whiteHole的分布式版本的时候呢,发现一个问题那就是通过充分考量业务的分析之后,鄙人一共创建了90多张表,6个数据库,还有两个没有创建(附加功能)保守估计加上一套完整的分级管理系统也就是120/30多张表嘛。

那么问题来了,有没有一张方案能够给我偷个懒呢,把这种简单的controller service dao 最好再来点前端页面给我写好呢?

答案是有的,如果熟练掌握了这个工具的使用,那么你像咱们C站或者某音那种博主一样,一个礼拜好几个xx管理项目拿过来圈粉是完全没问题的。只是文档稍微麻烦一点,当然也可以自动生成嘛。总之本文的目的就是教你如何合理的偷懒,一个礼拜N个项目还能赚赚外快是吧。

当然这也仅限于这种xx后台管理系统这也玩意,或者是不上线的玩意,因为这个还是一个毛坯房,有些东西还是要自己改一改的,不够你要是是毛坯房也够用的话,那也可以,毕竟像xx后台管理,或者xx大作业基本上不用考虑别的事情,不用那么麻烦。

工具下载

ok,废话不多说,我们开始,首先我们需要去获取我们的一个生成器,那么这个玩意的话,也是很早以前就有了的,再次突出:都2202年!当然偷懒的前提是已近掌握了。

我们先进入项目地址:https://github.com/renrenio/

在这里插入图片描述

这个项目里面的话是有好几个项目的,这里简单介绍一下。

renren-fast-vue

这个玩意是一套后端的管理系统,很多东西也是构建好了的,拿来用,改一下配就好了。那么这个是前后端分离的一个前端项目,是基于vue+elementui 做的。

renren-fast

这个是和咱们fast-vue配套的后端

其他的官网都有介绍。我这里就挑几个来look,look。

那么咱们这里还有使用到的呢就是 renren-generator 也就是咱们的代码生成器。

数据库创建

由于这个代码生成器主要是通过数据库,自动生成咱们的controller service dao 层,当然用mybatisplus其实也可以自动生成dao层,然后是基本的service,但是这里还有controller层,还有一些前端的代码生成(这个代码生的是vue+elementui,可以直接copy到你的前端工程)

这里的话,我们就拿WhiteHoleCloud的项目来做演示了。首先来看到咱们的这个项目吧在这里插入图片描述

这里是集成了它的后台和生成器,这个东西看你自己放在哪,我这边就先这样了。

我们用来演示的是user服务。那么对应的表是这张表:
在这里插入图片描述

环境准备

现在我们已经有了数据库,表啥的都建好了。

那么我们下载好源码
在这里插入图片描述
这个咋下载我就不说了,之后的话放在一共合适的地方在你的idea里面打开。我这里就放在了WhiteHoleCloud的项目下。

在这里插入图片描述
之后展开 :
在这里插入图片描述
在这里插入图片描述
这里注意下 tablePrefix表的前缀,我这个是user服务,所以前缀都是user_

在这里插入图片描述

然后我们运行它的Application

我这里启动9000端口(原来的8000被用了)
在这里插入图片描述
然后选择一下你的表,之后生成就好了,然后你会得到一个压缩包。

在这里插入图片描述

这里面有一些前端的代码,就在views下面,是vue+element写的

然后这里面还有提供了mapper,当然实际上生成的代码其实是mybatisplus的是注解式的。如果你有需要就导入也可以。

比如我这样就是这样的:

在这里插入图片描述

这里注意一点是我用idea把user这个包改了个名字,前面配置的时候写错了。

依赖导入

Maven依赖导入

现在的话我们是成功把代码迁移过来了,但是里面还有很多东西没有,最基本的就是依赖没有。

这里的话由于我是一个分布式的项目,所以的话,我这边有一个组件包 。然后我把依赖都放在这里面了,当然也可以放在root的pom文件下,但是还有一些包没有所以我直接创建组件来用。那么如果你是单体项目的话,那么你直接放在你那个项目的pom文件下,例如:
在这里插入图片描述
但是咱们这里不是这样的,不过都是一样的。

基本依赖如下:


    <dependencies>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.3.1</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.4</version>
        </dependency>

        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpcore</artifactId>
            <version>4.4.15</version>
        </dependency>


        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-core</artifactId>
            <version>9.0.60</version>
        </dependency>
        <dependency>
            <groupId>jakarta.validation</groupId>
            <artifactId>jakarta.validation-api</artifactId>
            <version>2.0.2</version>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.28</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.13</version>
        </dependency>
    </dependencies>


那么这个依赖我要说一下的就是,我这里还少了这个shiro的依赖,因为我要用的是SpringSecurity。

如果你要用Shiro的话你自己再导入进去就好了,我这里的话就不导入了,而且我还把Shiro相关的代码注释了。

在这里插入图片描述

那么如果你们自己的话,那就看情况了。

代码依赖

这个玩意毕竟是代码生成的嘛,还有一些它自己的代码依赖是需要导入的,这个可以去copy一下,你自己也可以去copy一下,但是注意的是要去renren-fast这个项目里面的代码去copy。

那么我这里的话就直接贴出来,你先把Maven依赖导入,然后创建对应的包,把这个代码拷贝进去,那个Maven依赖里面有些就是为这个代码依赖服务的。所以直接copy这里是不错的选择。

我把这些代码都放在了那个公共组件里面,那么如果你是单体的项目,那么你把common这个包创建在你的项目目录下就好了。
在这里插入图片描述

那么现在我就依次把对应的代码给出了,自己创建好后,复制就好了。

exception

在这里插入图片描述

/**
 * Copyright (c) 2016-2019 人人开源 All rights reserved.
 *
 * https://www.renren.io
 *
 * 版权所有,侵权必究!
 */

package com.huterox.common.exception;

/**
 * 自定义异常
 *
 * @author Mark [email protected]
 */
public class RRException extends RuntimeException {
	private static final long serialVersionUID = 1L;
	
    private String msg;
    private int code = 500;
    
    public RRException(String msg) {
		super(msg);
		this.msg = msg;
	}
	
	public RRException(String msg, Throwable e) {
		super(msg, e);
		this.msg = msg;
	}
	
	public RRException(String msg, int code) {
		super(msg);
		this.msg = msg;
		this.code = code;
	}
	
	public RRException(String msg, int code, Throwable e) {
		super(msg, e);
		this.msg = msg;
		this.code = code;
	}

	public String getMsg() {
		return msg;
	}

	public void setMsg(String msg) {
		this.msg = msg;
	}

	public int getCode() {
		return code;
	}

	public void setCode(int code) {
		this.code = code;
	}
	
	
}

utils

在这里插入图片描述

/**
 * Copyright (c) 2016-2019 人人开源 All rights reserved.
 * <p>
 * https://www.renren.io
 * <p>
 * 版权所有,侵权必究!
 */

package com.huterox.common.utils;

import com.huterox.common.validator.group.AliyunGroup;
import com.huterox.common.validator.group.QcloudGroup;
import com.huterox.common.validator.group.QiniuGroup;

import java.util.Optional;
import java.util.stream.Stream;

/**
 * 常量
 *
 * @author Mark [email protected]
 */
public class Constant {
    /**
     * 超级管理员ID
     */
    public static final int SUPER_ADMIN = 1;
    /**
     * 当前页码
     */
    public static final String PAGE = "page";
    /**
     * 每页显示记录数
     */
    public static final String LIMIT = "limit";
    /**
     * 排序字段
     */
    public static final String ORDER_FIELD = "sidx";
    /**
     * 排序方式
     */
    public static final String ORDER = "order";
    /**
     * 升序
     */
    public static final String ASC = "asc";

    /**
     * 菜单类型
     *
     * @author chenshun
     * @email [email protected]
     * @date 2016年11月15日 下午1:24:29
     */
    public enum MenuType {
        /**
         * 目录
         */
        CATALOG(0),
        /**
         * 菜单
         */
        MENU(1),
        /**
         * 按钮
         */
        BUTTON(2);

        private int value;

        MenuType(int value) {
            this.value = value;
        }

        public int getValue() {
            return value;
        }
    }

    /**
     * 定时任务状态
     *
     * @author chenshun
     * @email [email protected]
     * @date 2016年12月3日 上午12:07:22
     */
    public enum ScheduleStatus {
        /**
         * 正常
         */
        NORMAL(0),
        /**
         * 暂停
         */
        PAUSE(1);

        private int value;

        ScheduleStatus(int value) {
            this.value = value;
        }

        public int getValue() {
            return value;
        }
    }

    /**
     * 云服务商
     */
    public enum CloudService {
        /**
         * 七牛云
         */
        QINIU(1, QiniuGroup.class),
        /**
         * 阿里云
         */
        ALIYUN(2, AliyunGroup.class),
        /**
         * 腾讯云
         */
        QCLOUD(3, QcloudGroup.class);

        private int value;

        private Class<?> validatorGroupClass;

        CloudService(int value, Class<?> validatorGroupClass) {
            this.value = value;
            this.validatorGroupClass = validatorGroupClass;
        }

        public int getValue() {
            return value;
        }

        public Class<?> getValidatorGroupClass() {
            return this.validatorGroupClass;
        }

        public static CloudService getByValue(Integer value) {
            Optional<CloudService> first = Stream.of(CloudService.values()).filter(cs -> value.equals(cs.value)).findFirst();
            if (!first.isPresent()) {
                throw new IllegalArgumentException("非法的枚举值:" + value);
            }
            return first.get();
        }
    }

}

/**
 * Copyright (c) 2016-2019 人人开源 All rights reserved.
 *
 * https://www.renren.io
 *
 * 版权所有,侵权必究!
 */

package com.huterox.common.utils;

import com.baomidou.mybatisplus.core.metadata.IPage;

import java.io.Serializable;
import java.util.List;

/**
 * 分页工具类
 *
 * @author Mark [email protected]
 */
public class PageUtils implements Serializable {
	private static final long serialVersionUID = 1L;
	/**
	 * 总记录数
	 */
	private int totalCount;
	/**
	 * 每页记录数
	 */
	private int pageSize;
	/**
	 * 总页数
	 */
	private int totalPage;
	/**
	 * 当前页数
	 */
	private int currPage;
	/**
	 * 列表数据
	 */
	private List<?> list;
	
	/**
	 * 分页
	 * @param list        列表数据
	 * @param totalCount  总记录数
	 * @param pageSize    每页记录数
	 * @param currPage    当前页数
	 */
	public PageUtils(List<?> list, int totalCount, int pageSize, int currPage) {
		this.list = list;
		this.totalCount = totalCount;
		this.pageSize = pageSize;
		this.currPage = currPage;
		this.totalPage = (int)Math.ceil((double)totalCount/pageSize);
	}

	/**
	 * 分页
	 */
	public PageUtils(IPage<?> page) {
		this.list = page.getRecords();
		this.totalCount = (int)page.getTotal();
		this.pageSize = (int)page.getSize();
		this.currPage = (int)page.getCurrent();
		this.totalPage = (int)page.getPages();
	}

	public int getTotalCount() {
		return totalCount;
	}

	public void setTotalCount(int totalCount) {
		this.totalCount = totalCount;
	}

	public int getPageSize() {
		return pageSize;
	}

	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
	}

	public int getTotalPage() {
		return totalPage;
	}

	public void setTotalPage(int totalPage) {
		this.totalPage = totalPage;
	}

	public int getCurrPage() {
		return currPage;
	}

	public void setCurrPage(int currPage) {
		this.currPage = currPage;
	}

	public List<?> getList() {
		return list;
	}

	public void setList(List<?> list) {
		this.list = list;
	}
	
}

/**
 * Copyright (c) 2016-2019 人人开源 All rights reserved.
 *
 * https://www.renren.io
 *
 * 版权所有,侵权必究!
 */

package com.huterox.common.utils;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import com.huterox.common.xss.SQLFilter;
import org.apache.commons.lang.StringUtils;

import java.util.Map;

/**
 * 查询参数
 *
 * @author Mark [email protected]
 */
public class Query<T> {

    public IPage<T> getPage(Map<String, Object> params) {
        return this.getPage(params, null, false);
    }

    public IPage<T> getPage(Map<String, Object> params, String defaultOrderField, boolean isAsc) {
        //分页参数
        long curPage = 1;
        long limit = 10;

        if(params.get(Constant.PAGE) != null){
            curPage = Long.parseLong((String)params.get(Constant.PAGE));
        }
        if(params.get(Constant.LIMIT) != null){
            limit = Long.parseLong((String)params.get(Constant.LIMIT));
        }

        //分页对象
        Page<T> page = new Page<T>(curPage, limit);

        //分页参数
        params.put(Constant.PAGE, page);

        //排序字段
        //防止SQL注入(因为sidx、order是通过拼接SQL实现排序的,会有SQL注入风险)
        String orderField = SQLFilter.sqlInject((String)params.get(Constant.ORDER_FIELD));
        String order = (String)params.get(Constant.ORDER);


        //前端字段排序
        if(StringUtils.isNotEmpty(orderField) && StringUtils.isNotEmpty(order)){
            if(Constant.ASC.equalsIgnoreCase(order)) {
                return  page.addOrder(OrderItem.asc(orderField));
            }else {
                return page.addOrder(OrderItem.desc(orderField));
            }
        }

        //没有排序字段,则不排序
        if(StringUtils.isBlank(defaultOrderField)){
            return page;
        }

        //默认排序
        if(isAsc) {
            page.addOrder(OrderItem.asc(defaultOrderField));
        }else {
            page.addOrder(OrderItem.desc(defaultOrderField));
        }

        return page;
    }
}

/**
 * Copyright (c) 2016-2019 人人开源 All rights reserved.
 *
 * https://www.renren.io
 *
 * 版权所有,侵权必究!
 */

package com.huterox.common.utils;

import org.apache.http.HttpStatus;

import java.util.HashMap;
import java.util.Map;

/**
 * 返回数据
 *
 * @author Mark [email protected]
 */
public class R extends HashMap<String, Object> {
	private static final long serialVersionUID = 1L;
	
	public R() {
		put("code", 0);
		put("msg", "success");
	}
	
	public static R error() {
		return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, "未知异常,请联系管理员");
	}
	
	public static R error(String msg) {
		return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, msg);
	}
	
	public static R error(int code, String msg) {
		R r = new R();
		r.put("code", code);
		r.put("msg", msg);
		return r;
	}

	public static R ok(String msg) {
		R r = new R();
		r.put("msg", msg);
		return r;
	}
	
	public static R ok(Map<String, Object> map) {
		R r = new R();
		r.putAll(map);
		return r;
	}
	
	public static R ok() {
		return new R();
	}

	public R put(String key, Object value) {
		super.put(key, value);
		return this;
	}
}

validator

在这里插入图片描述

/**
 * Copyright (c) 2016-2019 人人开源 All rights reserved.
 *
 * https://www.renren.io
 *
 * 版权所有,侵权必究!
 */

package com.huterox.common.validator.group;

/**
 * 新增数据 Group
 *
 * @author Mark [email protected]
 */
public interface AddGroup {
}

/**
 * Copyright (c) 2016-2019 人人开源 All rights reserved.
 *
 * https://www.renren.io
 *
 * 版权所有,侵权必究!
 */

package com.huterox.common.validator.group;

/**
 * 阿里云
 *
 * @author Mark [email protected]
 */
public interface AliyunGroup {
}

/**
 * Copyright (c) 2016-2019 人人开源 All rights reserved.
 *
 * https://www.renren.io
 *
 * 版权所有,侵权必究!
 */

package com.huterox.common.validator.group;

import javax.validation.GroupSequence;

/**
 * 定义校验顺序,如果AddGroup组失败,则UpdateGroup组不会再校验
 *
 * @author Mark [email protected]
 */
@GroupSequence({AddGroup.class, UpdateGroup.class})
public interface Group {

}

/**
 * Copyright (c) 2016-2019 人人开源 All rights reserved.
 *
 * https://www.renren.io
 *
 * 版权所有,侵权必究!
 */

package com.huterox.common.validator.group;

/**
 * 腾讯云
 *
 * @author Mark [email protected]
 */
public interface QcloudGroup {
}

/**
 * Copyright (c) 2016-2019 人人开源 All rights reserved.
 *
 * https://www.renren.io
 *
 * 版权所有,侵权必究!
 */

package com.huterox.common.validator.group;

/**
 * 七牛
 *
 * @author Mark [email protected]
 */
public interface QiniuGroup {
}

/**
 * Copyright (c) 2016-2019 人人开源 All rights reserved.
 *
 * https://www.renren.io
 *
 * 版权所有,侵权必究!
 */

package com.huterox.common.validator.group;

/**
 * 更新数据 Group
 *
 * @author Mark [email protected]
 */

public interface UpdateGroup {

}

xxs

在这里插入图片描述

/**
 * Copyright (c) 2016-2019 人人开源 All rights reserved.
 *
 * https://www.renren.io
 *
 * 版权所有,侵权必究!
 */

package com.huterox.common.xss;


import com.huterox.common.exception.RRException;
import org.apache.commons.lang.StringUtils;

/**
 * SQL过滤
 *
 * @author Mark [email protected]
 */
public class SQLFilter {

    /**
     * SQL注入过滤
     * @param str  待验证的字符串
     */
    public static String sqlInject(String str){
        if(StringUtils.isBlank(str)){
            return null;
        }
        //去掉'|"|;|字符
        str = StringUtils.replace(str, "'", "");
        str = StringUtils.replace(str, """, "");
        str = StringUtils.replace(str, ";", "");
        str = StringUtils.replace(str, "\", "");

        //转换成小写
        str = str.toLowerCase();

        //非法字符
        String[] keywords = {"master", "truncate", "insert", "select", "delete", "update", "declare", "alter", "drop"};

        //判断是否包含非法字符
        for(String keyword : keywords){
            if(str.indexOf(keyword) != -1){
                throw new RRException("包含非法字符");
            }
        }

        return str;
    }
}

测试

ok,那么基本上就好了,我们测试一波。

我们先配置一下
在这里插入图片描述
如果是你自己的单体项目也一样。

然后我在controller里面访问一个接口看看。
在这里插入图片描述

ok,正常

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>