MyBatis 性能优化

1. 引言

1.1 什么是 MyBatis?

MyBatis 是一款流行的 Java 持久层框架,能够将 Java 对象与 SQL 数据库映射起来。与传统的 JDBC 不同,MyBatis 提供了灵活的 SQL 映射功能,使开发者可以专注于业务逻辑,而无需编写冗长的数据库操作代码。
MyBatis 的主要特点包括:

  • 轻量级:无需复杂配置即可快速上手。
  • 灵活的 SQL:开发者可以直接编写自定义 SQL,而不是依赖于 ORM 自动生成。
  • 强大的动态 SQL 支持:通过 XML 或注解生成动态 SQL。

尽管 MyBatis 的灵活性很强,但它的性能往往取决于 SQL 的设计与执行效率,因此在使用时需要特别关注性能问题。

1.2 多表关联和动态 SQL 的应用场景

在实际开发中,多表关联查询和动态 SQL 是 MyBatis 最常见的应用场景之一:

  • 多表关联查询:在复杂业务中,不同表的数据往往存在关联关系。例如,用户和订单、商品和分类的关系查询。多表关联查询能够高效地获取所需的数据。
  • 动态 SQL:业务需求变化多样,查询条件可能动态变化。MyBatis 的动态 SQL 功能允许根据不同参数生成相应的 SQL 查询,常见于复杂搜索、报表生成等场景。

典型案例

  • 用户管理系统:根据用户信息(姓名、角色、状态)动态筛选,并关联订单表统计购买记录。
  • 电商平台:根据商品属性(价格区间、分类、品牌)动态生成查询条件,并关联库存表查询可用数量。

虽然这些场景十分常见,但如果 SQL 编写不当或缺乏优化,可能会导致严重的性能问题。

1.3 性能优化的意义

随着数据量的增加,性能问题往往成为系统瓶颈,特别是在涉及多表关联和动态 SQL 的场景中:

  • 响应时间增加:复杂的 SQL 查询会导致响应时间变长,影响用户体验。
  • 数据库资源消耗过高:低效的查询会占用大量的数据库资源,如 CPU 和内存,甚至可能引发系统崩溃。
  • 系统扩展性受限:当查询性能不足时,系统很难通过增加硬件资源来支撑更高的并发量。

性能优化的目标是:

  1. 提高系统响应速度,确保用户体验流畅。
  2. 降低数据库负载,提高资源利用率。
  3. 提升系统的扩展性,为业务增长提供支持。

因此,在使用 MyBatis 时,了解其性能陷阱并掌握优化方法是开发者必须具备的能力。

2. MyBatis 多表关联中的常见性能陷阱

多表关联查询和动态 SQL 是 MyBatis 的核心功能之一,但如果使用不当,很容易导致性能问题。以下是一些常见的性能陷阱及其原因分析。

2.1 过多的关联查询

问题描述
在多表关联查询中,如果关联的表过多或表之间的关系过于复杂,可能导致以下问题:

  • SQL 执行时间过长。
  • 数据库计算压力过大。
  • 难以维护和优化 SQL。

场景示例
假设有一个三层嵌套的查询,涉及用户表、订单表和商品表,每次查询时需要返回完整的用户订单详情:

SELECT u.name, o.order_id, p.product_name
FROM user u
JOIN orders o ON u.user_id = o.user_id
JOIN product p ON o.product_id = p.product_id
WHERE u.status = 'active';

如果数据量庞大,这种多表关联会导致查询性能急剧下降。

解决方法

  • 降低关联表的数量,必要时进行表拆分或数据冗余。
  • 对复杂业务场景,考虑将查询拆分为多个步骤并在应用层合并结果。

2.2 动态 SQL 拼接过多

问题描述
动态 SQL 提供了灵活的查询能力,但如果过度使用,可能导致:

  • 生成的 SQL 复杂且难以调试。
  • 数据库优化器无法选择最优执行计划。
  • 缓存命中率低(动态 SQL 每次生成的新语句会导致缓存失效)。

