Mybatis优化检索的方法详解

 更新时间:2024年05月22日 09:55:53   作者:兔子队列  
MyBatis是一款优秀的基于Java的持久层框架,它可以将 SQL 语句和数据库中的记录映射成为 Java 对象,并且支持灵活的 SQL 查询语句,在Mybatis中,可以使用动态SQL来灵活构造SQL语句,从而满足各种不同的检索需求,本文介绍Mybatis如何优化检索,需要的朋友可以参考下

1.SQL 映射

  • MyBatis 允许开发者直接编写原生SQL或动态SQL,而不是依赖于ORM框架生成的SQL
  • 这种方式可以精确控制SQL执行,优化查询语句的性能,尤其是在处理复杂查询时
  • 示例
  • 1-数据库表结构
  • 假设有两个表:user 和 role,以及一个关联表 user_role
CREATE TABLE user (
    id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(255),
    email VARCHAR(255)
);

CREATE TABLE role (
    id INT AUTO_INCREMENT PRIMARY KEY,
    role_name VARCHAR(255)
);

CREATE TABLE user_role (
    user_id INT,
    role_id INT,
    FOREIGN KEY (user_id) REFERENCES user(id),
    FOREIGN KEY (role_id) REFERENCES role(id)
);
  • 2-MyBatis 配置文件(mybatis-config.xml)
  • 这是 MyBatis 的全局配置文件,设置了一些基本配置和环境信息
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis_demo"/>
                <property name="username" value="root"/>
                <property name="password" value="password"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <mapper resource="UserMapper.xml"/>
    </mappers>
</configuration>
  • 3-Mapper XML 文件(UserMapper.xml)
  • 这个文件定义了 SQL 映射和操作数据库的方法
<?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.example.mapper.UserMapper">
    <select id="selectUserById" resultType="com.example.model.User">
        SELECT * FROM user WHERE id = #{id}
    </select>

    <resultMap id="userRoleMap" type="com.example.model.User">
        <id column="id" property="id"/>
        <result column="username" property="username"/>
        <collection property="roles" ofType="com.example.model.Role">
            <id column="role_id" property="id"/>
            <result column="role_name" property="roleName"/>
        </collection>
    </resultMap>

    <select id="selectUserWithRoles" resultMap="userRoleMap">
        SELECT u.id, u.username, r.id AS role_id, r.role_name
        FROM user u
        LEFT JOIN user_role ur ON u.id = ur.user_id
        LEFT JOIN role r ON ur.role_id = r.id
        WHERE u.id = #{id}
    </select>
</mapper>

2.结果映射

  • MyBatis 提供了高度灵活的结果映射机制,可以将数据库结果直接映射到复杂的对象模型中
  • 它允许你将 SQL 查询返回的结果集映射到 Java 对象中
  • 这减少了数据转换和处理的开销,使得数据加载更为高效
  • 示例
  • 在 MyBatis 的 Mapper XML 中配置一个简单的结果映射如下:
<!-- Mapper XML 配置 -->
<mapper namespace="com.example.mapper.UserMapper">
    <!-- 定义结果映射 -->
    <resultMap id="BaseResultMap" type="com.example.model.User">
        <id column="id" property="id" />
        <result column="username" property="username" />
        <result column="email" property="email" />
    </resultMap>

    <!-- 使用定义好的结果映射查询用户 -->
    <select id="selectUserById" resultMap="BaseResultMap">
        SELECT id, username, email FROM user WHERE id = #{id}
    </select>
</mapper>
  • 在这个例子中
  • BaseResultMap 定义了如何将 user 表的列 idusername、和 email 映射到 Java 对象 User 的相应属性中

3.延迟加载

  • MyBatis 支持延迟加载技术,允许按需加载关联对象
  • 这意味着只有在使用到某个关联对象时,才会执行相应的SQL查询
  • 这种策略可以显著减少初始化对象时的数据库访问次数和网络延迟
  • MyBatis 支持延迟加载的配置可以在 mybatis-config.xml 中设置,例如:
<settings>
    <setting name="lazyLoadingEnabled" value="true"/>
    <setting name="aggressiveLazyLoading" value="false"/>
