idea插件开发案例:将批量插入方法转换成分批批量插入

news/2024/5/20 0:02:52/文章来源:https://blog.csdn.net/weixin_44174211/article/details/137028927

代码: idea-plugin-demo


1.背景

excel导入时都会使用批量插入或者批量更新到数据库,这在mysql下没有问题。
但因为公司国产化需求,换成达梦数据库就不行了,报sql超长。
一开始想写mybatis拦截器处理,又怕出现bug,这个问题是正式上线以后暴露的,测试没有用大数据测过。
后来想到一个将下划线和驼峰式转换的idea插件:CamelCasePlugin插件,如果可以实现类似的代码转换-将批量插入方法改写成分批批量插入,就比较保险了。

2.前期准备

  • 需要写一个通用的分批批量插入的方法

精简版

  • BatchUtil:通用分批操作工具类

    import org.springframework.util.CollectionUtils;import java.util.ArrayList;
    import java.util.List;
    import java.util.function.Function;/*** 通用分批操作 处理批量sql超长*/
    public class BatchUtil {private final static int BATCH_NUM = 10; // 每一批处理多少个public static void main(String[] args) {List<String> list = new ArrayList<>();for (int i = 0; i < 25; i++) {list.add("2");}System.out.println("----一个参数---");batchHandle(list, t1 -> t1.size());System.out.println("----多个参数---");// 只有list是可变的,其他参数一般都不会改变,所以归根结底,本质上也是一个参数batchHandle(list, t1 -> t1.size() + 1 + 2 + "1111".length());}/*** 分批处理 可能超过sql长度限制** @param list 要求要分批的集合必须放第一个* @param function 将方法当成参数传递* @param <T>*/public static <T> void batchHandle(List<T> list, Function<List<T>, Integer> function) {if (CollectionUtils.isEmpty(list) || function == null) {return;}int sum = list.size();// 每批多少条int count = BATCH_NUM;if (sum > count) {int limit = getSize(sum, count);for (int i = 0; i < limit; i++) {List subList = list.subList(i * count, i == (limit - 1) ? sum : (i + 1) * count);Integer apply = function.apply(subList);System.out.println("apply: " + apply);}} else {Integer apply = function.apply(list);System.out.println("apply: " + apply);}}/*** 方法描述:根据数据总数获取需要循环次数** @param count 数据总数* @return loop 每次数量*/public static int getSize(long count, int loop) {if (loop < 1) {return 0;}int size = 1;if (count > loop) {if (count % loop == 0) {size = (int) count / loop;} else {size = (int) count / loop + 1;}}return size;}}
  • Mybatis测试

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;import java.util.ArrayList;
    import java.util.Date;
    import java.util.List;import static com.ycxh.module.mybatis.batch.BatchUtil.batchHandle;@RestController
    @RequestMapping("/mybatis")
    public class MybatisController {@Autowiredprivate TestTable01Dao dao;@GetMapping("batchTest")public void batchTest() throws Exception {List<TestTable01> list = new ArrayList<>();for (int i = 0; i < 100; i++) {TestTable01 testTable01 = new TestTable01();testTable01.setId(i + 300);testTable01.setName(i + 300 + "name");testTable01.setAge(i + 300);testTable01.setSex(i % 2 + 1);testTable01.setCreatedTime(new Date());list.add(testTable01);}/*** select * from test_table_01 where id >= 300*/dao.batchDelete(list);// dao.batchInsert(list);// 分批处理 单个参数batchHandle(list, t1 -> dao.batchInsert(t1));// dao.batchUpdateSex(list, 2);// 分批处理 多个参数// BatchUtil_bak.batchHandle((t1, t2) -> dao.batchUpdateSex(t1, (Integer)t2[0]), list, 2);// 简化 一开始想复杂了 只有t1是变化的,所以用形参 其他都是不用变化的 所以它本质其实也是一个参数batchHandle(list, t1 -> dao.batchUpdateSex(t1, 2));// dao.batchUpdate(list);// dao.batchDeleteByNameAndSex(list);System.out.println();}}

想太多,复杂版,仅记录

import org.apache.commons.collections.CollectionUtils;import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;@FunctionalInterface
public interface MoreParamFunction<T1, T2, R> {// 可变参 第2个参数是一个数组R apply(T1 t1, T2... t2);}class Test {public static void main(String[] args) {List<String> list = new ArrayList<>();for (int i = 0; i < 25; i++) {list.add("2");}System.out.println("----一个参数---");batchHandle(list, t1 -> t1.size());System.out.println("----多个参数---");MoreParamFunction<List<String>, Object, Integer> function = (t1, t2) -> {// 可变参 第2个形参是一个数组return t1.size() + ((Integer) t2[0] + (Integer) t2[1]) + ((String) t2[2]).length();};batchHandle(function, list, 1, 2, "1111");}/*** 分批处理 可能超过sql长度限制* 一个参数 简洁一点,不需要写强转这些* @param list* @param function 将方法当成参数传递* @param <T>*/public static <T> void batchHandle(List<T> list, Function<List<T>, Integer> function) {batchHandle((t1, t2) -> function.apply(t1), list);}/*** 分批处理 可能超过sql长度限制* 可变参*/public static <T> void batchHandle(MoreParamFunction<List<T>, Object, Integer> function, List<T> list, Object... params) {if (CollectionUtils.isEmpty(list)) {return;}int sum = list.size();// 每批多少条int count = 10;if (sum > count) {int limit = getSize(sum, count);for (int i = 0; i < limit; i++) {List subList = list.subList(i * count, i == (limit - 1) ? sum : (i + 1) * count);Integer apply = function.apply(subList, params);System.out.println("apply: " + apply);}} else {Integer apply = function.apply(list, params);System.out.println("apply: " + apply);}}/*** 方法描述:根据数据总数获取需要循环次数** @param count 数据总数* @return loop 每次数量*/public static int getSize(long count, int loop) {if (loop < 1) {return 0;}int size = 1;if (count > loop) {if (count % loop == 0) {size = (int) count / loop;} else {size = (int) count / loop + 1;}}return size;}}

3.目标:插件要实现的功能

// 将批量插入方法改写成分批批量插入
dao.batchUpdateSex(list, 2);
转换为
batchHandle(list, t1 -> dao.batchUpdateSex(t1, 2));

4.搭建一个idea插件项目

插件的创建、配置、运行、打包流程,以及 action

直接从网上找一篇博客照着操作即可

  • 官网

  • Intellij IDEA 插件开发 | 京东云技术团队【推荐】

  • IDEA自定义插件开发总结

  • IDEA 插件开发入门

  • idea插件开发教程

  • IDEA插件开发实战

4.1.主要的插件类型

  • UI主题插件
  • 自定义语言支持插件
  • 框架集成插件
  • 工具集成插件

4.2.开发插件的三种方式

  • Using Gradle

  • Using GitHub Template

    • 在github上选择一个模板,会自动根据模板生成一个配置好的插件项目,可以直接clone到本地开发
    • 打开模板的Github地址:https://github.com/JetBrains/intellij-platform-plugin-template。
  • Using DevKit

    • 前2种是idea官方推荐的方式,但是都要使用Gradle
    • 如果不需要引入额外jar包,我觉得使用最后这种简单的方式即可

4.3.使用DevKit开发插件

4.3.1.设置开发环境
1.确认启用 Plugin DevKit插件

该插件是IDEA自带的插件

导航到 Settings | Plugins

image-20240314221908242

2.配置IntelliJ Platform Plugin SDK

IntelliJ Platform Plugin SDK 就是开发 IntelliJ 平台插件的 SDK, 是基于 JDK 之上运行的,类似于开发 Android 应用需要 Android SDK。

导航到 File | Project Structure,选择对话框左侧栏 Platform Settings 下的 SDKs

点击 + 按钮,如果还没有添加 JDK,先添加jdk,指定 JDK 的路径

再创建 IntelliJ Platform Plugin SDK,指定 home path 为 IDEA 的安装路径,然后还需要指定对应的jdk

image-20240314222638072

  • 选择idea安装目录

image-20240314222749489

  • 选择jdk

image-20240314222842304

  • 添加成功

image-20240314223013937

配置sdk源码路径,此步可以跳过,方便debug
  • 查看 build 号:打开 IDEA,Help | About,查看版本号及 build 号
  • IDEA Community 源码(https://github.com/JetBrains/intellij-community):切换到与build 号相同的分支,点击 Clone or download 按钮,选择 Download ZIP

image-20240314223705026

image-20240314223943561

  • 下载

网页:https://github.com/JetBrains/intellij-community/tree/183.4886

下载链接:https://codeload.github.com/JetBrains/intellij-community/zip/refs/heads/183.4886

  • github下载到最后,速度变为0,换镜像网站下载
    • 如果https://hub.nuaa.cf不能使用,就找找新的镜像站

网页:https://hub.nuaa.cf/JetBrains/intellij-community/tree/183.4886

下载链接:https://archive.nuaa.cf/JetBrains/intellij-community/archive/refs/heads/183.4886.zip

  • 选择 SDKs-> 选中之前在第 3 步添加的 sdk 点击 SourcePath 后,点击右侧+添加一个 sourcePath,选择上面下载额源码后点击 OK、点击 Apply
  • 要不要解压啊???不解压似乎也可以

image-20240314225914143

Sandbox 沙箱

IntelliJ IDEA 插件以 Debug/Run 模式运行时是在 SandBox 中进行的,不会影响当前的 IntelliJ IDEA;但是同一台机器同时开发多个插件时默认使用的同一个 sandbox,即在创建 IntelliJ Platform SDK 时默认指定的 Sandbox Home

如果需要每个插件的开发环境是相互独立的,可以创建多个 IntelliJ Platform SDK,为 Sandbox Home 指定不同的目录 。

设置沙箱目录, 插件项目的setting信息会保存在这个目录, 可以指定任意目录

image-20240314230657694

4.3.2.创建一个模块工程

选择 File | New | Project 或者 Modele,左侧栏中选择 IntelliJ Platform Plugin 类型

image-20240314231805530

image-20240314232107094

点击 Next,设置名称及位置,点击 Finish 完成创建。可以到 File | Project Structure 来自定义设置。

image-20240314232151456

4.3.3.插件工程结构

image-20240314232435316

  • src 实现插件功能的 classes
  • resources/META-INF/plugin.xml 插件的配置文件,指定插件名称、描述、版本号、支持的 IntelliJ IDEA 版本、插件的 components 和 actions 以及软件商等信息。
4.3.4.plugin.xml
  • 下面示例描述了可在 plugin.xml 文件配置的主要元素:
<idea-plugin><!-- 插件名称,别人在官方插件库搜索你的插件时使用的名称 --><name>MyPlugin</name><!-- 插件唯一id,不能和其他插件项目重复,所以推荐使用com.xxx.xxx的格式插件不同版本之间不能更改,若没有指定,则与插件名称相同 --><id>com.example.plugin.myplugin</id><!-- 插件的描述 --><description>my plugin description</description><!-- 插件版本变更信息,支持HTML标签;将展示在 settings | Plugins 对话框和插件仓库的Web页面 --><change-notes>Initial release of the plugin.</change-notes><!-- 插件版本 --><version>1.0</version><!-- 供应商主页和email--><vendor url="http://www.jetbrains.com" email="support@jetbrains.com" /><!-- 插件所依赖的其他插件的id --><depends>MyFirstPlugin</depends><!-- 插件兼容IDEA的最大和最小 build 号,两个属性可以任选一个或者同时使用官网详细介绍:http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/build_number_ranges.html--><idea-version since-build="3000" until-build="3999"/><!-- application components --><application-components><component><!-- 组件接口 --><interface-class>com.plugin.demo.Component1Interface</interface-class><!-- 组件的实现类 --><implementation-class>com.plugin.demo.impl.Component1Impl</implementation-class></component></application-components><!-- project components --><project-components><component><!-- 接口和实现类相同 --><interface-class>com.plugin.demo.impl.Component2</interface-class></component></project-components><!-- module components --><module-components><component><interface-class>com.plugin.demo.impl.Component3</interface-class></component></module-components><!-- Actions --><actions>...</actions><!-- 插件定义的扩展点,以供其他插件扩展该插件 --><extensionPoints>...</extensionPoints><!-- 声明该插件对IDEA core或其他插件的扩展 --><extensions xmlns="com.intellij">...</extensions>
</idea-plugin>
4.3.5.创建 Action

Action 是实现插件功能的类, 一个 Action 类需要继承 AnAction 并且实现 actionPerformed 方法。当用户点击菜单或者工具栏按钮, 按快捷键,或者通过 Help | Find Action 点击时, IntelliJ Platform 系统会回调对应 Action 的 actionPerformed 方法。

一个 Action 表示 IDEA 菜单里的一个 menu item 或工具栏上的一个按钮,通过继承 AnAction class 实现,当选择一个 menu item 或点击工具栏上的按钮时,就会调用 AnAction 类的 actionPerformed 方法。

实现自定义 Action 分两步:

  • 定义一个或多个 action
  • 注册 action,将 item 添加到菜单或工具栏上
4.3.5.1.定义 Action

定义一个 Java class,继承 AnAction 类,并重写 actionPerformed 方法, 如

public class ActionDemo extends AnAction {public void actionPerformed(AnActionEvent event) {Project project = event.getData(PlatformDataKeys.PROJECT);Messages.showInputDialog(project,"What is your name?","Input your name",Messages.getQuestionIcon());}
}
4.3.5.3.注册 Action

在 plugin.xml 文件的 <actions> 元素内注册

<actions><group id="MyPlugin.SampleMenu" text="Sample Menu" description="Sample menu"><add-to-group group-id="MainMenu" anchor="last"  /><action id="Myplugin.ActionDemo" class="Mypackage.ActionDemo" text="Text Boxes" description="A test menu item" /></group>
</actions>
  • 元素会定义一个 action,指定 action 的 id、实现类、显示文本、描述
  • 元素会定义一个 action group(多个 action),设置 action group 的 id、文本、描述
  • 元素指定其外部 action 或 action group 被添加到的位置

上面示例会定义一个被添加到 IDEA 主菜单的最后面的 “SampleMenu” 的菜单,点击该菜单将弹出一个 “Text Boxes” item,如图

img

  • 示例 多级菜单

    <!-- 插件动作声明,在这里可以声明自定义动作 --><actions><!--自己创建菜单组--><!--https://blog.csdn.net/a__int__/article/details/127762837--><!--https://zhuanlan.zhihu.com/p/408739679?utm_id=0--><!--https://gitee.com/pillowtree/scream-tool/blob/master/resources/META-INF/plugin.xml--><!--http://www.taodudu.cc/news/show-4799909.html?action=onClick--><!--多个action可以组成一个group,形成层级菜单--><!--popup="true"如果不设置,那么group的text不会在EditorPopupMenu上展示,无法形成层级菜单--><group id="ScreamTool.Tool" text="Scream Tool" popup="true" description="ScreamTool"><!--anchor 位置 first last --><add-to-group group-id="EditorPopupMenu" anchor="first"/><action id="ScreamTool.BeanToJsonString" class="helloBoy"text="BeanToJsonString"description="BeanToJsonString" /><action id="ScreamTool.BeanToJsonString" class="helloBoy2" text="changeCode"><!-- 快捷键冲突会使用不了 --><keyboard-shortcut keymap="$default" first-keystroke="ctrl F2"/></action></group><action id="ScreamTool.BeanToJsonString" class="helloBoy2" text="sayHello2"><add-to-group group-id="ScreamTool.Tool" anchor="first"/><!-- 快捷键冲突会使用不了 --><!--<keyboard-shortcut keymap="$default" first-keystroke="ctrl F2"/>--></action><!-- Add your actions here --><!-- 需要等一会才能从灰色变为可用 --><action id="com.idea.hello" class="helloBoy" text="sayHello"><!--系统默认有一些组--><!--ToolsMenu	Tools菜单栏--><!--EditorPopupMenu代码编辑页面右击出现--><add-to-group group-id="ToolsMenu" anchor="first"/><!-- 快捷键冲突会使用不了 --><keyboard-shortcut keymap="$default" first-keystroke="ctrl F2"/></action></actions>
    
4.3.5.3.快速创建 Action

https://idea.javaguide.cn/tips/plug-in-development-intro.html#_03-手动创建-action

Idea插件添加EditorPopupMenu显示JAVA对象的JSON字符串

IntelliJ Platform 提供了 New Action 向导,它会帮助我们创建 action class 并配置 plugin.xml 文件:

在目标 package 上右键,选择 New | Plugin DevKit | Action:

  • Action ID: action 唯一 id,推荐 format: PluginName.ID
  • Class Name: 要被创建的 action class 名称
  • Name: menu item 的文本
  • Description: action 描述,toolbar 上按钮的提示文本,可选
  • Add to Group:选择新 action 要被添加到的 action group(Groups, Actions)以及相对其他 actions 的位置(Anchor)
  • Keyboard Shortcuts:指定 action 的第一和第二快捷键

image-20240324202628908

image-20240324210041026

创建完成之后,我们的 plugin.xml<actions>节点下会自动生成我们刚刚创建的 Action 信息:

 <actions><!-- Add your actions here --><action id="BatchToSplitBatchTool" class="BatchToSplitBatchAction" text="BatchToSplitBatch" description="批量转分批批量"><add-to-group group-id="EditorPopupMenu" anchor="first"/><keyboard-shortcut keymap="$default" first-keystroke="ctrl F2"/></action></actions>

并且 java 目录下会生成一个叫做 BatchToSplitBatchAction 的类。这个类继承了 AnAction ,并覆盖了 actionPerformed() 方法。这个 actionPerformed 方法就好比 JS 中的 onClick 方法,会在你点击的时候触发对应的动作。

另外,每个动作都会归属到一个 Group 中,这个 Group 可以简单看作 IDEA 中已经存在的菜单。

注意:该向导只能向主菜单中已存在的 action group 或工具栏上添加 action,若要创建新的 action group,需要另想办法。

4.3.6.运行调试插件

运行 / 调试插件可直接在 IntelliJ IDEA 进行,选择 Run | Edit Configurations…,若左侧栏没有 Plugin 类型的 Configuration, 点击右上角 + 按钮,选择 Plugin 类型,如图

image-20240324210646990

  • 如果报错,则设置一下输出目录

image-20240324210715844

image-20240324210851159

点击run|debug之后,Intel IDEA 会另启一个装有该插件的 IDEA窗口,该idea中已经安装了你开发的插件。

在该idea中可以直接使用插件,使用过程中,可以在项目里面断点跟进。

启动的idea和正常idea操作是一样的,可以打开一个测试demo,来测试你的插件是否正常运行。

上面设置创建的group-id为EditorPopupMenu,所以可以在编辑窗口右键菜单中发现该插件。

image-20240324211136486

  • 存在2个快捷键一样的插件,是因为之前调试的另一个插件还在沙盒里面,可以删掉

    image-20240324233908841

  • 假如创建的 Action 的所属 Group 是 ToolsMenu(Tools) 。这样的话,创建的 Action 所在的位置就在 Tools 这个菜单下。

img

  • 假如创建的 Action 所属的 Group 是MainMenu (IDEA 最上方的主菜单栏)下的 FileMenu(File) 的话。
<actions><!-- Add your actions here --><action id="test.hello" class="HelloAction" text="Hello" description="IDEA 插件入门"><add-to-group group-id="FileMenu" anchor="first"/></action>
</actions>

我们创建的 Action 所在的位置就在 File 这个菜单下。

img

4.3.6.1.可能需要等一会,菜单项才能从灰色变为可用
4.3.6.2.调试 会打开一个新的idea窗口,可能需要重新激活
idea 2018.3永久简单激活。激活码
https://blog.csdn.net/weixin_44991324/article/details/1361533941.打开hosts文件将 0.0.0.0 account.jetbrains.com 添加到文件末尾
C:\Windows\System32\drivers\etc\hosts2.注册码:
4.3.4.打包安装插件
4.3.4.1.打包插件

选择 Build | Prepare Plugin Module ‘module name’ for Deployment 来打包插件:

image-20240324212811394

插件包位置:一般在工程根目录下
如果插件没有依赖任何 library,插件会被打包成一个 .jar ,否则会被打包成一个 .zip ,zip 中包含了所有的插
件依赖

image-20240324212921612

4.3.4.2.安装插件

导航到 File | Settings | Plugins 页面,点击 Install plugin from disk…

image-20240324213154166

5.导入一个idea插件项目

idea plugin 工程导入

idea中一个普通工程变为插件工程

  • 将.iml文件中的type属性值JAVA_MODULE其修改为PLUGIN_MODULE。

    • idea_plugin_demo/.idea/idea_plugin_demo.iml
  • 项目打开默认是java项目

<module type="JAVA_MODULE" version="4">
  • 修改为插件项目
<module type="PLUGIN_MODULE" version="4">

还要加上

<component name="DevKit.ModuleBuildProperties" url="file://$MODULE_DIR$/resources/META-INF/plugin.xml" />
  • 也可以直接创建一个idea插件项目,对比一下文件差异

  • 最终效果

<module type="PLUGIN_MODULE" version="4"><component name="DevKit.ModuleBuildProperties" url="file://$MODULE_DIR$/resources/META-INF/plugin.xml" /><component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8" inherit-compiler-output="true"><exclude-output /><content url="file://$MODULE_DIR$"><sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" /><sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" /></content><orderEntry type="jdk" jdkName="IntelliJ IDEA IU-183.4886.37" jdkType="IDEA JDK" /><orderEntry type="sourceFolder" forTests="false" /></component>
</module>

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

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

相关文章

MySQL为什么会选错索引

在平时不知道一有没有遇到过这种情况&#xff0c;我明明创建了索引&#xff0c;但是MySQL为何不用索引呢&#xff1f;为何要进行全索引扫描呢&#xff1f; 一、对索引进行函数操作 假设现在维护了一个交易系统&#xff0c;其中交易记录表 tradelog 包含交易流水号(tradeid)、交…

Ubuntu 中如何选择Java版本

如何在 Ubuntu 上安装多个版本的 Java 首先&#xff0c;我们得检查一下你的系统里是否已经装了 Java。这个很简单&#xff0c;只需运行下面这条命令&#xff1a; 在 Linux 上安装 Java 的实战示例update-java-alternatives --list 输出结果&#xff1a; 检查是否安装了 Java…

存储的过程

一、存储过程 1.1 概述 存储过程可以轻松而高效的去完成这个需求&#xff0c;有点类似shell脚本里的函数 1.2 特点 存储过程在数据库中创建并保存&#xff0c;它不仅仅是 SQL 语句的集合&#xff0c;还可以加入一些特殊的控制结构&#xff0c;也可以控制数据的访问方式。存储过…

lora-scripts 训练IP形象

CodeWithGPU | 能复现才是好算法CodeWithGPU | GitHub AI算法复现社区&#xff0c;能复现才是好算法https://www.codewithgpu.com/i/Akegarasu/lora-scripts/lora-trainstable-diffusion打造自己的lora模型&#xff08;使用lora-scripts&#xff09;-CSDN博客文章浏览阅读1.1k次…

web 技术中前端和后端交互过程

1、客户端服务器交互过程 客户端:上网过程中,负责浏览资源的电脑,叫客户端服务器:在因特网中,负责存放和对外提供资源的电脑叫服务器 服务器的本质: 就是一台电脑,只不过相比个人电脑它的性能高很多,个人电脑中可以通过安装浏览器的形式,访问服务器对外提供的各种资源。 个人…

如何在vue中使用echarts,与jquery中有啥不同。

一、vue中使用echarts的步骤 在 Vue 中使用 ECharts 可以按照以下步骤进行&#xff1a; 安装 ECharts&#xff1a;使用 npm 或 yarn 安装 ECharts&#xff1a; npm install echarts 在 Vue 组件中引入 ECharts&#xff1a; import echarts from echarts 在 Vue 组件的 mou…

http响应练习—在服务器端渲染html(SSR)

一、什么是服务器端渲染&#xff08;SSR&#xff09; 简单说&#xff0c;就是在服务器上把网页生成好&#xff0c;整个的HTML页面生成出来&#xff0c;生成出的页面已经包含了所有必要的数据和结构信息&#xff0c;然后直接发给浏览器进行展现。 二、例题 要求搭建http服务&a…

QT_day4:对话框

1、完善对话框&#xff0c;点击登录对话框&#xff0c;如果账号和密码匹配&#xff0c;则弹出信息对话框&#xff0c;给出提示”登录成功“&#xff0c;提供一个Ok按钮&#xff0c;用户点击Ok后&#xff0c;关闭登录界面&#xff0c;跳转到其他界面 如果账号和密码不匹配&…

其实StartAI也是一款修图工具 用StartAI修图之“去除背景”

其实StartAI不仅仅是一款AI绘画插件&#xff0c;更是一款可以对我们的摄影图片、广告海报进行修图的AI修图工具。StartAI包含了AI绘画、AI修图等多种复合型AI智能实用工具。 用【背景移除】功能对图片一个背景修图 1.实体广告图片 我们可以通过【背景移除】将广告图中的实体…

软考中级 --网络工程师真题试卷 2023下半年

在EIGRP协议中&#xff0c;某个路由器收到了两条路径到达目标网络&#xff0c;路径1的带宽为100Mbps&#xff0c;延迟2ms&#xff0c;路径2的带宽为50Mbps&#xff0c;迟为4ms&#xff0c;如果EIGRP使用带宽和延迟的综合度量标准&#xff0c;那么该路由器选择的最佳路径是(D)。…

【Flink】WaterMark 实战

WaterMark 实战 1.WaterMark 触发详解2.实际案例 1.WaterMark 触发详解 例如&#xff0c;现在我们有了一个 [12:00:00-12:00:10) 的时间窗口&#xff0c;现在事件如下图所示顺序 A、B、C、D、E、F … 到达。 在未设置 WaterMark 的情况下&#xff0c;当元素 C 到达的时候&…

[Semi-笔记]Switching Temporary Teachers for Semi-Supervised Semantic Segmentation

目录 概要创新一&#xff1a;Dual Temporary Teacher挑战&#xff1a;解决&#xff1a; 创新二&#xff1a;Implicit Consistency Learning&#xff08;隐式一致性学习&#xff09;挑战&#xff1a;解决&#xff1a; 实验结果小结论文地址代码地址 分享一篇2023年NeurIPS的文章…

Fastjson反序列化漏洞原理与漏洞复现(基于vulhub靶场)

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【Java、PHP】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收…

python实战之宝塔部署flask项目

一. 项目 这个demo只是提供了简单的几个api接口, 并没有前端页面 # -*- coding: utf-8 -*- import flask as fk from flask import jsonify, requestapp fk.Flask(__name__)app.route(/api/hello, methods[GET]) def get_data():return hello world# 假设我们要提供一个获取用…

文章解读与仿真程序复现思路——中国电机工程学报EI\CSCD\北大核心《考虑长周期供需不平衡风险的新型电力系统规划方法》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

【羊了个羊全套源码-前端-后端-配置教程】非常火爆的在线微信朋友圈小游戏羊了个羊手游-Linux服务端源码架设教程!

羊了个羊全套源码-前端-后端-配置教程】站长推荐非常火爆的在线微信朋友圈小游戏羊了个羊手游-2024年3月27日最新打包Linux服务端源码架设教程&#xff01;

Orbit 使用指南 10|在机器人上安装传感器 | Isaac Sim | Omniverse

如是我闻&#xff1a; 资产类&#xff08;asset classes&#xff09;允许我们创建和模拟机器人&#xff0c;而传感器 (sensors) 则帮助我们获取关于环境的信息&#xff0c;获取不同的本体感知和外界感知信息。例如&#xff0c;摄像头传感器可用于获取环境的视觉信息&#xff0c…

Django 三板斧、静态文件、request方法

【一】三板斧 【1】HttpResponse &#xff08;1&#xff09;介绍 HttpResponse是Django中的一个类&#xff0c;用于构建HTTP响应对象。它允许创建并返回包含特定内容的HTTP响应。 &#xff08;2&#xff09;使用 导入HttpResponse类 from django.http import HttpResponse创…

Centos7 防火墙iptables?

Centos7 防火墙iptables&#xff1f; 文章目录 Centos7 防火墙iptables&#xff1f;1. 介绍2. firewalld 和 iptables区别3. 区域管理概念区域管理有如下几种不同的初始化区域&#xff1a; 4.iptables的配置1.简述2.基本原理3.iptables传输数据包的过程4. iptables规则表和链5.…

Redis 教程系列之Redis PHP 使用 Redis(十二)

PHP 使用 Redis 安装 开始在 PHP 中使用 Redis 前&#xff0c; 我们需要确保已经安装了 redis 服务及 PHP redis 驱动&#xff0c;且你的机器上能正常使用 PHP。 接下来让我们安装 PHP redis 驱动&#xff1a;下载地址为:https://github.com/phpredis/phpredis/releases。 P…