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

文章目录

  • 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>

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

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

相关文章

【文献阅读】一种多波束阵列重构导航抗干扰算法

引言 针对导航信号在近地表的信号十分微弱、抗干扰能力差的问题&#xff0c;文章提出了自适应波束形成技术。 自适应波束形成技术可以分为调零抗干扰算法和多波束抗干扰算法。 调零抗干扰算法主要应用功率倒置技术&#xff0c;充分利用导航信号功率低于环境噪声功率的特点&…

Generative AI原理本质、技术内核及工程实践之基于Vertex AI的大模型 (二)Generative AI on Vertex AI 概览

LlaMA 3 系列博客 基于 LlaMA 3 LangGraph 在windows本地部署大模型 &#xff08;一&#xff09; 基于 LlaMA 3 LangGraph 在windows本地部署大模型 &#xff08;二&#xff09; 基于 LlaMA 3 LangGraph 在windows本地部署大模型 &#xff08;三&#xff09; 基于 LlaMA…

如何挑选靠谱的软件开发公司?

在数字化的大潮中&#xff0c;企业商家都明白一个道理&#xff1a;没有一艘强大的软件开发公司“战舰”&#xff0c;想在商海中乘风破浪可不容易。但问题是&#xff0c;市场上那么多软件开发公司&#xff0c;如何挑选出最靠谱的那一家呢&#xff1f;别急&#xff0c;这篇文章就…

进程和内存管理

内存的使用和剩余情况 当前cpu的负载情况 找进程的id 结束某个进程 检查内存&#xff1a; 方法一&#xff1a;/proc/meminfo注意&#xff1a;这是个伪文件&#xff0c;这个文件记录了内存的相关信息&#xff0c;不可以用vi打开&#xff0c;应该用cat查看方法二&#xff1a;fre…

数字员工将重塑工作与生产的未来格局?

数字员工&#xff0c;由AI、机器学习和自动化技术驱动&#xff0c;正逐渐取代或协助人类完成从基础到高端的任务&#xff0c;极大提升工作效率&#xff0c;并改变工作认知。它们不仅影响各行业&#xff0c;还重塑人与机器、社会、自然的关系。与二十世纪末的国企下岗变革相比&a…

SaaS企业营销:如何通过联盟计划实现销售增长?

联盟营销计划在国外saas行业非常盛行&#xff0c;国内如何借鉴国外的成功案例运用联盟计划实现销售增长呢&#xff1f;林叔今天以最近新发现的leadpages为例分享下经验。 Leadpages是一款用户友好的落地页制作工具&#xff0c;提供多种预设计模板、A/B测试和分析功能&#xff0…

实例详解C/C++中static与extern关键字的使用

目录 1、概述 2、编译C++代码时遇到的变量及函数重复定义的问题 3、用 extern 声明外部变量 4、extern与全局函数 5、为何在变量和函数前添加一个static关键字编译就没问题了呢? 6、静态局部变量 7、函数的声明与定义都放置到一个头文件中,不使用static,通过宏控制去…

安灯(andon)系统如何帮助工厂流水线实现精益生产

在当今竞争激烈的制造业领域&#xff0c;实现精益生产已成为众多工厂追求的目标。而安灯&#xff08;Andon&#xff09;系统在这一过程中发挥着至关重要的作用。 安灯&#xff08;Andon&#xff09;系统通过及时反馈和沟通机制&#xff0c;让生产过程中的问题能够迅速被察觉和解…

Si24R05—高度集成的低功耗 2.4G+125K SoC 芯片

Si24R05是一款高度集成的低功耗SoC芯片&#xff0c;具有低功耗、Low Pin Count、宽电压工作范围&#xff0c;集成了13/14/15/16位精度的ADC、LVD、UART、SPI、I2C、TIMER、WUP、IWDG、RTC、无线收发器、3D低频唤醒接收器等丰富的外设。内核采用RISC-V RV32IMAC&#xff08;2.6 …

VOP | Point Cloud

