构建spring boot web项目:四、集成Mybatis-plus

目录

一、Mysql数据库安装

二、创建Mysql功能模块

三、创建映射模型模块(domain)

四、修改pom.xml

五、配置mybatis-plus

六、管理应用模块(management)整合mybatis-plus

七、自定义springfox swagger对spring Pageable的支持

一、Mysql数据库安装

参考:docker中安装MySQL、Nacos_docker安装nacos mysql-CSDN博客

二、创建Mysql功能模块

三、创建映射模型模块(domain)

 

四、修改pom.xml

修改pom.xml(mysql)

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.lyj.initMode</groupId>
        <artifactId>initMode-function</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>initMode-function-mysql</artifactId>

    <description>mysql存储功能模块</description>

    <dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
        </dependency>
    </dependencies>

</project>

修改pom.xml(function)

    <modules>
        <module>mysql</module>
    </modules>

        <dependency>
            <groupId>com.lyj.initMode</groupId>
            <artifactId>initMode-common-domain</artifactId>
        </dependency>

修改pom.xml(initMode)


        <!--mybatis-plus版本-->
        <mybatis-plus.version>3.4.2</mybatis-plus.version>

            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>${mybatis-plus.version}</version>
            </dependency>
            <dependency>
                <groupId>com.lyj.initMode</groupId>
                <artifactId>initMode-common-domain</artifactId>
                <version>${project.version}</version>
            </dependency>

 修改pom.xml(base) 引入分页对象依赖,


        <!--数据库持久化 例如分页使用-->
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-commons</artifactId>
        </dependency>

 修改pom.xml(common)

<module>domain</module>

五、配置mybatis-plus

编辑配置类DatabaseConfig.java(mysql)

package com.lyj.function.mysql.config;

import com.lyj.common.base.enums.ErrorCodeEnum;
import com.lyj.common.base.util.BizExceptionUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DriverManagerDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

/**
 * mybatis-plus配置类
 */
@Configuration
@EntityScan(basePackages = {"com.lyj.**.entity"})
@Slf4j
public class DatabaseConfig {
    @Value("${spring.datasource.url}")
    private String dataSourceUrl;

    @Value("${spring.datasource.username}")
    private String dataSourceUsername;

    @Value("${spring.datasource.password}")
    private String dataSourcePassword;

    @Value("${spring.datasource.driver-class-name}")
    private String dataSourceDriverClassName;

    @Bean
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setUrl(dataSourceUrl);
        dataSource.setUsername(dataSourceUsername);
        dataSource.setPassword(dataSourcePassword);
        dataSource.setDriverClassName(dataSourceDriverClassName);
        testConnection(dataSource); // 调用检查连接方法
        return dataSource;
    }

    private void testConnection(DataSource dataSource) {
        try (Connection connection = dataSource.getConnection()) {
            log.info("数据库连接正常!");
        } catch (SQLException e) {
            // 连接异常处理
            //e.printStackTrace();
            log.error(ErrorCodeEnum.DATA_CONNECT_ERROR.getMessage());
            BizExceptionUtil.bizException(ErrorCodeEnum.DATA_CONNECT_ERROR);
        }
    }
}

六、管理应用模块(management)整合mybatis-plus

引入mysql模块

修改pom.xml(initMode)


            <dependency>
                <groupId>com.lyj.initMode</groupId>
                <artifactId>initMode-function-mysql</artifactId>
                <version>${project.version}</version>
            </dependency>

修改pom.xml(management)

    <dependencies>
        <dependency>
            <groupId>com.lyj.initMode</groupId>
            <artifactId>initMode-function-mysql</artifactId>
        </dependency>
    </dependencies>

 配置application.yml(management)

spring:
  datasource:
    url: jdbc:mysql://192.168.163.158:3306/init?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=UTC
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver

logging: #日志系统logback配置
  file:
    path: ./ #设置logback日志输出位置 ./代表当前项目下
  level:
    com.lyj.service.dao: debug #调整dao层的日志输出级别 在控制台和日志文件中输出sql日志

 在启动类上加 @MapperScan("com.lyj.function.mysql.dao")

启动测试

 七、添加EasyCode插件,生成基础代码

导入生成模板

EasyCodeConfig.json

