通过Docker启动DB2,并在Spring Boot整合DB2(Druid连接池)

news2024/11/26 23:46:28

1 简介

DB2是IBM的一款优秀的关系型数据库,简单学习一下。

2 Docker安装DB2

为了快速启动,直接使用Docker来安装DB2。先下载镜像如下:

docker pull ibmcom/db2
# or
docker pull ibmcom/db2:11.5.0.0

启动数据库如下:

docker run -itd \
  --name mydb2 \
    --privileged=true \
    -p 50000:50000 \
    -e LICENSE=accept \
    -e DB2INST1_PASSWORD=pkslow \
    -e DBNAME=testdb \
    ibmcom/db2:11.5.0.0

# or 
docker run -itd \
--name mydb2 \
--privileged=true \
-p 50000:50000 \
-e LICENSE=accept \
-e DB2INST1_PASSWORD=<choose an instance password> \
-e DBNAME=testdb \
-v <db storage dir>:/database ibmcom/db2

这样获得的数据库,具体信息如下:

  • 连接URL:jdbc:db2://localhost:50000/testdb
  • 用户名:db2inst1
  • 密码:pkslow

在IDEA上连接如下:

默认的Schema为DB2INST1,测试SQL如下:

创建表:

# 创建自增主键数据库表
# 建表SQL
    CREATE TABLE TEST_SCHEMA.mytest_increment_key_table(id BIGINT NOT NULL GENERATED ALWAYS AS IDENTITY(START WITH 1,INCREMENT BY 1,NO CACHE)
    PRIMARY KEY, timer_wheel_id BIGINT NOT NULL, create_time TIMESTAMP NOT NULL);

插入数据:

insert into TEST_SCHEMA.mytest_increment_key_table(timer_wheel_id, create_time) values (1, '2022-03-06 23:12:21.333')

查询:

SELECT * FROM TEST_SCHEMA.mytest_increment_key_table;

Spring Boot整合DB2

添加相关依赖:

<?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 http://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.12</version>
        <relativePath/>
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>11</java.version>
        <project-name>druid-hibernate-db2</project-name>
    </properties>

    <groupId>org.find</groupId>
    <artifactId>${project-name}</artifactId>
    <version>1.0</version>
    <packaging>jar</packaging>

    <name>${project-name}</name>
    <description>${project-name}</description>

    <dependencies>
        <!-- ============= db2 数据库 start ============== -->
        <!--阿里druid数据库链接依赖-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.16</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

        <!-- 引入jpa -->
        <!--依赖下面的spring-boot-starter-jdbc-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <!--事务管理:原子性,一致性,隔离性,持久性-->
        <!--依赖下面的spring-jdbc-->
        <!--<dependency>-->
        <!--    <groupId>org.springframework.boot</groupId>-->
        <!--    <artifactId>spring-boot-starter-jdbc</artifactId>-->
        <!--</dependency>-->

        <!--<dependency>-->
        <!--    <groupId>org.springframework</groupId>-->
        <!--    <artifactId>spring-jdbc</artifactId>-->
        <!--    <version>4.1.0.RELEASE</version>-->
        <!--</dependency>-->

        <!--db2链接依赖-->
        <!--<dependency>-->
        <!--    <groupId>com.ibm.db2</groupId>-->
        <!--    <artifactId>db2jcc4</artifactId>-->
        <!--    <version>4.32.28</version>-->
        <!--</dependency>-->
        <dependency>
            <groupId>com.ibm.db2</groupId>
            <artifactId>jcc</artifactId>
        </dependency>
        <!-- ============= db2 数据库 end ============== -->

        <!-- ================== 应用 =================== -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>

        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>31.1-jre</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>2.0.32</version>
        </dependency>

        <!-- javax api -->
        <dependency>
            <groupId>javax.inject</groupId>
            <artifactId>javax.inject</artifactId>
            <version>1</version>
        </dependency>

        <!-- 上边引入 parent,因此 下边无需指定版本 -->
        <!-- 包含 mvc,aop 等jar资源 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

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

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

    <build>
        <plugins>
            <!-- 解决资源文件的编码问题 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <configuration>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>

            <!-- maven打source包 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
                <executions>
                    <execution>
                        <id>attach-sources</id>
                        <!--<phase>verify</phase>-->
                        <goals>
                            <!--jar, jar-no-fork-->
                            <goal>jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <!-- spring Boot在编译的时候, 是有默认JDK版本的, 这里自定义指定JDK版本 -->
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>11</source>
                    <target>11</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>

            <!--拷贝依赖jar到指定的目录-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <executions>
                    <execution>
                        <id>copy-dependencies</id>
                        <phase>package</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${project.build.directory}/lib</outputDirectory>
                            <overWriteReleases>false</overWriteReleases>
                            <overWriteSnapshots>false</overWriteSnapshots>
                            <overWriteIfNewer>true</overWriteIfNewer>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <configuration>
                    <archive>
                        <manifest>
                            <!-- maven-jar-plugin用于生成META-INF/MANIFEST.MF文件的部分内容,  -->
                            <addClasspath>true</addClasspath>
                            <!-- 指定依赖包所在目录。 -->
                            <classpathPrefix>lib/</classpathPrefix>
                            <!-- 指定MANIFEST.MF中的Main-Class,  -->
                            <mainClass>org.fiend.MySpringbootApp</mainClass>
                            <useUniqueVersions>false</useUniqueVersions>
                        </manifest>
                    </archive>
                    <excludes>
                        <!--<exclude>*.properties</exclude>-->
                        <!--<exclude>*.yml</exclude>-->
                        <!--<exclude>*.xml</exclude>-->
                        <!--<exclude>org/fiend/controller/HomeController.class</exclude>-->
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

