【SpringBoot】最基础的项目架构(SpringBoot+Mybatis-plus+lombok+knife4j+hutool)

news2024/12/23 22:35:34

汝之观览,吾之幸也! 从本文开始讲下项目中用到的一些框架和技术,最基本的框架使用的是SpringBoot(2.5.10)+Mybatis-plus(3.5.3.2)+lombok(1.18.28)+knife4j(3.0.3)+hutool(5.8.21),可以做到代码自动生成,满足最基本的增删查改。

一、新建SpringBoot项目

使用Idea工具直接创建项目
在这里插入图片描述

输入项目名称等
在这里插入图片描述

生成web项目
在这里插入图片描述

二、配置pom

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.10</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.mitool</groupId>
    <artifactId>springboot</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
        <mybatis-plus.version>3.5.3.2</mybatis-plus.version>
        <freemarker.version>2.3.29</freemarker.version>
        <lombok.version>1.18.28</lombok.version>
        <knife4j.version>3.0.3</knife4j.version>
        <hutool.version>5.8.21</hutool.version>
        <pagehelper.version>1.4.7</pagehelper.version>
        <ali.cola.version>4.3.2</ali.cola.version>
        <org.mapstruct.version>1.4.2.Final</org.mapstruct.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- mysql 链接-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!-- mybatis-plus -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>${mybatis-plus.version}</version>
        </dependency>
        <!-- Mybatis-plus 代码生成器 依赖配置 -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>${mybatis-plus.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>com.baomidou</groupId>
                    <artifactId>mybatis-plus-extension</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--freemarker依赖-->
        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>${freemarker.version}</version>
        </dependency>
        <!-- lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok.version}</version>
            <scope>provided</scope>
        </dependency>
        <!-- knife4j -->
        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>knife4j-spring-boot-starter</artifactId>
            <version>${knife4j.version}</version>
        </dependency>
        <!-- hutool -->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>${hutool.version}</version>
        </dependency>
        <!-- pagehelper -->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
            <version>${pagehelper.version}</version>
        </dependency>
        <!-- 阿里cola -->
        <dependency>
            <groupId>com.alibaba.cola</groupId>
            <artifactId>cola-component-dto</artifactId>
            <version>${ali.cola.version}</version>
        </dependency>
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct</artifactId>
            <version>${org.mapstruct.version}</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <annotationProcessorPaths>
                        <path>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                            <version>${lombok.version}</version>
                        </path>
                        <path>
                            <groupId>org.mapstruct</groupId>
                            <artifactId>mapstruct-processor</artifactId>
                            <version>${org.mapstruct.version}</version>
                        </path>
                    </annotationProcessorPaths>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

三、配置application.properties

1、配置application.properties

配置application.properties文件,文件中包含数据库配置、knife4j配置

# 应用名称
spring.application.name=spring-demo
# 开发环境设置
spring.profiles.active=dev
# 应用路径
server.servlet.context-path=/springboot
# 编码字符集
server.servlet.encoding.charset=utf-8
# swagger
knife4j.enable=true
knife4j.production=false
knife4j.basic.enable=false

2、配置application-dev.properties

配置数据库,
localhost:数据库IP
db_source:数据库名称
username:用户名
password:密码

# 端口
server.port=9900
spring.datasource.url=jdbc:mysql://localhost:3306/db_source?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false
spring.datasource.username=username
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

# SSO
zsc.open.token.check=false

四、新建代码生成工具类 CodeGeneratorUtil

package com.mitool.springboot.utils;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.InjectionConfig;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import lombok.extern.slf4j.Slf4j;

import java.util.Arrays;
import java.util.Scanner;

/**
 * <p>Title: CodeGeneratorUtil</p>
 * <p>Description:
 * 描述:mybatis-plus 自动生成代码工具类
 * </p>
 *
 * @author Jimmy.Shen
 * @version v1.0.0
 * @since 2022-10-19 9:58
 */
@Slf4j
public class CodeGeneratorUtil {
    /**
     * 表前缀
     */
    private static final String[] PREFIX = new String[]{"illp_", "t_"};
    /**
     * 是否生成controller、service、serviceImpl、converter
     */
    private static final boolean ONLY_UPDATE_COLUMNS = true;

