SpringBoot+MyBatis批量插入数据的三种方式

news2024/10/7 4:27:02

文章目录

  • 1. 背景介绍
  • 2. 方案介绍
    • 2.1 第一种方案,用 for语句循环插入(不推荐)
    • 2.2 第二种方案,利用mybatis的foreach来实现循环插入(不推荐)
    • 2.3 第三种方案,使用sqlSessionFactory实现批量插入(推荐)
  • 3. 创建Springboot项目
    • 3.1 选择Spring Initializr(springboot项目)
    • 3.2 配置属性,完成点击next
    • 3.3 项目启动类
    • 3.4 Pom文件添加依赖
    • 3.5 配置application.yml文件
    • 3.6 导入数据库
    • 3.7 项目结构
  • 4. 方案测试
    • 4.1 测试第一种方案,用 for语句循环插入 10万 条数据
      • 1. 通过postman调用接口
      • 2. 查看耗时情况(20万条数据需要10几分钟!!!)
      • 3. 数据库数据
    • 4.2 测试第二种方案,用 for语句循环插入 10万 条数据
      • 1. 通过postman调用接口
      • 2. 查看耗时情况(测试2000,10000,50000,100000条数据)
    • 4.3 测试第三种方案,使用sqlSessionFactory实现批量插入 20万 条数据
      • 1. 通过postman调用接口
      • 2. 查看耗时情况(20万条数据大概17秒)
      • 3. 数据库数据
  • 6. 部分代码
    • 6.1 UserController
    • 6.2 UserServiceImpl
    • 6.3 UserMapper.xml

原文链接:SpringBoot+MyBatis批量插入数据的三种方式

1. 背景介绍

在开发过程中,我们经常会遇到往数据库表中插入大量数据的场景,比如excel批量导入数据。那么该如何快速地插入数据呢?

我们可以考虑使用批量插入来实现,实测100000条数据添加,后附具体实现代码。

2. 方案介绍

2.1 第一种方案,用 for语句循环插入(不推荐)

用一个 for 循环,把数据一条一条地插入。

insert into t_user values (?, ?, ?, ?, ?)
/**
* 第一种方案,用 for语句循环插入 10万 条数据
*/
@GetMapping("/test1")
public String test1(int count) {
    StopWatch stopWatch = new StopWatch();
    stopWatch.start();
    for (int i = 0; i < count; i++) {
        User user = new User();
        user.setName("方案1测试" + i);
        user.setGender("男");
        user.setUsername("方案1测试");
        user.setPassword("方案1测试");
        user.setRemark("方案1测试");
        userService.saveInfo(user);
    }
    stopWatch.stop();
    System.out.println("第一种方案,用 for语句循环插入耗时:" + stopWatch.getTotalTimeMillis());
    return "操作完成";
}

优势:JDBC 中的 PreparedStatement 有预编译功能,预编译之后会缓存起来。

之后SQL执行会比较快,且 JDBC可以开启批处理,这个批处理执行非常给力。

劣势:这种方式插入大量数据时,效率非常底下,不推荐。很多时候我们的 SQL 服务器和应用服务器可能并不是同一台,所以必须要考虑网络 IO。

如果网络 IO 比较费时间的话,那么可能会拖慢 SQL 执行的速度。

2.2 第二种方案,利用mybatis的foreach来实现循环插入(不推荐)

insert into t_user values (?, ?, ?, ?, ?) , (?, ?, ?, ?, ?) , (?, ?, ?, ?, ?)
/**
* 第二种方案,利用mybatis的foreach来实现循环插入 10万 条数据
*/
@GetMapping("/test2")
public String test2(int count) {
    StopWatch stopWatch = new StopWatch();
    stopWatch.start();
    List<User> list = new ArrayList<>();
    for (int i = 0; i < count; i++) {
        User user = new User();
        user.setName("方案2测试" + i);
        user.setGender("男");
        user.setUsername("方案2测试");
        user.setPassword("方案2测试");
        user.setRemark("方案2测试");
        list.add(user);
    }
    userService.saveList(list);
    stopWatch.stop();
    System.out.println("第二种方案,利用mybatis的foreach来实现循环插入耗时:" + stopWatch.getTotalTimeMillis());
    return "操作完成";
}
<insert id="saveList" parameterType="list">
    insert into t_user values
    <foreach collection="list" item="item" separator=",">
        (#{item.name}, #{item.gender}, #{item.username}, #{item.password}, #{item.remark})
    </foreach>
</insert>

优势:不用频繁访问数据库,一条sql搞定,效率比较高。

劣势:一当数据量太大时,会出现拼接的sql语句超长而执行失败,所以当数据量太大时,也不推荐。

二是 SQL 太长了,甚至可能需要分片后批量处理。

三是无法充分发挥 PreparedStatement 预编译的优势,SQL 要重新解析且无法复用

com.mysql.cj.jdbc.exceptions.PacketTooBigException: Packet for query is too large (4,879,714 > 4,194,304).
    You can change this value on the server by setting the 'max_allowed_packet' variable.

2.3 第三种方案,使用sqlSessionFactory实现批量插入(推荐)

@Resource
private SqlSessionFactory sqlSessionFactory;
// 关闭session的自动提交
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, false);
try {
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    list.stream().forEach(user -> userMapper.saveInfo(user));
    // 提交数据
    sqlSession.commit();
} catch (Exception e) {
    sqlSession.rollback();
} finally {
    sqlSession.close();
}