场景示例
以下动态 SQL 会根据不同条件拼接查询:

<where>
  <if test="status != null">
    AND status = #{status}
  </if>
  <if test="startDate != null">
    AND created_date >= #{startDate}
  </if>
  <if test="endDate != null">
    AND created_date <= #{endDate}
  </if>
</where>

当条件组合过多时,生成的 SQL 会呈指数增长。

解决方法

  • 限制动态条件数量,避免生成过于复杂的 SQL。
  • 使用 trimchoose 等标签优化拼接逻辑。

2.3 缺少分页支持

问题描述
未对查询结果进行分页处理会导致以下问题:

  • 数据量过大时,查询返回的数据超出内存限制。
  • 数据库和网络传输压力增加。

场景示例
以下查询没有进行分页控制:

SELECT * FROM orders WHERE status = 'pending';

如果 orders 表中有数百万条记录,单次查询将返回大量数据,影响系统性能。

解决方法

  • 始终为查询添加分页参数(LIMITOFFSET)。
  • 在大数据量场景中,优先考虑主键或游标分页。

2.4 缺少索引优化

问题描述
多表关联查询和条件筛选中,未为关联字段或查询条件字段建立索引,会导致全表扫描,影响性能。

场景示例
以下查询没有为 user_idstatus 建立索引:

SELECT * FROM orders WHERE user_id = 123 AND status = 'completed';

全表扫描会导致查询时间显著增加。

解决方法

  • 为关联字段和条件字段创建合适的索引。
  • 定期分析执行计划(EXPLAIN)并优化索引设计。

2.5 动态 SQL 导致缓存失效

问题描述
MyBatis 提供了一级和二级缓存,但动态 SQL 生成的语句如果每次都不同,缓存将无法命中,增加数据库查询压力。

场景示例
以下动态 SQL 由于条件组合不固定,导致生成的语句形式不同:

<if test="param1 != null"> AND column1 = #{param1}</if>
<if test="param2 != null"> AND column2 = #{param2}</if>

解决方法

  • 规范动态 SQL 的生成,尽量减少无意义的变体。
  • 结合缓存策略,尽量复用生成的 SQL。

2.6 N+1 查询问题

问题描述
在多表关联中,如果对每条记录执行一次独立查询,会产生大量小查询,严重影响性能。这种问题被称为 N+1 查询问题。

场景示例
以下代码会为每个用户单独查询其订单:

List<User> users = userMapper.getAllUsers();
for (User user : users) {
    List<Order> orders = orderMapper.getOrdersByUserId(user.getUserId());
}

如果有 1000 个用户,这段代码将产生 1001 次查询(1 次查询用户 + 1000 次查询订单)。

解决方法

  • 使用 JOIN 查询,一次性获取所有需要的数据。
  • 利用 MyBatis 的 resultMapcollection 标签将结果映射为嵌套对象。

3. 性能优化方法详解

在 MyBatis 的多表关联和动态 SQL 中,性能优化至关重要。以下是针对常见性能陷阱的优化方法详解。

3.1 合理设计 SQL

3.1.1 降低关联表数量
  • 目标:避免复杂的多表关联。
  • 方法:
    • 优化业务逻辑,减少非必要的关联查询。
    • 对频繁使用的关联表数据进行适当冗余存储,以换取查询效率。
3.1.2 拆分复杂查询
  • 目标:将复杂的 SQL 拆分为多个简单的查询。
  • 方法:
    • 使用临时表或中间表分步查询。
    • 在应用层进行数据合并处理,减少数据库负担。

3.2 实现高效分页

3.2.1 使用 LIMIT 和 OFFSET
  • 目标:限制查询返回的数据量。
  • 示例:
    SELECT * FROM orders WHERE status = 'pending' LIMIT 10 OFFSET 20;
    
3.2.2 主键或游标分页
  • 目标:在大数据量分页场景中,提高分页性能。
  • 方法:
    • 根据主键或唯一索引实现分页,而非使用 OFFSET
    • 示例:
      SELECT * FROM orders WHERE order_id > #{lastOrderId} LIMIT 10;
      

