偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

虛擬化KVM常用命令匯總

開發(fā)
今天這篇文章,我把 MyBatis 從基礎(chǔ)到高級的 25 個實用配置和 SQL 映射案例一次性講透,每個案例都配上真實業(yè)務(wù)場景的代碼示例,看完讓你對 MyBatis 的使用豁然開朗,開發(fā)效率直接翻倍!

還在為 MyBatis 的復(fù)雜配置頭疼?SQL 映射總是寫得亂七八糟?分頁查詢、動態(tài) SQL、關(guān)聯(lián)查詢這些場景總是搞不定?別慌!今天這篇文章,我把 MyBatis 從基礎(chǔ)到高級的 25 個實用配置和 SQL 映射案例一次性講透,每個案例都配上真實業(yè)務(wù)場景的代碼示例,看完讓你對 MyBatis 的使用豁然開朗,開發(fā)效率直接翻倍!

一、基礎(chǔ)配置:搭建 MyBatis 核心環(huán)境

1. 核心配置文件 mybatis-config.xml 基礎(chǔ)結(jié)構(gòu)

MyBatis 的全局配置文件,包含數(shù)據(jù)源、別名、Mapper 注冊等核心配置:

<?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>

   <!-- 環(huán)境配置:可配置多個環(huán)境,默認使用development -->

   <environments default="development">

       <environment id="development">

           <!-- 事務(wù)管理器:JDBC 事務(wù)管理 -->

           <transactionManager type="JDBC"/>

           <!-- 數(shù)據(jù)源:POOLED 表示使用連接池 -->

           <dataSource type="POOLED">

               <property name="driver" value="com.mysql.cj.jdbc.Driver"/>

               <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=false"/>

               <property name="username" value="root"/>

               <property name="password" value="123456"/>

           </dataSource>

       </environment>

   </environments>

   <!-- 注冊 Mapper 文件 -->

   <mappers>

       <mapper resource="mapper/UserMapper.xml"/>

       <mapper class="com.example.mapper.OrderMapper"/> <!-- 接口映射 -->

   </mappers>

</configuration>

關(guān)鍵說明:POOLED 數(shù)據(jù)源會緩存數(shù)據(jù)庫連接,避免頻繁創(chuàng)建連接的性能損耗,生產(chǎn)環(huán)境必用。

2. 映射文件 Mapper.xml 基礎(chǔ)結(jié)構(gòu)

定義 SQL 語句和結(jié)果映射的核心文件,與 Mapper 接口對應(yīng):

<?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">


<!-- namespace 必須與 Mapper 接口全類名一致 -->


<mapper namespace="com.example.mapper.UserMapper">


   <!-- 根據(jù) ID 查詢用戶 -->


   <select id="getUserById" parameterType="Long" resultType="com.example.pojo.User">


       SELECT id, username, age FROM user WHERE id = #{id}


   </select>


</mapper>

核心規(guī)則:namespace 必須與 Mapper 接口的全類名一致,id 必須與接口方法名一致,參數(shù)和返回值類型要匹配。

3. 接口綁定:無需實現(xiàn)類直接調(diào)用

MyBatis 最核心的特性之一,通過接口與 XML 映射文件綁定,直接調(diào)用接口方法執(zhí)行 SQL:

// Mapper 接口

public interface UserMapper {


   User getUserById(Long id);


}


// 調(diào)用方式

SqlSession sqlSession = MyBatisUtils.getSqlSession();


UserMapper userMapper = sqlSession.getMapper(UserMapper.class);


User user = userMapper.getUserById(1L); // 直接調(diào)用接口方法

優(yōu)勢:告別傳統(tǒng)的 DAO 實現(xiàn)類,代碼量減少 50%,專注于 SQL 編寫。

二、SQL 映射基礎(chǔ):CRUD 操作實戰(zhàn)

4. 新增用戶并返回自增主鍵

插入數(shù)據(jù)后需要獲取自動生成的主鍵(如 ID),用 useGeneratedKeys 和 keyProperty 配置:

<!-- 新增用戶并返回自增 ID -->