配置相关属性:

# tidb 环境配置
server:
  port: 8100
  max-http-header-size: 8192
  tomcat:
    max-connections: 10000 # 最大连接数, 默认为10000
    accept-count: 500 # 最大连接等待数, 默认100
    threads:
      max: 475  # 最大工作线程数, 默认200
      min-spare: 400 #最小工作线程数, 默认10
  servlet:
    encoding:
      charset: UTF-8
      force: true
      enabled: true
logging:
  level:
    root: info
spring:
  application:
    name: druid-hibernate-db2
  main:
    allow-bean-definition-overriding: true
  datasource:
    url: jdbc:db2://192.168.1.22:50000/MYTEST:currentSchema=TEST_SCHEMA;
    username: username
    password: 123123
    driver-class-name: com.ibm.db2.jcc.DB2Driver
#    type: com.alibaba.druid.pool.DruidDataSource
    type: com.alibaba.druid.pool.DruidDataSource

    # 连接池配置
    initial-size: 5
    max-active: 20
    max-idle: 10
    min-idle: 5
#    # ============================== druid ============================== #
    druid:
      # 最大活跃数
      maxActive: 20
      # 初始化数量
      initialSize: 1
      # 最大连接等待超时时间
      maxWait: 60000
      # 打开PSCache, 并且指定每个连接PSCache的大小
      poolPreparedStatements: true
      maxPoolPreparedStatementPerConnectionSize: 20
      #通过connectionProperties属性来打开mergeSql功能;慢SQL记录
      #connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
      minIdle: 1
      timeBetweenEvictionRunsMillis: 60000
      minEvictableIdleTimeMillis: 300000