</settings>
  • 这个配置确保了只有在实际需要使用用户的角色信息时,才会去数据库加载角色数据
  • 这种延迟加载可以提高应用的性能,特别是当数据结构复杂或数据量大时

4.缓存支持

  • MyBatis 内置了强大的缓存机制,用于存储已经执行过的查询结果
  • 以便在后续相同的查询请求中快速返回结果而无需再次执行实际的数据库查询
  • 包括一级缓存(会话缓存)和二级缓存(全局缓存)
  • 一级缓存默认开启,保证了同一会话中相同查询的结果可以被复用
  • 而二级缓存则可以跨会话复用查询结果,减少数据库的查询次数,提高应用性能

一级缓存(Session Cache)

  • 作用范围:一级缓存是基于 SQL 会话的,它仅在当前会话内有效
  • 当会话关闭或提交时,一级缓存也会被清除
  • 实现方式:默认情况下,MyBatis 的每个 SQL 会话有自己的一级缓存
  • 每当会话中执行查询时,MyBatis 首先检查缓存中是否已存在相应的结果
  • 如果有,则直接返回缓存结果;如果没有,则执行数据库查询并将查询结果放入缓存
  • 缓存内容:缓存的内容包括查询结果对象和执行过的查询语句

二级缓存(Global Cache)

  • 作用范围:二级缓存是跨会话的,它可以被不同的会话共享
  • 二级缓存的作用范围通常是映射器(Mapper)级别,不同的映射器持有各自的二级缓存
  • 配置方式:二级缓存需要在 MyBatis 配置文件或映射文件中显式开启
  • 开启后,查询结果可以跨会话重用,从而减少对数据库的查询次数,提高效率
  • 实现技术:二级缓存可以使用 MyBatis 自带的简单实现,也可以集成更强大的缓存解决方案,如 Ehcache、Redis 等

示例配置

  • 在 MyBatis 的 Mapper XML 中开启二级缓存的示例:
<!-- 开启当前 Mapper 的二级缓存 -->
<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>

缓存策略

  • eviction:缓存的回收策略
  • 常用的有 LRU(Least Recently Used 最少使用策略)、FIFO(First In First Out 先进先出策略)等
  • flushInterval:缓存刷新间隔,单位是毫秒
  • 设置后,缓存会在指定的时间间隔后自动清空
  • size:引用数目,设置缓存中可以存储多少个对象
  • readOnly:是否只读
  • 如果为 true,则所有获取的缓存对象都是只读的,这样可以提供一些性能优势

5.批量操作优化

  • MyBatis 提供了批处理的支持,允许在一个会话中执行多个更新操作
  • 这可以减少数据库交互次数,降低网络开销和数据库压力

6.动态 SQL

  • MyBatis 的动态SQL功能允许构建在运行时评估的SQL语句,根据不同的条件组装不同的SQL片段
  • 这不仅提高了SQL的灵活性,也避免了不必要的查询条件,从而优化了查询效率
  • 动态 SQL 的关键组件
  • 1-<if>标签
  • 根据条件是否为真来决定是否包含某个 SQL 片段
  • 这可以用来添加可选的查询条件或修改其他 SQL 构造
  • 2-<choose><when><otherwise>标签
  • 类似于 Java 中的 switch 语句,根据多个条件选择性地包括 SQL 片段
  • 3-<where>标签
  • 自动处理 SQL 查询中的 WHERE 子句,如果其内部的条件为真,就插入 WHERE 关键字
  • 同时也智能地处理多余的 AND 或 OR 关键字
  • 4-<set>标签
  • 用于动态构建 UPDATE 语句,自动处理列赋值的列表,并且在需要时智能插入逗号
  • 5-<foreach>标签
  • 用于在 SQL 语句中构建重复的 SQL 片段,如批量插入数据或构建 IN 子句
  • 6-<sql><include>标签
  • 用于SQL片段的抽取
  • <sql>:抽取SQL语句的标签
  • <sql id="片段唯一标识">抽取的SQL语句</sql>
  • <include>:引入SQL片段标签
  • <include refid="片段唯一标识" />
  • 示例
  • 以下是一些动态 SQL 的示例,展示如何在 MyBatis 的 Mapper XML 中使用它们