    /**
     * 数据源配置
     */
    private static final DataSourceConfig.Builder DATA_SOURCE_CONFIG = new DataSourceConfig
            .Builder("jdbc:mysql://10.10.177.151:3309/smart_park?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true",
            "root", "ztesoft");

    /**
     * 读取控制台内容
     */
    public static String scanner(String tip) {
        Scanner scanner = new Scanner(System.in);
        log.info("### 请输入" + tip);
        if (scanner.hasNext()) {
            String ipt = scanner.next();
            if (StrUtil.isNotEmpty(ipt)) {
                return ipt;
            }
        }
        throw new MybatisPlusException("请输入正确的" + tip + "!");
    }


    public static void main(String[] args) {
        String projectPath = System.getProperty("user.dir");
        String outputDir = projectPath + "/springboot/src/main/java/";
        String[] scannerArr = scanner("作者名,包名,表名").split(",");
        String authorName = scannerArr[0];
        String packageName = scannerArr[1];
        String tableName = scannerArr[2];
        // 规定代码路径,如果代码在不同项目中可进行调整
        String controllerName =
                projectPath + "/springboot/src/main/java/com/mitool/springboot/controller/" + packageName;
        String serviceName =
                projectPath + "/springboot/src/main/java/com/mitool/springboot/service/" + packageName;
        String serviceImplName =
                projectPath + "/springboot/src/main/java/com/mitool/springboot/service/" + packageName + "/impl/";
        String entityName =
                projectPath + "/springboot/src/main/java/com/mitool/springboot/entity/dataobject/" + packageName;
        String mapperName =
                projectPath + "/springboot/src/main/java/com/mitool/springboot/mapper/" + packageName;
        String mapperXmlName =
                projectPath + "/springboot/src/main/resources/mybatis-mapper/" + packageName;
        String voName =
                projectPath + "/springboot/src/main/java/com/mitool/springboot/entity/vo/" + packageName;
        String converterName =
                projectPath + "/springboot/src/main/java/com/mitool/springboot/converter/" + packageName;
        FastAutoGenerator.create(DATA_SOURCE_CONFIG)
                // 全局配置
                .globalConfig(builder ->
                        //作者名
                        builder.author(authorName)
                                // 开启 swagger 模式	默认值:false
                                .enableSwagger()
                                // 禁止打开输出目录	默认值:true
                                .disableOpenDir()
                                // 指定输出目录
                                .outputDir(outputDir))
                .packageConfig(builder -> builder.moduleName(packageName))
                .injectionConfig(builder -> {
                    updateColumn(entityName, mapperName, mapperXmlName, voName, builder);
                    if (ONLY_UPDATE_COLUMNS) {
                        updateTemplate(controllerName, serviceName, serviceImplName, converterName, builder);
                    }
                })
                //具体的生成文件的策略配置
                .strategyConfig(builder -> {
                    builder.addInclude(tableName.split("#"))
                            // .enableSkipView()
                            .addTablePrefix(Arrays.asList(PREFIX))
                            .entityBuilder()
                            .enableFileOverride()
                            .enableLombok()
                            // // controller
                            .controllerBuilder()
                            .enableRestStyle()
                            .formatFileName("%sController")
                            .enableFileOverride()
                            // service
                            .serviceBuilder()
                            .superServiceClass(IService.class)
                            .formatServiceFileName("%sService")
                            .formatServiceImplFileName("%sServiceImpl")
                            .enableFileOverride()
                            //开启生成mapper
                            .mapperBuilder()
                            .enableBaseResultMap()
                            .enableBaseColumnList()
                            .superClass(BaseMapper.class)
                            .formatMapperFileName("%sMapper")
                            .formatXmlFileName("%sXml")
                            .enableFileOverride();

                })
                //模板配置,如果你没有自定义的一些模板配置,这里直接使用默认即可。
                .templateConfig(config -> config.entity("/templates/entity.java"))
                //模板引擎配置
                .templateEngine(new FreemarkerTemplateEngine())
                .execute();

        // 删除生成的自带的 baomidou代码
        FileUtil.del(projectPath + "/springboot/src/main/java/com/baomidou");
    }