目录 Point Cloud Open —— 打开点云文件并搜索源位置周围的点 Point Cloud Find —— 返回最近点的点号列表 Point Cloud Find Radius —— 返回最近点的点号列表并考虑被搜索点的半径 Point Cloud Filter —— 过滤查询到的点以生成加权值 Point Cloud Farthest —— 查…

第二证券股市资讯:半导体,突发!

半导体又现突发&#xff01; 商场忽然传出&#xff0c;拜登政府正在考虑约束我国获取应用在人工智能&#xff08;AI) 芯片上的全栅级晶体管技能&#xff08;Gate-all-around, GAA) &#xff0c;但不过现在还不清楚美国官员何时会做出最终决议。从趋势来看&#xff0c;这意味着…

【Ardiuno】实验ESP32单片机自动配置Wifi功能(图文)

这里小飞鱼按照ESP32的示例代码&#xff0c;实验一下wifi的自动配置功能。所谓的自动配置&#xff0c;就是不用提前将wifi的名称和密码写到程序里&#xff0c;这样可以保证程序在烧录上传后&#xff0c;可以通过手机端的软件来进行配置&#xff0c;可以避免反复修改代码&#x…

【产品经理】ERP对接电商平台

电商ERP对接上游平台&#xff0c;会需要经历几个步骤环节&#xff0c;包括店铺设置等。 电商ERP对接上游电商平台&#xff0c;其主要设置为店铺设置、商品同步、库存同步&#xff0c;本次讲解下店铺设置应该如何进行设置&#xff0c;以及在设置过程中的可能出现的踩坑事项。 …

JAVA面试题:Redis分布式锁

Redis分布式锁 分布式锁使用的场景 集群情况下的定时任务,抢单,幂等性等场景 抢券场景 查询库存 -> 扣减库存 多个并发线程同时查询库存,出现超卖问题 添加互斥锁 所有线程执行操作之前必须尝试获取锁 保证一次只有一个线程能走查询库存->扣减库存的流程 Redis分…

物业管理的隐形杀手:纸质点检表,你还在用吗?

在日常的生活中&#xff0c;我们经常会看到小区物业保洁、客服人员在工作岗位忙忙碌碌&#xff0c;但忽略了默默为我们提供舒适环境的“隐形守护者”——物业设施设备。然而&#xff0c;一旦这些设备出现故障&#xff0c;我们的日常生活就会陷入混乱。那么&#xff0c;如何确保…

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

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

Keepalived LVS群集

一、Keepalived案例分析 企业应用中&#xff0c;单台服务器承担应用存在单点故障的危险 单点故障一旦发生&#xff0c;企业服务将发生中断&#xff0c;造成极大的危害 二、Keepalived工具介绍 专为LVS和HA设计的一款健康检查工具 支持故障自动切换&#xff08;Failover&#…

乡镇联盟一镇一码联合创始人第一届第二次研讨会在中山圆满落幕

乡镇联盟一镇一码联合创始人第一届第二次研讨会在中山圆满落幕 近日&#xff0c;由“乡镇联盟一镇一码”项目的联合创始人余向强先生亲自主持的第一届第二次研讨会在中山成功举行。此次研讨会汇聚了来自全国各地的乡镇代表、行业专家及联盟核心成员&#xff0c;共同探讨乡镇发…

面向计算病理学的通用基础模型| 文献速递-视觉通用模型与疾病诊断

Title 题目 Towards a general-purpose foundation model for computational pathology 面向计算病理学的通用基础模型 01 文献速递介绍 组织图像的定量评估对于计算病理学&#xff08;CPath&#xff09;任务至关重要&#xff0c;需要从全幻灯片图像&#xff08;WSIs&…

ITIL4背景下,ITSM产品应具备哪些特点?

点击进入IT管理知识库 随着信息技术的不断发展和普及&#xff0c;IT服务管理&#xff08;ITSM&#xff09;在企业中的地位日益凸显。而在ITIL4框架的指导下&#xff0c;ITSM产品的特点也随之发生了变化&#xff0c;更加注重灵活性、数字化和服务导向。本文将就ITIL4背景下&…