{
  "author" : "lyj",
  "version" : "1.2.8",
  "userSecure" : "",
  "currTypeMapperGroupName" : "Default",
  "currTemplateGroupName" : "MyEasyCode",
  "currColumnConfigGroupName" : "Default",
  "currGlobalConfigGroupName" : "Default",
  "typeMapper" : {
    "Default" : {
      "name" : "Default",
      "elementList" : [ {
        "matchType" : "REGEX",
        "columnType" : "varchar(\\(\\d+\\))?",
        "javaType" : "java.lang.String"
      }, {
        "matchType" : "REGEX",
        "columnType" : "char(\\(\\d+\\))?",
        "javaType" : "java.lang.String"
      }, {
        "matchType" : "REGEX",
        "columnType" : "(tiny|medium|long)*text",
        "javaType" : "java.lang.String"
      }, {
        "matchType" : "REGEX",
        "columnType" : "decimal(\\(\\d+,\\d+\\))?",
        "javaType" : "java.lang.Double"
      }, {
        "matchType" : "ORDINARY",
        "columnType" : "integer",
        "javaType" : "java.lang.Integer"
      }, {
        "matchType" : "REGEX",
        "columnType" : "(tiny|small|medium)*int(\\(\\d+\\))?",
        "javaType" : "java.lang.Integer"
      }, {
        "matchType" : "ORDINARY",
        "columnType" : "int4",
        "javaType" : "java.lang.Integer"
      }, {
        "matchType" : "ORDINARY",
        "columnType" : "int8",
        "javaType" : "java.lang.Long"
      }, {
        "matchType" : "REGEX",
        "columnType" : "bigint(\\(\\d+\\))?",
        "javaType" : "java.lang.Long"
      }, {
        "matchType" : "ORDINARY",
        "columnType" : "date",
        "javaType" : "java.time.LocalDate"
      }, {
        "matchType" : "ORDINARY",
        "columnType" : "datetime",
        "javaType" : "java.time.LocalDateTime"
      }, {
        "matchType" : "ORDINARY",
        "columnType" : "timestamp",
        "javaType" : "java.time.LocalDateTime"
      }, {
        "matchType" : "ORDINARY",
        "columnType" : "time",
        "javaType" : "java.time.LocalTime"
      }, {
        "matchType" : "ORDINARY",
        "columnType" : "boolean",
        "javaType" : "java.lang.Boolean"
      }, {
        "matchType" : "ORDINARY",
        "columnType" : "bigint unsigned",
        "javaType" : "java.lang.Long"
      }, {
        "matchType" : "ORDINARY",
        "columnType" : "tinyint unsigned",
        "javaType" : "java.lang.String"
      } ]
    }
  },
  "template" : {
    "MyEasyCode" : {
      "name" : "MyEasyCode",
      "elementList" : [ {
        "name" : "api.java.vm",
        "code" : "##导入宏定义\n$!{define.vm}\n\n##设置表后缀(宏定义)\n#setTableSuffix(\"Api\")\n\n##保存文件(宏定义)\n#save(\"/api/$!{tool.firstLowerCase($tableInfo.name)}\", \"Api.java\")\n\n##包路径(宏定义)\n#setPackageSuffix(\"api.$!{tool.firstLowerCase($tableInfo.name)}\")\n\n##定义服务名\n#set($serviceName = $!tool.append($!tool.firstLowerCase($!tableInfo.name), \"Service\"))\n\n##定义实体对象名\n#set($entityName = $!tool.firstLowerCase($!tableInfo.name))\n\nimport com.lyj.common.base.common.R;\nimport $!{tableInfo.savePackageName}.service.$!{tool.firstLowerCase($tableInfo.name)}.$!{tableInfo.name}Service;\nimport com.lyj.common.domain.$!{tool.firstLowerCase($tableInfo.name)}.dto.$!{tableInfo.name}DTO;\nimport com.lyj.common.domain.$!{tool.firstLowerCase($tableInfo.name)}.vo.$!{tableInfo.name}VO;\nimport org.springframework.data.domain.Pageable;\nimport org.springframework.data.domain.Page;\nimport org.springframework.web.bind.annotation.*;\nimport lombok.AllArgsConstructor;\nimport io.swagger.annotations.Api;\nimport io.swagger.annotations.ApiImplicitParam;\nimport io.swagger.annotations.ApiImplicitParams;\nimport io.swagger.annotations.ApiOperation;\n\nimport java.util.List;\n\n##表注释(宏定义)\n#tableComment(\"表控制层\")\n\n@Api(tags = \"$!{tableInfo.comment}API\")\n@AllArgsConstructor\n@RestController\n@RequestMapping(\"/api/$!tool.firstLowerCase($!tableInfo.name)\")\npublic class $!{tableName} {\n\t\n    private $!{tableInfo.name}Service $!{serviceName};\n\n    /**\n     * 分页查询所有数据\n     *\n     * @param pageable 分页对象\n     * @param $!{entityName}Dto 查询实体\n     * @return 所有数据\n     */\n    @GetMapping(\"/page\")\n    @ApiOperation(\"列表\")\n    public R<Page<$!{tableInfo.name}VO>> selectAll(Pageable pageable, $!{tableInfo.name}DTO $!{entityName}Dto) {\n        return R.ok(null);\n    }\n\n    /**\n     * 通过主键查询单条数据\n     *\n     * @param id 主键\n     * @return 单条数据\n     */\n    @GetMapping(\"/getById\")\n    @ApiOperation(\"单条查询\")\n    @ApiImplicitParams({\n            @ApiImplicitParam(name = \"id\", value = \"主键id\", required = true)\n    })\n    public R<$!{tableInfo.name}VO> selectOne(Long id) {\n        return R.ok(null);\n    }\n\n    /**\n     * 新增数据\n     *\n     * @param $!{entityName}Dto 实体对象\n     * @return 新增结果\n     */\n    @PostMapping(\"/insert\")\n    @ApiOperation(\"新增\")\n    public R<Boolean> insert(@RequestBody $!{tableInfo.name}DTO $!{entityName}Dto) {\n        return R.ok(true);\n    }\n\n    /**\n     * 修改数据\n     *\n     * @param $!{entityName}Dto 实体对象\n     * @return 修改结果\n     */\n    @PutMapping(\"/update\")\n    @ApiOperation(\"修改\")\n    public R<Boolean> update(@RequestBody $!{tableInfo.name}DTO $!{entityName}Dto) {\n        return R.ok(true);\n    }\n\n    /**\n     * 删除数据\n     *\n     * @param idList 主键结合\n     * @return 删除结果\n     */\n    @DeleteMapping(\"/delete\")\n    @ApiOperation(\"删除\")\n    public R<Boolean> delete(@RequestParam(\"idList\") List<Long> idList) {\n        return R.ok(true);\n    }\n}\n"
      }, {
        "name" : "entity.java.vm",
        "code" : "##导入宏定义\n$!{define.vm}\n\n##保存文件(宏定义)\n#save(\"/$!{tool.firstLowerCase($tableInfo.name)}/entity\", \".java\")\n\n##包路径(宏定义)\n#setPackageSuffix(\"$!{tool.firstLowerCase($tableInfo.name)}.entity\")\n\n##自动导入包(全局变量)\n$!{autoImport.vm}\nimport java.io.Serializable;\n\nimport com.baomidou.mybatisplus.annotation.*;\nimport lombok.AllArgsConstructor;\nimport lombok.Data;\nimport lombok.NoArgsConstructor;\n\n\n/**\n * $!{tableInfo.comment}($!{tableInfo.name})表实体类\n *\n * @author $!author\n * @since $!time.currTime()\n */\n@Data\n@NoArgsConstructor //无参构造\n@AllArgsConstructor //有参构造\n@TableName(\"$tableInfo.obj.name\")\npublic class $!{tableInfo.name} implements Serializable {\n \n    private static final long serialVersionUID = 1L; \n    /**\n    * 自增 => @TableId(type = IdType.AUTO)\n    */\n#foreach($column in $tableInfo.pkColumn)\n    #if(${column.comment})\n    /**\n    * $!{column.comment}\n    */\n    #end\n    @TableId(type = IdType.AUTO)\n    private $!{tool.getClsNameByFullName($column.type)} $!{column.name};\n#end\n\n#foreach($column in $tableInfo.otherColumn)\n    #if(${column.comment})\n    /**\n    * ${column.comment}\n    */\n    #end\n    @TableField(\"$!{column.obj.name}\")\n    private $!{tool.getClsNameByFullName($column.type)} $!{column.name};\n\n#end\n}"
      }, {
        "name" : "dto.java.vm",
        "code" : "##导入宏定义\n$!{define.vm}\n\n##设置表后缀(宏定义)\n#setTableSuffix(\"DTO\")\n\n##保存文件(宏定义)\n#save(\"/$!{tool.firstLowerCase($tableInfo.name)}/dto\", \"DTO.java\")\n\n##包路径(宏定义)\n#setPackageSuffix(\"$!{tool.firstLowerCase($tableInfo.name)}.dto\")\n\n##自动导入包(全局变量)\n$!{autoImport.vm}\nimport lombok.Data;\nimport java.io.Serializable;\nimport io.swagger.annotations.ApiModel;\nimport io.swagger.annotations.ApiModelProperty;\n\n/**\n * $!{tableInfo.comment}($!{tableInfo.name})表DTO层\n *\n * @author $!author\n * @since $!time.currTime()\n */\n@Data\n@ApiModel(\"$!{tableInfo.comment}查询入参\")\npublic class $!{tableInfo.name}DTO implements Serializable {\n \n    private static final long serialVersionUID = 1L; \n#foreach($column in $tableInfo.fullColumn)\n    #if(${column.comment})\n    /**\n    *${column.comment}\n    */#end\n    @ApiModelProperty(value = \"${column.comment}\")\n    private $!{tool.getClsNameByFullName($column.type)} $!{column.name};\n    \n    #end\n}"
      }, {
        "name" : "vo.java.vm",
        "code" : "##导入宏定义\n$!{define.vm}\n##设置表后缀(宏定义)\n#setTableSuffix(\"VO\")\n\n##保存文件(宏定义)\n#save(\"/$!{tool.firstLowerCase($tableInfo.name)}/vo\", \"VO.java\")\n\n##包路径(宏定义)\n#setPackageSuffix(\"$!{tool.firstLowerCase($tableInfo.name)}.vo\")\n\n##自动导入包(全局变量)\n$!{autoImport.vm}\nimport lombok.Data;\nimport lombok.experimental.Accessors;\nimport java.io.Serializable;\nimport io.swagger.annotations.ApiModel;\nimport io.swagger.annotations.ApiModelProperty;\n\n/**\n * $!{tableInfo.comment}($!{tableInfo.name})表VO层\n *\n * @author $!author\n * @since $!time.currTime()\n */\n@Data\n@Accessors(chain = true) //不写默认为false,当该值为 true 时,对应字段的 getter 方法前面就没有 get,setter 方法就不会有 set。\n@ApiModel(\"$!{tableInfo.comment}VO\")\npublic class $!{tableInfo.name}VO implements Serializable {\n \n    private static final long serialVersionUID = 1L; \n#foreach($column in $tableInfo.fullColumn)\n    #if(${column.comment})\n    /**\n    *${column.comment}\n    */#end\n    @ApiModelProperty(value = \"${column.comment}\")\n    private $!{tool.getClsNameByFullName($column.type)} $!{column.name};\n\n#end\n}"
      }, {
        "name" : "dao.java.vm",
        "code" : "##导入宏定义\n$!{define.vm}\n\n##设置表后缀(宏定义)\n#setTableSuffix(\"Mapper\")\n\n##保存文件(宏定义)\n#save(\"/dao/$!{tool.firstLowerCase($tableInfo.name)}\", \"Mapper.java\")\n\n##包路径(宏定义)\n#setPackageSuffix(\"dao.$!{tool.firstLowerCase($tableInfo.name)}\")\n\nimport com.baomidou.mybatisplus.core.mapper.BaseMapper;\nimport com.lyj.common.domain.$!{tool.firstLowerCase($tableInfo.name)}.entity.$!tableInfo.name;\nimport org.apache.ibatis.annotations.Mapper;\n\n##表注释(宏定义)\n#tableComment(\"表数据库访问层\")\n@Mapper\npublic interface $!{tableName} extends BaseMapper<$!tableInfo.name> {\n\n}\n"
      }, {
        "name" : "service.java.vm",
        "code" : "##导入宏定义\n$!{define.vm}\n\n##设置表后缀(宏定义)\n#setTableSuffix(\"Service\")\n\n##保存文件(宏定义)\n#save(\"/service/$!{tool.firstLowerCase($tableInfo.name)}\", \"Service.java\")\n\n##包路径(宏定义)\n#setPackageSuffix(\"service.$!{tool.firstLowerCase($tableInfo.name)}\")\n\nimport com.baomidou.mybatisplus.extension.service.IService;\nimport com.lyj.common.domain.$!{tool.firstLowerCase($tableInfo.name)}.entity.$!tableInfo.name;\n\n##表注释(宏定义)\n#tableComment(\"表服务接口\")\npublic interface $!{tableName} extends IService<$!tableInfo.name> {\n\n}\n"
      }, {
        "name" : "serviceImpl.java.vm",
        "code" : "##导入宏定义\n$!{define.vm}\n\n##设置表后缀(宏定义)\n#setTableSuffix(\"ServiceImpl\")\n\n##保存文件(宏定义)\n#save(\"/service/$!{tool.firstLowerCase($tableInfo.name)}/impl\", \"ServiceImpl.java\")\n\n##包路径(宏定义)\n#setPackageSuffix(\"service.$!{tool.firstLowerCase($tableInfo.name)}.impl\")\n\nimport com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;\nimport com.lyj.function.mysql.dao.$!{tool.firstLowerCase($tableInfo.name)}.$!{tableInfo.name}Mapper;\nimport com.lyj.common.domain.$!{tool.firstLowerCase($tableInfo.name)}.entity.$!{tableInfo.name};\nimport $!{tableInfo.savePackageName}.service.$!{tool.firstLowerCase($tableInfo.name)}.$!{tableInfo.name}Service;\nimport org.springframework.stereotype.Service;\nimport lombok.AllArgsConstructor;\nimport lombok.extern.slf4j.Slf4j;\n\n##表注释(宏定义)\n#tableComment(\"表服务实现类\")\n@Service\n@Slf4j\n@AllArgsConstructor\npublic class $!{tableName} extends ServiceImpl<$!{tableInfo.name}Mapper, $!{tableInfo.name}> implements $!{tableInfo.name}Service {\n    private $!{tableInfo.name}Mapper $!{tool.firstLowerCase($tableInfo.name)}Mapper;\n}\n"
      }, {
        "name" : "mapper.xml.vm",
        "code" : "##引入mybatis支持\n$!{mybatisSupport.vm}\n\n##设置保存名称与保存位置\n$!callback.setFileName($tool.append($!{tableInfo.name}, \"Mapper.xml\"))\n$!callback.setSavePath($tool.append($modulePath, \"/src/main/resources/mapper/$!{tool.firstLowerCase($tableInfo.name)}/\"))\n\n##拿到主键\n#if(!$tableInfo.pkColumn.isEmpty())\n    #set($pk = $tableInfo.pkColumn.get(0))\n#end\n\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">\n<mapper namespace=\"$!{tableInfo.savePackageName}.dao.$!{tool.firstLowerCase($tableInfo.name)}.$!{tableInfo.name}Mapper\">\n\n    <resultMap type=\"com.lyj.common.domain.$!{tool.firstLowerCase($tableInfo.name)}.entity.$!tableInfo.name\" id=\"$!{tableInfo.name}Map\">\n#foreach($column in $tableInfo.fullColumn)\n        <result property=\"$!column.name\" column=\"$!column.obj.name\" jdbcType=\"$!column.ext.jdbcType\"/>\n#end\n    </resultMap>\n\n    \n\n</mapper>\n"
      } ]
    }
  },
  "columnConfig" : {
    "Default" : {
      "name" : "Default",
      "elementList" : [ {
        "title" : "disable",
        "type" : "BOOLEAN",
        "selectValue" : ""
      }, {
        "title" : "support",
        "type" : "SELECT",
        "selectValue" : "add,edit,query,del,ui"
      } ]
    }
  },
  "globalConfig" : {
    "Default" : {
      "name" : "Default",
      "elementList" : [ {
        "name" : "autoImport.vm",
        "value" : "##自动导入包(仅导入实体属性需要的包,通常用于实体类)\n#foreach($import in $importList)\nimport $!import;\n#end"
      }, {
        "name" : "define.vm",
        "value" : "##(Velocity宏定义)\n\n##定义设置表名后缀的宏定义,调用方式:#setTableSuffix(\"Test\")\n#macro(setTableSuffix $suffix)\n    #set($tableName = $!tool.append($tableInfo.name, $suffix))\n#end\n\n##定义设置包名后缀的宏定义,调用方式:#setPackageSuffix(\"Test\")\n#macro(setPackageSuffix $suffix)\n#if($suffix!=\"\")package #end#if($tableInfo.savePackageName!=\"\")$!{tableInfo.savePackageName}.#{end}$!suffix;\n#end\n\n##定义直接保存路径与文件名简化的宏定义,调用方式:#save(\"/entity\", \".java\")\n#macro(save $path $fileName)\n    $!callback.setSavePath($tool.append($tableInfo.savePath, $path))\n    $!callback.setFileName($tool.append($tableInfo.name, $fileName))\n#end\n\n##定义表注释的宏定义,调用方式:#tableComment(\"注释信息\")\n#macro(tableComment $desc)\n/**\n * $!{tableInfo.comment}($!{tableInfo.name})$desc\n *\n * @author $!author\n * @since $!time.currTime()\n */\n#end\n\n##定义GET,SET方法的宏定义,调用方式:#getSetMethod($column)\n#macro(getSetMethod $column)\n\n    public $!{tool.getClsNameByFullName($column.type)} get$!{tool.firstUpperCase($column.name)}() {\n        return $!{column.name};\n    }\n\n    public void set$!{tool.firstUpperCase($column.name)}($!{tool.getClsNameByFullName($column.type)} $!{column.name}) {\n        this.$!{column.name} = $!{column.name};\n    }\n#end"
      }, {
        "name" : "init.vm",
        "value" : "##初始化区域\n\n##去掉表的t_前缀\n$!tableInfo.setName($tool.getClassName($tableInfo.obj.name.replaceFirst(\"book_\",\"\")))\n\n##参考阿里巴巴开发手册,POJO 类中布尔类型的变量,都不要加 is 前缀,否则部分框架解析会引起序列化错误\n#foreach($column in $tableInfo.fullColumn)\n#if($column.name.startsWith(\"is\") && $column.type.equals(\"java.lang.Boolean\"))\n    $!column.setName($tool.firstLowerCase($column.name.substring(2)))\n#end\n#end\n\n##实现动态排除列\n#set($temp = $tool.newHashSet(\"testCreateTime\", \"otherColumn\"))\n#foreach($item in $temp)\n    #set($newList = $tool.newArrayList())\n    #foreach($column in $tableInfo.fullColumn)\n        #if($column.name!=$item)\n            ##带有反回值的方法调用时使用$tool.call来消除返回值\n            $tool.call($newList.add($column))\n        #end\n    #end\n    ##重新保存\n    $tableInfo.setFullColumn($newList)\n#end\n\n##对importList进行篡改\n#set($temp = $tool.newHashSet())\n#foreach($column in $tableInfo.fullColumn)\n    #if(!$column.type.startsWith(\"java.lang.\"))\n        ##带有反回值的方法调用时使用$tool.call来消除返回值\n        $tool.call($temp.add($column.type))\n    #end\n#end\n##覆盖\n#set($importList = $temp)"
      }, {
        "name" : "mybatisSupport.vm",
        "value" : "##针对Mybatis 进行支持,主要用于生成xml文件\n#foreach($column in $tableInfo.fullColumn)\n    ##储存列类型\n    $tool.call($column.ext.put(\"sqlType\", $tool.getField($column.obj.dataType, \"typeName\")))\n    #if($tool.newHashSet(\"java.lang.String\").contains($column.type))\n        #set($jdbcType=\"VARCHAR\")\n    #elseif($tool.newHashSet(\"java.lang.Boolean\", \"boolean\").contains($column.type))\n        #set($jdbcType=\"BOOLEAN\")\n    #elseif($tool.newHashSet(\"java.lang.Byte\", \"byte\").contains($column.type))\n        #set($jdbcType=\"BYTE\")\n    #elseif($tool.newHashSet(\"java.lang.Integer\", \"int\", \"java.lang.Short\", \"short\").contains($column.type))\n        #set($jdbcType=\"INTEGER\")\n    #elseif($tool.newHashSet(\"java.lang.Long\", \"long\").contains($column.type))\n        #set($jdbcType=\"INTEGER\")\n    #elseif($tool.newHashSet(\"java.lang.Float\", \"float\", \"java.lang.Double\", \"double\").contains($column.type))\n        #set($jdbcType=\"NUMERIC\")\n    #elseif($tool.newHashSet(\"java.util.Date\", \"java.sql.Timestamp\", \"java.time.Instant\", \"java.time.LocalDateTime\", \"java.time.OffsetDateTime\", \"\tjava.time.ZonedDateTime\").contains($column.type))\n        #set($jdbcType=\"TIMESTAMP\")\n    #elseif($tool.newHashSet(\"java.sql.Date\", \"java.time.LocalDate\").contains($column.type))\n        #set($jdbcType=\"TIMESTAMP\")\n    #else\n        ##其他类型\n        #set($jdbcType=\"VARCHAR\")\n    #end\n    $tool.call($column.ext.put(\"jdbcType\", $jdbcType))\n#end\n\n##定义宏,查询所有列\n#macro(allSqlColumn)#foreach($column in $tableInfo.fullColumn)$column.obj.name#if($velocityHasNext), #end#end#end\n"
      } ]
    }
  }
}

