这也许是你不曾留意过的 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}%'
上面話有點長,這里小小總結下:
-
#{} :編譯好 SQL 語句再取值
-
${} :取值以后再去編譯SQL語句
?
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">SELECTbook_id,`name`,`number`FROMbookORDER BYbook_idLIMIT?#{offset}, #{limit} </select>可以看到?#{}?里面的值是和?@Param("value")?保持一致的,也一定要一致,否則 mybatis 會找不到這個值而導致報錯。另外,@Param("value")?中的 value 可以是任意的。
參考:
https://github.com/liyifeng1994/ssm
https://github.com/brianway/springmvc-mybatis-learning/blob/master/sourcecode/mybatis/config/SqlMapConfig.xml?
總結
以上是生活随笔為你收集整理的这也许是你不曾留意过的 Mybatis 细节的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 申请email邮箱方法 申请邮箱方法
- 下一篇: 2022年网站和应用的5个最佳Djang