当前位置: 首页 > news >正文

从0开始搭建一个生产级SpringBoot2.0.X项目(二)SpringBoot应用连接数据库集成mybatis-plus

前言

最近有个想法想整理一个内容比较完整springboot项目初始化Demo。

连接Oracle数据库集成mybatis-plus,自定义WrapperFactory。配置代码生成器

一、引入jar包

 <!--oracle驱动 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><dependency><groupId>com.oracle.ojdbc</groupId><artifactId>ojdbc8</artifactId><version>19.3.0.0</version></dependency><!-- oracle8 所需的字符集 --><dependency><groupId>cn.easyproject</groupId><artifactId>orai18n</artifactId><version>12.1.0.2.0</version></dependency><!--mybatis-plus--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.1</version></dependency><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.28</version></dependency><!--mybatis-plus-->

二、新建配置文件application-dev.yaml

以根据不同的环境配置不同的属性文件,application-{profile} 表示环境名称。
例如,application-dev.yaml用于开发环境,application-prod.yaml用于生产环境。

增加数据库配置 hikari连接池配置

spring:datasource:driver-class-name: oracle.jdbc.OracleDriverurl: jdbc:oracle:thin:@//127.0.0.1:1521/orclusername: murg_demopassword: 654321hikari:connection-test-query: SELECT 1 FROM DUALminimum-idle: 10maximum-pool-size: 50idle-timeout: 120000max-lifetime: 180000connection-timeout: 18000
logging:level:org.springframework.security: debug
启动服务看服务是否正常启动

三、自定义MyBatis 构造对象加工厂。

用于规定查询返回值格式 主要用于_处理和字段大小写规定

package com.murg.bootdemo.interceptor;import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.wrapper.ObjectWrapper;
import org.apache.ibatis.reflection.wrapper.ObjectWrapperFactory;
import java.util.Map;/*** 自定义ObjectWrapperFactory 结果处理 去除_  字段大写转小写*/
public class MapWrapperFactory implements ObjectWrapperFactory {@Overridepublic boolean hasWrapperFor(Object object) {return object instanceof Map;}@Overridepublic ObjectWrapper getWrapperFor(MetaObject metaObject, Object object) {return new MyMapWrapper(metaObject,(Map)object);}
}
package com.murg.bootdemo.interceptor;import org.apache.commons.lang3.math.NumberUtils;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.wrapper.MapWrapper;import java.util.Map;/*** mybatis 结果处理 去除_  字段大写转小写*/
public class MyMapWrapper extends MapWrapper {public MyMapWrapper(MetaObject metaObject, Map<String, Object> map) {super(metaObject, map);}@Overridepublic String findProperty(String name, boolean useCamelCaseMapping) {if (useCamelCaseMapping&& ((name.charAt(0) >= 'A' && name.charAt(0) <= 'Z')|| name.contains("_"))) {return underlineToCamelhump(name);}return name;}/*** 将下划线风格替换为驼峰风格* @param inputString* @return*/public String underlineToCamelhump(String inputString) {StringBuilder sb = new StringBuilder();boolean nextUpperCase = false;for (int i = 0; i < inputString.length(); i++) {char c = inputString.charAt(i);if (c == '_') {if (sb.length() > 0) {nextUpperCase = true;}} else {if (nextUpperCase) {if (NumberUtils.isNumber(String.valueOf(c))) {sb.append("_").append(c);} else {sb.append(Character.toUpperCase(c));}nextUpperCase = false;} else {sb.append(Character.toLowerCase(c));}}}return sb.toString();}
}

四、自定义WrapperFactoryConverter

以上配置好WrapperFactory后启动会报错

提示找不到合适的converter将string转化为ObjectWrapperFactory对象

缺少对应的converter,springboot不会提供反射机制来构建一个对象的converter,需要手写一个

package com.murg.bootdemo.interceptor;import org.apache.ibatis.reflection.wrapper.ObjectWrapperFactory;
import org.springframework.boot.context.properties.ConfigurationPropertiesBinding;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;@Component
@ConfigurationPropertiesBinding
public class ObjectWrapperFactoryConverter implements Converter<String, ObjectWrapperFactory> {@Overridepublic ObjectWrapperFactory convert(String source) {try {return (ObjectWrapperFactory) Class.forName(source).newInstance();} catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {throw new RuntimeException(e);}}
}

五、整合MyBatisPlus代码生成器 mybatis-plus-generator配合freemaker引擎