    private static void updateColumn(String entityName, String mapperName, String mapperXmlName, String voName, InjectionConfig.Builder builder) {
        builder.customFile(consumer -> consumer
                .fileName("DO.java")
                .filePath(entityName)
                .enableFileOverride()
                .templatePath("/templates/entity.java.ftl"));
        builder.customFile(consumer -> consumer
                .fileName("Mapper.java")
                .filePath(mapperName)
                .enableFileOverride()
                .templatePath("/templates/mapper.java.ftl"));
        builder.customFile(consumer -> consumer
                .fileName("Mapper.xml")
                .filePath(mapperXmlName)
                .enableFileOverride()
                .templatePath("/templates/mapper.xml.ftl"));
        builder.customFile(consumer -> consumer
                .fileName("VO.java")
                .filePath(voName)
                .enableFileOverride()
                .templatePath("/templates/vo.java.ftl"));
    }

    private static void updateTemplate(String controllerName,
                                       String serviceName, String serviceImplName,
                                       String converterName, InjectionConfig.Builder builder) {
        builder.customFile(consumer -> consumer
                .fileName("Controller.java")
                .filePath(controllerName)
                .enableFileOverride()
                .templatePath("/templates/controller.java.ftl"));
        builder.customFile(consumer -> consumer
                .fileName("Service.java")
                .filePath(serviceName)
                .enableFileOverride()
                .templatePath("/templates/service.java.ftl"));
        builder.customFile(consumer -> consumer
                .fileName("ServiceImpl.java")
                .filePath(serviceImplName)
                .enableFileOverride()
                .templatePath("/templates/serviceImpl.java.ftl"));
        builder.customFile(consumer -> consumer
                .fileName("AppConverter.java")
                .filePath(converterName)
                .enableFileOverride()
                .templatePath("/templates/converter.java.ftl"));
    }

}

五、模板(FreemarkerTemplate)

模板文件放在resource/templates下

1、controller.java.ftl

package com.mitool.springboot.controller.${package.ModuleName};

import com.mitool.springboot.utils.PageUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import com.mitool.springboot.service.${package.ModuleName}.${table.serviceName};
import com.mitool.springboot.entity.dataobject.${package.ModuleName}.${entity}DO;
import com.mitool.springboot.entity.vo.${package.ModuleName}.${entity}VO;
import com.mitool.springboot.converter.${package.ModuleName}.${entity}AppConverter;
import com.alibaba.cola.dto.SingleResponse;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
<#if superControllerClassPackage??>
    import ${superControllerClassPackage};
