SpringBoot实战(二十)集成Druid连接池

news2025/4/26 23:25:16

目录

    • 一、简介
      • 1.定义
      • 2.特点
      • 3.竞品对比
    • 二、搭建测试项目
      • 1.Maven依赖
      • 2.yaml配置
        • 2.1 JDBC配置
        • 2.2 连接池配置
        • 2.3 监控配置
    • 三、测试
      • 1.查看监控页面
      • 2.单元测试
    • 四、补充:
      • 1.如何打印慢SQL?
      • 2.去除广告
      • 3.如何手动获取监控内容

一、简介

1.定义

Druid数据库连接池:是一个 Java 语言编写的高性能、高可用性的开源数据库连接池组件,有阿里巴巴开发和维护。它提供了一种可靠的、可管理的、高性能的数据库连接池解决方案,可以在 Java 应用程序中管理和复用数据库连接。

  • GitHub地址: https://github.com/alibaba/druid
  • 官方文档: https://github.com/alibaba/druid/wiki/Druid连接池介绍
  • 常见问题: https://github.com/alibaba/druid/wiki/常见问题
  • starter文档: https://github.com/alibaba/druid/tree/master/druid-spring-boot-starter
  • 监控页面: http://localhost:8080/druid/index.html

2.特点

以下是Druid连接池组件的特点:

  1. 基于开放标准:Druid连接池 完全遵循 Java 数据库连接标准(JDBC),可以与任何标准的 JDBC 驱动程序一起使用。
  2. 高性能:Druid连接池 采用了一系列优化策略和技术,包括连接池预热、连接池缓存、合理的连接分配等,以提供高并发、低延迟的数据库连接服务。
  3. 监控和统计:Druid连接池 提供了一套完善的监控和统计功能,可以实时监控连接池的使用情况、性能指标以及 SQL 执行情况,方便开发人员进行系统调优和性能优化。
  4. 安全可靠:Druid连接池 通过内置的防火墙和黑名单机制,可以预防恶意攻击和 SQL 注入等安全威胁,保证系统的安全可靠性。
  5. 扩展性强:Druid连接池 支持定制化扩展,可以根据具体业务场景和需求进行灵活的配置和编程。

3.竞品对比

以下是各种数据库连接池对比:

功能类别功能DruidHikariCPDBCPTomcat-jdbcC3P0
性能PSCache
LRU
SLB负载均衡支持
稳定性ExceptionSorter
扩展扩展FilterJdbcIntercepter
监控监控方式jmx/log/httpjmx/metricsjmxjmxjmx
支持SQL级监控
Spring/Web关联监控
诊断支持LogFilter
连接泄露诊断logAbandoned
安全SQL防注入
支持配置加密

二、搭建测试项目

源码地址: https://gitee.com/acgkaka/SpringBootExamples/tree/master/springboot-mybatis-plus-druid

1.Maven依赖

Druid 的 Maven 依赖有两种,单独依赖starter依赖,这里由于我们是 SpringBoot 集成,所以使用 starter依赖

单独依赖:

<!-- Druid -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.12</version>
</dependency>

starter依赖:

<!-- Druid -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.1.18</version>
</dependency>

2.yaml配置

官方配置示例: https://github.com/alibaba/druid/blob/master/druid-spring-boot-starter/src/test/resources/application.properties

注意: spring.datasource.type 并不一定是必须要填的,取决于使用的是 druid 的哪种依赖。

  • 如果使用的是 Druid 的 单独依赖,则必须要设置 spring.datasource.type=com.alibaba.druid.pool.DruidDataSource,否则默认还是使用 Hikari 连接池。

  • 如果使用的是 Druid 的 starter依赖,则不需要手动设置 type,会自动将数据库连接池切换为 Druid。

    而且 druid-spring-boot-starter 不需要编写配置类,简化了配置。

下面是使用 Druid 的 starter依赖 集成后的配置内容:

官方配置文档: https://github.com/alibaba/druid/tree/master/druid-spring-boot-starter

2.1 JDBC配置

方式一:配置在 spring.datasource 下