5.1下面这些文件直接创建在resources/generator1/templates的目录下,把内容复制进去就行了。这些文件就是代码生成的格式模板。

controller.java.ftl

package ${package.Controller};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}*/
<#if restControllerStyle>
@RestController
<#else>
@Controller
</#if>
@RequestMapping("<#if package.ModuleName?? && package.ModuleName != "">/${package.ModuleName}</#if>/<#if controllerMappingHyphenStyle??>${controllerMappingHyphen}<#else>${table.entityPath}</#if>")
<#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>

entity.java.ftl

package ${package.Entity};<#list table.importPackages as pkg>
import ${pkg};
</#list>
<#if swagger>
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
</#if>
<#if entityLombokModel>
import lombok.Getter;
import lombok.Setter;<#if chainModel>
import lombok.experimental.Accessors;</#if>
</#if>/*** <p>* ${table.comment!}* </p>** @author ${author}* @since ${date}*/
<#if entityLombokModel>
@Getter
@Setter<#if chainModel>
@Accessors(chain = true)</#if>
</#if>
<#if table.convert>
@TableName("${schemaName}${table.name}")
</#if>
<#if swagger>
@ApiModel(value = "${entity}对象", description = "${table.comment!}")
</#if>
<#if superEntityClass??>
public class ${entity} extends ${superEntityClass}<#if activeRecord><${entity}></#if> {
<#elseif activeRecord>
public class ${entity} extends Model<${entity}> {
<#elseif entitySerialVersionUID>
public class ${entity} implements Serializable {
<#else>
public class ${entity} {
</#if>
<#if entitySerialVersionUID>private static final long serialVersionUID = 1L;
</#if>
<#-- ----------  BEGIN 字段循环遍历  ---------->
<#list table.fields as field><#if field.keyFlag><#assign keyPropertyName="${field.propertyName}"/></#if><#if field.comment!?length gt 0><#if swagger>@ApiModelProperty("${field.comment}")<#else>/*** ${field.comment}*/</#if></#if><#if field.keyFlag><#-- 主键 --><#if field.keyIdentityFlag>@TableId(value = "${field.annotationColumnName}", type = IdType.AUTO)<#elseif idType??>@TableId(value = "${field.annotationColumnName}", type = IdType.${idType})<#elseif field.convert>@TableId("${field.annotationColumnName}")</#if><#-- 普通字段 --><#elseif field.fill??><#-- -----   存在字段填充设置   -----><#if field.convert>@TableField(value = "${field.annotationColumnName}", fill = FieldFill.${field.fill})<#else>@TableField(fill = FieldFill.${field.fill})</#if><#elseif field.convert>@TableField("${field.annotationColumnName}")</#if><#-- 乐观锁注解 --><#if field.versionField>@Version</#if><#-- 逻辑删除注解 --><#if field.logicDeleteField>@TableLogic</#if>private ${field.propertyType} ${field.propertyName};
</#list>
<#------------  END 字段循环遍历  ----------><#if !entityLombokModel><#list table.fields as field><#if field.propertyType == "boolean"><#assign getprefix="is"/><#else><#assign getprefix="get"/></#if>public ${field.propertyType} ${getprefix}${field.capitalName}() {return ${field.propertyName};}<#if chainModel>public ${entity} set${field.capitalName}(${field.propertyType} ${field.propertyName}) {<#else>public void set${field.capitalName}(${field.propertyType} ${field.propertyName}) {</#if>this.${field.propertyName} = ${field.propertyName};<#if chainModel>return this;</#if>}</#list>
</#if><#if entityColumnConstant><#list table.fields as field>public static final String ${field.name?upper_case} = "${field.name}";</#list>
</#if>
<#if activeRecord>@Overridepublic Serializable pkVal() {<#if keyPropertyName??>return this.${keyPropertyName};<#else>return null;</#if>}</#if>
<#if !entityLombokModel>@Overridepublic String toString() {return "${entity}{" +<#list table.fields as field><#if field_index==0>"${field.propertyName}=" + ${field.propertyName} +<#else>", ${field.propertyName}=" + ${field.propertyName} +</#if></#list>"}";}
</#if>
}

entity.kt.ftl

package ${package.Entity}<#list table.importPackages as pkg>
import ${pkg}
</#list>
<#if swagger>
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
</#if>/*** <p>* ${table.comment}* </p>** @author ${author}* @since ${date}*/
<#if table.convert>
@TableName("${schemaName}${table.name}")
</#if>
<#if swagger>
@ApiModel(value = "${entity}对象", description = "${table.comment!}")
</#if>
<#if superEntityClass??>
class ${entity} : ${superEntityClass}<#if activeRecord><${entity}></#if> {
<#elseif activeRecord>
class ${entity} : Model<${entity}>() {
<#elseif entitySerialVersionUID>
class ${entity} : Serializable {
<#else>
class ${entity} {
</#if><#-- ----------  BEGIN 字段循环遍历  ---------->
<#list table.fields as field>
<#if field.keyFlag><#assign keyPropertyName="${field.propertyName}"/>
</#if>
<#if field.comment!?length gt 0>
<#if swagger>@ApiModelProperty("${field.comment}")
<#else>/*** ${field.comment}*/
</#if>
</#if>
<#if field.keyFlag>
<#-- 主键 -->
<#if field.keyIdentityFlag>@TableId(value = "${field.annotationColumnName}", type = IdType.AUTO)
<#elseif idType ??>@TableId(value = "${field.annotationColumnName}", type = IdType.${idType})
<#elseif field.convert>@TableId("${field.annotationColumnName}")
</#if>
<#-- 普通字段 -->
<#elseif field.fill??>
<#-- -----   存在字段填充设置   ----->
<#if field.convert>@TableField(value = "${field.annotationColumnName}", fill = FieldFill.${field.fill})
<#else>@TableField(fill = FieldFill.${field.fill})
</#if>
<#elseif field.convert>@TableField("${field.annotationColumnName}")
</#if>
<#-- 乐观锁注解 -->
<#if field.versionField>@Version
</#if>
<#-- 逻辑删除注解 -->
<#if field.logicDeleteField>@TableLogic
</#if><#if field.propertyType == "Integer">var ${field.propertyName}: Int? = null<#else>var ${field.propertyName}: ${field.propertyType}? = null</#if></#list>
<#-- ----------  END 字段循环遍历  ---------->
<#if entityColumnConstant>companion object {
<#list table.fields as field>const val ${field.name?upper_case} : String = "${field.name}"</#list>}</#if>
<#if activeRecord>override fun pkVal(): Serializable? {
<#if keyPropertyName??>return ${keyPropertyName}
<#else>return null
</#if>}</#if>override fun toString(): String {return "${entity}{" +
<#list table.fields as field>
<#if field_index==0>"${field.propertyName}=" + ${field.propertyName} +
<#else>", ${field.propertyName}=" + ${field.propertyName} +
</#if>
</#list>"}"}
}

mapper.java.ftl

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

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="${package.Mapper}.${table.mapperName}"><#if enableCache><!-- 开启二级缓存 --><cache type="${cacheClassName}"/></#if>
<#if baseResultMap><!-- 通用查询映射结果 --><resultMap id="BaseResultMap" type="${package.Entity}.${entity}">
<#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>
<#if baseColumnList><!-- 通用查询结果列 --><sql id="Base_Column_List">
<#list table.commonFields as field>${field.columnName},
</#list>${table.fieldNames}</sql></#if>
</mapper>

service.java.ftl

package ${package.Service};import ${package.Entity}.${entity};
import ${package.Mapper}.${table.mapperName};
import ${superServiceImplClassPackage};
import org.springframework.stereotype.Service;/**
* <p>* ${table.comment!} 服务实现类* </p>
*
* @author ${author}
* @since ${date}
*/
@Service
public class ${table.serviceImplName} extends ${superServiceImplClass}<${table.mapperName}, ${entity}> {}