</#if>
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.List;
/**
* <p>
* ${table.comment!} 前端控制器
* </p>
*
* @author ${author}
* @since ${date}
*/
@Slf4j
@RestController
@RequestMapping("/api/<#if controllerMappingHyphenStyle>${controllerMappingHyphen}<#else>${table.entityPath}</#if>")
@Api(value = "${table.comment!}", tags = "${table.comment!} 管理模块")
<#if superControllerClass??>
    public class ${table.controllerName} extends ${superControllerClass} {
<#else>
public class ${table.controllerName} {
</#if>

    @Resource
    private ${table.serviceName} service;

    @Resource
    private ${entity}AppConverter converter;

    @ApiOperation(value = "${table.comment!}分页查询", notes = "${table.comment!}分页查询")
    @GetMapping("/page")
    public SingleResponse<?> page(@RequestParam Integer pageIndex, @RequestParam Integer pageSize) {
        PageHelper.startPage(pageIndex, pageSize);
        List<${entity}DO> list = service.list();
        return SingleResponse.of(PageUtil.pageInfoCopy(new PageInfo<>(list), ${entity}VO.class, converter::toValueObject));
    }

    @ApiOperation(value = "${table.comment!}列表查询", notes = "${table.comment!}列表查询")
    @GetMapping("/list")
    public SingleResponse<?> list() {
        List<${entity}DO> list = service.list();
        return SingleResponse.of(converter.toValueObject(list));
    }

    @ApiOperation(value = "${table.comment!}详情", notes = "${table.comment!}详情")
    @GetMapping("/detail")
    public SingleResponse<?> detail(@RequestParam Integer id) {
        return SingleResponse.of(converter.toValueObject(service.getById(id)));
    }

    @ApiOperation("新增")
    @PostMapping("/save")
    public SingleResponse<?> save(@RequestBody ${entity}VO param) {
        ${entity}DO dataObject = converter.toDataObject(param);
        service.save(dataObject);
        return SingleResponse.buildSuccess();
    }

    @ApiOperation("更新")
    @PostMapping("/update")
    public SingleResponse<?> update(@RequestBody ${entity}VO param) {
        ${entity}DO dataObject = converter.toDataObject(param);
        service.updateById(dataObject);
        return SingleResponse.buildSuccess();
    }

    @ApiOperation("删除")
    @PostMapping("/remove")
    public SingleResponse<?> remove(@RequestBody ${entity}VO param) {
        service.removeById(param.getId());
        return SingleResponse.buildSuccess();
    }
}

2、converter.java.ftl

package com.mitool.springboot.converter.${package.ModuleName};

import com.mitool.springboot.entity.dataobject.${package.ModuleName}.${entity}DO;
import com.mitool.springboot.entity.vo.${package.ModuleName}.${entity}VO;

import org.mapstruct.Mapper;

import java.util.List;

/**
 * <p>
 * ${table.comment!} app 模型转换服务
 * </p>
 *
 * @author ${author}
 * @since ${date}
 */
@Mapper(componentModel = "spring")
public interface ${entity}AppConverter {

    ${entity}DO toDataObject(${entity}VO ${entity?uncap_first}VO);

    List<${entity}DO> toDataObject(List<${entity}VO> ${entity?uncap_first}VOList);

    ${entity}VO toValueObject(${entity}DO ${entity?uncap_first}DO);

    List<${entity}VO> toValueObject(List<${entity}DO> ${entity?uncap_first}DOList);
}

3、entity.java.ftl

package com.mitool.springboot.entity.dataobject.${package.ModuleName};

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

import java.io.Serializable;
import java.time.LocalDateTime;

/**
* <p>
 * Title:${entity}
 * </p>
 * <p>
 * Description:描述:${table.comment} 对象
 * </p>
 *
 * @author ${author}
 * @version 1.0.0
 * @since ${date}
**/
@Data
@TableName("${table.name}")
public class ${entity}DO implements Serializable {

    private static final long serialVersionUID = 1L;
<#-- ----------  BEGIN 字段循环遍历  ---------->
<#list table.fields as field>
    /**
     * ${field.comment}
     */
 <#if field.keyFlag>
  <#assign keyPropertyName="${field.propertyName}"/>
    @TableId(value = "${field.name}", type = IdType.AUTO)
 </#if>
    private ${field.propertyType} ${field.propertyName};
</#list>
<#------------  END 字段循环遍历  ---------->
}

4、mapper.java.ftl

package com.mitool.springboot.mapper.${package.ModuleName};

import com.mitool.springboot.entity.dataobject.${package.ModuleName}.${entity}DO;
import ${superMapperClassPackage};
<#if mapperAnnotationClass??>
 import ${mapperAnnotationClass.name};
</#if>
import org.apache.ibatis.annotations.Mapper;

/**
* <p>
 * ${table.comment!} Mapper 接口
 * </p>
 *
 * @author ${author}
 * @since ${date}
 */
<#if mapperAnnotationClass??>
@${mapperAnnotationClass.simpleName}
</#if>
<#if kotlin>
interface ${table.mapperName} : ${superMapperClass}<${entity}DO>
<#else>
@Mapper
public interface ${table.mapperName} extends ${superMapperClass}<${entity}DO> {

}
</#if>

5、mapper.xml.ftl

<?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.mitool.springboot.mapper.${package.ModuleName}.${table.mapperName}">

    <#if enableCache>
        <!-- 开启二级缓存 -->
        <cache type="${cacheClassName}"/>

    </#if>

    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap"
               type="com.mitool.springboot.entity.dataobject.${package.ModuleName}.${entity}DO">
        <#list table.fields as field>
            <#if field.keyFlag><#--生成主键排在第一位-->
            <id column="${field.name}" property="${field.propertyName}"/>
            </#if>
        </#list>
        <#list table.commonFields as field><#--生成公共字段 -->
            <result column="${field.name}" property="${field.propertyName}"/>
        </#list>
        <#list table.fields as field>
            <#if !field.keyFlag><#--生成普通字段 -->
        <result column="${field.name}" property="${field.propertyName}" />
</#if>
</#list>
    </resultMap>


<#if baseColumnList>
    <!-- 通用查询结果列 -->
    <sql id="Base_Column_List">
<#list table.commonFields as field>
        ${field.columnName},
</#list>
        ${table.fieldNames}
    </sql>

</#if>
</mapper>

6、service.java.ftl

package com.mitool.springboot.service.${package.ModuleName};

import ${superServiceClassPackage};
import com.mitool.springboot.entity.dataobject.${package.ModuleName}.${entity}DO;

/**
* <p>
 * ${table.comment!} 服务类
 * </p>
*
* @author ${author}
* @since ${date}
*/
<#if kotlin>
interface ${table.serviceName} : ${superServiceClass}<${entity}DO>
<#else>
public interface ${table.serviceName} extends ${superServiceClass}<${entity}DO> {

}
</#if>

7、serviceImpl.java.ftl

package com.mitool.springboot.service.${package.ModuleName}.impl;

import com.mitool.springboot.mapper.${package.ModuleName}.${table.mapperName};
import com.mitool.springboot.service.${package.ModuleName}.${table.serviceName};
import com.mitool.springboot.entity.dataobject.${package.ModuleName}.${entity}DO;
import ${superServiceImplClassPackage};
import org.springframework.stereotype.Service;

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

}
<#else>
public class ${table.serviceImplName} extends ${superServiceImplClass}<${table.mapperName}, ${entity}DO> implements ${table.serviceName} {

}
</#if>