spring:
  datasource:
    # JDBC 配置
    url: jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver

方式二:配置在 spring.datasource.druid 下

spring:
  datasource:
    druid:
      # JDBC 配置
      url: jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
      username: root
      password: root
      driver-class-name: com.mysql.cj.jdbc.Driver

2.2 连接池配置

spring:
  datasource:
    druid:
      # ########## 连接池配置-开始 ##########
      initial-size: 5 #初始化大小
      min-idle: 5 #最小连接数
      max-active: 20 #最大连接数
      max-wait: 60000 #配置获取连接等待超时的时间
      pool-prepared-statements: true #是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大,比如说oracle。在mysql5.5以下的版本中没有PSCache功能,建议关闭掉。5.5及以上版本有PSCache,建议开启。
      max-pool-prepared-statement-per-connection-size: 20 #配置PSCache的大小
      validation-query: SELECT 1 FROM DUAL #用来检测连接是否有效的sql,要求是一个查询语句,常用SELECT 1 FROM DUAL
      validation-query-timeout: 3000 #检测连接是否有效的超时时间,单位是秒。底层调用jdbc Statement对象的void setQueryTimeout(int seconds)方法
      test-on-borrow: false #申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能
      test-on-return: false #是否在归还到池中前进行检验
      test-while-idle: true #是否在连接池空闲一段时间后检验连接有效性
      time-between-eviction-runs-millis: 60000 #配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      min-evictable-idle-time-millis: 300000 #配置一个连接在池中最小生存的时间,单位是毫秒
      max-evictable-idle-time-millis: 600000 #配置连接池中连接,在时间段内一直空闲,被逐出连接池的时间,单位毫秒。在minEvictableIdleTimeMillis基础上扩展,会在minEvictableIdleTimeMillis基础上判断连接是否空闲(默认逐出时间就是minEvictableIdleTimeMillis)
      #max-open-prepared-statements: #和上面的等价
      #   配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
      #filters: stat,wall,log4j
      use-global-data-source-stat: true #是否使用统计
      connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 #合并多个DruidDataSource的监控数据
      # ########## 连接池配置-结束 ##########

2.3 监控配置

