Mybatis學習筆記--Mybatis動態SQL
技術標籤:Mybatis資料庫mybatissqlmysql
文章目錄
本文章涉及環境版本:
- mysql 5.7
- Mybatis 3.5.x
- Maven 3.6.x
- JDK 1.8
專案程式碼倉庫:
https://github.com/Gang-bb/Study-Record/tree/main/bzhan-mybatis-study
需要clone整個bzhan-mybatis-study專案
(整體是一個maven多module工程)
1. 動態SQL
什麼是動態SQL:動態SQL就是指根據不同的條件生成不同的SQL語句
利用動態 SQL 這一特性可以徹底擺脫這種痛苦。
動態 SQL 元素和 JSTL 或基於類似 XML 的文字處理器相似。在 MyBatis 之前的版本中,有很多元素需要花時間瞭解。MyBatis 3 大大精簡了元素種類,現在只需學習原來一半的元素便可。MyBatis 採用功能強大的基於 OGNL 的表示式來淘汰其它大部分元素。
2. 搭建環境
- 建表
CREATE TABLE `blog` (
`id` varchar(50) NOT NULL COMMENT '部落格id',
`title` varchar(100) NOT NULL COMMENT '部落格標題',
`author` varchar(30) NOT NULL COMMENT '部落格作者',
`create_time` datetime NOT NULL COMMENT '建立時間',
`views` int(30) NOT NULL COMMENT '瀏覽量'
) ENGINE=InnoDB DEFAULT CHARSET=utf8
準備一些測試資料:
- POJO類編寫
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Blog {
private Integer id;
private String title;
private String author;
private Date createTime;
private Integer views;
}
- 編寫dao層mapper介面和mapper.xml檔案
3. IF語句使用
- BlogMapper
List<Blog> getBlogsIf(Map map);
- BlogMapper.xml
<select id="getBlogsIf" resultType="com.gangbb.model.pojo.Blog">
select * from blog where 1=1
<if test="title != null">
and title = #{title}
</if>
<if test="author != null">
and author = #{author}
</if>
</select>
或者:(涉及where標籤知識內容)
<select id="getBlogsIf" resultType="com.gangbb.model.pojo.Blog">
select * from blog
<where>
<if test="title != null">
title = #{title}
</if>
<if test="author != null">
and author = #{author}
</if>
</where>
</select>
- 測試類
@Test
public void getBlogs(){
SqlSession sqlSession = null;
try {
sqlSession = MybatisUtil.openSession();
BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class);
Map map = new HashMap();
map.put("author", "Gangbb");
List<Blog> blogList = blogMapper.getBlogsIf(map);
for (int i = 0; i < blogList.size(); i++) {
Blog blog = blogList.get(i);
System.out.println(blog);
}
} finally {
sqlSession.close();
}
}
4. choose (when, otherwise)語句使用
有時候,我們不想使用所有的條件,而只是想從多個條件中選擇一個使用。針對這種情況,MyBatis 提供了 choose 元素,它有點像 Java 中的 switch 語句。
- BlogMapper
List<Blog> getBlogsChoose(Map map);
- BlogMapper.xml
<select id="getBlogsChoose" parameterType="map" resultType="com.gangbb.model.pojo.Blog">
select * from blog
<where>
<choose>
<when test="title != null">
title = #{title}
</when>
<when test="author != null">
author = #{author}
</when>
<otherwise>
views = 99999999
</otherwise>
</choose>
</where>
</select>
- 測試類
@Test
public void BlogChoose(){
SqlSession sqlSession = null;
try {
sqlSession = MybatisUtil.openSession();
BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class);
Map map = new HashMap();
//下面兩個隨意填入條件測試
//map.put("title", "學習如何找女朋友");
//map.put("author", "Gangbb");
List<Blog> blogList = blogMapper.getBlogsChoose(map);
for (Blog blog : blogList) {
System.out.println(blog);
}
} finally {
sqlSession.close();
}
}
5. trim (where,set)語句使用
where 元素只會在子元素返回任何內容的情況下才插入 “WHERE” 子句。而且,若子句的開頭為 “AND” 或 “OR”,where 元素也會將它們去除。
如果 where 元素與你期望的不太一樣,你也可以通過自定義 trim 元素來定製 where 元素的功能。比如,和 where 元素等價的自定義 trim 元素為:
<trim prefix="WHERE" prefixOverrides="AND |OR ">
...
</trim>
例項使用:
<update id="updateBlog" parameterType="map">
update blog
<set>
<if test="title != null">
title = #{title},
</if>
<if test="author != null">
author = #{author}
</if>
</set>
where id = #{id}
</update>
set 元素會動態地在行首插入 SET 關鍵字,並會刪掉額外的逗號(這些逗號是在使用條件語句給列賦值時引入的)。
等價於:
<trim prefix="SET" suffixOverrides=",">
...
</trim>
所謂的動態SQL,本質還是SQL語句 , 只是我們可以在SQL層面,去執行一個邏輯程式碼
6. SQL片段
有的時候,我們可能會將一些功能的部分抽取出來,方便複用!
-
使用SQL標籤抽取公共的部分
<sql id="if-title-author"> <if test="title != null"> title = #{title} </if> <if test="author != null"> and author = #{author} </if> </sql>
-
在需要使用的地方使用Include標籤引用即可
<select id="queryBlogIF" parameterType="map" resultType="blog"> select * from mybatis.blog <where> <include refid="if-title-author"></include> </where> </select>
注意事項:
-
最好基於單表來定義SQL片段!
-
不要存在where標籤
7. Foreach語句
- BlogMapper
List<Blog> getBlogsChoose(Map map);
- BlogMapper.xml
<!--
select * from mybatis.blog where 1=1 and (id=1 or id = 2 or id=3)
我們現在傳遞一個萬能的map , 這map中可以存在一個集合!
-->
<select id="getBlogForeach" parameterType="map" resultType="blog">
select * from blog
<where>
<foreach collection="ids" item="id" open="and (" close=")" separator="or">
id = #{id}
</foreach>
</where>
</select>
- 測試類
@Test
public void BlogForeach(){
SqlSession sqlSession = null;
try {
sqlSession = MybatisUtil.openSession();
BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class);
Map map = new HashMap();
ArrayList<Integer> ids = new ArrayList<Integer>();
ids.add(1);
map.put("ids", ids);
List<Blog> blogList = blogMapper.getBlogForeach(map);
for (Blog blog : blogList) {
System.out.println(blog);
}
} finally {
sqlSession.close();
}
}
動態SQL就是在拼接SQL語句,我們只要保證SQL的正確性,按照SQL的格式,去排列組合就可以了
建議:
- 現在Mysql中寫出完整的SQL,再對應的去修改成為我們的動態SQL實現通用即可!