从头开始开发一个java后端项目:7集成druid、代码生成插件

322 阅读4分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路

前言

我们在之前的文章中继承了knife4j,但是我们修改了关于mvc的配置,后期我们准备加上acator监控。这和我们的配置有冲突,我们先还原spring-boot-parent的版本号为2.5.7,以后的系列文章也基于该版本,等knife4j修复之后我们再更新版本。

druid集成

我们在上一篇文章juejin.cn/post/705825…集成了p6spy进行sql打印,但是我们不是每个人都能登录正式环境查看执行sql,且如果想要只查询sql的话往往需要翻很多页。我们集成阿里的druid来配置sql连接池和在线监控sql执行情况

添加pom依赖

在pom.xml的dependencies中添加依赖如下

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.2.8</version>
</dependency>

修改配置文件

在application.yml中修改spring的配置如下

spring:
  datasource:
    driver-class-name: com.p6spy.engine.spy.P6SpyDriver
    url: jdbc:p6spy:mysql://???:3306/xxx?useUnicode=true&characterEncoding=UTF-8&useSSL=false
    username: root
    password: supporter
    type: com.alibaba.druid.pool.DruidDataSource
    #   数据源其他配置
    druid:
      #     配置初始化大小、最小、最大线程数
      initialSize: 5
      minIdle: 5
      #     CPU核数+1,也可以大些但不要超过20,数据库加锁时连接过多性能下降
      maxActive: 20
      #     最大等待时间,内网:800,外网:1200(三次握手1s)
      maxWait: 60000
      timeBetweenEvictionRunsMillis: 60000
      #     配置一个连接在池中最大空间时间,单位是毫秒
      minEvictableIdleTimeMillis: 300000
      validationQuery: SELECT 1
      testWhileIdle: true
      #     设置从连接池获取连接时是否检查连接有效性,true检查,false不检查
      testOnBorrow: true
      #     设置从连接池归还连接时是否检查连接有效性,true检查,false不检查
      testOnReturn: true
      #     可以支持PSCache(提升写入、查询效率)
      poolPreparedStatements: true
      #   配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
      filters: stat,wall,slf4j
      #     保持长连接
      keepAlive: true
      maxPoolPreparedStatementPerConnectionSize: 20
      useGlobalDataSourceStat: true
      connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
      db-type: mysql
      stat-view-servlet: #配置监控页功能
        enabled: true  #默认开启,这里显示说明
        login-username: root #登录名
        login-password: supporter #登录密码
        reset-enable: false #禁用重置按钮
      web-stat-filter: #监控web
        enabled: true
        url-pattern: /* #监控所有
        exclusions: '*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*'  #放行
      filter:
        stat: #对上面filters里的stat的详细配置
          slow-sql-millis: 1000 #慢sql时间是毫秒单位的  执行时间1秒以上的为慢SQL
          log-slow-sql: true #日志记录
          enabled: true
        wall:
          enabled: true
          config:
            drop-table-allow: false #禁用删除表的SQL

验证

这里主要的配置项在注释里写的差不多了,我们现在可以直接重启项目,然后访问http://127.0.0.1:1001/druid/login.html输入配置里设置的账号,密码,即可登录进入管理页面。我们执行编写的test的add代码,然后刷新监控页面。即可看到刚才执行的sql

代码生成器集成

mybaits-plus官方提供了代码集成的依赖,我们集成一些减少自己的工作量

集成依赖

仍然在pom.xml的dependencies中添加依赖,如下所示

<!-- 代码生成 -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>3.5.1</version>
</dependency>
<!-- 代码生成的模板 -->
<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.30</version>
</dependency>

这里可以看到我们也引入了freemarker来作为模板生成代码

创建模板

我们再ressources下新建templates文件夹,新建如下文件

  • templates/controller.java
package ${package.Controller};
import io.swagger.annotations.Api;
import org.springframework.web.bind.annotation.RequestMapping;
<#if restControllerStyle>
import org.springframework.web.bind.annotation.RestController;
<#else>
import org.springframework.stereotype.Controller;
</#if>
<#if superControllerClassPackage??>
    import ${superControllerClassPackage};
</#if>

/**
* <p>
    * ${table.comment!} 前端控制器
    * </p>
*
* @author ${author}
* @since ${date}
*/
@Api(tags = "${table.controllerName}")
<#if restControllerStyle>
@RestController
<#else>
@Controller
</#if>
@RequestMapping("${table.entityPath}")
<#if kotlin>
class ${table.controllerName}<#if superControllerClass??> : ${superControllerClass}()</#if>
<#else>
<#if superControllerClass??>
public class ${table.controllerName} extends ${superControllerClass} {
<#else>
public class ${table.controllerName} {
</#if>
}
</#if>
  • templates/service.java
package ${package.Service};

import ${package.Entity}.${entity};
import ${superServiceClassPackage};
/**
* <p>
* ${table.comment!} 服务类
* </p>
*
* @author ${author}
* @since ${date}
*/
<#if kotlin>
    interface ${table.serviceName} : ${superServiceClass}<${entity}>
<#else>
public interface ${table.serviceName} extends ${superServiceClass}<${entity}> {
}
</#if>
  • templates/mapper.java
package ${package.Mapper};

import ${package.Entity}.${entity};
import ${superMapperClassPackage};
/**
* ${table.comment!} Mapper 接口
*
* @author ${author}
* @since ${date}
*/
<#if kotlin>
interface ${table.mapperName} : ${superMapperClass}<${entity}>
<#else>
public interface ${table.mapperName} extends ${superMapperClass}<${entity}> {

}
</#if>
  • templates/serviceImpl.java
package ${package.ServiceImpl};
import ${package.Entity}.${entity};
import ${package.Mapper}.${table.mapperName};
import ${package.Service}.${table.serviceName};
import ${superServiceImplClassPackage};
import org.springframework.stereotype.Service;

/**
* <p>
* ${table.comment!} 服务实现类
* </p>
*
* @author ${author}
* @since ${date}
*/
<#if kotlin>
open class ${table.serviceImplName} : ${superServiceImplClass}<${table.mapperName}, ${entity}>(), ${table.serviceName} {

}
<#else>
@Service
public class ${table.serviceImplName} extends ${superServiceImplClass}<${table.mapperName}, ${entity}> implements ${table.serviceName} {
}
</#if>

编写一个执行方法

public static void main(String[] args) {
    String moduleName = "demo";
    String tableName = "demo";
    String tablePrefix = "";
    FastAutoGenerator
            .create("jdbc:mysql://121.42.229.14:3306/back-end-boot?useSSL=false", "root", "supporter")
            .globalConfig(builder -> {
                builder.author("lmh")               //作者
                        .outputDir(System.getProperty("user.dir") + "\src\main\java")    //输出路径(写到java目录)
                        .enableSwagger()           //开启swagger
                        .fileOverride();            //开启覆盖之前生成的文件
            })
            .packageConfig(builder -> builder.parent("code.liang.top.admin.boot.modules")
                    .moduleName(moduleName)
                    .pathInfo(Collections.singletonMap(OutputFile.mapperXml, System.getProperty("user.dir") + "\src\main\resources\mapper")))
            .strategyConfig(builder -> {
                builder.enableCapitalMode()// 全局大写命名
                        .addTablePrefix(StringUtils.isBlank(tablePrefix) ? "" : tablePrefix)// 此处可以修改为自己的表前缀
                        .addInclude(tableName)// 需要生成的表
                        //此处向下为实体类builder
                        .entityBuilder()
                        .superClass(BaseEntity.class)// 自定义实体父类
                        .addSuperEntityColumns(
                                "id", "versionNo", "createId", "createName", "createTime",
                                "updateId", "updateName", "updateTime", "delFlag")// 自定义实体,公共字段
                        .enableLombok()//开启lombok模型
                        .enableRemoveIsPrefix()// Boolean类型字段是否移除is前缀处理
                        .enableChainModel()//开启链式模型
                        //此处向下为mapper builder
                        .mapperBuilder()
                        .superClass(BaseMapper.class)// 自定义 mapper 父类
                        //此处向下为service builder
                        .serviceBuilder()
                        .superServiceClass(IService.class)// 自定义 service 父类
                        .superServiceImplClass(ServiceImpl.class)// 自定义 service 实现类父类
                        .formatServiceFileName("I%sService")
                        .formatServiceImplFileName("%sServiceImpl")
                        .controllerBuilder()
                        .enableRestStyle()//开启生成@RestController控制器
                        .enableHyphenStyle();//开启驼峰转连字符;
            })
            .templateConfig(builder -> builder.mapperXml("")
                    .controller("templates/controller.java")
                    .service("templates/service.java")
                    .mapper("templates/mapper.java")
                    .serviceImpl("templates/serviceImpl.java"))
            .templateEngine(new FreemarkerTemplateEngine())
            .execute();
}

在数据库中复制一个表,我们先复制test表重命名为demo

验证代码生成

我们直接执行上边的代码,即可在modules下生成demo相关的代码

结语

本篇文章我们集成了druid在线sql监控和代码生成插件,现在我们集成完了mybatis-plus的大部分实用功能。下篇文章我们介绍一下后端的多环境配置和其他的监控工具。 本文所有代码已上传的gitee,欢迎有兴趣的掘友们startgitee.com/liangminghu…
欢迎关注我的掘金账号:juejin.cn/user/261290…
下期预告:后端多环境配置、actuator监控集成