spring:
  datasource:
    druid:
      # ########## 连接池监控配置-开始 ##########
      # WebStatFilter配置,说明请参考Druid Wiki,配置_配置WebStatFilter
      web-stat-filter:
        enabled: true #是否启用StatFilter,默认值false
        url-pattern: '/*' #需要拦截的url
        exclusions: '*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*' #过滤器忽略的资源
        session-stat-enable: true #是否开启session统计功能,默认值false
        session-stat-max-count: 1000 #session统计最大值
        principal-session-name: #session用户信息
        principal-cookie-name: #session用户cookie名称
        profile-enable: true #监控单个url调用的sql列表
      # StatViewServlet配置,说明请参考Druid Wiki,配置_StatViewServlet配置
      stat-view-servlet:
        enabled: true #是否启用StatViewServlet(监控页面)默认值为false(考虑到安全问题默认并未启动,如需启用建议设置密码或白名单以保障安全)
        url-pattern: /druid/* #监控页面拦截url
        reset-enable: false #是否启用重置功能
        login-username: admin #监控页面登录用户名
        login-password: admin #监控页面登录用户密码
        #StatViewSerlvet展示出来的监控信息比较敏感,是系统运行的内部情况,如果你需要做访问控制,可以配置allow和deny这两个参数
        #deny优先于allow,如果在deny列表中,就算在allow列表中,也会被拒绝。如果allow没有配置或者为空,则允许所有访问
        #配置的格式
        #<IP>或者<IP>/<SUB_NET_MASK_size>其中128.242.127.1/24,配置多个英文逗号分隔
        #24表示,前面24位是子网掩码,比对的时候,前面24位相同就匹配,不支持IPV6。
        allow: #监控页面白名单
        deny: #黑名单
      # Spring监控配置,说明请参考Druid Github Wiki,配置_Druid和Spring关联监控配置
      #aop-patterns: com.demo.*.service.* #Spring监控AOP切入点,如x.y.z.service.*,配置多个英文逗号分隔
      # ########## 连接池监控配置-结束 ##########

配置内容涉及参考地址:

  • web-stat-filter:https://github.com/alibaba/druid/wiki/配置_配置WebStatFilter
  • stat-view-servlet:https://github.com/alibaba/druid/wiki/配置_StatViewServlet配置
  • aop-patterns:https://github.com/alibaba/druid/wiki/配置_Druid和Spring关联监控配置

补充:

  • 如果需要 Spring 监控,除了配置 aop-patterns 之外,还需要引入 spring-boot-starter-aop 依赖,否则 Spring 监控页面会一片空白。

三、测试

1.查看监控页面

监控页面地址: http://localhost:8081/druid/index.html

访问监控页面,输入账号密码,如果页面中的参数和配置的参数一致,则说明集成成功。

在这里插入图片描述

在这里插入图片描述

2.单元测试

DemoApplicationTests.java

package com.demo;

import com.alibaba.druid.pool.DruidDataSource;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import javax.sql.DataSource;
import java.sql.Connection;

@SpringBootTest
class DemoApplicationTests {

    @Autowired
    DataSource dataSource;

    /**
     * 验证数据库连接
     * @throws Exception
     */
    @Test
    void testConnection() throws Exception {
        // 默认:class com.zaxxer.hikari.HikariDataSource
        // Druid:class com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceWrapper
        System.out.println(dataSource.getClass());
        Connection connection = dataSource.getConnection();
        // 默认:HikariProxyConnection@1323996324 wrapping com.mysql.cj.jdbc.ConnectionImpl@7c281eb8
        // Druid:com.mysql.cj.jdbc.ConnectionImpl@3166f664
        System.out.println(connection);
        connection.close();
    }

    /**
     * 验证连接池的配置信息,是否生效
     * @throws Exception
     */
    @Test
    void contextLoads() throws Exception {
        System.out.println(dataSource.getClass());
        DruidDataSource druidDataSource = (DruidDataSource) dataSource;
        System.out.println("initSize:" + druidDataSource.getInitialSize());
        System.out.println("maxSize:" + druidDataSource.getMaxActive());
        Connection connection = dataSource.getConnection();
        System.out.println(connection);
        connection.close();
    }

}

连接测试结果:

引入 Druid 连接池依赖之前,执行连接测试,结果如下:(默认使用的是 Hikari 连接池)

在这里插入图片描述

引入 Druid 连接池依赖之后,执行连接测试,结果如下:(改为使用的是 Druid 连接池)

在这里插入图片描述

配置测试结果:

使用 Druid 连接池之后,测试结果如下:

在这里插入图片描述

我们可以看到代码打印的结果与我们的配置一致,说明配置正常生效了。

在这里插入图片描述

源码地址: https://gitee.com/acgkaka/SpringBootExamples/tree/master/springboot-mybatis-plus-druid

四、补充:

1.如何打印慢SQL?

想要在日志中输出慢SQL日志,首先需要进行如下配置:

spring:
  datasource:
    druid:
      filter:
        stat:
          enabled: true #是否启用统计
          slow-sql-millis: 5000 #慢SQL记录,默认值为3000,单位毫秒
          log-slow-sql: true #是否打印慢日志
          merge-sql: true #是否合并SQL
          db-type: mysql #数据库类型,用于支持统计分析

除此之外,还需要再 filters 属性中加入项目使用的日志框架,如:log4j 或者 slf4j,并引入对应依赖。

logback.xml配置:

<!--druid start-->
<appender name="DruidFile"
          class="ch.qos.logback.core.rolling.RollingFileAppender">
    <File>${LOG_HOME:-d:/}logs/slow_sql/slow_sql.log</File>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
        <FileNamePattern>${LOG_HOME:-d:/}logs/slow_sql/slow_sql-%d{yyyy-MM-dd}.%i.log
        </FileNamePattern>
        <MaxHistory>60</MaxHistory>
        <TimeBasedFileNamingAndTriggeringPolicy
                class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
            <MaxFileSize>5MB</MaxFileSize>
        </TimeBasedFileNamingAndTriggeringPolicy>
    </rollingPolicy>
    <layout class="ch.qos.logback.classic.PatternLayout">
        <pattern>[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %logger{36} - %msg%n
        </pattern>
    </layout>
    <filter class="ch.qos.logback.classic.filter.LevelFilter"><!-- 只打印错误日志 -->
        <level>ERROR</level>
        <onMatch>ACCEPT</onMatch>
        <onMismatch>DENY</onMismatch>
    </filter>
</appender>
 
<logger name="com.alibaba.druid.filter.stat.StatFilter" additivity="false">
    <!-- 这里可以按需配置日志级别 -->
    <level value="error" />
    <appender-ref ref="DruidFile" />
</logger>
<!--druid end-->

慢SQL日志:

根据 logback.xml 配置,会产生慢 SQL 日志 slow_sql.log,内容如下所示:

[ERROR] 2022-08-30 22:44:15.651 [http-nio-8080-exec-1] c.a.druid.filter.stat.StatFilter - slow sql 4698 millis. SELECT  id,name,no,create_time,update_time  FROM user[]
[ERROR] 2022-08-30 22:57:15.183 [http-nio-8080-exec-2] c.a.druid.filter.stat.StatFilter - slow sql 3645 millis. SELECT  id,name,no,create_time,update_time  FROM user[]

2.去除广告

Druid 的监控页面下方有阿里云的广告,可以通过代码去除。

创建 DruidAdConfig.java 配置类:

import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure;
import com.alibaba.druid.spring.boot.autoconfigure.properties.DruidStatProperties;
import com.alibaba.druid.util.Utils;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.*;
import java.io.IOException;

/**
 * Druid广告配置
 *
 * @author zzp
 */
@Configuration
@ConditionalOnWebApplication
@AutoConfigureAfter(DruidDataSourceAutoConfigure.class)
@ConditionalOnProperty(
        name = "spring.datasource.druid.stat-view-servlet.enabled",
        havingValue = "true",
        matchIfMissing = true)
public class DruidAdConfig {

    /**
     * 去除监控页面底部广告
     *
     * @param properties
     * @return org.springframework.boot.web.servlet.FilterRegistrationBean
     */
    @Bean
    public FilterRegistrationBean removeDruidAdFilterRegistrationBean(
            DruidStatProperties properties) {
        // 获取web监控页面的参数
        DruidStatProperties.StatViewServlet config = properties.getStatViewServlet();
        // 提取common.js的配置路径
        String pattern = config.getUrlPattern() != null ? config.getUrlPattern() : "/druid/*";
        String commonJsPattern = pattern.replaceAll("\\*", "js/common.js");

        final String filePath = "support/http/resources/js/common.js";

        // 创建filter进行过滤
        Filter filter =
                new Filter() {
                    @Override
                    public void init(FilterConfig filterConfig) throws ServletException {}

                    @Override
                    public void doFilter(
                            ServletRequest request, ServletResponse response, FilterChain chain)
                            throws IOException, ServletException {
                        chain.doFilter(request, response);
                        // 重置缓冲区,响应头不会被重置
                        response.resetBuffer();
                        // 获取common.js
                        String text = Utils.readFromResource(filePath);
                        // 正则替换banner, 除去底部的广告信息
                        text = text.replaceAll("<a.*?banner\"></a><br/>", "");
                        text = text.replaceAll("powered.*?shrek.wang</a>", "");
                        response.getWriter().write(text);
                    }

                    @Override
                    public void destroy() {}
                };
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        registrationBean.setFilter(filter);
        registrationBean.addUrlPatterns(commonJsPattern);
        return registrationBean;
    }
}

3.如何手动获取监控内容

官方说明: https://github.com/alibaba/druid/tree/master/druid-spring-boot-starter

  • Druid 的监控数据可以在开启 StatFilter 后通过 DruidStatManagerFacade 进行获取。

  • 获取到监控数据之后你可以将其暴露给你的监控系统进行使用。Druid 默认的监控系统数据也来源于此。

下面做一个简单的演示,在 SpringBoot 中国你如何通过 HTTP 接口将 Druid 监控数据以 JSON 的形式暴露出去,实际使用中你可以根据你的需要自动地对监控数据、暴露方式进行扩展。

import com.alibaba.druid.stat.DruidStatManagerFacade;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DruidStatController {
    
    @GetMapping("/druidStat")
    public Object druidStat(){
        // DruidStatManagerFacade#getDataSourceStatDataList 该方法可以获取所有数据源的监控数据,
        // 除此之外 DruidStatManagerFacade 还提供了一些其他方法,你可以按需选择使用。
        return DruidStatManagerFacade.getInstance().getDataSourceStatDataList();
    }
}

返回结果如下:

在这里插入图片描述

详细内容如下:

[
  {
    "Identity": 2122837918,
    "Name": "DataSource-2122837918",
    "DbType": "mysql",
    "DriverClassName": "com.mysql.cj.jdbc.Driver",
    "URL": "jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai",
    "UserName": "root",
    "FilterClassNames": [
      "com.alibaba.druid.filter.stat.StatFilter"
    ],
    "WaitThreadCount": 0,
    "NotEmptyWaitCount": 0,
    "NotEmptyWaitMillis": 0,
    "PoolingCount": 5,
    "PoolingPeak": 5,
    "PoolingPeakTime": "2023-07-08T16:29:24.569+0000",
    "ActiveCount": 0,
    "ActivePeak": 0,
    "ActivePeakTime": null,
    "InitialSize": 5,
    "MinIdle": 5,
    "MaxActive": 20,
    "QueryTimeout": 0,
    "TransactionQueryTimeout": 0,
    "LoginTimeout": 0,
    "ValidConnectionCheckerClassName": "com.alibaba.druid.pool.vendor.MySqlValidConnectionChecker",
    "ExceptionSorterClassName": "com.alibaba.druid.pool.vendor.MySqlExceptionSorter",
    "TestOnBorrow": false,
    "TestOnReturn": false,
    "TestWhileIdle": true,
    "DefaultAutoCommit": true,
    "DefaultReadOnly": null,
    "DefaultTransactionIsolation": null,
    "LogicConnectCount": 0,
    "LogicCloseCount": 0,
    "LogicConnectErrorCount": 0,
    "PhysicalConnectCount": 5,
    "PhysicalCloseCount": 0,
    "PhysicalConnectErrorCount": 0,
    "DiscardCount": 0,
    "ExecuteCount": 0,
    "ExecuteUpdateCount": 0,
    "ExecuteQueryCount": 0,
    "ExecuteBatchCount": 0,
    "ErrorCount": 0,
    "CommitCount": 0,
    "RollbackCount": 0,
    "PSCacheAccessCount": 0,
    "PSCacheHitCount": 0,
    "PSCacheMissCount": 0,
    "StartTransactionCount": 0,
    "TransactionHistogram": [
      0,
      0,
      0,
      0,
      0,
      0,
      0
    ],
    "ConnectionHoldTimeHistogram": [
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0
    ],
    "RemoveAbandoned": false,
    "ClobOpenCount": 0,
    "BlobOpenCount": 0,
    "KeepAliveCheckCount": 0,
    "KeepAlive": false,
    "FailFast": false,
    "MaxWait": 60000,
    "MaxWaitThreadCount": -1,
    "PoolPreparedStatements": true,
    "MaxPoolPreparedStatementPerConnectionSize": 20,
    "MinEvictableIdleTimeMillis": 300000,
    "MaxEvictableIdleTimeMillis": 600000,
    "LogDifferentThread": true,
    "RecycleErrorCount": 0,
    "PreparedStatementOpenCount": 0,
    "PreparedStatementClosedCount": 0,
    "UseUnfairLock": false,
    "InitGlobalVariants": false,
    "InitVariants": false
  }
]

整理完毕,完结撒花~ 🌻





参考地址:

1.Springboot 整合 druid,https://blog.csdn.net/qq_51133939/article/details/126248389

2.SpringBoot配置Druid,https://blog.csdn.net/promsing/article/details/126446143

3.Springboot 集成Druid,https://blog.csdn.net/qq_34285557/article/details/125945877

4.druid慢sql监控,https://blog.csdn.net/xixingzhe2/article/details/126614581

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

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

相关文章

简析电力系统网络靶场建设的价值、挑战与趋势

在当下已经演变为持久战的俄乌地区冲突中&#xff0c;通信、交通、能源供应等相关国家关键基础设施一直是双方互相攻击的重点目标。同时&#xff0c;“网络战”作为先行战场&#xff0c;也把关基设施作为主阵地&#xff0c;不断以相对轻量级成本制造比想象中更广泛的破坏和社会…

Haproxy搭建Web群集和脑裂的概念

目录 脑裂概念 脑裂如何生的: 解决方法 Haproxy概念 HAProxy的主要特性有&#xff1a; HAProxy负载均衡策略非常多&#xff0c;常见的有如下8种&#xff1a; CDN Nginx LVS haproxy haproxy服务器部署 关闭防火墙 编译安装 Haproxy Haproxy服务器配置 添加haprox…

Spring MVC教程

Spring MVC属于SpringFrameWork的后续产品&#xff0c;已经融合在Spring Web Flow里面。 Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。 使用 Spring 可插入的 MVC 架构&#xff0c;从而在使用Spring进行WEB开发时&#xff0c;可以选择使用Spring的Spring MVC框架或集…

明明都是2000坐标的地形图,怎么位置就不一样呢?

前几天有一个同事在工作中遇到一个问题,核心说起来就是,甲方发来两个年份的同一个片区的地形图,并且言之凿凿都是2000坐标的,但是在一个CAD复制后,到另一个CAD中使用“粘贴到原坐标”,就是位置对不上。 以下使用测试数据还原一下情景。 地形图A,是一个高程点: 地形图…

【网络系统集成】Windows Server集群实验

1.实验名称 Windows Server集群实验 2.实验目的 通过使用Windows 2003进行实验,理解与掌握服务器技术与系统集成相关知识点。 3.实验内容 (1)在Vmware Workstation中安装Windows Server 2003 (2)在Windows Server 2008中完成DNS,WEB的配置

LinuxI2C应用编程——访问EEPROM

文章目录 介绍读芯片手册代码编译运行 阅读博文&#xff1a;LinuxI2C应用编程——I2C-Tools的使用 介绍 EEPROM (Electrically Erasable Programmable read only memory)&#xff0c;指带电可擦可编程只读存储器。是一种掉电后数据不丢失的存储芯片。 读芯片手册 首先按如图…

SSMP整合案例(15) 解决分页中删除最后一页的最后一条数据,导致查询错位问题

上文 我们还是做了个比较重要的是 将我们的查询全部逻辑改为了分页查询 但是 目前 我们的删除和分页配合起来 它会有一点点问题 例如 这种情况 我们最后一页只有一条数据了 我们操作删除 将这条数据给他干掉 删除完之后 它会调分页查询 但我们当前页的条件还是之前的 例如 我…

【网络】UDP协议详解

目录 UDP的感性理解 UDP协议格式 UDP协议格式感性理解 UDP特点 UDP的缓冲区 UDP的感性理解 UDP的传输过程类似于寄信&#xff0c;假设你要写一封家书寄回家里&#xff1a;首先你要在信封上填写好寄件人和收件人的地址&#xff0c;其次在贴好邮票&#xff0c;最后将信件投放…

MySQL数据库 库表操作

1. (1) mysql> create database Market; 创建数据库 mysql> use Market 使用Market数据库(2) mysql> create table customers(-> c_num int(11) primary key auto_increment,-> c_name varchar(50),-> c_contact varchar(50),-> c_city varc…

ChatGPT炒股:从巨潮资讯网上批量下载特定主题的股票公告

巨潮资讯网是股票公告的指定披露渠道之一&#xff0c;上面有非常详细的A股股票公告内容。 现在&#xff0c;我们要获取2023-01-04~2023-07-04期间所有新三板公司中标题包含“2023年日常性关联交易”的公告。 首先从network中获取到真实网址&#xff1a;http://www.cninfo.com…

大一下学期期末考wp

【web】 1.sign 打开题目 发现有1000个页面 打开第9999个和第9998个页面&#xff0c;发现是utf-8编码 当再随机打开其他页面时&#xff0c;页面又出现了另外一种情况 于是我们猜测&#xff0c;flag是由utf-8编码的&#xff0c;编码被拆散了随机放在10000个页面中的几个页面中…

找不到msvcp140.dll解决方法有哪些?那个修复方法更简单

是使用Windows操作系统的计算机时&#xff0c;总是不可避免会遇到系统报错。像计算机提示找不到msvcp140.dll&#xff0c;msvcp140.dll是一个Windows操作系统中的动态链接库文件&#xff0c;它属于Microsoft Visual C Redistributable包的一部分。这个文件包含了一些供C程序使用…

计算机的大脑 CPU

晶体管 N型MOS管P型MOS管 算术逻辑单元 ALU 晶体管–>门电路–>加法器–>ALU 既可以做逻辑运算、也可以做逻辑运算、成为计算机CPU中非常核心的组件。 指令 一条指令只完成一个基本操作的精简指令集 RISC 、它们的指令长度基本上是固定的。比如 ARM一条指令可以…

【SLAM14讲】02 视觉SLAM基本架构

一、传感器 1.1 安装位置分类 根据安装位置分为两类&#xff1a; 携带于机器人本体 上的传感器&#xff0c;比如激光传感器、相机、轮式编码器、惯性测量单元&#xff08;Inertial Measurement Unit, IMU&#xff09;等等&#xff0c;它们测到的通常都是一些间接的物理量而不…

一键创建日期命名的txt文件(方便日报)

背景 刚工作&#xff0c;免不了写日报&#xff0c;写日计划的时候。为了方便&#xff0c;写了一个bat文件直接点击即可创建今天时间命名的txt文件 代码 win10我的笔记本 echo set tmp%date:~3,4%%date:~8,2%%date:~11,2% type nul > %tmp%.txtwindows 下创建文件就是 t…

排序算法性能分析

目录 实现插入排序、冒泡排序、选择排序、合并排序、快速排序算法&#xff08;从小到大&#xff09; ①插入排序 ②冒泡排序 ③选择排序 ⑥快速排序 五种排序 现在有10亿的数据&#xff08;每个数据四个字节&#xff09;&#xff0c;请快速挑选出最大的十个数&#xff0…

红黑树与234树

红黑树 参考&#xff1a;宇文新粥&#xff1a;红黑树红黑树可视化 234树 这个树有三种节点&#xff0c;分别包含1/2/3个元素&#xff0c;下方可以有2/3/4个子节点理解234树的插入 红黑树与234树之间的关系 红黑树有几个特性&#xff0c;但如果从234树的角度理解红黑树&…

在微软十年了!

时光飞逝&#xff0c;光阴如梭。 2013 年的 7 月 8 号&#xff0c;我在隔壁的交大软院毕业后&#xff0c;正式入职紫竹微软。 至今&#xff0c;已是整整 10 年了。 记得当时的闵行回市区的交通还不是那么堵&#xff0c;坐 5点半的班车下班&#xff0c;S4中环一路走&#xff0c;…

【C++ OJ练习】4.字符串中的第一个唯一字符

1.题目链接 力扣 2.解题思路 利用计数排序的思想 映射进行计数 最后计数为1的那个字符就是唯一字符 从前往后遍历 可以得到 第一个唯一字符 3.代码 class Solution { public:int firstUniqChar(string s) {//使用映射的方式统计次数 计数排序思想int count[26] { 0 };fo…

机器视觉硬件选型-工业光源-环形光源

视觉人机器视觉-硬件发货前硬件确认效果 工业光源根据灯的几何形状可分为条形光源,分区光源&#xff0c;环形光源、圆顶&#xff08;积分&#xff09;光源、平面光源&#xff0c;同轴光源&#xff0c;方形光源&#xff0c;线扫光源&#xff0c;点光源&#xff0c;线光源等等。 …