创建用户、部门表

-- init.sys_dept definition

CREATE TABLE `sys_dept` (
  `id` bigint unsigned NOT NULL AUTO_INCREMENT,
  `dept_name` varchar(255) DEFAULT NULL COMMENT '部门名称',
  `parent_dept_id` bigint unsigned DEFAULT NULL COMMENT '上级部门id',
  `dept_show_name` varchar(255) DEFAULT NULL COMMENT '部门展示名称',
  `show_flag` tinyint DEFAULT '1' COMMENT '是否展示',
  `efficient` tinyint DEFAULT NULL COMMENT '0-有效,1-失效(注销),2 - 暂时冻结',
  `sort` int DEFAULT NULL COMMENT '排序',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=4807 DEFAULT CHARSET=utf8mb3 COMMENT='系统部门表';


-- init.sys_user definition

CREATE TABLE `sys_user` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键Id',
  `account` varchar(128) DEFAULT NULL COMMENT '账号',
  `name` varchar(128) DEFAULT NULL COMMENT '用户姓名',
  `nickname` varchar(128) DEFAULT NULL COMMENT '用户昵称',
  `password` varchar(128) DEFAULT NULL COMMENT '用户密码 (同步数据时 设置初始密码)',
  `salt` varchar(20) DEFAULT NULL COMMENT '盐',
  `email` varchar(128) DEFAULT NULL COMMENT '用户邮箱',
  `phone` varchar(128) DEFAULT NULL COMMENT '手机号码',
  `work_phone` varchar(128) DEFAULT NULL COMMENT '办公手机号',
  `role_id` bigint unsigned DEFAULT NULL COMMENT '角色id',
  `dept_id` varchar(128) DEFAULT NULL COMMENT '部门id',
  `status` tinyint DEFAULT '0' COMMENT '账号状态  0:有效 1:失效',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  `delete_flag` tinyint unsigned DEFAULT '0' COMMENT '是否删除',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1586928776831629436 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC COMMENT='管理端用户表';


-- init.sys_user_dept definition

CREATE TABLE `sys_user_dept` (
  `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '主键id',
  `user_id` bigint DEFAULT NULL COMMENT '用户id',
  `dept_id` bigint DEFAULT NULL COMMENT '部门id',
  `dept_name` varchar(255) DEFAULT NULL COMMENT '部门名称',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7253 DEFAULT CHARSET=utf8mb3 COMMENT='系统人员部门关联表';

INSERT INTO init.sys_user
(id, account, name, nickname, password, salt, email, phone, work_phone, role_id, dept_id, status, create_time, update_time, delete_flag)
VALUES(1, 'admin', '默认管理员', '默认管理员', 'b92cb1cbffcebd1f0d43521efcb93b7fda8491fa6a09c6665168899de44b28a171d0f4111643d0ca9534a1c27db45d77fa7980afdebbbf1ea8ec5664f475aa82', 'abcdefg1234567', 'qinfengfei@dimpt.com', '16638168614', '331366', 1, NULL, 0, '2021-12-31 00:00:00', '2024-06-28 07:42:53', 0);


INSERT INTO init.sys_dept
(id, dept_name, parent_dept_id, dept_show_name, show_flag, efficient, sort, create_time, update_time)
VALUES(1, '中国', NULL, '中华人民共和国', 1, 0, 1, '2024-06-27 08:45:36', '2024-06-27 08:45:36');


INSERT INTO init.sys_user_dept
(id, user_id, dept_id, dept_name)
VALUES(1, 1, 1, '中华人民共和国');

连接数据库

生成entity、DTO、VO

 生成dao.java、mapp.xml

生成api、service、serviceImpl

修改SysDeptApi.java

package com.lyj.service.management.api.sysDept;


import cn.hutool.core.bean.BeanUtil;
import com.lyj.common.base.common.R;
import com.lyj.service.management.service.sysDept.SysDeptService;
import com.lyj.common.domain.sysDept.dto.SysDeptDTO;
import com.lyj.common.domain.sysDept.vo.SysDeptVO;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;
import lombok.AllArgsConstructor;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

import java.util.List;

/**
 * 系统部门表(SysDept)表控制层
 *
 * @author lyj
 * @since 2024-07-02 20:09:45
 */

@Api(tags = "系统部门表API")
@AllArgsConstructor
@RestController
@RequestMapping("/api/sysDept")
public class SysDeptApi {

    private SysDeptService sysDeptService;

    /**
     * 分页查询所有数据
     *
     * @param pageable   分页对象
     * @param sysDeptDto 查询实体
     * @return 所有数据
     */
    @GetMapping("/page")
    @ApiOperation("列表")
    public R<Page<SysDeptVO>> selectAll(Pageable pageable, SysDeptDTO sysDeptDto) {
        return R.ok(null);
    }

    /**
     * 通过主键查询单条数据
     *
     * @param id 主键
     * @return 单条数据
     */
    @GetMapping("/getById")
    @ApiOperation("单条查询")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "主键id", required = true)
    })
    public R<SysDeptVO> selectOne(Long id) {
        return R.ok(BeanUtil.toBean(sysDeptService.getById(id),SysDeptVO.class));
    }

    /**
     * 新增数据
     *
     * @param sysDeptDto 实体对象
     * @return 新增结果
     */
    @PostMapping("/insert")
    @ApiOperation("新增")
    public R<Boolean> insert(@RequestBody SysDeptDTO sysDeptDto) {
        return R.ok(true);
    }

    /**
     * 修改数据
     *
     * @param sysDeptDto 实体对象
     * @return 修改结果
     */
    @PutMapping("/update")
    @ApiOperation("修改")
    public R<Boolean> update(@RequestBody SysDeptDTO sysDeptDto) {
        return R.ok(true);
    }

    /**
     * 删除数据
     *
     * @param idList 主键结合
     * @return 删除结果
     */
    @DeleteMapping("/delete")
    @ApiOperation("删除")
    public R<Boolean> delete(@RequestParam("idList") List<Long> idList) {
        return R.ok(true);
    }
}

启动测试

七、自定义springfox swagger对spring Pageable的支持

修改前

Pageable入参说明展示不友好

引入依赖(base)

        <!--工具类 为集合,缓存,基元支持,并发,通用注释,字符串处理,I / O和验证提供实用程序方法-->
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>25.1-jre</version>
        </dependency>

创建(base)注解动态代理类(Knife4j配置时使用) AnnotationProxy.java

package com.lyj.common.base.proxy;

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.experimental.Accessors;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;

/**
 * annotation 注解动态代理类(Knife4j配置时使用)
 * @author faminefree
 */
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Accessors(fluent = true)
public class AnnotationProxy implements Annotation, InvocationHandler {

    @Getter
    private final Class<? extends Annotation> annotationType;
    private final Map<String, Object> values;

    public static <A extends Annotation> A of(Class<A> annotation, Map<String, Object> values) {
        return (A) Proxy.newProxyInstance(annotation.getClassLoader(),
                new Class[]{annotation},
                new AnnotationProxy(annotation, new HashMap<String, Object>(values) {{
                    // Required because getDefaultValue() returns null for this call
                    put("annotationType", annotation);
                }}));
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) {
        return values.getOrDefault(method.getName(), method.getDefaultValue());
    }
}

修改Knife4j配置类 Knife4jConfiguration.java

package com.lyj.common.base.config;

import com.fasterxml.classmate.TypeResolver;
import com.google.common.collect.ImmutableMap;
import com.lyj.common.base.properties.Knife4jProperties;
import com.lyj.common.base.proxy.AnnotationProxy;
import io.swagger.annotations.ApiParam;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.data.domain.Pageable;
import springfox.documentation.builders.*;
import springfox.documentation.schema.AlternateTypeRule;
import springfox.documentation.schema.AlternateTypeRuleConvention;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc;

import java.lang.reflect.Type;
import java.util.*;

import static com.google.common.collect.Lists.newArrayList;
import static springfox.documentation.schema.AlternateTypeRules.newRule;

/**
 * Knife4j配置类
 */
@ConditionalOnProperty(name = "swagger.enable", havingValue = "true")//当存在该属性并且值为true时配置bean才生成
@Configuration
@EnableSwagger2WebMvc
@EnableConfigurationProperties({Knife4jProperties.class})
public class Knife4jConfiguration {

    @Bean(value = "defaultApi")
    public Docket defaultApi(Knife4jProperties properties) {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(new ApiInfoBuilder()
                        .title(properties.getTitle())
                        .description(properties.getDescription())
                        .termsOfServiceUrl(properties.getServiceUrl())
                        .contact(new Contact(properties.getContactName(), properties.getContactUrl(), properties.getContactEmail()))
                        .version(properties.getVersion())
                        .build())
                .groupName("default")
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.lyj"))
                .paths(PathSelectors.any())
                .build();
    }

    //自定义springfox swagger对spring Pageable的支持
    @Bean
    public AlternateTypeRuleConvention pageableConvention(final TypeResolver resolver) {
        return new AlternateTypeRuleConvention() {
            @Override
            public int getOrder() {
                return Ordered.LOWEST_PRECEDENCE;
            }

            @Override
            public List<AlternateTypeRule> rules() {
                return newArrayList(newRule(resolver.resolve(Pageable.class), resolver.resolve(pageableResolver())));
            }
        };
    }

    private Type pageableResolver() {
        return new AlternateTypeBuilder()
                .fullyQualifiedClassName(
                        String.format("%s.generated.%s",
                                Pageable.class.getPackage().getName(),
                                Pageable.class.getSimpleName()))
                .withProperties(Arrays.asList(
                        property(Integer.class, "page", ImmutableMap.of(
                                "value", "页码," + String.format("允许范围[%s, %s]", 0, Integer.MAX_VALUE),
                                "defaultValue", "0",
                                "allowableValues", String.format("range[%s, %s]", 0, Integer.MAX_VALUE),
                                "example", "0"
                        )),
                        property(Integer.class, "size", ImmutableMap.of(
                                "value", "每页大小," + String.format("允许范围[%s, %s]", 0, Integer.MAX_VALUE),
                                "defaultValue", "20",
                                "allowableValues", String.format("range[%s, %s]", 0, Integer.MAX_VALUE),
                                "example", "20"
                        )),
                        property(String.class, "sort", ImmutableMap.of(
                                "value", "页面排序,格式为: 字段名,(asc|desc)。asc表升序,desc表降序"
                        ))
                ))
                .build();
    }

    private AlternateTypePropertyBuilder property(Class<?> type, String name, Map<String, Object> parameters) {
        return new AlternateTypePropertyBuilder()
                .withName(name)
                .withType(type)
                .withCanRead(true)
                .withCanWrite(true)
                .withAnnotations(Collections.singletonList(AnnotationProxy.of(ApiParam.class, parameters)));
    }
}

修改后Pageable入参说明

  • 9
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值