#      validationQuery: select 1 from dual
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      #配置监控统计拦截的filters, 去掉后监控界面sql将无法统计,'wall'用于防火墙
      filters: stat, wall, log4j

  # ============================= spring jpa 配置 ============================= #
  jpa:
    # 禁止 hibernate sql 输出
    show-sql: false
    database-platform: org.hibernate.dialect.DB2Dialect
    hibernate:
    # create, create-drop, update, none 和 validate 五个属性
    # create :     Create the schema and destroy previous data. 会根据model类来生成表,但是每次运行都会删除上一次的表,重新生成表,哪怕2次没有任何改变
    # create-drop : Create and then destroy the schema at the end of the session.
    #               根据model类生成表,但是sessionFactory一关闭,表就自动删除
    # update : Update the schema if necessary. 最常用的属性, 也根据model类生成表,即使表结构改变了,表中的行仍然存在,不会删除以前的行
    # validate : Validate the schema, make no changes to the database.
    #                只会和数据库中的表进行比较,不会创建新表, 但是会插入新值
    # none :   Disable DDL handling.
    # 这里优先级较低(相对hbm2ddl.auto),不会生效
      ddl-auto: none
    properties:
      hibernate:
        dialect: org.hibernate.dialect.DB2Dialect
        # 用于配置自动创建、更新或验证数据库表结构的行为
        # 1. create:每次应用程序启动时,Hibernate 会删除现有的数据库表并重新创建它们。这是最简单的选项,但也是最危险的选项,因为它会丢失所有现有数据。
        # 2. update:每次应用程序启动时,Hibernate 会检查数据库表结构与映射文件(或实体类)的差异,并根据需要更新表结构。如果表不存在,Hibernate将创建新表;如果表已经存在,它将添加缺少的列或索引。但是,它不会删除或修改现有的列或约束。这是在开发和测试环境中常用的选项。
        # 3. validate:Hibernate 会在应用程序启动时验证数据库表结构与映射文件(或实体类)是否匹配,但不会对其进行任何更改。如果存在结构不匹配的情况,Hibernate会抛出异常并停止应用程序启动。
        # 4. none:Hibernate 不会自动创建、更新或验证数据库表结构。这意味着您需要手动管理数据库表结构的创建和更新。
        # 请注意,虽然 hbm2ddl.auto 属性在开发和测试环境中可能很方便,但在生产环境中慎重使用。
        # 在生产环境中,建议手动管理数据库表结构,并使用数据库迁移工具(如Flyway或Liquibase)来进行版本控制和演化
        hbm2ddl.auto: none
        jdbc.lob.non_contextual_creation: true
        format_sql: true
        temp:
          # 兼容SpringBoot2.X, 关闭 Hibernate尝试验证Mysql的CLOB特性
          use_jdbc_metadata_defaults: false

创建Entity:

package org.fiend.entity;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.springframework.format.annotation.DateTimeFormat;

import javax.persistence.*;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.sql.Timestamp;

/**
 * @author langpf 2023/06/10
 */
@Entity
@Table(catalog = "TEST_SCHEMA", name = "mytest_increment_key_table")
public class IncrementKeyEntity implements Serializable {
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "timer_wheel_id", nullable = false)
    private Long timerWheelId;

    @NotNull(message = "create_time 不可为空!")
    @JsonProperty("create_time")
    @Column(name = "create_time", nullable = false, columnDefinition = "timestamp")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSS")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSS")
    private Timestamp createTime;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Long getTimerWheelId() {
        return timerWheelId;
    }

    public void setTimerWheelId(Long timerWheelId) {
        this.timerWheelId = timerWheelId;
    }

    public Timestamp getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Timestamp createTime) {
        this.createTime = createTime;
    }
}

创建Repository类用于操作数据库:

package org.fiend.repository;

import org.fiend.entity.IncrementKeyEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

/**
 * @author langpf 2018/12/10
 */
@Repository
public interface IncrementKeyRepo extends JpaRepository<IncrementKeyEntity, Long> {
}

测试方法

IncrementKeyController.java
package org.fiend.c.web.controller;

import com.alibaba.fastjson.JSONObject;
import org.fiend.c.web.service.IncrementKeyTestService;
import org.fiend.entity.IncrementKeyEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * @author 86133 2023-07-11 15:43:00
 */
@RestController
public class IncrementKeyController {
    Logger log = LoggerFactory.getLogger(getClass());

    @Autowired
    IncrementKeyTestService incrementKeyTestService;

    @RequestMapping(value = "getData")
    public List<IncrementKeyEntity> getData() {
        return incrementKeyTestService.getData();
    }

    @RequestMapping(value = "insertByJdbc")
    public String insertByJdbc() {
        return incrementKeyTestService.insertByJdbc();
    }

    @RequestMapping(value = "insertByHibernate")
    public String insertByHibernate() {
        return incrementKeyTestService.insertByHibernate();
    }

    @RequestMapping(value = "batchInsertByJdbc")
    public JSONObject batchInsertByJdbc(int count) {
        incrementKeyTestService.batchInsertByJdbc(count);
        return incrementKeyTestService.getIncrementSpendTime();
    }