<!-- Mapper XML 文件中的示例 -->
<mapper namespace="com.example.mapper.UserMapper">
    <!-- 动态生成 SELECT 查询 -->
    <select id="findUsersByConditions" resultType="User">
        <where>
            <if test="username != null">
                AND username = #{username}
            </if>
            <if test="email != null">
                AND email = #{email}
            </if>
        </where>
    </select>

    <!-- 动态生成 UPDATE 查询 -->
    <update id="updateUser">
        UPDATE users
        <set>
            <if test="username != null">
                username = #{username},
            </if>
            <if test="email != null">
                email = #{email},
            </if>
        </set>
        WHERE id = #{id}
    </update>

    <!-- 使用 foreach 生成 IN 子句 -->
    <select id="findUsersByIds" resultType="User">
        SELECT * FROM users
        WHERE id IN
        <foreach item="id" collection="ids" open="(" separator="," close=")">
            #{id}
        </foreach>
    </select>
</mapper>

7.插件和拦截器

  • MyBatis 允许使用插件对查询过程进行拦截和修改
  • 开发者可以通过插件来添加或改写某些操作的行为
  • 如执行查询前的参数处理或执行后的结果处理,进一步优化查询性能
  • MyBatis 插件本质上是通过拦截器(Interceptor)实现的
  • MyBatis 的拦截器是实现了 Interceptor 接口的组件,用于在SQL执行的关键环节插入自定义逻辑

以上就是Mybatis优化检索的方法详解的详细内容,更多关于Mybatis优化检索的资料请关注脚本之家其它相关文章!

相关文章

  • 带你入门Java的方法

    带你入门Java的方法

    这篇文章主要介绍了java基础之方法详解,文中有非常详细的代码示例,对正在学习java基础的小伙伴们有非常好的帮助,需要的朋友可以参考下
    2021-07-07
  • Spring Data JPA实现动态查询的两种方法

    Spring Data JPA实现动态查询的两种方法

    本篇文章主要介绍了Spring Data JPA实现动态查询的两种方法,具有一定的参考价值,有兴趣的可以了解一下。
    2017-04-04
  • java中建立0-10m的消息(字符串)实现方法

    java中建立0-10m的消息(字符串)实现方法

    下面小编就为大家带来一篇java中建立0-10m的消息(字符串)实现方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-05-05
  • 如何基于http代理解决Java固定ip问题

    如何基于http代理解决Java固定ip问题

    这篇文章主要介绍了如何基于http代理解决Java固定ip问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03
  • 浅谈Java的WeakHashMap源码

    浅谈Java的WeakHashMap源码

    这篇文章主要介绍了浅谈Java的WeakHashMap源码,WeakHashMap,从名字可以看出它是某种 Map,它的特殊之处在于 WeakHashMap 里的entry可能会被GC自动删除,即使程序员没有调用remove()或者clear()方法,需要的朋友可以参考下
    2023-09-09
  • SpringBoot入坑笔记之spring-boot-starter-web 配置文件的使用

    SpringBoot入坑笔记之spring-boot-starter-web 配置文件的使用

    本篇向小伙伴介绍springboot配置文件的配置,已经全局配置参数如何使用的。需要的朋友跟随脚本之家小编一起学习吧
    2018-01-01
  • 学会在Java中使用Optional功能

    学会在Java中使用Optional功能

    这篇文章主要介绍了学会在Java中使用Optional功能,在本文中,我们将了解如何、何时以及在哪里最好地应用Optional,具体相关内容需要的朋友可以参考下面文章内容
    2022-09-09
  • Sentinel熔断规则原理示例详解分析

    Sentinel熔断规则原理示例详解分析

    这篇文章主要介绍了Sentinel熔断规则,采用了示例代码的方式对Sentinel熔断规则进行了详细的分析,以便广大读者朋友们更易理解,有需要的朋友可以参考下
    2021-09-09
  • Spring AOP底层原理及代理模式

    Spring AOP底层原理及代理模式

    这篇文章主要为大家介绍了Spring AOP底层原理及代理模式详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-05-05
  • SpringMVC使用hibernate-validator进行参数校验最佳实践记录

    SpringMVC使用hibernate-validator进行参数校验最佳实践记录

    这篇文章主要介绍了SpringMVC使用hibernate-validator进行参数校验最佳实践,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-05-05

最新评论