优势:这种方式可以说是集第一种和第二种方式的优点于一身,既可以提高运行效率,又可以保证大数据量时执行成功,大数据量时推荐使用这种方式。

3. 创建Springboot项目

3.1 选择Spring Initializr(springboot项目)

在这里插入图片描述

3.2 配置属性,完成点击next

在这里插入图片描述

3.3 项目启动类

在这里插入图片描述

3.4 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.7.5</version>
        <relativePath/>
    </parent>

    <groupId>com.liyh</groupId>
    <artifactId>springboot_mybatis</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot_mybatis</name>
    <description>springboot_mybatis</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--mysql驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!--jdbc 数据库连接-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <!--引入阿里数据库连接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.6</version>
        </dependency>
        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!--mybatis-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.2</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

3.5 配置application.yml文件

# 配置端口
server:
  port: 8091

spring:
  # 配置数据源
  datasource:
    url: jdbc:mysql://localhost:3306/test?useSSL=false&serverTimezone=UTC
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver

# mybatis相关配置
mybatis:
  mapper-locations: classpath*:mapper/*.xml   #指定mapper映射文件路径
  type-aliases-package: com.liyh.mybatis.entity  # 别名
  configuration:
    map-underscore-to-camel-case: true

#打印sql,保存到文件
logging:
  level:
    com.liyh.mybatis.mapper: debug

3.6 导入数据库

CREATE TABLE `t_user`  (
  `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `gender` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `remark` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '批量导入用户表' ROW_FORMAT = COMPACT;

3.7 项目结构

在这里插入图片描述

4. 方案测试

4.1 测试第一种方案,用 for语句循环插入 10万 条数据

1. 通过postman调用接口

在这里插入图片描述

2. 查看耗时情况(20万条数据需要10几分钟!!!)

在这里插入图片描述
在这里插入图片描述

3. 数据库数据

在这里插入图片描述

4.2 测试第二种方案,用 for语句循环插入 10万 条数据

1. 通过postman调用接口

在这里插入图片描述

2. 查看耗时情况(测试2000,10000,50000,100000条数据)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
当数据量达到5万条时,报错了!!!(单批次少量数据效率还可以)
在这里插入图片描述

### Cause: com.mysql.cj.jdbc.exceptions.PacketTooBigException: Packet for query is too large (5,238,915 > 4,194,304). You can change this value on the server by setting the 'max_allowed_packet' variable.
; Packet for query is too large (5,238,915 > 4,194,304). You can change this value on the server by setting the 'max_allowed_packet' variable.; nested exception is com.mysql.cj.jdbc.exceptions.PacketTooBigException: Packet for query is too large (5,238,915 > 4,194,304). You can change this value on the server by setting the 'max_allowed_packet' variable.] with root cause

com.mysql.cj.jdbc.exceptions.PacketTooBigException: Packet for query is too large (5,238,915 > 4,194,304). You can change this value on the server by setting the 'max_allowed_packet' variable.
	at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:107) ~[mysql-connector-j-8.0.31.jar:8.0.31]
	at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:916) ~[mysql-connector-j-8.0.31.jar:8.0.31]
	at com.mysql.cj.jdbc.ClientPreparedStatement.execute(ClientPreparedStatement.java:354) ~[mysql-connector-j-8.0.31.jar:8.0.31]
	at com.zaxxer.hikari.pool.ProxyPreparedStatement.execute(ProxyPreparedStatement.java:44) ~[HikariCP-4.0.3.jar:na]
	at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.execute(HikariProxyPreparedStatement.java) ~[HikariCP-4.0.3.jar:na]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_201]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_201]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_201]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_201]
	at org.apache.ibatis.logging.jdbc.PreparedStatementLogger.invoke(PreparedStatementLogger.java:59) ~[mybatis-3.5.9.jar:3.5.9]
	at com.sun.proxy.$Proxy72.execute(Unknown Source) ~[na:na]
	at org.apache.ibatis.executor.statement.PreparedStatementHandler.update(PreparedStatementHandler.java:47) ~[mybatis-3.5.9.jar:3.5.9]
	at org.apache.ibatis.executor.statement.RoutingStatementHandler.update(RoutingStatementHandler.java:74) ~[mybatis-3.5.9.jar:3.5.9]
	at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:50) ~[mybatis-3.5.9.jar:3.5.9]
	at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:117) ~[mybatis-3.5.9.jar:3.5.9]
	at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:76) ~[mybatis-3.5.9.jar:3.5.9]

4.3 测试第三种方案,使用sqlSessionFactory实现批量插入 20万 条数据

1. 通过postman调用接口

在这里插入图片描述

2. 查看耗时情况(20万条数据大概17秒)

在这里插入图片描述
在这里插入图片描述

3. 数据库数据

在这里插入图片描述

6. 部分代码

6.1 UserController

package com.liyh.mybatis.controller;

import com.liyh.mybatis.entity.User;
import com.liyh.mybatis.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StopWatch;
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.List;

/**
 * 测试接口
 *
 * @Author: liyh
 */
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    UserService userService;

    /**
     * 第一种方案,用 for语句循环插入 10万 条数据
     */
    @GetMapping("/test1")
    public String test1(int count) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        for (int i = 0; i < count; i++) {
            User user = new User();
            user.setName("方案1测试" + i);
            user.setGender("男");
            user.setUsername("方案1测试");
            user.setPassword("方案1测试");
            user.setRemark("方案1测试");
            userService.saveInfo(user);
        }
        stopWatch.stop();
        System.out.println("第一种方案,用 for语句循环插入耗时:" + stopWatch.getTotalTimeMillis());
        return "操作完成";
    }

    /**
     * 第二种方案,利用mybatis的foreach来实现循环插入 10万 条数据
     */
    @GetMapping("/test2")
    public String test2(int count) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        List<User> list = new ArrayList<>();
        for (int i = 0; i < count; i++) {
            User user = new User();
            user.setName("方案2测试" + i);
            user.setGender("男");
            user.setUsername("方案2测试");
            user.setPassword("方案2测试");
            user.setRemark("方案2测试");
            list.add(user);
        }
        userService.saveList(list);
        stopWatch.stop();
        System.out.println("第二种方案,利用mybatis的foreach来实现循环插入耗时:" + stopWatch.getTotalTimeMillis());
        return "操作完成";
    }

    /**
     * 第三种方案,使用sqlSessionFactory实现批量插入 10万 条数据
     */
    @GetMapping("/test3")
    public String test3(int count) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        List<User> list = new ArrayList<>();
        for (int i = 0; i < count; i++) {
            User user = new User();
            user.setName("方案3测试" + i);
            user.setGender("男");
            user.setUsername("方案3测试");
            user.setPassword("方案3测试");
            user.setRemark("方案3测试");
            list.add(user);
        }
        userService.saveBeach(list);
        stopWatch.stop();
        System.out.println("第三种方案,使用sqlSessionFactory实现批量插入:" + stopWatch.getTotalTimeMillis());
        return "操作完成";
    }

}

