新版Guns基于SpringBoot全面升级,完美整合springmvc + shiro + MyBatis 通用 Mapper + 分页插件 PageHelper + beetl!css
本项目 fork 自 stylefeng 的 Guns!html
通过对 Guns 项目的修改,使得该项目成为一个通用 Mapper 和 分页插件使用的示例。前端
项目引入了下面两个依赖:java
<dependency>
<groupId>tk.mybatis</groupId> <artifactId>mapper-spring-boot-starter</artifactId> <version>${mapper-starter.version}</version> </dependency> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>${pagehelper-starter.version}</version> </dependency>
彻底使用 MyBatis 官方的 Starter.mysql
一个最简单的 Spring Boot 集成项目:jquery
https://github.com/abel533/MyBatis-Spring-Bootlinux
本项目对 Guns 的改动为:git
com.stylefeng.guns.modular.system.dao
包中的全部DAO,将方法放到对应的Mapper接口中.关于二者的对比,能够经过 commit 信息查看。github
更多 MyBatis 相关工具能够访问: http://mybatis.tkweb
Guns目前支持三种启动方式:
clean package -Dmaven.test.skip=true
并从target目录中找到guns-1.0.0-SNAPSHOT.jar,并在jar包的目录下执行以下java命令
java -jar guns-1.0.0-SNAPSHOT.jar
<packaging>jar</packaging>
改成
<packaging>war</packaging>
并打包放入到tomcat中执行
最新版项目最低支持jdk1.7
├─main │ │ │ ├─java │ │ │ │ │ ├─com.stylefeng.guns----------------项目主代码 │ │ │ │ │ │ │ ├─common----------------项目公用的部分(业务中常常调用的类,例如常量,异常,实体,注解,分页类,节点类) │ │ │ │ │ │ │ ├─config----------------项目配置代码(例如mybtais-plus配置,ehcache配置等) │ │ │ │ │ │ │ ├─core----------------项目运行的核心依靠(例如aop日志记录,拦截器,监听器,guns模板引擎,shiro权限检查等) │ │ │ │ │ │ │ ├─modular----------------项目业务代码 │ │ │ │ │ │ │ ├─GunsApplication类----------------以main方法启动springboot的类 │ │ │ │ │ │ │ └─GunsServletInitializer类----------------用servlet容器启动springboot的核心类 │ │ │ │ │ └─generator----------------mybatis-plus Entity生成器 │ │ │ ├─resources----------------项目资源文件 │ │ │ │ │ ├─gunsTemplate----------------guns代码生成模板 │ │ │ │ │ ├─application.yml----------------springboot项目配置 │ │ │ │ │ └─ehcache.xml----------------ehcache缓存配置 │ │ │ └─webapp----------------web页面和静态资源存放的目录 │
注:SpringBoot项目默认不支持将静态资源和模板(web页面)放到webapp目录,可是我的感受resources目录只放项目的配置更加简洁,因此就将web页面继续放到webapp目录了.
Guns以简洁为核心,抛弃了传统的易错,臃肿xml配置,采用javabean的方式配置spring,简化了项目的配置,以下示例为配置mybatis-plus和数据源:
@Configuration @MapperScan(basePackages = {"com.stylefeng.guns.modular.*.dao", "com.stylefeng.guns.common.persistence.dao"}) public class MybatisPlusConfig { @Autowired DruidProperties druidProperties; /** * mybatis-plus分页插件 */ @Bean public PaginationInterceptor paginationInterceptor() { PaginationInterceptor paginationInterceptor = new PaginationInterceptor(); paginationInterceptor.setDialectType(DBType.MYSQL.getDb()); return paginationInterceptor; } /** * druid数据库链接池 */ @Bean(initMethod = "init") public DruidDataSource dataSource() { DruidDataSource dataSource = new DruidDataSource(); druidProperties.coinfig(dataSource); return dataSource; } }
日志记录采用aop(LogAop类)方式对全部包含@BussinessLog注解的方法进行aop切入,会记录下当前用户执行了哪些操做(即@BussinessLog value属性的内容),若是涉及到数据修改,会取当前http请求的全部requestParameters与LogObjectHolder类中缓存的Object对象的全部字段做比较(因此在编辑以前的获取详情接口中须要缓存被修改对象以前的字段信息),日志内容会异步存入数据库中(经过ScheduledThreadPoolExecutor类)。
例如,把主页拆分红三部分,每一个部分单独一个页面,更加便于维护
<!--左侧导航开始--> @include("/common/_tab.html"){} <!--左侧导航结束--> <!--右侧部分开始--> @include("/common/_right.html"){} <!--右侧部分结束--> <!--右侧边栏开始--> @include("/common/_theme.html"){} <!--右侧边栏结束-->
以及对重复的html进行包装,使前端页面更加专一于业务实现,例如,把全部页面引用包进行提取
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="renderer" content="webkit" /><!-- 让360浏览器默认选择webkit内核 --> <!-- 全局css --> <link rel="shortcut icon" href="${ctxPath}/static/favicon.ico"> <!-- 全局js --> <script src="${ctxPath}/static/js/jquery.min.js?v=2.1.4"></script> <body class="gray-bg"> <div class="wrapper wrapper-content animated fadeInRight"> ${layoutContent} </div> <script src="${ctxPath}/static/js/content.js?v=1.0.0"></script> </body> </html>
开发页面时,只需编写以下代码便可
@layout("/common/_container.html"){ <div class="row"> <div class="col-sm-12"> <div class="ibox float-e-margins"> <div class="ibox-title"> <h5>部门管理</h5> </div> <div class="ibox-content"> //自定义内容 </div> </div> </div> </div> <script src="${ctxPath}/static/modular/system/dept/dept.js"></script> @}
以上beetl的用法请参考beetl说明文档。
在webapp/static/js/common目录中,有对经常使用js代码的封装,例如Feng.js,其中Feng.info(),Feng.success(),Feng.error()三个方法,分别封装了普通提示,成功提示,错误提示的代码,简化了layer提示层插件的使用。
guns对web-upload进行二次封装,让图片的上传功能呢只用2行代码便可实现,以下
var avatarUp = new $WebUpload("avatar"); avatarUp.init();
具体实现请参考static/js/common/web-upload-object.js
map+warpper方式即为把controller层的返回结果使用BeanKit工具类把原有bean转化为Map的的形式(或者原有bean直接是map的形式),再用单独写的一个包装类再包装一次这个map,使里面的参数更加具体,更加有含义,下面举一个例子,例如,在返回给前台一个性别时,数据库查出来1是男2是女,假如直接返回给前台,那么前台显示的时候还须要增长一次判断,而且先后端分离开发时又增长了一次交流和文档的成本,可是采用warpper包装的形式,能够直接把返回结果包装一下,例如动态增长一个字段sexName直接返回给前台性别的中文名称便可。
Guns的数据范围控制是指,对拥有相同角色的用户,根据部门的不一样进行相应的数据筛选,若是部门不相同,那么有可能展现出的具体数据是不一致的.因此说Guns对数据范围控制是以部门id为单位来标识的,如何增长数据范围拦截呢?只需在相关的mapper接口的参数中增长一个DataScope对象便可,DataScope中有两个字段,scopeName用来标识sql语句中部门id的字段名称,例如deptiid或者id,另外一个字段deptIds就是具体须要过滤的部门id的集合.拦截器原理以下:拦截mapper中包含DataScope对象的方法,获取其原始sql,并作一个包装限制部门id在deptIds范围内的数据进行展现.
swagger会管理全部包含@ApiOperation注解的控制器方法,同时,可利用@ApiImplicitParams注解标记接口中的参数,具体用法请参考CodeController类中的用法。
@ApiOperation("生成代码") @ApiImplicitParams({ @ApiImplicitParam(name = "moduleName", value = "模块名称", required = true, dataType = "String"), @ApiImplicitParam(name = "bizChName", value = "业务名称", required = true, dataType = "String"), @ApiImplicitParam(name = "bizEnName", value = "业务英文名称", required = true, dataType = "String"), @ApiImplicitParam(name = "path", value = "项目生成类路径", required = true, dataType = "String") }) @RequestMapping(value = "/generate", method = RequestMethod.POST)