8、vo.java.ftl

package com.mitool.springboot.entity.vo.${package.ModuleName};

<#list table.importPackages as pkg>
    <#if pkg?contains("baomidou")>
    <#elseif pkg?contains("Serializable")>
    <#else>
import ${pkg};
    </#if>
</#list>
import lombok.Data;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

/**
 * <p>
 * ${table.comment!} 请求模型
 * </p>
 *
 * @author ${author}
 * @since ${date}
 */
@ApiModel(value="${entity}对象", description="${table.comment!}")
@Data
public class ${entity}VO {

<#-- ----------  BEGIN 字段循环遍历  ---------->
<#list table.fields as field>
    <#if field.name != "is_delete">
        <#if field.keyFlag>
            <#assign keyPropertyName="${field.propertyName}"/>
        </#if>

        <#if field.comment!?length gt 0>
    /**
     * ${field.comment}
     */
    @ApiModelProperty(value = "${field.comment}")
        </#if>
    private ${field.propertyType} ${field.propertyName};
    </#if>
</#list>
<#------------  END 字段循环遍历  ---------->
}

六、用到的其他类 PageUtil

使用到了分页的工具类,放在utils目录下

package com.mitool.springboot.utils;

import com.github.pagehelper.PageInfo;

import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 分页工具类
 *
 * @author Jimmy.Shen
 * @since 2021/11/26
 */
public class PageUtil {

    /**
     * 通用pageInfo转换
     *
     * @param sourcePageInfo 源数据
     * @param targetClass    目标类型
     * @param mapper         list转换方法
     * @param <T>            目标类型
     * @param <S>            源类型
     */
    public static <T, S> PageInfo<T> pageInfoCopy(PageInfo<S> sourcePageInfo, Class<T> targetClass, Function<S, T> mapper) {
        PageInfo<T> respPageInfo = new PageInfo<>();
        respPageInfo.setPageNum(sourcePageInfo.getPageNum());
        respPageInfo.setPageSize(sourcePageInfo.getPageSize());
        respPageInfo.setSize(sourcePageInfo.getSize());
        respPageInfo.setStartRow(sourcePageInfo.getStartRow());
        respPageInfo.setEndRow(sourcePageInfo.getEndRow());
        respPageInfo.setPages(sourcePageInfo.getPages());
        respPageInfo.setPrePage(sourcePageInfo.getPrePage());
        respPageInfo.setNextPage(sourcePageInfo.getNextPage());
        respPageInfo.setIsFirstPage(sourcePageInfo.isIsFirstPage());
        respPageInfo.setIsLastPage(sourcePageInfo.isIsLastPage());
        respPageInfo.setHasPreviousPage(sourcePageInfo.isHasPreviousPage());
        respPageInfo.setHasNextPage(sourcePageInfo.isHasNextPage());
        respPageInfo.setNavigatePages(sourcePageInfo.getNavigatePages());
        respPageInfo.setNavigatepageNums(sourcePageInfo.getNavigatepageNums());
        respPageInfo.setNavigateFirstPage(sourcePageInfo.getNavigateFirstPage());
        respPageInfo.setNavigateLastPage(sourcePageInfo.getNavigateLastPage());
        respPageInfo.setTotal(sourcePageInfo.getTotal());

        List<T> pageList = sourcePageInfo.getList().stream().map(mapper).collect(Collectors.toList());
        respPageInfo.setList(pageList);
        return respPageInfo;
    }
}

