1. 程式人生 > >【本人禿頂程式設計師】這也許是你不曾留意過的 Mybatis 細節

【本人禿頂程式設計師】這也許是你不曾留意過的 Mybatis 細節

←←←←←←←←←←←← 我都禿頂了,還不點關注!

本人禿頂程式設計師

Mybatis 可以說是 Java 後端的必備技能,可能你和我一樣經常使用到它。但有時 cv 多了,會忘記了一些細節處理,比如為什麼要加上這個註解?它的作用是什麼等等。

這篇文章是我以前寫的一些關於 Mybatis 細節,希望對各位有起到查漏補缺的作用。

1. 配置檔案

SqlMapConfig.xml 檔案各引數介紹:

<configuration>
   <!-- 載入屬性檔案 -->
   <properties resource="jdbc.properties">
       <!--properties中還可以配置一些屬性名和屬性值  -->
       <!-- <property name="jdbc.driver" value=""/> -->
   </properties>

   <!-- 全域性配置引數,需要時再設定 -->
   <settings>
       <!-- 開啟延遲載入的開關,預設為false -->
       <setting name="lazyLoadingEnabled" value="true"/>
       <!-- 開啟二級快取,預設為true -->
       <setting name="cacheEnabled" value="true"/>
       <!-- 使用jdbc的getGeneratedKeys獲取資料庫自增主鍵值 -->
       <setting name="useGeneratedKeys" value="true"/>
   </settings>

   <!-- 別名定義 -->
   <typeAliases>
       <!-- 針對單個別名定義
       type:型別的路徑,alias:別名。示例:-->
       <typeAlias type="com.czd.mybatis.po.User" alias="user"/>
       <!-- 批量別名定義
       指定包名,mybatis自動掃描包中的po類,自動定義別名,別名就是類名(首字母大寫或小寫都可以)-->
       <package name="com.czd.mybatis.po"/>

   </typeAliases>

   <!-- 和spring整合後 environments配置將廢除-->
   <environments default="development">
       <environment id="development">
           <!-- 使用jdbc事務管理,事務控制由mybatis-->
           <transactionManager type="JDBC"/>
           <!-- 資料庫連線池,由mybatis管理-->
           <dataSource type="POOLED">
               <property name="driver" value="${jdbc.driver}"/>
               <property name="url" value="${jdbc.url}"/>
               <property name="username" value="${jdbc.username}"/>
               <property name="password" value="${jdbc.password}"/>
           </dataSource>
       </environment>
   </environments>

<!--載入對映檔案有 3 種方法,如下所示-->
<mappers> 
<mapper resource="sqlmap/User.xml"/>
       <!--1. 通過 resource 方法一次載入一個對映檔案 -->
       <!-- <mapper resource="mapper/UserMapper.xml"/> -->

       <!-- 2. 通過 mapper 介面載入單個對映檔案
       遵循一些規範:需要將 mapper 介面類名和 mapper.xml 對映檔名稱保持一致,且在一個目錄中
        -->
       <!-- <mapper class="com.iot.mybatis.mapper.UserMapper"/> -->

       <!-- 3. 批量載入 mapper
       指定 mapper 介面的包名,mybatis 自動掃描包下邊所有 mapper 介面進行載入
       遵循一些規範:需要將 mapper 介面類名和 mapper.xml對映檔名稱保持一致,且在一個目錄中
        -->
       <package name="com.czd.mybatis.mapper"/>

<mappers/>

2. # 和 $ 的區別

使用 #{parameterName} 引用引數的時候,Mybatis 會把這個引數認為是一個字串,例如在下面的 sql 傳入引數 “Smith”,

Select from emp where name = #{employeeName}

就會被轉換為:

Select from emp where name = ‘Smith’;

同理在下面 sql 傳入引數 “Smith”:

Select from emp where name = ${employeeName}

使用的時候就會被轉換為 :

Select from emp where name = Smith;

簡單來說, #{} 是經過預編譯的,是安全的,而 ${} 是未經過預編譯的,僅僅是取變數的值,是非安全的,存在 sql 注入的危險。# 將傳入的資料都當成一個字串,會對自動傳入的資料加一個雙引號。

使用 ${} 的情況,order by、like 語句只能用 ${} 了,用 #{} 會多個 ’ ’ 導致 sql 語句失效.此外動態拼接 sql,模糊查詢時也要用 ${}。

舉個栗子,假如 name=陳,那麼該 sql 就是 … LiKE ‘%陳%’,

DELETE FROM stu WHERE `name` LIKE '%${name}%'

3.SQL 語句中的列名與關鍵字衝突時怎麼辦

比如:name 欄位。

解決方法:在列名兩邊加上兩個 ` 即可,如下:

DELETE FROM stu WHERE `name` LIKE '%${name}%'

4.列名和 bean 屬性名不一樣,導致獲取不到資料時怎麼辦

那麼為什麼會導致查詢的 SQL 語句無法得到正確結果呢?

因為 mybatis 會通過反射得到 bean ,由於欄位名和屬性名不一樣,導致無法將查詢到的表字段資料 set 到 bean 屬性中。

解決方法:

【不推薦】修改表字段名稱或 bean 屬性名稱,使它們同名即可

【推薦】修改 標籤中的相應內容,如下圖所示
在這裡插入圖片描述

5. @Param 引數的作用

作用:相當於給其修飾的引數指定一個別名。

若介面只有一個引數則可以不用指定別名,List 引數除外。當有多個引數時一定要指定,否則 mybatis 對映不到對應的欄位。

如下程式碼:

List<Book> queryAll(@Param("offset")int offset, @Param("limit")int limit);

該介面方法對應的 mapper 實現如下:

<select id="queryAll" resultType="Book">
       SELECT
           book_id,
           `name`,
           `number`
       FROM
           book
       ORDER BY
           book_id
       LIMIT #{offset}, #{limit}
</select>

可以看到 #{} 裡面的值是和 @Param(“value”) 保持一致的,也一定要一致,否則 mybatis 會找不到這個值而導致報錯。另外,@Param(“value”) 中的 value 可以是任意的。