3.3 索引优化

3.3.1 如何创建覆盖索引
  • 目标:避免全表扫描,加快查询速度。
  • 方法:
    • 创建包含所有查询字段的覆盖索引。
    • 示例:
      CREATE INDEX idx_user_status ON orders (user_id, status);
      
3.3.2 索引设计的最佳实践
  • 对查询条件中经常使用的字段建立索引。
  • 避免为低选择性字段(如布尔值)创建索引。
  • 定期检查和清理无用索引。

3.4 使用缓存机制

3.4.1 MyBatis 一级缓存
  • 目标:在单个会话中复用查询结果。
  • 默认开启,无需额外配置。
3.4.2 MyBatis 二级缓存
  • 目标:在不同会话间共享查询结果。
  • 配置示例:
    <cache eviction="LRU" flushInterval="60000" size="512" readOnly="true"/>
    
  • 注意:
    • 缓存适合频繁查询但不经常更新的数据。
    • 动态 SQL 需优化生成逻辑,确保缓存命中率。

3.5 避免 N+1 查询

3.5.1 使用 JOIN 查询
  • 目标:一次性获取所有需要的数据。
  • 示例:
    SELECT u.name, o.order_id 
    FROM user u
    JOIN orders o ON u.user_id = o.user_id;
    
3.5.2 使用 ResultMap 和 Collection
  • 目标:在单次查询中将结果映射为嵌套对象。
  • 配置示例:
    <resultMap id="userOrderMap" type="User">
      <id property="userId" column="user_id"/>
      <result property="name" column="name"/>
      <collection property="orders" ofType="Order">
        <id property="orderId" column="order_id"/>
        <result property="status" column="status"/>
      </collection>
    </resultMap>
    

3.6 监控和分析工具

3.6.1 慢查询日志
  • 目标:记录运行时间超过阈值的查询。
  • 配置示例(MySQL):
    SET GLOBAL slow_query_log = 'ON';
    SET GLOBAL long_query_time = 1; -- 查询时间超过 1 秒记录
    
3.6.2 数据库执行计划(EXPLAIN)
  • 目标:分析 SQL 的执行计划,定位性能瓶颈。
  • 使用示例:
    EXPLAIN SELECT * FROM orders WHERE user_id = 123;
    
  • 注意查看:
    • 是否存在全表扫描。
    • 索引是否被正确使用。

3.7 分库分表与读写分离

3.7.1 分库分表
  • 目标:解决单表数据量过大的问题。
  • 方法:
    • 按业务分库:将不同模块的数据存储在不同的数据库中。
    • 按字段分表:根据主键或分片键分割大表。
3.7.2 读写分离
  • 目标:将写操作分配到主库,读操作分配到从库。
  • 方法:
    • 使用中间件(如 MyCAT)或数据库自带功能实现。

4. 案例分析

通过具体的案例分析,可以更直观地理解 MyBatis 中的性能问题及优化效果。本节将以常见场景为例,展示问题 SQL、优化方法及性能对比。

4.1 问题场景 SQL 示例