6.2 UserServiceImpl

package com.liyh.mybatis.service.impl;

import com.liyh.mybatis.entity.User;
import com.liyh.mybatis.mapper.UserMapper;
import com.liyh.mybatis.service.UserService;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

/**
 * 用户业务实现类
 *
 * @Author: liyh
 */
@Service
@Transactional
public class UserServiceImpl implements UserService {

    @Resource
    private UserMapper userMapper;

    @Resource
    private SqlSessionFactory sqlSessionFactory;

    @Override
    public void saveInfo(User user) {
        userMapper.saveInfo(user);
    }

    @Override
    public void saveList(List<User> list) {
        userMapper.saveList(list);
    }

    @Override
    public void saveBeach(List<User> list) {
        // ExecutorType.SIMPLE: 这个执行器类型不做特殊的事情。它为每个语句的执行创建一个新的预处理语句。
        // ExecutorType.REUSE: 这个执行器类型会复用预处理语句。
        // ExecutorType.BATCH: 这个执行器会批量执行所有更新语句,如果 SELECT 在它们中间执行还会标定它们是 必须的,来保证一个简单并易于理解的行为。

        // 关闭session的自动提交
        SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, false);
        try {
            UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
            list.stream().forEach(user -> userMapper.saveInfo(user));
            // 提交数据
            sqlSession.commit();
        } catch (Exception e) {
            sqlSession.rollback();
        } finally {
            sqlSession.close();
        }
    }
}