    @RequestMapping(value = "batchInsertByHibernate")
    public JSONObject batchInsertByHibernate(int count) {
        incrementKeyTestService.batchInsertByHibernate(count);
        return incrementKeyTestService.getIncrementSpendTime();
    }

    @RequestMapping(value = "clearSpendTime")
    public String clearSpendTime() {
        return incrementKeyTestService.clearSpendTime();
    }

    @RequestMapping(value = "getIncrementSpendTime")
    public JSONObject getIncrementSpendTime() {
        return incrementKeyTestService.getIncrementSpendTime();
    }
}

 IncrementKeyTestService.java

package org.fiend.c.web.service;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import org.fiend.entity.IncrementKeyEntity;
import org.fiend.repository.IncrementKeyRepo;
import org.fiend.util.DateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * @author Administrator
 */
@Service
public class IncrementKeyTestService {
    Logger log = LoggerFactory.getLogger(getClass());

    @Autowired
    JdbcTemplate jdbcTemplate;

    @Autowired
    IncrementKeyRepo incrementKeyRepo;

    AtomicLong maxSpendTime = new AtomicLong(0);
    AtomicLong totalSpendTime = new AtomicLong(0);
    AtomicInteger totalCount = new AtomicInteger(0);

    private final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    private final ReentrantReadWriteLock.WriteLock writeLock = readWriteLock.writeLock();

    @Transactional
    public List<IncrementKeyEntity> getData() {
        return incrementKeyRepo.findAll();
    }

    public String insertByJdbc() {
        long start = System.currentTimeMillis();
        String msg = "insert user failed!";
        String sql2 = "insert into TEST_SCHEMA.mytest_increment_key_table(timer_wheel_id, create_time) values (?, ?)";
        int result = jdbcTemplate.update(sql2, 2, DateUtil.getTimestamp());
        if (result < 1) {
            log.error(msg);
            throw new RuntimeException(msg);
        }
        long spendTime = System.currentTimeMillis() - start;

        calcSpendTime(spendTime);
        log.info("spend time: {}ms", spendTime);

        return "ok";
    }

    public String insertByHibernate() {
        IncrementKeyEntity incrementKeyEntity;
        incrementKeyEntity = new IncrementKeyEntity();
        incrementKeyEntity.setTimerWheelId((long) 2);
        incrementKeyEntity.setCreateTime(DateUtil.getTimestamp());

        long start = System.currentTimeMillis();
        incrementKeyRepo.save(incrementKeyEntity);
        long spendTime = System.currentTimeMillis() - start;

        calcSpendTime(spendTime);

        log.info("spend time: {}ms", spendTime);

        return "ok";
    }

    public void batchInsertByJdbc(int count) {
        clearSpendTime();

        int loopTimes = 10;
        int i = loopTimes;
        while (i > 0) {
            List<Object[]> batchArgs = Lists.newArrayList();
            int j = count;
            while (j > 0) {
                batchArgs.add(new Object[]{j, DateUtil.getTimestamp()});
                j--;
            }

            String sql2 = "insert into mytest_increment_key_table(timer_wheel_id, create_time) values (?, ?)";
            long start = System.currentTimeMillis();
            int[] result = jdbcTemplate.batchUpdate(sql2, batchArgs);
            long spendTime = System.currentTimeMillis() - start;
            log.info("spendTime: {}ms, result: {}", spendTime, result);

            calcSpendTime(spendTime);

            i--;
        }

        log.info("batch size: {}, maxSpendTime: {}ms, avg spend time: {}ms", count,
                maxSpendTime.get(), totalSpendTime.get() / loopTimes);
    }