场景描述
在一个电商平台中,需要根据用户筛选条件查询订单及商品详情。查询条件包括:

  • 用户状态(status
  • 订单创建时间范围(startDateendDate
  • 商品分类(category

SQL 示例:

SELECT u.user_id, u.name, o.order_id, o.created_date, p.product_name, p.category
FROM user u
JOIN orders o ON u.user_id = o.user_id
JOIN product p ON o.product_id = p.product_id
WHERE u.status = 'active'
  AND o.created_date BETWEEN '2023-01-01' AND '2023-12-31'
  AND p.category = 'electronics';

问题分析

  1. 过多的关联查询:三表关联导致 SQL 复杂度高。
  2. 缺少分页:查询可能返回大量数据。
  3. 未使用索引created_datecategory 未建立索引。
  4. 动态条件不固定:查询条件动态变化,可能导致缓存失效。

4.2 动态 SQL 的优化示例

原始动态 SQL 示例

<select id="getOrders" resultType="map">
  SELECT u.user_id, u.name, o.order_id, o.created_date, p.product_name, p.category
  FROM user u
  JOIN orders o ON u.user_id = o.user_id
  JOIN product p ON o.product_id = p.product_id
  <where>
    <if test="status != null">
      AND u.status = #{status}
    </if>
    <if test="startDate != null and endDate != null">
      AND o.created_date BETWEEN #{startDate} AND #{endDate}
    </if>
    <if test="category != null">
      AND p.category = #{category}
    </if>
  </where>
</select>

问题优化

  1. 优化分页
    添加分页参数,避免查询返回过多数据:

    LIMIT #{pageSize} OFFSET #{offset}
    
  2. 索引优化
    为常用筛选条件字段建立索引:

    CREATE INDEX idx_status ON user (status);
    CREATE INDEX idx_created_date ON orders (created_date);
    CREATE INDEX idx_category ON product (category);
    
  3. 减少关联查询复杂度
    优化为两步查询,先查询订单,再关联用户和商品:

    SELECT o.order_id, o.created_date, o.user_id, o.product_id
    FROM orders o
    WHERE o.created_date BETWEEN #{startDate} AND #{endDate}
      AND EXISTS (
        SELECT 1 FROM user u WHERE u.user_id = o.user_id AND u.status = #{status}
      )
      AND EXISTS (
        SELECT 1 FROM product p WHERE p.product_id = o.product_id AND p.category = #{category}
      )
    LIMIT #{pageSize} OFFSET #{offset};
    

4.3 优化前后性能对比

测试环境
  • 数据量:
    • 用户表:1,000,000 条记录
    • 订单表:10,000,000 条记录
    • 商品表:500,000 条记录
  • 查询条件:
    • 用户状态:active
    • 创建时间范围:2023-01-012023-12-31
    • 商品分类:electronics
性能对比表
优化项优化前响应时间优化后响应时间备注
多表关联查询12 秒3 秒通过减少关联表数量和两步查询显著提升性能
分页处理未测(返回 1GB 数据)500ms添加分页后返回数据量大幅减少
索引优化8 秒300ms索引减少了全表扫描,提升查询效率
动态 SQL 缓存命中率无法命中命中率 80%规范动态 SQL 生成,提高缓存复用率

结果总结
通过优化动态 SQL、分页、索引和查询逻辑,将查询性能从 12 秒优化到 300 毫秒,大幅提升了系统效率。在生产环境中,应定期检查 SQL 的执行计划,结合业务需求进一步优化。

5. 高级优化技巧

针对大规模数据和高并发场景,除了基础的性能优化外,还可以采用更高级的优化方案,如分库分表、读写分离与负载均衡,以及数据库连接池调优。

5.1 分库分表方案

5.1.1 什么是分库分表?

分库分表是将一张大表或一个数据库的数据按照一定规则分散存储到多个数据库或表中,从而减少单个库或表的压力,提高查询性能和系统扩展性。

5.1.2 分库分表的类型
  1. 垂直分库分表

    • 按业务模块拆分数据库或表。
    • 适用于不同业务模块之间无强关联的场景。
    • 示例:
      • 用户表存储在 user_db,订单表存储在 order_db
  2. 水平分库分表

    • 按一定规则(如用户 ID 或订单 ID)将同一业务数据拆分到多个数据库或表中。
    • 适用于单表数据量过大的场景。
    • 示例:
      • orders_001 存储用户 ID 为 1-1000 的订单,orders_002 存储用户 ID 为 1001-2000 的订单。
5.1.3 分库分表的挑战
  • 分布式事务:跨库操作需要解决事务一致性问题。
  • 查询复杂性:跨库查询和统计需要额外的合并逻辑。
  • 路由规则设计:需要设计合理的分片规则,避免数据倾斜。
5.1.4 实现方式
  • 使用分库分表中间件(如 ShardingSphere、MyCAT)。
  • 自行实现分库分表逻辑,结合数据库代理或路由层。

5.2 读写分离与负载均衡

5.2.1 什么是读写分离?

读写分离是将数据库的写操作分配到主库,读操作分配到从库,从而分散主库的压力,提高系统吞吐量。

5.2.2 读写分离的实现
  1. 主从复制

    • 使用数据库的主从复制功能(如 MySQL 的主从复制),实现主库写数据后同步到从库。
    • 主库:处理写请求。
    • 从库:处理读请求。
  2. 读写路由

    • 在应用层或中间件中设置读写分离路由规则。
    • 示例:
      datasource:
        master: jdbc:mysql://master-db:3306/app_db
        slave: jdbc:mysql://slave-db:3306/app_db
      
5.2.3 负载均衡
  • 概念:将读请求分配到多个从库,平衡负载。
  • 实现方式
    • 数据库中间件(如 ProxySQL、MaxScale)。
    • 应用层通过算法(如轮询、最小连接数)实现。
5.2.4 注意事项
  • 数据延迟:主从复制存在延迟,可能导致读取的数据不一致。
  • 从库压力:从库需要处理大量查询,可能成为新的瓶颈。

5.3 数据库连接池调优

5.3.1 数据库连接池的重要性

数据库连接池(如 HikariCP、Druid)通过复用连接提升数据库操作效率,是高并发场景的关键优化点。

5.3.2 连接池调优的核心参数
  1. 最大连接数(maxConnections)

    • 定义连接池中最大活跃连接数量。
    • 调优建议:
      • 根据数据库性能和业务并发量设置。
      • 避免过大或过小,过大可能导致数据库连接耗尽,过小可能导致请求阻塞。
  2. 最小连接数(minConnections)

    • 定义连接池中维持的最小空闲连接数。
    • 调优建议:
      • 设置为低并发场景下的最低需求,节省资源。
  3. 连接超时时间(connectionTimeout)

    • 指定连接池等待可用连接的最大时间。
    • 调优建议:
      • 设置为合理值(如 30 秒),防止长时间阻塞。
  4. 空闲连接的最大存活时间(idleTimeout)

    • 设置空闲连接的最大保留时间,避免无效连接占用资源。
    • 调优建议:
      • 设置为 1-5 分钟,具体根据业务需求调整。
5.3.3 监控与调试
  • 使用数据库连接池监控工具(如 Druid 的内置监控)。
  • 定期检查连接池性能指标(如连接使用率、等待时间)。

6. 总结

通过前文的分析和优化技巧,我们深入探讨了 MyBatis 多表关联和动态 SQL 的常见性能陷阱以及优化方法。在本节中,我们将回顾性能优化的关键点,并梳理在实际项目中应用这些优化时需要注意的事项。

6.1 性能优化的关键点回顾

  1. SQL 的合理设计

    • 降低多表关联的复杂度,尽可能减少不必要的关联。
    • 将复杂的查询拆分为多个简单的查询步骤,在应用层进行数据整合。
  2. 高效的分页处理

    • 使用 LIMITOFFSET 实现分页,避免一次性返回大数据量。
    • 在大数据场景中优先使用主键或游标分页以提高效率。
  3. 索引优化

    • 针对常用查询条件和关联字段创建合理的索引。
    • 定期审查和调整索引,避免无用索引和冗余索引。
  4. 动态 SQL 的规范化

    • 避免过多动态拼接,确保生成的 SQL 语句结构清晰、稳定。
    • 优化动态 SQL 的条件设计,提高缓存命中率。
  5. 缓存机制

    • 利用 MyBatis 的一级和二级缓存减少重复查询。
    • 对不频繁更新的数据启用二级缓存,提高查询效率。
  6. 高级优化方案

    • 使用分库分表解决大数据量问题,提升系统扩展能力。
    • 采用读写分离和负载均衡减轻主库压力。
    • 调优数据库连接池参数以优化连接管理。
  7. 监控与分析

    • 使用慢查询日志和数据库执行计划(EXPLAIN)定位性能瓶颈。
    • 定期监控系统性能,结合实际场景持续优化。

6.2 在实际项目中应用的注意事项

  1. 结合业务需求选择优化策略

    • 每种优化策略都有适用场景,不盲目追求复杂的解决方案。
    • 在简单场景下,优先优化 SQL 和索引,而非直接引入分库分表等复杂方案。
  2. 性能与成本的平衡

    • 高级优化方案(如分库分表)可能引入额外的开发和维护成本。
    • 根据系统规模和业务需求评估优化的必要性,避免过度优化。
  3. 测试与验证

    • 在实施优化前,进行详细的性能测试,验证优化效果。
    • 定期对系统进行负载测试,确保优化策略在高并发场景下的稳定性。
  4. 监控和回滚机制

    • 优化后的系统需要持续监控,确保在实际运行中的效果。
    • 为所有优化措施设计回滚机制,确保在紧急情况下能快速恢复。
  5. 关注团队协作与维护

    • 在团队中分享优化的最佳实践,统一编码规范和 SQL 优化标准。
    • 针对复杂优化方案,完善文档和监控,便于后续维护。

7. 扩展阅读

在学习和实践 MyBatis 性能优化的过程中,深入了解相关工具和技术的原理与最佳实践至关重要。本节提供一些重要的参考资料,供读者进一步扩展学习。

7.1 MyBatis 官方文档

推荐阅读内容
  • MyBatis 入门指南
    • 包括 MyBatis 的基本概念、核心组件及配置方法。
  • 动态 SQL
    • 详细介绍动态 SQL 的标签及用法。
  • 缓存机制
    • 讲解一级缓存和二级缓存的使用与配置。
  • 性能优化相关章节
    • 涉及 MyBatis 在性能优化中的注意事项。
学习建议
  • 熟悉 MyBatis 核心配置和动态 SQL 的使用方法,理解其性能特点。
  • 实践中通过阅读官方文档深入掌握 MyBatis 的高级特性和限制。

7.2 数据库索引设计的最佳实践

参考资料
  • 《高性能 MySQL》
    • 包括索引设计、查询优化和性能调优的详细讲解。
  • 数据库官方文档(如 MySQL、PostgreSQL)
    • 详细说明索引类型、创建方法及优化技巧。
  • 社区文章:
    • MySQL 索引优化实战
关键内容
  1. 索引类型
    • 单列索引、复合索引、唯一索引、全文索引。
  2. 创建原则
    • 为高频查询字段创建索引。
    • 优先为区分度高的字段创建索引。
  3. 常见误区
    • 过多索引会增加写操作的开销。
    • 对低选择性字段(如布尔值)创建索引可能无效。
  4. 索引调试
    • 使用 EXPLAIN 命令分析查询计划,检查索引的使用情况。
学习建议
  • 理解索引的作用机制,避免常见误区。
  • 在实际项目中通过慢查询日志和执行计划优化索引策略。

7.3 高性能分页的研究与实现

参考资料
  • MySQL 高性能分页技术
    • 涉及 LIMITOFFSET 的使用技巧及优化方法。
  • 技术博客:
    • 《深度剖析 MySQL 分页性能问题及优化策略》
    • 《大数据分页实现与最佳实践》
关键内容
  1. 分页方法
    • 基础分页:LIMIT + OFFSET
    • 游标分页:通过主键范围限制实现高效分页。
  2. 性能对比
    • 使用 OFFSET 时,大偏移量的性能较低。
    • 游标分页在大数据量场景下性能表现更优。
  3. 代码实现
    • 基础分页:
      SELECT * FROM orders LIMIT 10 OFFSET 1000;
      
    • 游标分页:
      SELECT * FROM orders WHERE order_id > #{lastOrderId} LIMIT 10;
      
学习建议
  • 在项目中根据数据规模和性能需求选择合适的分页策略。
  • 深入理解游标分页的原理,特别是在大数据量场景中的应用。

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

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

相关文章

(五)ROS通信编程——参数服务器

前言 参数服务器在ROS中主要用于实现不同节点之间的数据共享&#xff08;P2P&#xff09;。参数服务器相当于是独立于所有节点的一个公共容器&#xff0c;可以将数据存储在该容器中&#xff0c;被不同的节点调用&#xff0c;当然不同的节点也可以往其中存储数据&#xff0c;关…

自动化测试框架搭建-数据库方法连接-初阶

目的 将数据库连接的步骤封装成一个方法&#xff0c;在需要连接数据库时&#xff0c;传入指定的参数&#xff08;SQL&#xff09;即可实现对数据查询和修改 代码实现 1、编写数据库连接方法 2、导入其他方法中使用步骤一 import pymysqldef mysqlConnetion(Sql):# 数据库连…

vivado 时钟指南

时钟指南 每个 FPGA 架构都为时钟提供有专用资源。掌握 FPGA 架构中的时钟资源&#xff0c;使您能够规划好自己的时钟&#xff0c;从而实现时钟 资源的最佳利用。大多数设计无需您了解这些细节。但如果您能够控制布局&#xff0c;同时对每个时钟域上的扇出有良好的思 路&a…

【微信小程序】回到顶部图标-页面滚动事件 | 漫画-综合实训

一、回到顶部-页面滚动事件 在微信小程序中&#xff0c;如果你想将“回到顶部”的功能按钮换成图标&#xff0c;你可以通过以下步骤实现&#xff1a; 1. 准备图标 首先&#xff0c;你需要准备一个图标图片。这个图标可以是任何你选择的格式&#xff0c;如 PNG 或 SVG。将图标…

通过一个含多个包且引用外部jar包的项目实例感受Maven的便利性

目录 1 引言2 手工构建3 基于Maven的构建4 总结 1 引言 最近在阅读一本Java Web的书籍1时&#xff0c;手工实现书上的一个含多个Packages的例子&#xff0c;手工进行编译、运行&#xff0c;最终实现了效果。但感觉到整个构建过程非常繁琐&#xff0c;不仅要手写各个源文件的编…

el-tree拖拽光标错位问题

背景&#xff1a;el-tree实现的分类树增加拖拽功能后&#xff0c;当分类树由于数量较多产生滚动条&#xff0c;如果分类树已滚动&#xff0c;进行拖拽时会造成光标错位的问题: 原因&#xff1a;el-tree拖拽光标定位的高度并未加上滚动的高度解决&#xff1a;将滚动的样式属性放…

【YashanDB知识库】解决mybatis的mapper文件sql语句结尾加分号“;“报错

本文内容来自YashanDB官网&#xff0c;原文内容请见 https://www.yashandb.com/newsinfo/7863046.html?templateId1718516 现象 mybatis或mybaits-plus的mapper文件sql结尾加分号";" 执行时报错&#xff1a;”YAS-04209 unexpected word;“ 解决办法 将sql结尾…

day03-前端Web-Vue3.0基础

目录 前言1. Vue概述2. 快速入门2.1 需求2.2 步骤2.3 实现 3. Vue指令3.1 介绍3.2 v-for3.2.1 介绍3.2.2 演示3.2.3 v-for的key3.2.4 案例-列表渲染 3.3 v-bind3.3.1 介绍3.3.2 演示3.3.3 案例-图片展示 3.4 v-if & v-show3.4.1 介绍3.4.2 案例-性别职位展示 3.6 v-model3.…

Spring Web 嵌套对象校验失效

问题复现 当开发一个学籍管理系统时&#xff0c;我们会提供了一个 API 接口去添加学生的相关信息&#xff0c;学生中有个嵌套属性联系电话&#xff0c;其对象定义参考下面的代码&#xff1a; import lombok.Data; import javax.validation.constraints.Size; Data public class…

计算机网络 (27)IP多播

前言 IP多播&#xff08;也称多址广播或组播&#xff09;技术是一种允许一台或多台主机&#xff08;多播源&#xff09;发送单一数据包到多台主机&#xff08;一次性的、同时的&#xff09;的TCP/IP网络技术。 一、基本概念 定义&#xff1a;多播作为一点对多点的通信&#xff…

计算机毕业设计PyHive+Hadoop深圳共享单车预测系统 共享单车数据分析可视化大屏 共享单车爬虫 共享单车数据仓库 机器学习 深度学习

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

口碑很好的国产LDO芯片,有哪些?

在几乎任何一个电路设计中&#xff0c;都可能会使用LDO&#xff08;低压差线性稳压器&#xff09;这个器件。 虽然LDO不是什么高性能的IC&#xff0c;但LDO芯片市场竞争异常激烈。最近几年&#xff0c;诞生了越来越多的精品国产LDO&#xff0c;让人看得眼花缭乱。 业内人士曾经…

Transformer:深度学习的变革力量

深度学习领域的发展日新月异&#xff0c;在自然语言处理&#xff08;NLP&#xff09;、计算机视觉等领域取得了巨大突破。然而&#xff0c;早期的循环神经网络&#xff08;RNN&#xff09;在处理长序列时面临着梯度消失、并行计算能力不足等瓶颈。而 Transformer 的横空出世&am…

低代码从“产品驱动”向“场景驱动”转型,助力数字化平台构建

一、前言 在数字化时代的大潮中&#xff0c;从宏观层面来看&#xff0c;新技术的落地速度不断加快&#xff0c;各行各业的数字化进程呈现出如火如荼的态势。而从微观层面剖析&#xff0c;企业面临着行业格局快速变化、市场竞争日益激烈以及成本压力显著增强等诸多挑战。 据专…

01-51单片机LED与独立按键

一、单片机概述 注意&#xff1a;个人学习笔记&#xff0c;里面涉及到的C语言和进程转换相关的知识在C语言部分已经写了&#xff0c;这里是默认都会的状态学习单片机。 1.什么是单片机 单片机&#xff0c;英文Micro Controller Unit&#xff0c;简称MCU。其内部集成了CPU、R…

腾讯云AI代码助手编程挑战赛-刑说

作品简介 鉴于当代普法力度不够大&#xff0c;这个刑说可以帮助大家更好的普及法律知识 技术架构 采用了全后端分离的架构&#xff0c;前端使用Vue.js&#xff0c;腾讯云的AI服务处理自然语言理解与生成。 实现过程 开发环境、开发流程 系统&#xff1a;win11 开发工具&…

Elasticsearch:聚合操作

这里写目录标题 一、聚合的概述二、聚合的分类1、指标聚合&#xff08;Metric Aggregation&#xff09;2、桶聚合&#xff08;Bucket Aggregation&#xff09;3、管道聚合&#xff08;Pipeline Aggregation&#xff09; 三、ES聚合分析不精准原因分析四、聚合性能优化1、ES聚合…

升级 Spring Boot 3 配置讲解 —— 为何 SpringBoot3 淘汰了 JDK8?

学会这款 &#x1f525;全新设计的 Java 脚手架 &#xff0c;从此面试不再怕&#xff01; 随着 Spring Boot 3 的发布&#xff0c;许多开发者发现了一个重要的变化&#xff1a;Spring Boot 3 不再支持 JDK 8。这一变化引发了不少讨论&#xff0c;尤其是对于那些仍然在使用 JDK …

rhcsa练习(3)

1 、创建文件命令练习&#xff1a; &#xff08; 1 &#xff09; 在 / 目录下创建一个临时目录 test &#xff1b; mkdir /test &#xff08; 2 &#xff09;在临时目录 test 下创建五个文件&#xff0c;文件名分别为 passwd &#xff0c; group &#xff0c; bashrc &#x…

汽车免拆诊断 | 2007款保时捷Carrera S车行驶中发动机冷却液温度报警灯异常点亮

故障现象 一辆2007款保时捷Carrera S车&#xff0c;搭载3.8 L自然吸气发动机&#xff0c;累计行驶里程约为7.8万km。车主反映&#xff0c;车辆行驶一段距离后&#xff0c;组合仪表上的发动机冷却液温度报警灯异常点亮。为此&#xff0c;在其他维修厂已更换过节温器、发动机冷却…