<insert id="insertUser" useGeneratedKeys="true" keyProperty="id">

   INSERT INTO user (username, age) VALUES (#{username}, #{age})


</insert>
// 調(diào)用后 user.getId() 即可獲取自增主鍵

User user = new User();


user.setUsername("張三");


user.setAge(25);


userMapper.insertUser(user);


System.out.println("新增用戶 ID:" + user.getId()); // 輸出插入后的 ID

5. 根據(jù) ID 更新用戶信息

使用 set 標簽處理動態(tài)更新,自動忽略空值字段:

<!-- 更新用戶信息(只更新非空字段) -->


<update id="updateUser">

   UPDATE user


   <set>

       <if test="username != null">username = #{username},</if>

       <if test="age != null">age = #{age}</if>

   </set>

   WHERE id = #{id}


</update>

優(yōu)勢:如果 username 為 null,會自動忽略該字段,避免將字段更新為 null。

6. 根據(jù) ID 刪除用戶

簡單的刪除操作,注意參數(shù)傳遞方式:

<!-- 根據(jù) ID 刪除用戶 -->


<delete id="deleteUserById" parameterType="Long">

   DELETE FROM user WHERE id = #{id}


</delete>
userMapper.deleteUserById(1L);


sqlSession.commit(); // 增刪改必須提交事務(wù)

7. 批量刪除用戶(傳入 ID 列表)

用 foreach 標簽處理批量刪除,遍歷集合生成 SQL:

<!-- 批量刪除用戶 -->


<delete id="batchDelete">

   DELETE FROM user WHERE id IN


   <foreach collection="list" item="id" open="(" separator="," close=")">

       #{id}


   </foreach>

</delete>
List<Long> ids = Arrays.asList(1L, 2L, 3L);


userMapper.batchDelete(ids); // 一次刪除多個用戶

foreach 參數(shù)說明:

  • collection:集合參數(shù)名稱(list、array 或自定義名稱)
  • item:遍歷的元素變量名
  • open/close:包裹整個集合的符號(如 ( 和 ))
  • separator:元素之間的分隔符(如 ,)

三、參數(shù)處理:多種參數(shù)傳遞方式

8. 單個參數(shù)傳遞

直接使用 #{參數(shù)名} 接收,參數(shù)名可任意(建議與方法參數(shù)名一致):

<!-- 單個參數(shù):根據(jù)用戶名查詢 -->


<select id="getUserByUsername" resultType="User">

   SELECT id, username, age FROM user WHERE username = #{username}


</select>
User user = userMapper.getUserByUsername("張三");

9. 多個參數(shù)傳遞(@Param 注解)

方法有多個參數(shù)時,用 @Param 注解指定參數(shù)名稱,避免參數(shù)混淆:

// 接口方法(多個參數(shù)用 @Param 注解)

User getUserByUsernameAndAge(@Param("username") String username, @Param("age") Integer age);
<!-- 接收多個參數(shù) -->


<select id="getUserByUsernameAndAge" resultType="User">

   SELECT id, username, age FROM user


   WHERE username = #{username} AND age = #{age}


</select>

10. 傳遞 JavaBean 參數(shù)

直接傳遞實體類對象,用 #{屬性名} 接收參數(shù):

// 傳遞 User 對象作為參數(shù)

List<User> getUsersByCondition(User user);
<!-- 使用 JavaBean 屬性作為參數(shù) -->


<select id="getUsersByCondition" resultType="User">

   SELECT id, username, age FROM user


   WHERE 1=1


   <if test="username != null">AND username LIKE CONCAT('%', #{username}, '%')</if>

   <if test="age != null">AND age = #{age}</if>

</select>

11. 傳遞 Map 參數(shù)

靈活傳遞多個零散參數(shù),用 #{key} 接收 Map 中的鍵值對:

// 傳遞 Map 作為參數(shù)

List<User> getUsersByMap(Map<String, Object> params);
<!-- 使用 Map 的 key 作為參數(shù) -->


<select id="getUsersByMap" resultType="User">

   SELECT id, username, age FROM user


   WHERE username = #{name} AND age > #{minAge}


</select>
// 調(diào)用方式

Map<String, Object> params = new HashMap<>();


params.put("name", "張三");


params.put("minAge", 18);


List<User> users = userMapper.getUsersByMap(params);

四、動態(tài) SQL:靈活處理條件查詢

12. if + where 標簽:動態(tài)條件查詢

where 標簽會自動處理多余的 AND/OR,避免 SQL 語法錯誤:

<!-- 動態(tài)條件查詢(自動處理 AND) -->


<select id="getUserList" resultType="User">

   SELECT id, username, age FROM user


   <where>

       <if test="username != null">AND username LIKE #{username}</if>

       <if test="age != null">AND age = #{age}</if>

   </where>

</select>

對比傳統(tǒng) SQL:無需手動拼接 WHERE 1=1,where 標簽會智能判斷是否添加 WHERE 關(guān)鍵字,多余的 AND 會自動刪除。

13. choose + when + otherwise:多條件分支判斷

類似 Java 中的 if-else,只執(zhí)行第一個滿足條件的分支:

<!-- 多條件分支查詢 -->


<select id="getUserByCondition" resultType="User">

   SELECT id, username, age FROM user


   WHERE 1=1


   <choose>

       <when test="id != null">AND id = #{id}</when> <!-- 優(yōu)先按 ID 查詢 -->

       <when test="username != null">AND username = #{username}</when> <!-- 其次按用戶名查詢 -->

       <otherwise>AND age > 18</otherwise> <!-- 都不滿足時的默認條件 -->

   </choose>

</select>

14. foreach 批量插入

一次性插入多條數(shù)據(jù),比循環(huán)單條插入效率提升 10 倍:

<!-- 批量插入用戶 -->


<insert id="batchInsert">

   INSERT INTO user (username, age) VALUES


   <foreach collection="list" item="user" separator=",">

       (#{user.username}, #{user.age})


   </foreach>

</insert>
List<User> users = Arrays.asList(


   new User("張三", 20),


   new User("李四", 22)


);


userMapper.batchInsert(users); // 一次插入多條數(shù)據(jù)

五、結(jié)果映射:解決字段與屬性不一致問題

15. resultMap:自定義字段與屬性映射

當數(shù)據(jù)庫字段與 Java 實體類屬性名稱不一致時,用 resultMap 手動映射:

<!-- 自定義結(jié)果映射(解決字段與屬性名不一致) -->


<resultMap id="userResultMap" type="User">

   <id property="userId" column="id"/> <!-- 主鍵映射 -->

   <result property="userName" column="username"/> <!-- 普通字段映射 -->

   <result property="userAge" column="age"/>

</resultMap>

<select id="getUserById" resultMap="userResultMap">

   SELECT id, username, age FROM user WHERE id = #{id}


</select>
// 實體類屬性與數(shù)據(jù)庫字段不同

public class User {


   private Long userId; // 對應(yīng)數(shù)據(jù)庫 id

   private String userName; // 對應(yīng)數(shù)據(jù)庫 username

   private Integer userAge; // 對應(yīng)數(shù)據(jù)庫 age

   // getter/setter

}

16. 一對一關(guān)聯(lián)查詢(如訂單關(guān)聯(lián)用戶)

查詢訂單時同時關(guān)聯(lián)查詢用戶信息,用 association 標簽配置:

<!-- 訂單關(guān)聯(lián)查詢用戶(一對一) -->


<resultMap id="orderResultMap" type="Order">

   <id property="id" column="order_id"/>

   <result property="orderNo" column="order_no"/>

   <!-- 關(guān)聯(lián)用戶信息 -->

   <association property="user" javaType="User">

       <id property="id" column="user_id"/>

       <result property="username" column="username"/>

   </association>

</resultMap>

<select id="getOrderById" resultMap="orderResultMap">

   SELECT o.id AS order_id, o.order_no, u.id AS user_id, u.username


   FROM order o


   LEFT JOIN user u ON o.user_id = u.id


   WHERE o.id = #{id}


</select>
// 訂單實體類包含用戶對象

public class Order {


   private Long id;


   private String orderNo;


   private User user; // 關(guān)聯(lián)的用戶信息

   // getter/setter

}

17. 一對多關(guān)聯(lián)查詢(如用戶關(guān)聯(lián)訂單列表)

查詢用戶時同時查詢其所有訂單,用 collection 標簽配置:

<!-- 用戶關(guān)聯(lián)查詢訂單列表(一對多) -->


<resultMap id="userOrderResultMap" type="User">

   <id property="id" column="user_id"/>

   <result property="username" column="username"/>

   <!-- 關(guān)聯(lián)訂單列表 -->

   <collection property="orders" ofType="Order">

       <id property="id" column="order_id"/>

       <result property="orderNo" column="order_no"/>

   </collection>

</resultMap>

<select id="getUserWithOrders" resultMap="userOrderResultMap">

   SELECT u.id AS user_id, u.username, o.id AS order_id, o.order_no


   FROM user u


   LEFT JOIN order o ON u.id = o.user_id


   WHERE u.id = #{id}


</select>
// 用戶實體類包含訂單列表

public class User {


   private Long id;


   private String username;


   private List<Order> orders; // 關(guān)聯(lián)的訂單列表

   // getter/setter

}

六、高級配置:提升性能與靈活性

18. 別名配置:簡化類名書寫

在全局配置文件中定義別名,XML 映射文件中直接使用短名稱,避免寫全類名:

<!-- mybatis-config.xml 中配置別名 -->


<typeAliases>

   <typeAlias type="com.example.pojo.User" alias="User"/> <!-- 單個類別名 -->

   <package name="com.example.pojo"/> <!-- 包下所有類自動取首字母小寫別名 -->

</typeAliases>
<!-- 直接使用別名 -->


<select id="getUserById" resultType="User"> <!-- 無需寫全類名 -->

   SELECT id, username FROM user WHERE id = #{id}


</select>

19. 分頁查詢:使用 PageHelper 插件

MyBatis 本身不支持物理分頁,集成 PageHelper 插件實現(xiàn)高效分頁:

<!-- pom.xml 引入依賴 -->


<dependency>

   <groupId>com.github.pagehelper</groupId>

   <artifactId>pagehelper-spring-boot-starter</artifactId>

   <version>1.4.6</version>

</dependency>
// 分頁查詢(PageHelper 自動攔截 SQL 添加分頁條件)

PageHelper.startPage(1, 10); // 第 1 頁,每頁 10 條

List<User> userList = userMapper.getUserList();


Page<User> page = (Page<User>) userList;


System.out.println("總條數(shù):" + page.getTotal());


System.out.println("總頁數(shù):" + page.getPages());

20. 緩存配置:一級緩存與二級緩存

MyBatis 自帶緩存機制,減少數(shù)據(jù)庫查詢次數(shù):

  • 一級緩存:默認開啟,SqlSession 級別的緩存,同一 SqlSession 內(nèi)查詢相同數(shù)據(jù)會命中緩存。
  • 二級緩存:Mapper 級別的緩存,多個 SqlSession 共享,需手動開啟。
<!-- 在 Mapper.xml 中開啟二級緩存 -->


<cache eviction="LRU" flushInterval="60000" size="1024" readOnly="true"/>

<!-- 禁用某個方法的緩存 -->


<select id="getUserById" useCache="false">

   SELECT id, username FROM user WHERE id = #{id}


</select>

注意:二級緩存適合查詢頻繁、修改較少的數(shù)據(jù),且實體類需實現(xiàn) Serializable 接口。

21. 類型轉(zhuǎn)換器:處理特殊類型

自定義類型轉(zhuǎn)換器,解決數(shù)據(jù)庫類型與 Java 類型不匹配問題(如數(shù)據(jù)庫 VARCHAR 存儲 JSON 字符串,轉(zhuǎn)換為 Java 對象):

// 自定義類型轉(zhuǎn)換器

public class JsonTypeHandler<T> extends BaseTypeHandler<T> {


   private Class<T> type;


   // 實現(xiàn) getResult、setParameter 等方法,完成 JSON 與對象的轉(zhuǎn)換

}
<!-- 配置類型轉(zhuǎn)換器 -->


<typeHandlers>

   <typeHandler handler="com.example.handler.JsonTypeHandler" javaType="com.example.pojo.Info"/>

</typeHandlers>

<!-- 在 SQL 映射中使用 -->


<resultMap id="userResultMap" type="User">

   <result property="info" column="info" typeHandler="com.example.handler.JsonTypeHandler"/>

</resultMap>

七、實戰(zhàn)技巧:避坑與性能優(yōu)化

22. #{} 與 ${} 的區(qū)別:防止 SQL 注入

#{} 會預(yù)編譯 SQL(參數(shù)用?占位),${} 直接拼接 SQL(有注入風(fēng)險):

<!-- 安全:#{} 預(yù)編譯,參數(shù)作為值傳入 -->


SELECT * FROM user WHERE username = #{username}


<!-- 危險:${} 直接拼接,可能導(dǎo)致 SQL 注入 -->


SELECT * FROM user WHERE username = '${username}'


<!-- 如果 username 為 '張三' OR '1'='1,會查詢所有用戶 -->

使用原則:優(yōu)先用 #{},只有在動態(tài)拼接表名、排序字段時才用 ${},且必須嚴格校驗參數(shù)。

23. 批量更新:減少 SQL 執(zhí)行次數(shù)

通過 foreach 拼接批量更新語句,比循環(huán)單條更新效率提升 10 倍:

<!-- 批量更新(MySQL 支持,需開啟 allowMultiQueries=true) -->


<update id="batchUpdate">

   <foreach collection="list" item="user" separator=";">

       UPDATE user SET username = #{user.username} WHERE id = #{user.id}


   </foreach>

</update>

注意:MySQL 需在連接 URL 中添加 allowMultiQueries=true 才能支持批量更新。

24. 懶加載:按需加載關(guān)聯(lián)數(shù)據(jù)

關(guān)聯(lián)查詢時默認不加載關(guān)聯(lián)數(shù)據(jù),用到時才查詢,減少不必要的 SQL 執(zhí)行:

<!-- 全局配置開啟懶加載 -->


<settings>

   <setting name="lazyLoadingEnabled" value="true"/>

   <setting name="aggressiveLazyLoading" value="false"/>

</settings>

<!-- 一對一懶加載 -->


<association property="user" javaType="User" select="getUserById" column="user_id"/>
// 調(diào)用時只查詢訂單,訪問 user 屬性時才查詢用戶

Order order = orderMapper.getOrderById(1L); // 只執(zhí)行訂單查詢 SQL

User user = order.getUser(); // 此時才執(zhí)行用戶查詢 SQL

25. SQL 片段:復(fù)用重復(fù) SQL

將重復(fù)的 SQL 片段抽取為 <sql> 標簽,用 <include> 引用,減少代碼冗余:

<!-- 定義 SQL 片段 -->


<sql id="userColumns">id, username, age</sql>

<!-- 引用 SQL 片段 -->


<select id="getUserById" resultType="User">

   SELECT <include refid="userColumns"/> FROM user WHERE id = #{id}


</select>

<select id="getUserList" resultType="User">

   SELECT <include refid="userColumns"/> FROM user


</select>

為什么掌握這些能讓你少加班?

MyBatis 是 Java 后端開發(fā)的必備技能,但 80% 的開發(fā)者都在重復(fù)踩坑:SQL 注入、關(guān)聯(lián)查詢混亂、動態(tài) SQL 拼接錯誤、性能低下…… 這 25 個案例覆蓋了 90% 的實際開發(fā)場景,從基礎(chǔ)配置到高級優(yōu)化,讓你:

  • 寫出更安全的 SQL(避免注入)
  • 減少 50% 的代碼量(接口綁定 + 動態(tài) SQL)
  • 提升查詢性能(緩存 + 批量操作 + 懶加載)
責任編輯:趙寧寧 來源: 編程江湖
相關(guān)推薦

2025-07-17 12:26:46

LinuxKVM虛擬化

2010-05-25 11:40:12

MySQL 常用命令

2010-05-28 18:28:51

MySQL常用命令

2010-05-27 13:12:10

MySQL 常用命令

2025-04-14 08:00:00

Docker命令運維

2025-05-06 07:50:00

Ansible命令運維

2025-09-11 08:00:00

MySQL運維數(shù)據(jù)庫

2011-01-19 17:00:09

Postfix常用命令

2014-01-02 09:57:56

PostgreSQL命令

2014-07-25 10:55:36

Linux命令

2011-03-16 10:07:00

2020-09-28 15:14:31

Linux常用命令實用命令

2010-03-29 10:16:39

CentOS常用命令

2010-03-02 13:14:36

LinuxYUM常用命

2010-04-01 17:19:04

CentOS常用命令

2010-06-29 16:57:53

SNMP協(xié)議

2013-04-28 14:03:26

Android開發(fā)Android常用命令

2010-04-21 10:19:40

Unix Shell

2010-01-07 17:59:50

Ubuntu APT
點贊
收藏

51CTO技術(shù)棧公眾號