若依代码生成器原理velocity模板引擎(自用)
1.源码分析
代码生成器:导入表结构(预览、编辑、删除、同步)、生成前后端代码

代码生成器表结构说明:
若依提供了两张核心表来存储导入的业务表信息:
gen_table:存储业务表的基本信息 ,它对应于配置代码基本信息和生成信息的页面
gen_table_column:存储业务表的字段信息 它对应于配置代码字段信息的页面。
这两张表是一对多的关系,一张业务表可以有多个字段的信息,所以在字段信息表中有个外键table_id指向

代码生成器目录结构:

查询数据库列表

当管理员在界面上点击导入按钮时,会弹出一个对话框,此时,前端需要向后端发送请求,查询数据库并返回到前端,展示当前项目库中所有待导入的业务表。
前端:
此功能涉及前端相关的代码位于views/tool/index.vue这个视图组件中,负责实现导入业务表的用户界面和交互逻辑。
/** 打开导入表弹窗 */
function openImportTable() {proxy.$refs["importRef"].show();
}
后端:
后端处理逻辑则在代码生成模块的GenController中,负责接收前端的请求,处理业务逻辑,并返回查询结果。
/*** 查询数据库列表*/
@PreAuthorize("@ss.hasPermi('tool:gen:list')")
@GetMapping("/db/list")
public TableDataInfo dataList(GenTable genTable)
{startPage();List<GenTable> list = genTableService.selectDbTableList(genTable);return getDataTable(list);
}
具体的执行流程如下图:

导入表结构:

前端:此功能涉及前端相关的代码位于views/tool/importTable.vue这个视图组件中,负责实现导入业务表的用户界面和交互逻辑。
/** 导入按钮操作 */
function handleImportTable() {const tableNames = tables.value.join(",");if (tableNames == "") {proxy.$modal.msgError("请选择要导入的表");return;}importTable({ tables: tableNames }).then(res => {proxy.$modal.msgSuccess(res.msg);if (res.code === 200) {visible.value = false;emit("ok");}});
}
后端:后端处理逻辑则在代码生成模块的GenController中,负责接收前端的请求,处理业务逻辑,保存业务表的基本信息和字段信息
/*** 导入表结构(保存)*/
@PreAuthorize("@ss.hasPermi('tool:gen:import')")
@Log(title = "代码生成", businessType = BusinessType.IMPORT)
@PostMapping("/importTable")
public AjaxResult importTableSave(String tables)
{// 将表名字符串转换为数组 tb_task_collect,tb_vendout_runningString[] tableNames = Convert.toStrArray(tables);// 查询表信息List<GenTable> tableList = genTableService.selectDbTableListByNames(tableNames);// 导入表结构(保存)genTableService.importGenTable(tableList, SecurityUtils.getUsername());return success();
}
具体的执行的流程如下图:

生成代码
首先管理员,选中需要下载的业务表,并点击生成按钮来触发代码生成并下载的过程。
前端随后向后端发送请求,这个请求会告知服务器需要生成代码的业务表。

前端:
负责实现这一功能的前端代码位于views/tool/index.vue这个视图组件中,负责实现生成业务表的用户界面和交互逻辑。
/** 生成代码操作 */
function handleGenTable(row) {const tbNames = row.tableName || tableNames.value;if (tbNames == "") {proxy.$modal.msgError("请选择要生成的数据");return;}if (row.genType === "1") {genCode(row.tableName).then(response => {proxy.$modal.msgSuccess("成功生成到自定义路径:" + row.genPath);});} else {proxy.$download.zip("/tool/gen/batchGenCode?tables=" + tbNames, "ruoyi.zip");}
}
后端:后端的逻辑处理则在代码生成模块的GenController中,这里是处理前端请求、执行代码生成逻辑,将生成的代码字节流通过HTTP响应返回给客户端。
/*** 批量生成代码*/
@PreAuthorize("@ss.hasPermi('tool:gen:code')")
@Log(title = "代码生成", businessType = BusinessType.GENCODE)
@GetMapping("/batchGenCode")
public void batchGenCode(HttpServletResponse response, String tables) throws IOException
{// 将表名字符串转换为数组 tb_task_collect,tb_vendout_runningString[] tableNames = Convert.toStrArray(tables);// 根据表名下载生成的代码字节数组byte[] data = genTableService.downloadCode(tableNames);// 将生成的代码字节流通过HTTP响应返回给客户端genCode(response, data);
}
具体的执行的流程如下图:

问题分析
我们已经对代码生成器的工作原理有了一定的了解,接下来我们解决一些项目中使用的问题,比如:
每次生成代码都需要修改作者,去除实体类前缀过于繁琐,现在我们可以修改generator.yml配置文件来调整为自己项目的

# 代码生成
gen:# 作者author: itheima# 默认生成包路径 system 需改成自己的模块名称 如 system monitor toolpackageName: com.dkd.manage# 自动去除表前缀,默认是falseautoRemovePre: true# 表前缀(生成类名不会包含表前缀,多个用逗号分隔)tablePrefix: sys_,tb_
velocity模板引擎
- Velocity官网:https://velocity.apache.org
- Velocitv是一个|ava模板引擎,它使用特定语法在模板中嵌入lava对象数据,实现界面与代码的分离

常见的应用场景:
-
Web内容生成 : 生成动态Web页面。
-
代码生成 : 生成Java源代码、SQL脚本、XML配置文件等。
-
网页静态化 : 生成静态网页。
入门
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>velocity快速入门</title>
</head>
<body><h3>心怀梦想,坚持不懈,成功即在前方。加油少年!!</h3></body>
</html>

准备模板
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>velocity快速入门</title>
</head>
<body><h3>心怀梦想,坚持不懈,成功即在前方。${message}</h3></body>
</html>
上述代码中的 加油少年 修改为了 ${message} 这是一个动态变量(占位符),方便动态填充数据
数据填充
编写java代码实现数据填充,并生成文件
package com.dkd.test;import com.dkd.generator.util.VelocityInitializer;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;import java.io.FileWriter;
import java.util.List;public class VelocityDemoTest {public static void main(String[] args) throws Exception {//1. 初始化模板引擎VelocityInitializer.initVelocity();//2. 准备数据模型VelocityContext velocityContext = new VelocityContext();velocityContext.put("message", "加油朋友!!");//3. 读取模板Template template = Velocity.getTemplate("vm/index.html.vm", "UTF-8");//4. 渲染模板FileWriter fileWriter = new FileWriter("D:\\workspace\\index.html");template.merge(velocityContext, fileWriter);fileWriter.close();}
}
基础语法-变量
Velocity中的变量有两类
-
在模板中定义变量:
#set开头,比如#set($name = "velocity") -
获取变量的的值:
$name或者${name}
下面是案例,基于刚才的入门案例模板改进
##双#号 是vm的注释
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>velocity快速入门</title>
</head>
<body><h3>心怀梦想,坚持不懈,成功即在前方。${message}</h3>
##定义变量
#set ($name = "velocity")##输出变量
第一种情况:${name} <br>
第二种情况:$name## 第三种情况:orderService#set($column = "order")
字符串拼接:${column}Service <br>
</body>
</html>
对象的定义获取
在ruoyi-generator模块下新增一个区域的实体类
package com.dkd.test;import com.dkd.common.annotation.Excel;
import com.dkd.common.core.domain.BaseEntity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;/*** 区域管理对象 tb_region** @author itheima* @date 2024-06-05*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Region extends BaseEntity {private static final long serialVersionUID = 1L;/*** 主键ID*/private Long id;/*** 区域名称*/@Excel(name = "区域名称")private String regionName;}
准备模型数据
package com.dkd.test;import com.dkd.generator.util.VelocityInitializer;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;import java.io.FileWriter;
import java.util.List;public class VelocityDemoTest {public static void main(String[] args) throws Exception {//1. 初始化模板引擎VelocityInitializer.initVelocity();//2. 准备数据模型VelocityContext velocityContext = new VelocityContext();velocityContext.put("message", "加油朋友!!");// 创建区域对象Region region = new Region(1L, "北京北五环");velocityContext.put("region", region);//3. 读取模板Template template = Velocity.getTemplate("vm/index.html.vm", "UTF-8");//4. 渲染模板FileWriter fileWriter = new FileWriter("D:\\workspace\\index.html");template.merge(velocityContext, fileWriter);fileWriter.close();}
}
动态模板展示数据
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>velocity快速入门</title>
</head>
<body><h3>心怀梦想,坚持不懈,成功即在前方。${message}</h3>## 定义变量
#set($name = "velocity")## 输出变量
第一种情况:${name} <br>
第二种情况:$name <br>## 第三种情况:orderService
#set($column = "order")
字符串拼接:${column}Service <br>
<hr>## 获取区域对象中的数据
区域ID:$region.id <br>
区域名称:${region.regionName} <br>
<hr>
</body>
</html>
基础语法-循环
循环的语法:#foreach(...) ... #end
##定义一个集合
#set($list = ["春", "夏", "秋", "冬"]) ## 遍历循环
#foreach($item in $list)序号[$foreach.count] $item <br> ## count从1开始 index从0开始
#end
准备模型数据
// 创建区域对象
Region region1 = new Region(1L, "北京北五环");
Region region2 = new Region(2L, "北京北四环");
velocityContext.put("region", region1);
List<Region> regionList = List.of(region1, region2);
velocityContext.put("regionList", regionList);
动态模板展示数据
## 遍历区域
#foreach($item in $regionList)序号[$foreach.count],区域ID:$item.id,区域名称:$item.regionName <br>
#end
</br>
基础语法-if判断
判断的语法:#if(condition) ... #elseif(condition) ... #else ... #end
##定义变量
#set($score=80)## if判断
#if($score>=80)优秀
#elseif($score>=60)及格
#else不及格
#end
## 对象obj不为空才会执行里面的逻辑
#if($obj) ..... #end## 对象obj为空才会执行里面的逻辑
#if(!$obj) ..... #end
模板阅读
我们不需要使用velocity去开发新的模板,若依已经提供好了,在它基础上进行调整即可
下面这个是关于实体类的模板
package ${packageName}.domain;## 根据列类型获取导入包
#foreach ($import in $importList)
import ${import};
#end
## 导入Apache Commons Lang库,用于对象的toString方法
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
## 导入项目自定义的Excel注解,用于生成Excel文档
import com.dkd.common.annotation.Excel;
#if($table.crud || $table.sub)
## 如果表具有CRUD操作或子表,继承BaseEntity
import com.dkd.common.core.domain.BaseEntity;
#elseif($table.tree)
## 如果表是树形结构,继承TreeEntity
import com.dkd.common.core.domain.TreeEntity;
#end/*** ${functionName}对象 ${tableName}** @author ${author}* @date ${datetime}*/
#if($table.crud || $table.sub)#set($Entity="BaseEntity")
#elseif($table.tree)#set($Entity="TreeEntity")
#end
public class ${ClassName} extends ${Entity}{ ## 定义类的序列化版本ID
private static final long serialVersionUID = 1L;
## 根据表的列定义实体类的属性
#foreach ($column in $columns)## 如果不是父类的属性,则生成属性#if(!$table.isSuperColumn($column.javaField))/** $column.columnComment */## 如果字段需要在列表中展示,使用Excel注解标记#if($column.list)#set($parentheseIndex=$column.columnComment.indexOf("("))#if($parentheseIndex != -1)#set($comment=$column.columnComment.substring(0, $parentheseIndex))#else#set($comment=$column.columnComment)#end#if($parentheseIndex != -1)@Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")#elseif($column.javaType == 'Date')@JsonFormat(pattern = "yyyy-MM-dd")@Excel(name = "${comment}", width = 30, dateFormat = "yyyy-MM-dd")#else@Excel(name = "${comment}")#end#endprivate $column.javaType $column.javaField;#end
#end
## 如果表有子表,定义子表信息的集合
#if($table.sub)
/** $table.subTable.functionName信息 */
private List<${subClassName}> ${subclassName}List;#end
## 为每个属性字段生成getter和setter方法
#foreach ($column in $columns)#if(!$table.isSuperColumn($column.javaField))#if($column.javaField.length() > 2 && $column.javaField.substring(1,2).matches("[A-Z]"))#set($AttrName=$column.javaField)#else#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})#endpublic void set${AttrName}($column.javaType $column.javaField){this.$column.javaField = $column.javaField;}public $column.javaType get${AttrName}(){return $column.javaField;}#end
#end
## 如果表有子表,生成子表信息的getter和setter方法
#if($table.sub)
public List<${subClassName}> get${subClassName}List(){return ${subclassName}List;}public void set${subClassName}List(List<${subClassName}> ${subclassName}List){this.${subclassName}List = ${subclassName}List;}#end
## 重写toString方法,使用Apache Commons Lang的ToStringBuilder
@Override
public String toString() {return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)#foreach ($column in $columns)#if($column.javaField.length() > 2 && $column.javaField.substring(1,2).matches("[A-Z]"))#set($AttrName=$column.javaField)#else#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})#end.append("${column.javaField}", get${AttrName}())#end#if($table.sub).append("${subclassName}List", get${subClassName}List())#end.toString();}}
Lombok集成
目前,我们已经基本熟悉了velocity的作用和一些语法,那接下来,我们就通过这些知识来去改造若依框架的代码生成部分
在common模块的pom.xml中添加lombok坐标
<!-- lombok工具-->
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId>
</dependency>
修改模板
在enerator模块的domain.java.vm模板中添加lombok注解
package ${packageName}.domain;## 根据列类型获取导入包
#foreach ($import in $importList)
import ${import};
#end
## 导入项目自定义的Excel注解,用于生成Excel文档
import com.dkd.common.annotation.Excel;
#if($table.crud || $table.sub)
## 如果表具有CRUD操作或子表,继承BaseEntity
import com.dkd.common.core.domain.BaseEntity;
#elseif($table.tree)
## 如果表是树形结构,继承TreeEntity
import com.dkd.common.core.domain.TreeEntity;
#end
## 注意lombok导包
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;/*** ${functionName}对象 ${tableName}** @author ${author}* @date ${datetime}*/
#if($table.crud || $table.sub)
#set($Entity="BaseEntity")
#elseif($table.tree)
#set($Entity="TreeEntity")
#end
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class ${ClassName} extends ${Entity}{ ## 定义类的序列化版本ID
private static final long serialVersionUID=1L;
## 根据表的列定义实体类的属性
#foreach ($column in $columns)## 如果不是父类的属性,则生成属性#if(!$table.isSuperColumn($column.javaField))/** $column.columnComment */## 如果字段需要在列表中展示,使用Excel注解标记#if($column.list)#set($parentheseIndex=$column.columnComment.indexOf("("))#if($parentheseIndex != -1)#set($comment=$column.columnComment.substring(0, $parentheseIndex))#else#set($comment=$column.columnComment)#end#if($parentheseIndex != -1)@Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")#elseif($column.javaType == 'Date')@JsonFormat(pattern = "yyyy-MM-dd")@Excel(name = "${comment}", width = 30, dateFormat = "yyyy-MM-dd")#else@Excel(name = "${comment}")#end#endprivate $column.javaType $column.javaField;#end
#end
## 如果表有子表,定义子表信息的集合
#if($table.sub)
/** $table.subTable.functionName信息 */
private List<${subClassName}> ${subclassName}List;#end
}
正常添加了关于lombok的注解
删除了set 、 get 、toString 等方法
可以把生成后的代码,拷贝到项目中,如果订单管理能够正常访问和操作,就算修改成功了,后期再次生成的代码,全部都支持lombok
Swagger集成
在generator模块的 controller.java.vm模板中添加Swagger注解
package ${packageName}.controller;import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.dkd.common.annotation.Log;
import com.dkd.common.core.controller.BaseController;
import com.dkd.common.core.domain.AjaxResult;
import com.dkd.common.enums.BusinessType;
import ${packageName}.domain.${ClassName};
import ${packageName}.service.I${ClassName}Service;
import com.dkd.common.utils.poi.ExcelUtil;
#if($table.crud || $table.sub)
import com.dkd.common.core.page.TableDataInfo;
#elseif($table.tree)
#end
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;/*** ${functionName}Controller** @author ${author}* @date ${datetime}*/
@Api(tags = "${functionName}Controller")
@RestController
@RequestMapping("/${moduleName}/${businessName}")
public class ${ClassName}Controller extends BaseController
{@Autowiredprivate I${ClassName}Service ${className}Service;/*** 查询${functionName}列表*/@ApiOperation("查询${functionName}列表")@PreAuthorize("@ss.hasPermi('${permissionPrefix}:list')")@GetMapping("/list")
#if($table.crud || $table.sub)public TableDataInfo list(${ClassName} ${className}){startPage();List<${ClassName}> list = ${className}Service.select${ClassName}List(${className});return getDataTable(list);}
#elseif($table.tree)public AjaxResult list(${ClassName} ${className}){List<${ClassName}> list = ${className}Service.select${ClassName}List(${className});return success(list);}
#end/*** 导出${functionName}列表*/@ApiOperation("导出${functionName}列表")@PreAuthorize("@ss.hasPermi('${permissionPrefix}:export')")@Log(title = "${functionName}", businessType = BusinessType.EXPORT)@PostMapping("/export")public void export(HttpServletResponse response, ${ClassName} ${className}){List<${ClassName}> list = ${className}Service.select${ClassName}List(${className});ExcelUtil<${ClassName}> util = new ExcelUtil<${ClassName}>(${ClassName}.class);util.exportExcel(response, list, "${functionName}数据");}/*** 获取${functionName}详细信息*/@ApiOperation("获取${functionName}详细信息")@PreAuthorize("@ss.hasPermi('${permissionPrefix}:query')")@GetMapping(value = "/{${pkColumn.javaField}}")public AjaxResult getInfo(@PathVariable("${pkColumn.javaField}") ${pkColumn.javaType} ${pkColumn.javaField}){return success(${className}Service.select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaField}));}/*** 新增${functionName}*/@ApiOperation("新增${functionName}")@PreAuthorize("@ss.hasPermi('${permissionPrefix}:add')")@Log(title = "${functionName}", businessType = BusinessType.INSERT)@PostMappingpublic AjaxResult add(@RequestBody ${ClassName} ${className}){return toAjax(${className}Service.insert${ClassName}(${className}));}/*** 修改${functionName}*/@ApiOperation("修改${functionName}")@PreAuthorize("@ss.hasPermi('${permissionPrefix}:edit')")@Log(title = "${functionName}", businessType = BusinessType.UPDATE)@PutMappingpublic AjaxResult edit(@RequestBody ${ClassName} ${className}){return toAjax(${className}Service.update${ClassName}(${className}));}/*** 删除${functionName}*/@ApiOperation("删除${functionName}")@PreAuthorize("@ss.hasPermi('${permissionPrefix}:remove')")@Log(title = "${functionName}", businessType = BusinessType.DELETE)@DeleteMapping("/{${pkColumn.javaField}s}")public AjaxResult remove(@PathVariable ${pkColumn.javaType}[] ${pkColumn.javaField}s){return toAjax(${className}Service.delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaField}s));}
}
相关文章:
若依代码生成器原理velocity模板引擎(自用)
1.源码分析 代码生成器:导入表结构(预览、编辑、删除、同步)、生成前后端代码 代码生成器表结构说明: 若依提供了两张核心表来存储导入的业务表信息: gen_table:存储业务表的基本信息 ,它对应于配置代码基本信息和生成信息的页…...
OpenCV直方图均衡化全面解析:从灰度到彩色图像的增强技术
目录 一、直方图均衡化基础:原理与核心思想 二、彩色图像的直方图均衡化:挑战与解决方案 三、进阶技巧与注意事项 四、应用场景与典型案 一、直方图均衡化基础:原理与核心思想 1. 直方图的本质与作用 直方图是图像像素强度分布的统计图表…...
【Pandas】pandas DataFrame keys
Pandas2.2 DataFrame Indexing, iteration 方法描述DataFrame.head([n])用于返回 DataFrame 的前几行DataFrame.at快速访问和修改 DataFrame 中单个值的方法DataFrame.iat快速访问和修改 DataFrame 中单个值的方法DataFrame.loc用于基于标签(行标签和列标签&#…...
Web前端之Vue+Element实现表格动态复杂的合并行功能、localeCompare、forEach、table、push、sort、Map
MENU 效果图公共数据数据未排序时(需要合并的行数据未处于相邻位置)固定合并行方法(写死)动态合并行,行数计算方法当太合并行,合并方法方法(函数)执行 效果图 公共数据 Html <e…...
【DDR 内存学习专栏 1.4 -- DDR 的 Bank Group】
文章目录 BankgroupBankgroup 与 Bank 的关系 DDR4 中的 BankgroupDDR4-3200 8Gb芯片为例组织结构访问场景 实际应用示例 Bankgroup Bankgroup是DDR4及后续标准(DDR5)中引入的一个更高层次的组织结构。它将多个Bank组合在一起形成一个Bankgroup,目的是为了进一步提…...
嵌入式进阶:如何选择合适的开发平台?
随着现代工业、物联网以及人工智能技术的迅速发展,嵌入式系统已经由简单的控制器向复杂的高性能系统迈进。从传统家电到智能机器人、从自动驾驶汽车到工业自动化,每一项应用都对嵌入式系统的响应速度、运行稳定性和能耗管理提出了更高要求。在这种背景下…...
【HTML】动态背景效果前端页面
下面是一个带有多种动态背景效果的现代化前端页面,包含粒子效果、渐变波浪和星空背景三种可选动态背景。直接上代码!! <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name&quo…...
酶动力学参数预测,瓶颈识别……中科院深圳先进技术研究院罗小舟分享AI在酶领域的创新应用
蛋白质,作为生命的基石,在生命活动中发挥着关键作用,其结构和功能的研究,对创新药物研发、合成生物学、酶制剂生产等领域,有着极其重要的意义。但传统蛋白质设计面临诸多难题,蛋白质结构复杂,序…...
【Redis】布隆过滤器应对缓存穿透的go调用实现
布隆过滤器 https://pkg.go.dev/github.com/bits-and-blooms/bloom/v3 作用: 判断一个元素是不是在集合中 工作原理: 一个位数组(bit array),初始全为0。多个哈希函数,运算输入,从而映射到位数…...
【LLM】解锁Agent协作:深入了解谷歌 A2A 协议与 Python 实现
人工智能(AI)智能体正迅速成为企业提高生产力、自动化工作流程和增强运营能力的关键工具。从处理日常重复性任务到协助复杂的决策,智能体的潜力巨大。然而,当这些智能体来自不同的供应商、使用不同的框架或被限制在孤立的数据系统…...
kafka4.0浅尝辄止
最近工作中接触消息队列比较多,前几周又看到kafka4.0发布,故写一篇博客对消息队列做一个复盘。 目录 消息队列对比1. Apache Kafka 4.02. RabbitMQ3. RocketMQ4. ActiveMQ5. Apache Pulsar6. NSQ kafka4.0鲜明的新特性Java 版本要求升级API 更新与精简移…...
数据库原理及应用mysql版陈业斌实验三
🏝️专栏:Mysql_猫咪-9527的博客-CSDN博客 🌅主页:猫咪-9527-CSDN博客 “欲穷千里目,更上一层楼。会当凌绝顶,一览众山小。” 目录 实验三多表查询 1.实验数据如下 student 表(学生表&#…...
OpenHarmony - 小型系统内核(LiteOS-A)(二)
OpenHarmony - 小型系统内核(LiteOS-A)(二) 三、基础内核 3.1、中断及异常处理 基本概念 中断是指出现需要时,CPU暂停执行当前程序,转而执行新程序的过程。即在程序运行过程中,出现了一个必须…...
数字化引擎再升级:小匠物联十周年庆典与全链路创新实践
4月11日,浙江宁波的小匠物联十周年庆典拉开帷幕。本次活动以“拾阶而上,智创未来”为主题,从全员签到、心愿书写,到董事长致辞、切蛋糕及全体合影,每一个环节都精心设计,展现出企业在家用物联网领域的卓越技…...
机器学习核心知识:从基础概念到关键算法
摘要 本文深度剖析机器学习知识体系,从基本概念、学习方式,到分类算法、逻辑回归等关键内容均有涉及。详细阐述各知识点原理与应用场景,并对比多种算法的优劣。 关键词:机器学习;监督学习;分类算法&#x…...
开发工具-jetbrains使用技巧
更详细的可以看 狂神说Java】JavaWeb入门到实战 p6 idea中maven的操作 可以设置怎么调试 然后还可以wsl、远程方式等运行 maven 这里的相当于cmd的操作 命令行去执行这些东西...
HarmonyOS:页面滚动时标题悬浮、背景渐变
一、需求场景 进入到app首页或者分页列表首页时,随着页面滚动,分类tab要求固定悬浮在顶部。进入到app首页、者分页列表首页、商品详情页时,页面滚动时,顶部导航栏(菜单、标题)背景渐变。 二、相关技术知识点…...
Python——Matplotlib库的练习
1、 import matplotlib.pyplot as plt import numpy as npx np.linspace(0,2*np.pi,100) y1 np.sin(x) y2 np.cos(x)plt.plot(x,y1,"r--o",linewidth1.5,markersize6) plt.plot(x,y2,"g-s",linewidth2,markersize8)plt.show() 2、 import matplotlib…...
信息系统项目管理师-第十八章-项目绩效域
本文章记录学习过程中,重要的知识点,是否为重点的依据,来源于官方教材和历年考题,持续更新共勉 本文章记录学习过程中,重要的知识点,是否为重点的依据,来源于官方教材和历年考题,持续更新共勉 在整个生命周期过程中,项目管理者需要始终坚持项目管理原则,通过涵盖 10 …...
Windows 操作系统 - Windows 10 磁盘管理无法为 C 盘选择扩展卷
Windows 10 磁盘管理无法为 C 盘选择扩展卷 在 Windows 10 的磁盘管理中,无法为 C 盘选择扩展卷(选项灰色不可用),主要原因是未分配空间没有紧邻 C 盘的右侧 补充:Windows 10 磁盘管理打开方式 1. 按下快捷键【Win …...
[NOIP 2003 普及组] 栈 Java
import java.io.*;public class Main {public static void main(String[] args) throws IOException {BufferedReader br new BufferedReader(new InputStreamReader(System.in));int n Integer.parseInt(br.readLine());int[] dp new int[n 1];dp[0] 1; // 空序列只有一种…...
C++ (类的设计,对象的创建,this指针,构造函数)
类的设计 C对结构体是有增强的 可以包含函数作为结构体成员 可以直接定义变量 在结构体成员函数里面可以直接访问结构体成员变量 struct student{string name;int age;float score;void play_game(const string &name);}void student::play_game(const string game){}…...
笔记:代码随想录算法训练营day67:Floyd 算法精讲、A * 算法精讲 (A star算法) 严重超时完结,不过,撒花
学习资料:代码随想录 Floyd 算法精讲 卡码网:97. 小明逛公园 首先明确floyd算法解决的是多源最短路径问题,对边的权的正负值没有要求,而且是动态规划的思想 五部曲: 定义:grid[i][j][k]表示从i出发到j…...
面试篇 - Transformer模型中的位置编码
1. 位置编码的引入 背景:Transformer模型通过自注意力机制(Self-Attention)处理序列数据,但自注意力机制本身并不包含序列中元素的位置信息。因此,需要一种方法来为模型提供位置信息。 解决方案:位置编码&…...
蓝桥杯篇---客观题
文章目录 前言 前言 本文简单介绍了蓝桥杯中客观题各个部分的知识点。 一、单片机相关 IAP15F2K61S2单片机的定时器0具有4种工作模式,当采用外部12MHz晶振时,定时器最大定时长度65535us。8051单片机的P0口,当使用外部存储器时它是一个传输低…...
ES6 新增特性 箭头函数
简述: ECMAScript 6(简称ES6)是于2015年6月正式发布的JavaScript语言的标准,正式名为ECMAScript 2015(ES2015)。它的目标是使得JavaScript语言可以用来编写复杂的大型应用程序,成为企业级开发语…...
Javaweb后端 maven高级 maven聚合
聚合用modules...
vue+flask图书知识图谱推荐系统
文章结尾部分有CSDN官方提供的学长 联系方式名片 文章结尾部分有CSDN官方提供的学长 联系方式名片 关注B站,有好处! 编号: F025 架构: vueflaskneo4jmysql 亮点:协同过滤推荐算法知识图谱可视化 支持爬取图书数据,数据超过万条&am…...
vue2 走马灯 展示多个
使用 npm install “swiper”: “^11.2.4”, 在这里插入代码片 <template><section class"swiper pc-banner"><div class"swiper-container"><div class"swiper-wrapper"><div v-for"(item, index) in swiperD…...
《MySQL从入门到精通》
文章目录 《MySQL从入门到精通》1. 基础-SQL通用语法及分类2. 基础-SQL-DDL-数据库操作3. 基础-SQL-DDL-表操作-创建&查询4. 基础-SQL-DDL-数据类型及案例4.1 数值类型4.2 字符串类型4.3 时间和日期类型 5. 基础-SQL-DDL-表操作-修改&删除5.1 DDL-表操作-修改5.2 DDL-表…...
