MyBatis plus自动生成代码

image-20240316213036489

1.pom文件配置

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.3</version>
</dependency>
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>3.5.3</version>
</dependency>
<dependency>

温馨提示:

从上面的pom.xml配置可以看出,使用的mybatis版本为:3.5.3。不同的版本其实现自动生成代码的方式不同,特别是3.5.1及其以上的版本和之前的版本有很大区别。

这是官网中的说明:

image-20240316211558889

2.工具类具体代码实现

package com.mycompany.common.utils;

import com.au.sa.common.services.CommonAbstractService;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.Collections;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author xiaohuihui
 * @creteTime 2024-03-16 10:11
 * @description
 */
@Slf4j
public class MyBatisAutoGeneratorUtil {
    /**
     * 数据库连接串
     */
    public static final String DB_URL = "jdbc:mysql://{ip}:{port}/{dbName}?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=true&autoReconnect=true";
    /**
     * 数据库连接用户名
     */
    public static final String DB_USER_NAME = "username";
    /**
     * 数据库连接密码
     */
    public static final String DB_PASSWORD = "*****";
    /**
     * 注释的作者
     */
    public static final String AUTHOR = "xiaohuihui";
    /**
     * 公共父类实体类中含有的字段
     */
    private static final String[] SUPPER_ENTITY_CONTAINS_FIELD = {"delete_flag", "version_num", "creation_date", "created_by", "last_update_date", "last_updated_by"};
    /**
     * 生成的代码默认输出文件目录
     */
    private static final String DEFAULT_OUT_PUT_DIR = "D://MyBatisPlusAutoGeneratorDir";
    private static final String RESP_OUT_PUT_DIR = "D://MyBatisPlusAutoGeneratorDir";
    /**
     * 默认包名称
     */
    private static final String DEFAULT_PARENT_PACK = "com.au.sa.storeRebate";
    /**
     * 默认父级实体类全路径类 实体类继承的父类
     */
    private static final String BASE_SUPER_ENTITY_CLASS_NAME = "com.au.sa.storeRebate.common.entity.BaseDbEntity";
    /**
     * 要生成代码的表名
     */
    private static final String[] TABLE_NAMES = new String[]{"table_name"};


    public static void main(String[] args) {
        FastAutoGenerator.create(DB_URL, DB_USER_NAME, DB_PASSWORD).globalConfig(builder -> {
            builder.author(AUTHOR) // 设置作者
                    .enableSwagger() // 开启 swagger 模式
                    .outputDir(DEFAULT_OUT_PUT_DIR); // 指定输出目录
        }).packageConfig(builder -> {
            builder.parent("com.au.sa") // 设置父包名
                    .moduleName("storeRebate") // 设置父包模块名
                    .pathInfo(Collections.singletonMap(OutputFile.xml, DEFAULT_OUT_PUT_DIR)); // 设置mapperXml生成路径
        }).strategyConfig(builder -> {
            builder.addInclude(TABLE_NAMES) // 设置需要生成的表名
                    .entityBuilder()
                    .enableTableFieldAnnotation()
                    .enableLombok()
                    .enableFileOverride()
                    .superClass(BASE_SUPER_ENTITY_CLASS_NAME)
                    .controllerBuilder()
                    .superClass(CommonAbstractService.class)//Controller想要继承的父类
                    .enableHyphenStyle()
                    .enableRestStyle()
                    .enableFileOverride()
                    .formatFileName("%sController")
                    .serviceBuilder()
                    .enableFileOverride()
                    .formatServiceFileName("%sService")
                    .formatServiceImplFileName("%sServiceImpl")
                    .mapperBuilder()
                    .enableFileOverride()
                    .enableBaseResultMap()
                    .enableBaseColumnList()
                    .formatMapperFileName("%sDao");
        }).templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
                .execute();

        // 生成Vo对象。如果不需要生成前端返回resp对象,可以不加,这段是自己加的,不是MyBatis-Plus提供
        produceViewObject(false, TABLE_NAMES);

    }