    public void batchInsertByHibernate(int count) {
        clearSpendTime();

        int loopTimes = 10;
        int i = loopTimes;
        while (i > 0) {
            List<IncrementKeyEntity> list = Lists.newArrayList();
            int j = count;
            IncrementKeyEntity incrementKeyEntity;
            while (j > 0) {
                incrementKeyEntity = new IncrementKeyEntity();
                incrementKeyEntity.setTimerWheelId((long) 2);
                incrementKeyEntity.setCreateTime(DateUtil.getTimestamp());
                list.add(incrementKeyEntity);
                j--;
            }

            long start = System.currentTimeMillis();
            incrementKeyRepo.saveAll(list);
            long spendTime = System.currentTimeMillis() - start;

            log.info("spend time: {}ms", spendTime);

            calcSpendTime(spendTime);

            i--;
        }

        log.info("batch size: {}, maxSpendTime: {}ms, avg spend time: {}ms", count,
                maxSpendTime.get(), totalSpendTime.get() / loopTimes);
    }

    public String clearSpendTime() {
        maxSpendTime.set(0);
        totalSpendTime.set(0);
        totalCount.set(0);

        log.info("max spend time: {}ms, avg spend time: {}ms",
                maxSpendTime.get(), totalCount.get() == 0 ? 0 : totalSpendTime.get() / totalCount.get());

        return "ok";
    }

    public JSONObject getIncrementSpendTime() {
        JSONObject json = new JSONObject();
        json.put("maxSpendTime", maxSpendTime.get() + "ms");
        json.put("avgSpendTime", totalCount.get() == 0 ? 0 + "ms" : totalSpendTime.get() / totalCount.get() + "ms");

        log.info(JSONObject.toJSONString(json));

        return json;
    }

    private void calcSpendTime(long spendTime) {
        writeLock.lock();
        if (spendTime > maxSpendTime.get()) {
            maxSpendTime.set(spendTime);
        }
        writeLock.unlock();
        totalCount.incrementAndGet();
        totalSpendTime.addAndGet(spendTime);
    }
}

表数据如下:

Hibernate与Jdbc测试结果

# 建表SQL
    CREATE TABLE TEST_SCHEMA.mytest_increment_key_table(id BIGINT NOT NULL GENERATED ALWAYS AS IDENTITY(START WITH 1,INCREMENT BY 1,NO CACHE)
    PRIMARY KEY, timer_wheel_id BIGINT NOT NULL, create_time TIMESTAMP NOT NULL);

    ## insert sql
    insert into TEST_SCHEMA.mytest_increment_key_table(timer_wheel_id, create_time) values (1, '2022-03-06 23:12:21.333')

# ---------------- IncrementKey测试 ---------------- #

### springboot 启动
    测试机器: (2核1G)
    启动参数: java -jar -Xms868m -Xmx868m druid-hibernate-db2-1.0.jar

## 单条数据写入效率测试

### 测试参数
    jmeter 线程数:90, 常数吞吐量: 21000.0/min, 持续时间90s

### 测试数据
    #### 调用 insertByJdbc 方法
        "avgSpendTime": "9ms", "maxSpendTime": "277ms", 吞吐量: 333/sec
    
    #### 调用 insertByHibernate 方法
         "avgSpendTime": "11ms", "maxSpendTime": "351ms", 吞吐量: 329/sec
    
### 结论
    采用jdbc写入, 吞吐量和平均耗时均略优于Hibernate方式,因此推荐, 采用jdbc的方式写入数据

## 批量写入效率测试

### 测试数据
    调用 batchInsertByJdbc 方法
batch size: 10, "avgSpendTime":"16ms","maxSpendTime":"44ms"
batch size: 20, "avgSpendTime":"22ms","maxSpendTime":"28ms"
batch size: 30, "avgSpendTime":"34ms","maxSpendTime":"41ms"
batch size: 40, "avgSpendTime":"43ms","maxSpendTime":"69ms"
batch size: 50, "avgSpendTime":"53ms","maxSpendTime":"63ms"

    调用 batchInsertByHibernate 方法
batch size: 10, "avgSpendTime":"79ms",  "maxSpendTime":"381ms"  
batch size: 20, "avgSpendTime":"88ms",  "maxSpendTime":"143ms"  
batch size: 30, "avgSpendTime":"118ms", "maxSpendTime":"126ms"  
batch size: 40, "avgSpendTime":"147ms", "maxSpendTime":"161ms"
batch size: 50, "avgSpendTime":"192ms", "maxSpendTime":"253ms"