七、运行 CodeGeneratorUtil main方法

输入作者、包、表名生成文件,启动项目后可生成代码
在这里插入图片描述
生成的项目架构
在这里插入图片描述
使用swagger查看
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/950496.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

从零开始探索C语言(三)----运算符和判断语句

文章目录 1. C 运算符1.1 算术运算符1.2 关系运算符1.3 逻辑运算符1.4 位运算符1.5 赋值运算符1.6 杂项运算符 ↦ sizeof & 三元1.7 C 中的运算符优先级 2. C 判断2.1 if 语句2.2 if...else 语句2.3 if...else if...else 语句2.4 ? : 运算符(三元运算符) 1. C 运算符 运算…

商业模式案例:七星拼团—微三云门门

企业战略角度&#xff1a; 七星拼团模式是一种以互联网思维为引流方式的商业战略&#xff0c;通过终端用户自主裂变新用户&#xff0c;为推荐人带来拉新奖励&#xff0c;从而构建一个共赢的商业生态系统。 终端用户角度&#xff1a; 七星拼团模式为终端用户提供了零门槛、零…

如何轻松搭建 Web 自动化测试框架(Python+selenium)

在程序员的世界中&#xff0c;一切重复性的工作&#xff0c;都应该通过程序自动执行。「自动化测试」就是一个最好的例子。 随着互联网应用开发周期越来越短&#xff0c;迭代速度越来越快&#xff0c;只会点点点&#xff0c;不懂开发的手工测试&#xff0c;已经无法满足如今的…

【Go 基础篇】Go语言结构体详解:打开自定义类型的大门

嗨&#xff0c;Go语言学习者们&#xff01;在编程的世界里&#xff0c;数据是核心&#xff0c;而结构体&#xff08;Struct&#xff09;是一种能够帮助我们更有组织地存储和操作数据的重要工具。在本篇博客中&#xff0c;我们将深入探讨Go语言中结构体的概念、定义、初始化、嵌…

【Flutter】Flutter 使用 fluttertoast 实现显示 Toast 消息

【Flutter】Flutter 使用 fluttertoast 实现显示 Toast 消息 文章目录 一、前言二、安装和基础使用三、不同平台的支持情况四、如何自定义 Toast五、在实际业务中的应用六、完整的业务代码示例&#xff08;基于 Web 端&#xff09;七、总结 一、前言 在这篇文章中&#xff0c;…

关于使用远程工具连接mysql数据库时,提示:Public Key Retrieval is not allowed

我在使用DBeaver工具连接 数据库时&#xff0c;提示&#xff1a;Public Key Retrieval is not allowed&#xff0c; 我在前一天还是可以连接的&#xff0c;但是今天突然无法连接了&#xff0c; 但是最后捣鼓了一下又可以了。 具体方法&#xff1a;首先先把mysql服务停了&#x…

【触动精灵】IDE 连接设备

文章目录 1. 安装 TSStudio2. 下载 蒲公英VPN使用方法后台管理设备 3. 下载 雷电模拟器雷电设置安装蒲公英安装触动精灵 4. IDE 连入设备 1. 安装 TSStudio 登录触动官网&#xff0c;注册触动账号。 左下角开发工具&#xff0c;选择下载 IDE 触动脚本编辑器界面如下&#xff…

Java基础二十一(异常捕获和处理)

1. 异常 1.1 概述 (1) 认识异常 异常是指程序在运行过程中出现非正常情况。 (2) Java 异常体系结构 所有异常类都是 Throwable 类的子类&#xff0c;它派生出两个子类&#xff0c;Error 类和 Exception 类。 &#xff08;1&#xff09;Error 类 : 表示程序无法恢复的严重错误…

blender界面认识01