    /**
     * 根据表名生成VO对象,用于mybatis-plus代码生成以后再生成
     *
     * @param isTablePrefix
     * @param tableNames
     */
    private static void produceViewObject(boolean isTablePrefix, String... tableNames) {
        for (int i = 0; i < tableNames.length; i++) {
            String tableName = tableNames[i];
            tableName = isTablePrefix ? tableName.substring(tableName.indexOf("_") + 1) : tableName;
            String outPutDir = RESP_OUT_PUT_DIR + "/" + (DEFAULT_PARENT_PACK.replace(".", "/")) + "/resp/";
            String baseFileName = underline2Camel(tableName, false);
            try {
                File outFile = new File(outPutDir);
                if (!outFile.exists()) {
                    outFile.mkdirs();
                }
                File voFile = new File(outFile, baseFileName + "Resp.java");
                if (!voFile.exists()) {
                    voFile.createNewFile();
                }
                BufferedReader reader = new BufferedReader(
                        new FileReader(DEFAULT_OUT_PUT_DIR + "/" + (DEFAULT_PARENT_PACK.replace(".", "/")) + "/entity/"
                                + baseFileName + ".java"));
                FileWriter fw = new FileWriter(voFile);
                String line = null;
                String description = null;
                String regex = "([\u4e00-\u9fa5]+)";
                while ((line = reader.readLine()) != null) {
                    Matcher matcher = Pattern.compile(regex).matcher(line); //匹配字段描述
                    if (matcher.find()) {
                        description = matcher.group(1);
                    }
                    // 将实体类中的entity变为Vo
                    int index = line.indexOf(baseFileName);
                    if (line.contains("package")) {
                        line = StringUtils.substringBeforeLast(line, ".") + ".resp;";
                    } else if (index > -1 && !line.contains("@ApiModel")) {
                        if (line.contains("+")) {
                            line = StringUtils.substring(line, 0, index + baseFileName.length()) + "{\" +"; //解决toString()
                        } else {
                            line = StringUtils.substring(line, 0, index + baseFileName.length()) + "{";
                        }
                        line = line.replace(baseFileName, baseFileName + "Resp");
                    } else if (line.contains("@TableName")) {
                        description = "";
                        continue;
                    } else if (line.contains("@TableField") || line.contains("@TableId")) {
                        boolean required = true;
                        for (String col : SUPPER_ENTITY_CONTAINS_FIELD) {
                            if (line.contains(col) && !StringUtils.equals("version_num", col)) {
                                required = false;
                                break;
                            }
                        }
                        description = "";
                        continue;
                    } else if (line.contains("@Accessors") || line.contains("@Override") || line.contains("@TableLogic") || line.contains("@Version")) {
                        continue;
                    }
                    line += "\r\n";
                    fw.write(line);
                }
                fw.close();
                reader.close();
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
        }
    }

    /**
     * 下划线转驼峰法(默认小驼峰)
     *
     * @param line       源字符串
     * @param smallCamel 大小驼峰,是否为小驼峰(驼峰,第一个字符是大写还是小写)
     * @return 转换后的字符串
     */
    public static String underline2Camel(String line, boolean... smallCamel) {
        if (StringUtils.isBlank(line)) {
            return "";
        }
        StringBuffer sb = new StringBuffer();
        Pattern pattern = Pattern.compile("([A-Za-z\\d]+)(_)?");
        Matcher matcher = pattern.matcher(line);
        // 匹配正则表达式
        while (matcher.find()) {
            String word = matcher.group();
            // 当是true 或则是空的情况
            if ((smallCamel.length == 0 || smallCamel[0]) && matcher.start() == 0) {
                sb.append(Character.toLowerCase(word.charAt(0)));
            } else {
                sb.append(Character.toUpperCase(word.charAt(0)));
            }

            int index = word.lastIndexOf('_');
            if (index > 0) {
                sb.append(word.substring(1, index).toLowerCase());
            } else {
                sb.append(word.substring(1).toLowerCase());
            }
        }
        return sb.toString();
    }
}

3.相关配置说明

参考官网:MyBatis-Plus代码生成器配置

#数据库配置(DataSourceConfig)

#基础配置

属性说明示例
urljdbc 路径jdbc:mysql://127.0.0.1:3306/mybatis-plus
username数据库账号root
password数据库密码123456
new DataSourceConfig.Builder("jdbc:mysql://127.0.0.1:3306/mybatis-plus","root","123456")
    .build();

#可选配置

方法说明示例
dbQuery(IDbQuery)数据库查询new MySqlQuery(),只在SQLQuery下生效
schema(String)数据库 schema(部分数据库适用)mybatis-plus
typeConvert(ITypeConvert)数据库类型转换器new MySqlTypeConvert(),只在SQLQuery下生效
keyWordsHandler(IKeyWordsHandler)数据库关键字处理器new MySqlKeyWordsHandler()
typeConvertHandler(ITypeConvertHandler)类型转换器(默认)自定义实现ITypeConvertHandler,只在DefaultQuery下生效
databaseQueryClass(AbstractDatabaseQuery)数据库查询方式默认DefaultQuery.class(通用元数据), SQLQuery.class(SQL查询)
// 使用SQL查询的方式生成代码,属于旧的代码生成方式,通用性不是好,老的代码可以继续使用,适配数据库需要完成dbQuery和typeConvert的扩展,后期不再维护这种方式
new DataSourceConfig.Builder("jdbc:mysql://127.0.0.1:3306/mybatis-plus","root","123456")
    .dbQuery(new MySqlQuery())
    .schema("mybatis-plus")
    .typeConvert(new MySqlTypeConvert())
    .keyWordsHandler(new MySqlKeyWordsHandler())
    .databaseQueryClass(SQLQuery.class)
    .build();

// 使用元数据查询的方式生成代码,默认已经根据jdbcType来适配java类型,支持使用typeConvertHandler来转换需要映射的类型映射
new DataSourceConfig.Builder("jdbc:mysql://127.0.0.1:3306/mybatis-plus","root","123456")
    .schema("mybatis-plus")
    .keyWordsHandler(new MySqlKeyWordsHandler())
    .build();

#全局配置(GlobalConfig)

方法说明示例
disableOpenDir禁止打开输出目录默认值:true
outputDir(String)指定输出目录/opt/baomidou/ 默认值: windows:D:// linux or mac : /tmp
author(String)作者名baomidou 默认值:作者
enableKotlin开启 kotlin 模式默认值:false
enableSwagger开启 swagger 模式默认值:false
dateType(DateType)时间策略DateType.ONLY_DATE 默认值: DateType.TIME_PACK
commentDate(String)注释日期默认值: yyyy-MM-dd
new GlobalConfig.Builder()
    .fileOverride()
    .outputDir("/opt/baomidou")
    .author("baomidou")
    .enableKotlin()
    .enableSwagger()
    .dateType(DateType.TIME_PACK)
    .commentDate("yyyy-MM-dd")
    .build();

#包配置(PackageConfig)

方法说明示例
parent(String)父包名默认值:com.baomidou
moduleName(String)父包模块名默认值:无
entity(String)Entity 包名默认值:entity
service(String)Service 包名默认值:service
serviceImpl(String)Service Impl 包名默认值:service.impl
mapper(String)Mapper 包名默认值:mapper
xml(String)Mapper XML 包名默认值:mapper.xml
controller(String)Controller 包名默认值:controller
other(String)自定义文件包名输出自定义文件时所用到的包名
pathInfo(Map<OutputFile, String>)路径配置信息Collections.singletonMap(OutputFile.mapperXml, “D://”)
new PackageConfig.Builder()
    .parent("com.baomidou.mybatisplus.samples.generator")
    .moduleName("sys")
    .entity("po")
    .service("service")
    .serviceImpl("service.impl")
    .mapper("mapper")
    .xml("mapper.xml")
    .controller("controller")
    .other("other")
    .pathInfo(Collections.singletonMap(OutputFile.mapperXml, "D://"))
    .build();

#模板配置(TemplateConfig)

方法说明示例
disable禁用所有模板
disable(TemplateType…)禁用模板TemplateType.ENTITY
entity(String)设置实体模板路径(JAVA)/templates/entity.java
entityKt(String)设置实体模板路径(kotlin)/templates/entity.java
service(String)设置 service 模板路径/templates/service.java
serviceImpl(String)设置 serviceImpl 模板路径/templates/serviceImpl.java
mapper(String)设置 mapper 模板路径/templates/mapper.java
mapperXml(String)设置 mapperXml 模板路径/templates/mapper.xml
controller(String)设置 controller 模板路径/templates/controller.java
new TemplateConfig.Builder()
    .disable(TemplateType.ENTITY)
    .entity("/templates/entity.java")
    .service("/templates/service.java")
    .serviceImpl("/templates/serviceImpl.java")
    .mapper("/templates/mapper.java")
    .mapperXml("/templates/mapper.xml")
    .controller("/templates/controller.java")
    .build();

#注入配置(InjectionConfig)

方法说明示例
beforeOutputFile(BiConsumer<TableInfo, Map<String, Object>>)输出文件之前消费者
customMap(Map<String, Object>)自定义配置 Map 对象Collections.singletonMap(“test”, “baomidou”)
customFile(Map<String, String>)自定义配置模板文件Collections.singletonMap(“test.txt”, “/templates/test.vm”) 方法 formatNameFunction 可以格式化文件,参考测试用例 H2CodeGeneratorTest.testCustomFileByList
new InjectionConfig.Builder()
    .beforeOutputFile((tableInfo, objectMap) -> {
        System.out.println("tableInfo: " + tableInfo.getEntityName() + " objectMap: " + objectMap.size());
    })
    .customMap(Collections.singletonMap("test", "baomidou"))
    .customFile(Collections.singletonMap("test.txt", "/templates/test.vm"))
    .build();

#策略配置(StrategyConfig)

方法说明示例
enableCapitalMode开启大写命名默认值:false
enableSkipView开启跳过视图默认值:false
disableSqlFilter禁用 sql 过滤默认值:true,语法不能支持使用 sql 过滤表的话,可以考虑关闭此开关
enableSchema启用 schema默认值:false,多 schema 场景的时候打开
likeTable(LikeTable)模糊表匹配(sql 过滤)likeTable 与 notLikeTable 只能配置一项
notLikeTable(LikeTable)模糊表排除(sql 过滤)likeTable 与 notLikeTable 只能配置一项
addInclude(String…)增加表匹配(内存过滤)include 与 exclude 只能配置一项 ,支持正则匹配、例如 ^t_.* 所有 t_ 开头的表名
addExclude(String…)增加表排除匹配(内存过滤)include 与 exclude 只能配置一项 ,支持正则匹配、例如 .*st$ 所有 st 结尾的表名
addTablePrefix(String…)增加过滤表前缀
addTableSuffix(String…)增加过滤表后缀
addFieldPrefix(String…)增加过滤字段前缀
addFieldSuffix(String…)增加过滤字段后缀
outputFile内置模板输出文件处理参考测试用例 H2CodeGeneratorTest.testOutputFile
entityBuilder实体策略配置
controllerBuildercontroller 策略配置
mapperBuildermapper 策略配置
serviceBuilderservice 策略配置
new StrategyConfig.Builder()
    .enableCapitalMode()
    .enableSkipView()
    .disableSqlFilter()
    .likeTable(new LikeTable("USER"))
    .addInclude("t_simple")
    .addTablePrefix("t_", "c_")
    .addFieldSuffix("_flag")
    .build();

#Entity 策略配置

方法说明示例
nameConvert(INameConvert)名称转换实现
superClass(Class<?>)设置父类BaseEntity.class
superClass(String)设置父类com.baomidou.global.BaseEntity
disableSerialVersionUID禁用生成 serialVersionUID默认值:true
enableFileOverride覆盖已生成文件默认值:false
enableColumnConstant开启生成字段常量默认值:false
enableChainModel开启链式模型默认值:false
enableLombok开启 lombok 模型默认值:false
enableRemoveIsPrefix开启 Boolean 类型字段移除 is 前缀默认值:false
enableTableFieldAnnotation开启生成实体时生成字段注解默认值:false
enableActiveRecord开启 ActiveRecord 模型默认值:false
versionColumnName(String)乐观锁字段名(数据库字段)versionColumnName与versionPropertyName二选一即可
versionPropertyName(String)乐观锁属性名(实体)versionColumnName与versionPropertyName二选一即可
logicDeleteColumnName(String)逻辑删除字段名(数据库字段)logicDeleteColumnName与logicDeletePropertyName二选一即可
logicDeletePropertyName(String)逻辑删除属性名(实体)logicDeleteColumnName与logicDeletePropertyName二选一即可
naming数据库表映射到实体的命名策略默认下划线转驼峰命名:NamingStrategy.underline_to_camel
columnNaming数据库表字段映射到实体的命名策略默认为 null,未指定按照 naming 执行
addSuperEntityColumns(String…)添加父类公共字段
addIgnoreColumns(String…)添加忽略字段
addTableFills(IFill…)添加表字段填充
addTableFills(List)添加表字段填充
idType(IdType)全局主键类型
convertFileName(ConverterFileName)转换文件名称
formatFileName(String)格式化文件名称
new StrategyConfig.Builder()
    .entityBuilder()
    .superClass(BaseEntity.class)
    .disableSerialVersionUID()
    .enableChainModel()
    .enableLombok()
    .enableRemoveIsPrefix()
    .enableTableFieldAnnotation()
    .enableActiveRecord()
    .versionColumnName("version")
    //.versionPropertyName("version") 
    .logicDeleteColumnName("deleted")
    //.logicDeletePropertyName("deleteFlag")
    .naming(NamingStrategy.no_change)
    .columnNaming(NamingStrategy.underline_to_camel)
    .addSuperEntityColumns("id", "created_by", "created_time", "updated_by", "updated_time")
    .addIgnoreColumns("age")
    .addTableFills(new Column("create_time", FieldFill.INSERT))
    .addTableFills(new Property("updateTime", FieldFill.INSERT_UPDATE))
    .idType(IdType.AUTO)
    .formatFileName("%sEntity")
    .build();

#Controller 策略配置

方法说明示例
superClass(Class<?>)设置父类BaseController.class
superClass(String)设置父类com.baomidou.global.BaseController
enableFileOverride覆盖已生成文件默认值:false
enableHyphenStyle开启驼峰转连字符默认值:false
enableRestStyle开启生成@RestController 控制器默认值:false
convertFileName(ConverterFileName)转换文件名称
formatFileName(String)格式化文件名称
new StrategyConfig.Builder()
    .controllerBuilder()
    .superClass(BaseController.class)
    .enableHyphenStyle()
    .enableRestStyle()
    .formatFileName("%sAction")
    .build();

#Service 策略配置

方法说明示例
superServiceClass(Class<?>)设置 service 接口父类BaseService.class
superServiceClass(String)设置 service 接口父类com.baomidou.global.BaseService
superServiceImplClass(Class<?>)设置 service 实现类父类BaseServiceImpl.class
superServiceImplClass(String)设置 service 实现类父类com.baomidou.global.BaseServiceImpl
enableFileOverride覆盖已生成文件默认值:false
convertServiceFileName(ConverterFileName)转换 service 接口文件名称
convertServiceImplFileName(ConverterFileName)转换 service 实现类文件名称
formatServiceFileName(String)格式化 service 接口文件名称
formatServiceImplFileName(String)格式化 service 实现类文件名称
new StrategyConfig.Builder()
    .serviceBuilder()
    .superServiceClass(BaseService.class)
    .superServiceImplClass(BaseServiceImpl.class)
    .formatServiceFileName("%sService")
    .formatServiceImplFileName("%sServiceImp")
    .build();

#Mapper 策略配置

方法说明示例
superClass(Class<?>)设置父类BaseMapper.class
superClass(String)设置父类com.baomidou.global.BaseMapper
enableFileOverride覆盖已生成文件默认值:false
enableMapperAnnotation开启 @Mapper 注解默认值:false
enableBaseResultMap启用 BaseResultMap 生成默认值:false
enableBaseColumnList启用 BaseColumnList默认值:false
cache(Class<? extends Cache>)设置缓存实现类MyMapperCache.class
convertMapperFileName(ConverterFileName)转换 mapper 类文件名称
convertXmlFileName(ConverterFileName)转换 xml 文件名称
formatMapperFileName(String)格式化 mapper 文件名称
formatXmlFileName(String)格式化 xml 实现类文件名称
new StrategyConfig.Builder()
    .mapperBuilder()
    .superClass(BaseMapper.class)
    .enableMapperAnnotation()
    .enableBaseResultMap()
    .enableBaseColumnList()
    .cache(MyMapperCache.class)
    .formatMapperFileName("%sDao")
    .formatXmlFileName("%sXml")
    .build();

#自定义模版支持(DTO\VO等)配置

#Freemarker模版支持(DTO\VO等)配置

/**
 * 代码生成器支持自定义[DTO\VO等]模版
 */
public final class EnhanceFreemarkerTemplateEngine extends FreemarkerTemplateEngine {

    @Override
    protected void outputCustomFile(@NotNull Map<String, String> customFile, @NotNull TableInfo tableInfo, @NotNull Map<String, Object> objectMap) {
        String entityName = tableInfo.getEntityName();
        String otherPath = this.getPathInfo(OutputFile.other);
        customFile.forEach((key, value) -> {
            String fileName = String.format(otherPath + File.separator + entityName + "%s", key);
            this.outputFile(new File(fileName), objectMap, value);
        });
    }
}

使用方式样例(其他细节参数请查看文档)

entityDTO.java.ftl 可参考源码内entity.java.ftl文件

FastAutoGenerator.create(url, username, password)
                .globalConfig(builder -> {
                    builder.author("abc") // 设置作者
                            .enableSwagger() // 开启 swagger 模式
                            .fileOverride() // 覆盖已生成文件
                            .disableOpenDir() //禁止打开输出目录
                            .outputDir(finalProjectPath + "/src/main/java"); // 指定输出目录
                })
                .packageConfig(builder -> {
                    builder.parent("com.baomidou.mybatisplus.samples") // 设置父包名
                            .moduleName("test") // 设置父包模块名
                            .entity("model.entity") //设置entity包名
                            .other("model.dto") // 设置dto包名
                            .pathInfo(Collections.singletonMap(OutputFile.xml, finalProjectPath + "/src/main/resources/mapper")); // 设置mapperXml生成路径

                })
                .injectionConfig(consumer -> {
                    Map<String, String> customFile = new HashMap<>();
                    // DTO
                    customFile.put("DTO.java", "/templates/entityDTO.java.ftl");
                    consumer.customFile(customFile);
                });

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

VLC抓取m3u8视频

前言 最近想看一些网络视频&#xff0c;但是很多时候网页上是m3u8推流的&#xff0c;如果在线看&#xff0c;速度又慢&#xff0c;所以就想下载下来&#xff0c;就想到了VLC的推流&#xff0c;转换能力&#xff0c;查阅资料&#xff0c;加上实践&#xff0c;总结心得。 设置中…

<Linux> 线程的同步与互斥

目录 前言&#xff1a; 一、资源共享问题 &#xff08;一&#xff09;多线程并发访问 &#xff08;二&#xff09;临界资源与临界区 &#xff08;三&#xff09;“锁” 是什么 二、多线程抢票场景 &#xff08;一&#xff09;并发抢票 &#xff08;二&#xff09;并发访…

flink1.18.0 自定义函数 接收row类型的参数

比如sql中某字段类型 array<row<f1 string,f2 string,f3 string,f4 bigint>> 现在需要编写 tableFunction 需要接受的参数如上 解决方案 用户定义函数|阿帕奇弗林克 --- User-defined Functions | Apache Flink

React 实现下拉刷新效果

简介 本文基于react实现下拉刷新效果&#xff0c;在下拉的时候会进入loading状态。 实现效果 效果如上图所示&#xff0c;在下拉到底部时候&#xff0c;会出现loading条&#xff0c;在处理完成后loading条消失。 具体代码 布局 & 逻辑 import {useRef, useState} from …

基于Java+Springmvc+vue+element实现高校心理健康系统详细设计和实现

基于JavaSpringmvcvueelement实现高校心理健康系统详细设计和实现 博主介绍&#xff1a;多年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐…

Docker 笔记(五)--链接

这篇笔记记录了Docker 的Link。 官方文档&#xff1a; Legacy container links - Communication across links 目录 参考Legacy container linksConnect using network port mappingConnect with the linking systemThe importance of naming Communication across linksEnviro…

java多线程学习(二)

多线程学习&#xff08;一&#xff09;&#xff1a;http://t.csdnimg.cn/o3ygn 目录 一、线程安全 二、线程同步 三、加锁的实现方式一&#xff1a;同步代码块 四、加锁的实现方式二&#xff1a;同步方法 五、同步方法和同步代码块的比较 六、加锁的实现方式三&#xff…

zookeeper快速入门一:zookeeper安装与启动

本文是zookeeper系列之快速入门中的第一篇&#xff0c;欢迎大家观看与指出不足。 写在前面&#xff1a; 不影响教程&#xff0c;笔者安装zookeeper用的是WSL(windows下的linux子系统&#xff09;&#xff0c;当然你想直接在windows上用zookeeper也是可以的。 如果你也想用ws…

全国农产品价格分析预测可视化系统设计与实现

全国农产品价格分析预测可视化系统设计与实现 【摘要】在当今信息化社会&#xff0c;数据的可视化已成为决策和分析的重要工具。尤其是在农业领域&#xff0c;了解和预测农产品价格趋势对于农民、政府和相关企业都至关重要。为了满足这一需求&#xff0c;设计并实现了全国农产…

向量相似性度量的常用方法

向量相似性度量的常用方法 0. 引言1. 欧氏距离(Euclidean distance)2. 余弦相似度(Cosine similarity)3. 汉明距离(Hamming distance)4. 点积相似度 (Dot Product Similarity)5. 曼哈顿距离 (Manhattan Distance) 0. 引言 今天花时间学习学习向量相似性度量的常用方法&#xf…

[蓝桥杯练习题]确定字符串是否包含唯一字符/确定字符串是否是另一个的排列

确定字符串是否包含唯一字符 #include<bits/stdc.h> using namespace std; int main(){ios::sync_with_stdio(0);cin.tie(nullptr);cout.tie(nullptr);map<char,int>m;string s;cin>>s;for(int i0;i<s.size();i){if(isalpha(s[i]))s[i]tolower(s[i]);if(…

Mock.js了解(Mock就是模拟一个后端,Postman模拟前端)

JSON5 Node.js Vue CLI与Mock.js Jquery与Mock.js Mock与分页

NeRF学习——NeRF-Pytorch的源码解读

学习 github 上 NeRF 的 pytorch 实现项目&#xff08;https://github.com/yenchenlin/nerf-pytorch&#xff09;的一些笔记 1 参数 部分参数配置&#xff1a; 训练参数&#xff1a; 这段代码是在设置一些命令行参数&#xff0c;这些参数用于控制NeRF&#xff08;Neural Radi…

智慧城市与数字孪生:共创未来城市的智慧生活

目录 一、智慧城市与数字孪生的概念与特点 二、智慧城市与数字孪生共创智慧生活的路径 1、城市规划与建设的智能化 2、城市管理与服务的智慧化 3、城市安全与应急管理的智能化 三、智慧城市与数字孪生面临的挑战与对策 四、智慧城市与数字孪生的发展趋势与展望 1、技术…

redis中List和hash数据类型

list类型是用来存储多个有序的字符串的&#xff0c;列表当中的每一个字符看做一个元素&#xff0c;一个列表当中可以存储一个或者多个元素&#xff0c;redis的list支持存储2^32-1个元素。redis可以从列表的两端进行插入&#xff08;pubsh&#xff09;和弹出&#xff08;pop&…

游戏引擎中网络游戏的基础

一、前言 网络游戏所面临的挑战&#xff1a; 一致性&#xff1a;如何在所有的主机内都保持一样的表现可靠性&#xff1a;网络传输有可能出现丢包安全性&#xff1a;反作弊&#xff0c;反信息泄漏。多样性&#xff1a;不同设备之间链接&#xff0c;比如手机&#xff0c;ipad&a…

专升本 C语言笔记-07 逗号运算符

1.逗号表达式的用法 就是用逗号隔开的多个表达式。逗号表达式&#xff0c;从左向右依次执行。 2.逗号表达式的特性 2.1.当没有括号时&#xff0c;第一个表达式为整个表达式的值。 代码 int x 3,y 5,a 0; a x,y; printf("a %d",a); 说明:因为逗号优先级最低,会…

OpenCV4.9.0开源计算机视觉库在 Linux 中安装

返回目录&#xff1a;OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 上一篇&#xff1a;OpenCV 环境变量参考 下一篇&#xff1a;将OpenCV与gcc和CMake结合使用 引言&#xff1a; OpenCV是一个开源的计算机视觉库&#xff0c;由英特尔公司所赞助。它是一个跨…

确保云原生部署中的网络安全

数字环境正在以惊人的速度发展&#xff0c;组织正在迅速采用云原生部署和现代化使用微服务和容器构建的应用程序&#xff08;通常运行在 Kubernetes 等平台上&#xff09;&#xff0c;以推动增长。 无论我们谈论可扩展性、效率还是灵活性&#xff0c;对于努力提供无与伦比的用…

源码|批量执行invokeAll()多选一invokeAny()

ExecutorService中定义了两个批量执行任务的方法&#xff0c;invokeAll()和invokeAny()&#xff0c;在批量执行或多选一的业务场景中非常方便。invokeAll()在所有任务都完成&#xff08;包括成功/被中断/超时&#xff09;后才会返回&#xff0c;invokeAny()在任意一个任务成功&…