### 结论
    在相同batch size下, 批量写入, 无论是平均耗时, 还是最大耗时, Jdbc均远远优于Hibernate.

 


References:

Docker Image

Statements Insert

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

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

相关文章

【树上操作】定长裁剪 CF1833 G

Problem - G - Codeforces 题意&#xff1a; 给定一棵n个节点的树&#xff0c;请你减掉一些边&#xff0c;使得剪掉后的每个树只有三个节点&#xff0c; 如果可以&#xff0c;第一行返回减掉边的数量&#xff0c;第二行返回减掉边的编号&#xff1b;如果无解&#xff0c;输出…

opencv 图像腐蚀膨胀 erode dilate

#include "iostream" #include "opencv2/opencv.hpp" using namespace std; using namespace cv;int main() {Mat img, dst, dstbin, distancetransform,rel, rel2;img imread("m3.jpg");//转为灰度图cvtColor(img, dst, COLOR_BGR2GRAY);//二…

springcloudAlibaba之nacos集群部署和nginx负载均衡

1.环境准备 nacos server安装包&#xff1a;https://github.com/alibaba/nacos nginx安装包&#xff1a;https://nginx.org/en/download.html 2、nacos配置 将下载好的nacos-server的压缩包解压好以后&#xff0c;复制出N份&#xff08;这里取决于你集群的数量&#xff09;&…

AC自动机(java)

AC自动机 AC自动机介绍代码演示 indexTree AC自动机介绍 AC自动机算法是一种基于Trie树和有限状态机的字符串匹配算法。它在查找字符串时&#xff0c;利用额外的失配指针进行回退&#xff0c;转向其他分支&#xff0c;避免重复匹配前缀&#xff0c;从而提高算法效率。当一个字典…

编译内联导致内存泄漏的问题定位修复

作者&#xff1a;0x264 问题 线上长时间存在一个跟异步 inflate 相关的量级较大的内存泄漏&#xff0c;如下所示&#xff1a; 第一次分析 从内存泄漏粗略看有几个信息&#xff1a; 被泄漏的Activity有很多&#xff0c;所以可能跟某个具体业务的关系不大引用链特别短&#xf…

SkyWalking链路追踪中span全解

基本概念 在SkyWalking链路追踪中&#xff0c;Span&#xff08;跨度&#xff09;是Trace&#xff08;追踪&#xff09;的组成部分之一。Span代表一次调用或操作的单个组件&#xff0c;可以是一个方法调用、一个HTTP请求或者其他类型的操作。 每个Span都包含了一些关键的信息&am…

yaml语法详解

#kv #对空格的严格要求十分高 #注入到我们的配置类中 #普通的keyvalue name: qinjiang#对象 student:name: qingjiangage: 3#行内写法 student1: {name: qinjiang,age: 3}#数组 pets:- cat- dog- pigpet: [cat,dog,pig]yaml可以给实体类赋值 person:name: kuangshenage: 19happ…

css——box-sizing属性

含义 盒子模型由四部分构成&#xff0c;外边距(margin), 边框(border),内边距(padding), 内容content box-sizing 就是指定盒子的大小和结构的。 box-sizing: content-box; //默认值 内容真正宽度 设置的宽度box-sizing: border-box; // 内容真正宽度width 设置的width- 左右p…

LabVIEW可重入VI,VI模板和动态VI之间的差异

LabVIEW可重入VI&#xff0c;VI模板和动态VI之间的差异 应该在何时使用可重入VI、模板VI和动态调用VI&#xff1f;这三种类型之间有什么区别&#xff1f; 可重入VI 当想要同时运行同一VI的多个实例时&#xff0c;将使用可重入VI。当VI不可重入时&#xff0c;VI只有一个数据空…

浏览器对跨域请求携带Cookie的方法

文章目录 一、前后端协商配置1.1 前端页面搭建1.2后端服务器搭建 二、配置允许跨域浏览器三、Chrome浏览器安装ModHeader插件 企业开发时会分开发环境、测试环境以及生产环境&#xff0c;但是有的企业开发只有真正发布到线上的生产环境的流程才会严格配置&#xff0c;有的项目开…

C++线性技巧,STL