6.3 UserMapper.xml

<?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.liyh.mybatis.mapper.UserMapper">

    <insert id="saveInfo">
        insert into t_user
        values (#{name}, #{gender}, #{username}, #{password}, #{remark})
    </insert>

    <insert id="saveList" parameterType="list">
        insert into t_user values
        <foreach collection="list" item="item" separator=",">
            (#{item.name}, #{item.gender}, #{item.username}, #{item.password}, #{item.remark})
        </foreach>
    </insert>


</mapper>

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

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

相关文章

3.00003 postmaster守护线程的启动流程调用以及辅助流程的启动流程调用是怎样的

文章目录 架构图相关数据结构child_process_kinds[]数组 (launch_backend.c:179)相关函数main.cPostmasterMain(postmaster.c:489)ServerLoop(postmaster.c:1624)BackendStartup(postmaster.c:3544)postmaster_child_launch (launch_backend.c:265)StartChildProcess (postma…

肾合能量不足?揭秘手心热出汗的真相

想象一下&#xff0c;我们的身体如同一座精密的城堡&#xff0c;城堡内的每一个房间都代表着一个器官&#xff0c;而城堡的守卫——气血&#xff0c;则是维系城堡和谐稳定的重要力量。当城堡中的守卫力量不足&#xff0c;或是城堡内的环境出现紊乱时&#xff0c;城堡的某个角落…

C# 生成解决方案时出现的一些异常及解决方法

一、ResolveAssemblyReference任务意外失败 在使用VS2022生成C#解决方案时&#xff0c;出现如下错误&#xff1a; 解决方法&#xff1a; 项目的依赖项出现问题&#xff0c;重新更新一下依赖项即可 二、生成Win32资源时出错 产生这个原因的主要原因是配置的应用程序的图标文…

计算机视觉全系列实战教程:(八)图像变换-点运算、灰度变换、直方图变换

图像变换&#xff1a;点运算、灰度变换、直方图变换 1.点运算(1)What(2)Why 2.灰度变换(1)What(2)Why(作用)(3)Which(有哪些灰度变换&#xff09; 3.直方图修正(1)直方图均衡化 1.点运算 (1)What 通过点运算&#xff0c;输出图像的每个像素的灰度值仅仅取决于输入图像中相对应…

AI预测体彩排3采取888=3策略+和值012路或双胆下一测试6月11日新模型预测第1弹

很抱歉各位小伙伴&#xff0c;端午节三天去了趟外地&#xff0c;没有按时更新3D和排三的预测。前面跟大家说过&#xff0c;8码定位是关键&#xff0c;8码定位能稳定在80%的命中率&#xff0c;才有望通过缩号缩至200-250注以内通过等额方式进行投资。由于前面的模型对8码定位的效…

家用洗地机怎么选?四大行业精品集合,识别度超高

家用洗地机&#xff0c;作为一种能够高效清洁地面的清洁工具&#xff0c;不仅减轻了人们家务的轻度&#xff0c;也给人们腾出了很多空闲的时间去享受生活。但是洗地机那么多&#xff0c;我们在面对洗地机选购的时候&#xff0c;我们应该要注意哪些呢&#xff1f;下面就为大家详…

每日一练:攻防世界:base64stego

base64stego&#xff1a; 打开压缩包发现被加密&#xff0c;用winhex查看&#xff0c;发现是伪加密&#xff0c;修改文件目录区的全局方式位标记&#xff0c;成功打开压缩包&#xff0c;得到一个文本 这里我想的有三种情况&#xff1a;1.直接base64解码&#xff0c;然后看解码…

搭建个人知识库 | 手把手教你本地部署大模型

一、引言 今天给大家分享的是手把手教你如何部署本地大模型以及搭建个人知识库 读完本文&#xff0c;你会学习到 如何使用Ollama一键部署本地大模型通过搭建本地的聊天工具&#xff0c;了解ChatGPT的信息是如何流转的RAG的概念以及所用到的一些核心技术如何通过AnythingLLM这…

PGFed: Personalize Each Client’s Global Objective for Federated Learning

ICCV-2023, 文章提出显式隐式的概念,作者通过实验发现显式比隐式的效果好,显式方式通过直接与多个客户的经验风险互动来更新模型,并用泰勒展开式降为 O ( N ) O(N) O(N)通讯成本。 文章地址:arxiv code: 作者开源 贡献 1.我们发现个性化 FL 算法的显式性赋予了其更强的…

wordpress旅游网站模板

旅行社wordpress主题 简洁实用的旅行社wordpress主题&#xff0c;适用于旅行社建网站的wordpress主题模板。 https://www.jianzhanpress.com/?p4296 旅游WordPress主题 简洁实用的旅游WordPress主题&#xff0c;适合做旅游公司网站的WordPress主题模板。 https://www.jian…

Ecovadis审核的内容

Ecovadis审核的内容。Ecovadis是一家国际性的企业社会责任评估机构&#xff0c;旨在为全球供应链的可持续性发展提供评估和审核。在本文中&#xff0c;我们将从以下几个方面详细介绍Ecovadis审核的内容&#xff1a; 一、Ecovadis审核的范围和目的 Ecovadis审核的范围涵盖了各个…

新增的JDK17语法特性

一、引入 从springboot3.0开始&#xff0c;已经不支持JDK8了&#xff0c;从3.0开始&#xff0c;转变为JDK17 了解详情点击官方博客链接&#xff1a;https://spring.io/blog/2022/01/20/spring-boot-3-0-0-m1-is-now-available?spma2c6h.12873639.article-detail.24.766d46b4…

最新下载:CorelDraw 2023【软件附加安装教程】

简介&#xff1a; CorelDRAW Graphics Suite 订阅版拥有配备齐全的专业设计工具包&#xff0c;可以通过非常高的效率提供令人惊艳的矢量插图、布局、照片编辑和排版项目。价格实惠的订阅就能获得令人难以置信的持续价值&#xff0c;即时、有保障地获得独家的新功能和内容、一流…

目标检测6:采用yolov8, RK3568推理的性能

最近有个小伙伴&#xff0c;问我rk3568上推理图片&#xff0c;1秒能达到多少&#xff1f; 本次采用模型为yolov8s.rknn&#xff0c;作了一次验证。 解析一段视频文件&#xff0c;1280*720, fps 24。读取视频文件&#xff0c;然后进行推理。 通过性能优化&#xff0c;发现推理…

RPA实战案例解析,一文看懂RPA工作原理

在这个快节奏的时代&#xff0c;我们渴望更多时间追求梦想。面对电脑前堆积的数据录入和商品上架等重复工作&#xff0c;我们感到束缚。然而&#xff0c;RPA机器人——这位“数字精灵”&#xff0c;正悄然改变我们的生活。它不仅是工具&#xff0c;更是我们工作的伙伴和创新的助…

Codesys中根据时间生成随机数字

一、 说明 LTIME()函数返回LTIME 时间类型数据 这个函数产生自系统启动以来经过的时间&#xff0c;以纳秒为单位&#xff0c;以扫描周期1ms为例&#xff0c;这个函数每次获得的纳妙数是随机的&#xff0c;没有规律。 二、作用 例如用来生成0到100的随机数&#xff0c;可以用L…

WebSocket 基础使用

1.基本概念 WebSocket 支持双方通信即服务端可以主动推送给用户端&#xff0c;用户端也可以主动推送消息给服务器。前端必须进行协议升级为 WebSocket 名称值Upgradewebsocket 2. 后端代码 package com.koshi.websocket.server;import com.alibaba.fastjson.JSON; import com…

互联网医院系统源码的创新应用:预约挂号小程序开发实战

预约挂号小程序作为互联网医院系统的创新应用&#xff0c;更加贴近用户需求&#xff0c;实现了预约挂号的便捷化和智能化。本篇文章&#xff0c;笔者将带领读者进入预约挂号小程序开发的实战过程&#xff0c;探索互联网医院系统源码在小程序开发中的创新应用。 一、互联网医院系…

【大模型应用开发极简入门】微调(一):1.微调基础原理介绍、2. 微调的步骤、3. 微调的应用(Copilot、邮件、法律文本分析等)

文章目录 一. 开始微调1. 选择合适的基础模型2. 微调和少样本学习2.1. 对比微调和少样本学习2.2. 微调需要的数据量 二. 使用OpenAI API进行微调1. 数据生成1.1. JSONL的数据格式1.2. 数据生成工具1.3. 数据文件的细节注意 2. 上传数据来训练模型3. 创建微调模型4. 列出微调作业…

用 Kotlin 多平台开发构建跨平台应用程序:深入探索 KMP 模板工程

用 Kotlin 多平台开发构建跨平台应用程序&#xff1a;深入探索 KMP 模板工程 Kotlin 多平台开发 (KMP) 是一种强大的工具&#xff0c;可用于构建跨平台移动、桌面和 Web 应用程序。它提供了一种统一的代码基础&#xff0c;使开发人员能够高效地针对多个平台开发应用程序。 KM…