 5.2创建生成代码类CodeGenerator 

package com.murg.bootdemo.util;import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.ConstVal;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.TemplateType;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import org.apache.commons.lang3.StringUtils;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;/*** Generator生成代码**/
public class CodeGenerator {public static void main(String[] args) {generator();}public static void generator() {final String[] moduleName = new String[1];FastAutoGenerator.create(new DataSourceConfig.Builder("jdbc:oracle:thin:@//127.0.0.1:1521/orcl","murg_test","654321"))// 全局配置.globalConfig((scanner, builder) -> builder.author(StringUtils.defaultString(getGitUsername(), "codeGenerator")).fileOverride().outputDir(System.getProperty("user.dir") +"/src/main/java").disableOpenDir().enableSwagger().dateType(DateType.ONLY_DATE))// 包配置.packageConfig((scanner, builder) -> builder.parent("com.murg.bootdemo." + scanner.apply("请输入包名(从"+ "com.murg.bootdemo."+ "开始 )?")).xml("mapper").serviceImpl("service")).templateConfig((builder -> builder.disable(TemplateType.SERVICE, TemplateType.CONTROLLER).serviceImpl("/templates/service.java")))// 策略配置.strategyConfig((scanner, builder) -> builder.addInclude(getTables(scanner.apply("请输入表名,多个英文逗号分隔?所有输入 all").toUpperCase())).controllerBuilder().enableRestStyle().enableHyphenStyle().serviceBuilder().convertServiceImplFileName((entityName -> entityName + ConstVal.SERVICE)).entityBuilder().enableLombok().idType(IdType.INPUT).build()).templateEngine(new FreemarkerTemplateEngine())//.addIgnoreColumns("prseno") 排除某个字段.execute();}private static String getGitUsername() {Runtime runtime = Runtime.getRuntime();Process exec;try {exec = runtime.exec("git config user.name");} catch (IOException e) {e.printStackTrace();return null;}InputStreamReader inputStreamReader = new InputStreamReader(exec.getInputStream());BufferedReader bufferedReader = new BufferedReader(inputStreamReader);try {return bufferedReader.readLine();} catch (IOException e) {e.printStackTrace();return null;}}// 处理 all 情况protected static List<String> getTables(String tables) {return "all".equals(tables) ? Collections.emptyList() : Arrays.asList(tables.split(","));}
}

5.3运行CodeGenerator 生成代码

点击左侧按钮 运行main方法控制台输出内容

按照控制台输出内容输入包名和表名,多个表名用英文逗号分隔,会在输入的包下生成文件

六、测试服务数据库连接 获取TT26相关数据

6.1启动类增加注解MapperScan 指定mapper扫描位置
@MapperScan("com.murg.bootdemo.**.mapper")

package com.murg.bootdemo;import org.mybatis.spring.annotation.MapperScan;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cache.annotation.EnableCaching;@MapperScan("com.murg.bootdemo.**.mapper")
@SpringBootApplication
public class BootdemoApplication {public static void main(String[] args) {SpringApplication.run(BootdemoApplication.class, args);}}


6.2创建测试接口controller

引入Tt26Service 调用getOne方法查询数据库获取Tt26数据

getOne方法为MyBatis-Plus 通用IService使用不了解的同学可以了解一下MyBatis-Plus用法。

package com.murg.bootdemo.business.controller;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.murg.bootdemo.business.entity.Tt26;
import com.murg.bootdemo.business.service.Tt26Service;
import com.murg.bootdemo.common.WebResult;
import lombok.RequiredArgsConstructor;
import org.springframework.http.*;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import java.util.HashMap;
import java.util.Map;@RequiredArgsConstructor
@RestController
public class TestRestController {private final RestTemplate restTemplate;private final Tt26Service tt26Service;@RequestMapping(value = "/getTt26", method = RequestMethod.GET)public Tt26 getTt26(@RequestParam String code){//通过不同的id获取不同的namereturn tt26Service.getOne(Wrappers.<Tt26>lambdaQuery().eq(Tt26::getCode,code))}}

启动服务访问接口测试结果

相关文章:

从0开始搭建一个生产级SpringBoot2.0.X项目(二)SpringBoot应用连接数据库集成mybatis-plus

前言 最近有个想法想整理一个内容比较完整springboot项目初始化Demo。 连接Oracle数据库集成mybatis-plus&#xff0c;自定义WrapperFactory。配置代码生成器 一、引入jar包 <!--oracle驱动 --><dependency><groupId>org.springframework.boot</groupI…...

Docker部署教程:打造流畅的斗地主网页小游戏

Docker部署教程&#xff1a;打造流畅的斗地主网页小游戏 一、项目介绍项目简介项目预览 二、系统要求环境要求环境检查Docker版本检查检查操作系统版本 三、部署斗地主网页小游戏下载镜像创建容器检查容器状态查看容器日志安全设置 四、访问斗地主网页小游戏五、总结 一、项目介…...

redis的客户端

目录 redis的客户端一&#xff1a;jedis1&#xff1a;jedis的使用步骤&#xff1a;2&#xff1a;jedis连接池 二&#xff1a;springDataRedis1:入门使用2&#xff1a;配置序列化器3&#xff1a;stringRedisTemplate redis的客户端 一&#xff1a;jedis 1&#xff1a;jedis的使…...

图片分类标注工具python

图片分类标注工具 运行代码&#xff1a;将代码保存到 Python 文件中并运行。选择文件夹&#xff1a;运行时会弹出对话框&#xff0c;选择要分类的图片文件夹。标注分类&#xff1a;程序会逐张显示图片&#xff0c;你可以在下方输入框中输入类别标签&#xff0c;并点击“Next”…...

Rust命令行,实现自动反编译Android APK包工具

Rust-CLI实现自动反编译APK Rust提供了比较好的CLI接口,可以快速的编写命令行应用, 用于日常的工具类使用。 分享一个用Rust命令行实现自动反编译Android APK包工具&#xff0c;是之前学习Rust写的一个练手小工具&#xff0c;可以快速反编译APK&#xff0c;同时也学习下用Rust…...

10. NSTableView Table 数据表格

表格是非常重要和复杂的一个控件&#xff0c;本节会用大量篇幅来把表格这东西力求讲清楚。 基本设置 表格结构 表格是 OS X 组件中为数不多采用了MVC设计模式来实现的控件&#xff0c;即tableView–dataSource–Delegate&#xff0c;这种分层架构给处理数据带来了极大的便利…...

javase笔记8---File与IO流

File类型 简介 在程序中&#xff0c;使用java.io.File这个类来描述和操作磁盘上的一个文件或文件夹(目录)。 File这个类&#xff0c;能新建、删除、移动&#xff0c;重命名文件或文件夹&#xff0c;也能获取或者修改文件或文件夹的信息(如大小&#xff0c;修改时间等)&#xf…...

docker上传离线镜像包到Artifactory

docker上传离线镜像包到Artifactory 原创 大阳 北京晓数神州科技有限公司 2024年10月25日 17:33 北京 随着docker官方源的封禁&#xff0c;最近国内资源也出现无法拉取的问题&#xff0c;Artifactory在生产环境中&#xff0c;很少挂外网代理去官方源拉取&#xff0c;小编提供…...

【专用名词的离线语音识别在2024年底的解决方法调查-会议签到的补充】

语音识别在会议点名中的使用 概要解决问题的过程不行的一些参考可以的一个package自定义词语的拼音转换遗留的问题 小结 概要 提示&#xff1a;这里可以添加技术概要 这里只实现一个方面,每个android会议设备都可通过语音发送参会者姓名,自动转换成文字添加到人员名单. 语音采集…...

OS基础-

OS基础 内存管理 内核用户设备管理 设备框架I/O子系统网络多媒体 音频视频运维 控制台GUIdebug审计计算机组成 CPU ALUregister SPLRPCR0-R12CPSRcacheclockInterrupt Vector tableIVTRMMU/MPU 内存访问权限配置&#xff0c;支持多进程BUSMEMORYI/O单线程 特点&#xff1a;结构…...

《大型语言模型实战指南:应用实践与场景落地》一文详解大型语言模型的11种微调方法

导读&#xff1a;大型预训练模型是一种在大规模语料库上预先训练的深度学习模型&#xff0c;它们可以通过在大量无标注数据上进行训练来学习通用语言表示&#xff0c;并在各种下游任务中进行微调和迁移。随着模型参数规模的扩大&#xff0c;微调和推理阶段的资源消耗也在增加。…...

嵌入式浏览器 -- Chromium VS Firefox

嵌入式浏览器概念 嵌入式浏览器是嵌入式系统中的核心组件之一&#xff0c;用于为设备提供网络访问能力和内容显示功能。与传统PC浏览器相比&#xff0c;嵌入式浏览器更加注重性能优化和资源效率&#xff0c;同时确保核心功能可用&#xff0c;如HTML渲染、JavaScript支持和多媒…...

权限大、数量多、破坏强、管理难......企业特权访问管理怎么管?

特权账号&#xff0c;通往企业数据大门的“钥匙”。 它权限大&#xff0c;具有高危命令或操作的执行权限&#xff1b; 破坏性强&#xff0c;操作可能影响他人使用或其他系统故障&#xff1b; 信息泄露风险大&#xff0c;操作可能获取别人或其他系统相关隐私信息&#xff1b;…...

UE5 第一人称示例代码阅读0 UEnhancedInputComponent

UEnhancedInputComponent使用流程 我的总结示例分析firstthenand thenfinally&代码关于键盘输入XYZ 我的总结 这个东西是一个对输入进行控制的系统&#xff0c;看了一下第一人称例子里&#xff0c;算是看明白了&#xff0c;但是感觉这东西使用起来有点绕&#xff0c;特此梳…...

如何在Linux下安装和配置Docker

文章目录 安装前的准备在Debian/Ubuntu上安装Docker添加Docker仓库安装Docker验证安装 在CentOS/RHEL上安装Docker安装必要的软件包设置Docker仓库安装Docker启动Docker服务 Docker的基本使用拉取一个镜像运行一个容器 配置Docker创建Docker目录使用非root用户运行Docker 结语 …...

apisix的原理及作用,跟spring cloud gateway有什么区别?

apache APISIX 是一个高性能、可扩展的开源 API 网关&#xff0c;它主要用于处理 API 请求、流量管理、安全控制和服务治理。APISIX 可以将复杂的服务架构中的不同服务通过统一的网关来进行管理和监控&#xff0c;为微服务架构提供了便捷的流量入口管理方式。 APISIX 的原理 …...

华为HarmonyOS实现实时语音识别转文本

场景介绍 将一段音频信息&#xff08;短语音模式不超过60s&#xff0c;长语音模式不超过8h&#xff09;转换为文本&#xff0c;音频信息可以为pcm音频文件或者实时语音。 开发步骤 在使用语音识别时&#xff0c;将实现语音识别相关的类添加至工程。 import { speechRecogni…...

DIY可视化-uniapp悬浮菜单支持拖动、吸附-代码生成器

在Uniapp中&#xff0c;悬浮菜单支持拖动和吸附功能&#xff0c;可以为用户带来更加灵活和便捷的操作体验。以下是对这两个功能的详细解释&#xff1a; 悬浮菜单支持拖动 提高用户体验&#xff1a;用户可以根据自己的需要&#xff0c;将悬浮菜单拖动到屏幕上的任意位置&#x…...

HTTP cookie 与 session

一.Cookie 定义&#xff1a; 是服务器发送到用户浏览器并保存在浏览器上的一小块数据&#xff0c; 它会在浏览器之后向同一服务器再次发起请求时被携带并发送到服务器上。 通常&#xff0c; 它用于告知服务端两个请求是否来自同一浏览器&#xff0c; 如保持用户的登录状态、 …...

智慧停车场导航系统架构及反向寻车系统解决方案

一、系统概述&#xff1a; 随着当前室内定位导航技术在大型公共场所如政务中心、商业综合体、车站中的应用越来越多&#xff0c;人们对智慧停车场的需求也日益凸显出来&#xff0c;并且智慧停车场对大型公共场所智慧化的整体建设起到重要作用。如何更有效提高停车效率&#xf…...

【小程序上传图片封装2024,支持多图,带进度,上传头像】

import config from ./config;// 支持多图&#xff0c;显示进度 export function uploadImages(count 1, sourceType, onLoading null, showProgress false, fileKey file) {return new Promise((resolve, reject) > {wx.chooseMedia({count: count, // 可以选择的图片数…...

[A-14]ARMv8/ARMv9-Memory-内存模型的类型(Device Normal)

ver0.1 [看前序文章有惊喜。] 前言 前面花了很大的精力把ARM构建的VMSA中的几个核心的议题给大家做了介绍,相信大家已经能够理解并掌握ARM的内存子系统的工作原理大致框架。接下来我们会规划一些文章,对ARM内存子系统的一些细节做一下介绍,使ARM的内存子系统更加的丰满。本…...

驾校管理系统|基于java和小程序的驾校管理系统设计与实现(源码+数据库+文档)

驾校管理系统平台 目录 基于java和小程序的驾校管理系统设计与实现 一、前言 二、系统设计 三、系统功能设计 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博主介绍&#xff1a;✌️大厂码农|毕设布道师&#…...

@Mapper使用中遇到的问题解法汇总

最近终于有时间写点代码相关的文章了&#xff0c;工作真的太忙了&#xff0c;果然又要测试又要开发的人最&#x1f402;&#x1f434;。 1.查询数据库有数据&#xff0c;但是代码中写select语句的时候查出为null Select("SELECT * FROM xx_manager order by id limit 1&q…...

深度学习:YOLO V3 网络架构解析

引言 YOLO V3&#xff08;You Only Look Once Version 3&#xff09;是YOLO系列算法的第三个版本&#xff0c;相比之前的版本&#xff0c;它在多个方面进行了优化和改进&#xff0c;不仅提升了检测精度&#xff0c;还保持了较快的检测速度。本文将详细介绍YOLO V3的主要改进以…...

SpringCloudAlibaba-Sentinel-熔断与限流

版本说明 <spring.boot.version>3.2.0</spring.boot.version> <spring.cloud.version>2023.0.0</spring.cloud.version> <spring.cloud.alibaba.version>2023.0.1.2</spring.cloud.alibaba.version>是什么 能干嘛 面试题 服务雪崩 安装使…...

mysql中的mvcc理解

是什么&#xff1a;MVCC指的是在读已提交、可重复读这两种隔离级别下的事务在执行普通的select操作时&#xff0c;访问记录的版本链的过程&#xff0c;可以使不同事务的读写操作并发执行&#xff0c;提高性能。 MVCC 隐藏字段 undo log 版本链 ReadView 1.隐藏字段&#xf…...

ETF申购赎回指南:详解注意事项与低费率券商推荐!

​ETF 申购&赎回 ETF申购赎回是个啥业务&#xff1f; 01 ETF申购、赎回是一种交易委托方式&#xff0c;指投资者通过申购方式(买入方向)获得ETF份额&#xff0c;通过赎回的方式&#xff08;卖出方向&#xff09;换掉/卖出ETF份额。ETF申购&#xff0c;通常是通过一篮子成…...

List<T>属性和方法使用

//author&#xff1a;shark_ddd using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;//使用函数来减少长度namespace List_T {class Student{public string Name { get; set; }public int Age { get; set; …...

记一次:使用使用Dbeaver连接Clickhouse

前言&#xff1a;使用了navicat连接了clickhouse我感觉不太好用&#xff0c;就整理了一下dbeaver连接 0、使用Navicat连接clickhouse 测试连接 但是不能双击打开&#xff0c;可是使用命令页界面&#xff0c;右键命令页界面&#xff0c;然后可以用sql去测试 但是不太好用&#…...

南充二手房/seo推广外包

学习总结 当我们在两个分支中对同一个文件的同一个部分进行了不同的修改&#xff0c;Git就没有办法顺利的合并他们&#xff0c;会在合并的时候产生合并冲突。比如我们在issue102分支和master分支下对issue102.md文件进行了修改&#xff0c;当我们将issue102分支融合到主分支上…...

电子产品首页网站版模/做网站需要多少钱

产品三环 三环是指用户体验、企业需求和技术 用户体验&#xff1a;色彩感受 企业需求&#xff1a;需求池&#xff08;常见四大需求来源&#xff1a;商业需求、干系人需求、过渡性需求、解决方案需求&#xff09; 常见商业模式&#xff1a; 1.流量变现&#xff1a;下载收费、广…...

六安seo地址/成都seo优化排名推广

<asp:textbox id"txtWXMT" runat"server" Width"100%" Height"108px" TextMode"MultiLine"></asp:textbox>...

如何自己开一个公众号/北京整站线上推广优化

用sqlplus的时候 连接用户总是出现ORACLE not available 解决办法&#xff1a; 第一步: 输入sqlplus 再输入用户名: sys as sysdba 输入口令: 已连接到空闲例程。 第二步&#xff1a; 先连接到管理员用户下将用例开启 SQL> startup; ORACLE 例程已经启动。 然后就会出现…...

自己在公司上班做网站宣传 侵权吗/百度推广人联系方式

想当年&#xff0c;想弄iOS的版本必须弄台mac机器&#xff0c;虽然一开始要弄iOS的时候觉得在mac上开发感觉挺高富帅的&#xff0c;但是做多了之后就觉得在mac上开发各种不方便。现在好了&#xff0c;Unity3D 4.3开始支持在Windows切换到iOS平台&#xff0c;可以设置iOS特定参数…...

免费房地产网站模板/宁波seo公司排名榜

参考文章:http://blog.csdn.net/mythma/archive/2008/08/31/2857664.aspx 作者:力为http://blog.csdn.net/kamaliang/archive/2009/08/30/4499488.aspx 作者:evilshadow1. 点击【开始】->【运行】 命令&#xff1a;regedit.2. 定位到HKEY_LOCALMACHINE -> SOFTWARE ->…...