例题1&#xff1a;字串计算 样例输入 10101 样例输出 0 2 01 2 1 3 10 2 101 2 直接上代码&#xff1a; #include<iostream> #include<string> #include<map> using namespace std; map<string,int>mp;//用map存储每一个子串出现的次数 string str…

漏洞复现-yapi远程执行命令漏洞复现

目录 漏洞原理漏洞发现漏洞描述影响范围 yapi学习漏洞复现环境搭建exp 入侵检测与防御参考 漏洞原理 漏洞发现 查看issue2229 漏洞描述 网站开放注册功能时可随意注册&#xff0c;设置全局mock脚本可执行任意代码。 影响范围 Yapi < 1.9.2 yapi学习 YApi 是高效、易…

Docker(四)

文章目录 1. docker其他命令补充2. docker-registry使用3. docker-hub的使用4. 企业级私有仓库harbor4.1 harbor安装4.2 harbor配置https4.3 harbor常见使用4.3.1 harbor新建项目仓库4.3.2 harbor创建用户4.3.3 harbor仓库管理4.3.4 harbor复制管理4.3.5 harbor删除镜像 5. doc…

【JavaEE】Spring中注解的方式去获取Bean对象

【JavaEE】Spring的开发要点总结&#xff08;3&#xff09; 文章目录 【JavaEE】Spring的开发要点总结&#xff08;3&#xff09;1. 属性注入1.1 Autowired注解1.2 依赖查找 VS 依赖注入1.3 配合Qualifier 筛选Bean对象1.4 属性注入的优缺点 2. Setter注入2.1 Autowired注解2.2…

【漏洞复现】​金蝶云星空管理中心反序列化命令执行漏洞(RCE)

文章目录 前言声明一、系统简介二、漏洞描述三、影响版本四、漏洞复现五、整改意见 前言 ​金蝶云星空管理中心存在反序列化命令执行,攻击者可通过该漏洞获取敏感信息&#xff0c;进而接管服务器。 声明 请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文…

Mybatis-plus 配置自定义sql(.xml文件)查询语句的步骤

这是使用Mybatis-plus 的自动生成实体类代码生成.xml文件&#xff0c; 所以他会在java目录下&#xff0c;不在resources目录下 如果在java目录下的xml文件&#xff0c;需要分别配置application.yml和pom.xml文件 application.yml 文件进行以下配置&#xff1a; mybatis-plus…

视频增强技术-对比度增强

在图像处理中&#xff0c;由于获取的图像质量不好&#xff0c;需要通过对比度增强来提升图片质量&#xff0c;主要解决的是由于图像灰度级范围较小造成的对比度较低的问题&#xff0c;作用是使图像的灰度级范围放大&#xff0c;从而让图像更加清晰。主要对比度增强方法包括线性…

CentOS 7.9 安装 mydumper(RPM方式)

链接&#xff1a;https://pan.baidu.com/s/1sGhtiKPOmJw1xj0zv-djkA?pwdtaoz 码&#xff1a;taoz 开始正文啦&#xff1a; rpm -ivh mydumper-0.14.5-3-zstd.el7.x86_64.rpm 问题如下&#xff1a; 解决&#xff1a; yum -y install epel-release yum install -y libzstd …

分布式消息流处理平台kafka(一)-kafka单机、集群环境搭建流程及使用入门

1.kafka概述 1.1 kafka的前世今生 kafka最初是LinkedIn的一个内部基础设施系统。最初开发的起因是&#xff0c;LinkedIn虽然有了数据库和其他系统可以用来存储数据&#xff0c;但是缺乏一个可以帮助处理持续数据流的组件。 所以在设计理念上&#xff0c;开发者不想只是开发一…

通过 EXPLAIN 分析 SQL 的执行计划

通过 EXPLAIN 分析 SQL 的执行计划 EXPLAIN SELECTleave_station_area_id,ROUND( ( SUM( station_dist ) / 1000 ) / ( SUM( station_travel_time ) / 60 ), 2 ) evnPeakAvgSpeedFROMV3_SHIFT_ANALYSISWHERESTAT_DATE DATE_SUB( CURRENT_DATE, INTERVAL 1 DAY )AND LEAVE_STA…