学习视频 【基础篇】1.2 让手听话_哔哩哔哩_bilibili 目录 控制视角 控制物体 选择对象1 小结 控制视角 长按鼠标中键-----视角旋转 shift鼠标中键-----视角平移 滚动鼠标中键-----视角缩放 也可以通过界面的快捷工具实现 这个视角旋转有一点像catia中罗盘&#xff0c…

基于ADAU1452 DSP ANC和AEC算法的实现

是否需要申请加入数字音频系统研究开发交流答疑群(课题组)?加我微信hezkz17, 本群提供音频技术答疑服务,+群附加赠送,DSP音频项目核心开发资料, 1 使用Sigma中的NLMS算法模块 对应C源代码:

向函数传递参数(传地址)

过往课程 向函数传递参数&#xff08;传值、传引用、传const引用&#xff09; 传地址 向函数传地址&#xff0c;是指将变量的地址传递给函数。 函数通过声明参数为地址变量来接收一个变量的地址。 示例如下&#xff1a; #include <iostream> using namespace std;v…

checkstyle检查Java编程样式:隐藏属性

checkstyle可以使用HiddenField检查是否存在隐藏属性的行为&#xff1a;局部变量或者参数是否隐藏了在同一个类中的属性。 所谓隐藏属性&#xff0c;就是指局部变量、或者参数&#xff08;例如构造器的参数、方法的参数&#xff09;的名字和同一个类中的属性的名字相同。如果相…

kafka架构和原理详解

Apache Kafka 是一个分布式流数据平台,用于高吞吐量、持久性、可扩展的发布和订阅消息。它具有高度的可靠性,被广泛用于构建实时数据流处理、日志收集和数据管道等应用。 基本架构 1. 主题(Topic): 主题是消息的逻辑分类生产者将消息发布到特定的主题中,而消费者可以订阅…

数据结构day07(栈和队列)

今日任务 链式队列&#xff1a; head.h #ifndef __HEAD_H__ #define __HEAD_H__#include <stdio.h> #include <stdlib.h>typedef int datatype; typedef struct link_list{datatype data;struct link_list* next; }link,*linkp; typedef struct circulate_line_t…

nvm版本管理

引文地址&#xff1a;https://blog.csdn.net/HuangsTing/article/details/113857145

【计算机组成原理】一文快速入门,很适合JAVA后端看

作者简介&#xff1a; CSDN内容合伙人、CSDN新星计划导师、JAVA领域优质创作者、阿里云专家博主&#xff0c;计算机科班出身、多年IT从业经验、精通计算机核心理论、Java SE、Java EE、数据库、中间件、分布式技术&#xff0c;参加过国产中间件的核心研发&#xff0c;对后端有…

系统学习Linux-ELK日志收集系统

ELK日志收集系统集群实验 实验环境 角色主机名IP接口httpd192.168.31.50ens33node1192.168.31.51ens33noed2192.168.31.53ens33 环境配置 设置各个主机的ip地址为拓扑中的静态ip&#xff0c;并修改主机名 #httpd [rootlocalhost ~]# hostnamectl set-hostname httpd [root…

【第四阶段】kotlin语言的mutator函数学习

1.mutator特性1&#xff1a;使用list可以直接 - fun main() {val list mutableListOf(123,456,789)//特性1 可是直接使用list -list 111list-123println(list) }执行结果 2.mutator特性2&#xff1a;removeIF() 如果实现是true 会自动遍历整个集合&#xff0c;一个一个的移除…

弯道超车必做好题集锦三(C语言选择题)

前言&#xff1a; 编程想要学的好&#xff0c;刷题少不了&#xff0c;我们不仅要多刷题&#xff0c;还要刷好题&#xff01;为此我开启了一个弯道超车必做好题锦集的系列&#xff0c;每篇大约10题左右。此为第三篇选择题篇&#xff0c;该系列会不定期更新&#xff0c;后续还会…

xxl-job:定时任务执行流程及调度机制

1、Scheduled及Quartz的不足 1.1、Scheduled的不足 Spring的Scheduled对于单机的简单任务使用起来很方便&#xff0c;但只能单节点运行&#xff0c;不利于横向扩展。 1.2、Quartz的不足 Quartz作为开源作业调度中的佼佼者&#xff0c;是作业调度的首选。但是集群环境中Quart…