Mybatis優(yōu)化檢索的方法詳解
1.SQL 映射
- MyBatis 允許開發(fā)者直接編寫原生SQL或動態(tài)SQL,而不是依賴于ORM框架生成的SQL
- 這種方式可以精確控制SQL執(zhí)行,優(yōu)化查詢語句的性能,尤其是在處理復雜查詢時
- 示例:
- 1-數(shù)據(jù)庫表結(jié)構(gòu)
- 假設有兩個表:
user和role,以及一個關(guān)聯(lián)表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 的全局配置文件,設置了一些基本配置和環(huán)境信息
<?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 映射和操作數(shù)據(jù)庫的方法
<?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.結(jié)果映射
- MyBatis 提供了高度靈活的結(jié)果映射機制,可以將數(shù)據(jù)庫結(jié)果直接映射到復雜的對象模型中
- 它允許你將 SQL 查詢返回的結(jié)果集映射到 Java 對象中
- 這減少了數(shù)據(jù)轉(zhuǎn)換和處理的開銷,使得數(shù)據(jù)加載更為高效
- 示例:
- 在 MyBatis 的 Mapper XML 中配置一個簡單的結(jié)果映射如下:
<!-- Mapper XML 配置 -->
<mapper namespace="com.example.mapper.UserMapper">
<!-- 定義結(jié)果映射 -->
<resultMap id="BaseResultMap" type="com.example.model.User">
<id column="id" property="id" />
<result column="username" property="username" />
<result column="email" property="email" />
</resultMap>
<!-- 使用定義好的結(jié)果映射查詢用戶 -->
<select id="selectUserById" resultMap="BaseResultMap">
SELECT id, username, email FROM user WHERE id = #{id}
</select>
</mapper>
- 在這個例子中
BaseResultMap定義了如何將user表的列id、username、和email映射到 Java 對象User的相應屬性中
3.延遲加載
- MyBatis 支持延遲加載技術(shù),允許按需加載關(guān)聯(lián)對象
- 這意味著只有在使用到某個關(guān)聯(lián)對象時,才會執(zhí)行相應的SQL查詢
- 這種策略可以顯著減少初始化對象時的數(shù)據(jù)庫訪問次數(shù)和網(wǎng)絡延遲
- MyBatis 支持延遲加載的配置可以在
mybatis-config.xml中設置,例如:
<settings>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
- 這個配置確保了只有在實際需要使用用戶的角色信息時,才會去數(shù)據(jù)庫加載角色數(shù)據(jù)
- 這種延遲加載可以提高應用的性能,特別是當數(shù)據(jù)結(jié)構(gòu)復雜或數(shù)據(jù)量大時
4.緩存支持
- MyBatis 內(nèi)置了強大的緩存機制,用于存儲已經(jīng)執(zhí)行過的查詢結(jié)果
- 以便在后續(xù)相同的查詢請求中快速返回結(jié)果而無需再次執(zhí)行實際的數(shù)據(jù)庫查詢
- 包括一級緩存(會話緩存)和二級緩存(全局緩存)
- 一級緩存默認開啟,保證了同一會話中相同查詢的結(jié)果可以被復用
- 而二級緩存則可以跨會話復用查詢結(jié)果,減少數(shù)據(jù)庫的查詢次數(shù),提高應用性能
一級緩存(Session Cache):
- 作用范圍:一級緩存是基于 SQL 會話的,它僅在當前會話內(nèi)有效
- 當會話關(guān)閉或提交時,一級緩存也會被清除
- 實現(xiàn)方式:默認情況下,MyBatis 的每個 SQL 會話有自己的一級緩存
- 每當會話中執(zhí)行查詢時,MyBatis 首先檢查緩存中是否已存在相應的結(jié)果
- 如果有,則直接返回緩存結(jié)果;如果沒有,則執(zhí)行數(shù)據(jù)庫查詢并將查詢結(jié)果放入緩存
- 緩存內(nèi)容:緩存的內(nèi)容包括查詢結(jié)果對象和執(zhí)行過的查詢語句
二級緩存(Global Cache):
- 作用范圍:二級緩存是跨會話的,它可以被不同的會話共享
- 二級緩存的作用范圍通常是映射器(Mapper)級別,不同的映射器持有各自的二級緩存
- 配置方式:二級緩存需要在 MyBatis 配置文件或映射文件中顯式開啟
- 開啟后,查詢結(jié)果可以跨會話重用,從而減少對數(shù)據(jù)庫的查詢次數(shù),提高效率
- 實現(xiàn)技術(shù):二級緩存可以使用 MyBatis 自帶的簡單實現(xiàn),也可以集成更強大的緩存解決方案,如 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:引用數(shù)目,設置緩存中可以存儲多少個對象
- readOnly:是否只讀
- 如果為
true,則所有獲取的緩存對象都是只讀的,這樣可以提供一些性能優(yōu)勢
5.批量操作優(yōu)化
- MyBatis 提供了批處理的支持,允許在一個會話中執(zhí)行多個更新操作
- 這可以減少數(shù)據(jù)庫交互次數(shù),降低網(wǎng)絡開銷和數(shù)據(jù)庫壓力
6.動態(tài) SQL
- MyBatis 的動態(tài)SQL功能允許構(gòu)建在運行時評估的SQL語句,根據(jù)不同的條件組裝不同的SQL片段
- 這不僅提高了SQL的靈活性,也避免了不必要的查詢條件,從而優(yōu)化了查詢效率
- 動態(tài) SQL 的關(guān)鍵組件:
- 1-
<if>標簽: - 根據(jù)條件是否為真來決定是否包含某個 SQL 片段
- 這可以用來添加可選的查詢條件或修改其他 SQL 構(gòu)造
- 2-
<choose>,<when>,<otherwise>標簽: - 類似于 Java 中的
switch語句,根據(jù)多個條件選擇性地包括 SQL 片段 - 3-
<where>標簽: - 自動處理 SQL 查詢中的
WHERE子句,如果其內(nèi)部的條件為真,就插入WHERE關(guān)鍵字 - 同時也智能地處理多余的
AND或OR關(guān)鍵字 - 4-
<set>標簽: - 用于動態(tài)構(gòu)建
UPDATE語句,自動處理列賦值的列表,并且在需要時智能插入逗號 - 5-
<foreach>標簽: - 用于在 SQL 語句中構(gòu)建重復的 SQL 片段,如批量插入數(shù)據(jù)或構(gòu)建
IN子句 - 6-
<sql>和<include>標簽: - 用于SQL片段的抽取
<sql>:抽取SQL語句的標簽<sql id="片段唯一標識">抽取的SQL語句</sql><include>:引入SQL片段標簽<include refid="片段唯一標識" />- 示例:
- 以下是一些動態(tài) SQL 的示例,展示如何在 MyBatis 的 Mapper XML 中使用它們
<!-- Mapper XML 文件中的示例 -->
<mapper namespace="com.example.mapper.UserMapper">
<!-- 動態(tài)生成 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>
<!-- 動態(tài)生成 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 允許使用插件對查詢過程進行攔截和修改
- 開發(fā)者可以通過插件來添加或改寫某些操作的行為
- 如執(zhí)行查詢前的參數(shù)處理或執(zhí)行后的結(jié)果處理,進一步優(yōu)化查詢性能
- MyBatis 插件本質(zhì)上是通過攔截器(Interceptor)實現(xiàn)的
- MyBatis 的攔截器是實現(xiàn)了 Interceptor 接口的組件,用于在SQL執(zhí)行的關(guān)鍵環(huán)節(jié)插入自定義邏輯
以上就是Mybatis優(yōu)化檢索的方法詳解的詳細內(nèi)容,更多關(guān)于Mybatis優(yōu)化檢索的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
springboot結(jié)合easyexcel實現(xiàn)動態(tài)表頭的實踐
這篇文章主要介紹了springboot結(jié)合easyexcel實現(xiàn)動態(tài)表頭的實踐,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2025-06-06
Java的super關(guān)鍵字與instanceof運算符使用方法
這篇文章主要介紹了Java的super關(guān)鍵字與instanceof運算符使用方法,是Java入門學習中的基礎(chǔ)知識,需要的朋友可以參考下2015-09-09
java-springboot3.2+多數(shù)據(jù)源+hikari連接池的配置使用
本文給大家介紹java-springboot3.2+多數(shù)據(jù)源+hikari連接池的配置使用,本文結(jié)合實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧2025-11-11
String.intern()作用與常量池關(guān)系示例解析
這篇文章主要為大家介紹了String.intern()作用與常量池關(guān)系示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-08-08
解決mybatis plus字段為null或空字符串無法保存到數(shù)據(jù)庫的問題
這篇文章主要介紹了解決mybatis plus字段為null或空字符串無法保存到數(shù)據(jù)庫的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-02-02
Java實現(xiàn)將文件或者文件夾壓縮成zip的詳細代碼
這篇文章主要介紹了Java實現(xiàn)將文件或者文件夾壓縮成zip的詳細代碼,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-11-11

