寫在前面
大家好,我是Think-Coder,比較通俗的暱稱,寓意是做一個有思考的程序猿,現在的狀態是邊做項目邊學習;
博客是我平時做項目和學習的過程,很基礎,但是每一篇我很認真在寫,力求讓讀者,讀的清楚,看的明白。
不是大佬,但努力成爲,如果您也對Java、算法感興趣,可以相互關注,一起成長,相信滴水穿石的力量
文章目錄
一、基礎知識
動態sql是什麼
- 動態SQL指的是事先無法預知具體的條件,需要在運行時根據具體的情況動態地生成SQL語句
動態sql作用
- 之前的博客主要是增刪改查基本操作,當業務變得複雜得時候使用動態sql標籤可以減少冗餘代碼
二、動態sql標籤總覽
參考了網上大佬的博客,開頭的博客已經涉及了前兩個分支,接着寫向下的分支
本篇博客的練習是基於之前的博客環境搭建,因爲Dao層接口和測試類大同小異,所以下面只給出映射文件中的sql語句
三、動態sql標籤詳解
3.1 控制sql語句拼接
3.1.1 if標籤
- 如:<if test=“address != null”>,test屬性判斷address字段值是否爲空
作用
- 用於select、insert、update語句中
- 根據參數判斷值判斷使用哪個查詢條件,是否更新某個字段,是否插入某個字段
舉例
<select id="findByUser" resultType="com.thinkcoder.domain.User" parameterType="com.thinkcoder.domain.User">
select
id,
username,
birthday,
sex,
address
from
user
where
1=1
<if test="username !=null and username != ''"> //判斷username值是否爲空
and username like #{username}
</if>
<if test="address != null"> //判斷address值是否爲空
and address like #{address}
</if>
</select>
生成的sql語句
假如username值爲空,address值不爲空
select id,username,birthday,sex,address
from user
where 1=1
and address like #{address}
3.1.2 choose|when|otherwise標籤
一般這三個標籤一起使用,相當於java中switch語句
- choose爲switch
- when爲case
- otherwise爲default
標籤執行流程
Mybatis提供choose元素,按順序判斷when中條件是否成立
如果一個成立,choose結束
當when所有的條件都不滿足時,則執行otherwise中的sql語句
舉例
<select id="findByUser" resultType="com.thinkcoder.domain.User" parameterType="com.thinkcoder.domain.User">
select
id,
username,
birthday,
sex,
address
from
user
where
1=1
<choose>
<when test="username !=null and username != ''">
and username like #{username}
</when>
<when test="address != null">
and address like #{address}
</when>
<otherwise>
and sex='男'
</otherwise>
</choose>
</select>
生成的sql語句
假如現在username不爲空
select id,username,birthday,sex,address
from user
where 1=1
and username like #{username}
直接拼接第一個when元素的後面的sql語句,下面的when和otherwise元素不再判斷
if和choose標籤區別
- if可以將所有的sql語句拼接起來,choose|when|otherwise只選擇其中的一個標籤下的sql語句
3.1.3 foreach標籤
作用
- 遍歷集合,構建in條件語句或者批量操作語句
標籤屬性
屬性 | 含義 |
---|---|
collection | 表示迭代集合的名稱,可以使用@Param註解指定,必選參數 |
item | 表示本次迭代獲取元素,若collection爲List類型,表示其中元素,爲map類型表示key-value的value |
open | 表示語句以什麼開始,通常爲’('左括弧,可選參數 |
close | 表示語句以什麼結束,通常爲’)'右括弧,可選參數 |
index | List中表示當前迭代位置,Map中表示元素key,可選參數 |
separator | 每次迭代後加的字符 |
舉例
1.批量插入用戶
測試類代碼
@Test
public void bulkInsertUser(){
List<User> users = new ArrayList<User>();
users.add(new User("趙一",new Date(),"男","河北邯鄲"));
users.add(new User("錢一",new Date(),"女","河北張家口"));
users.add(new User("孫一",new Date(),"男","河北石家莊"));
int ids = userDao.bulkInsertUser(users);
System.out.println(ids);//3
//提交事務
session.commit();
}
IUserDao接口
//批量添加用戶
//參數users便爲collection屬性值
int bulkInsertUser(@Param(value = "users") List<User> users);
IUserDao.xml映射文件
<insert id="bulkInsertUser">
insert into
user(username,birthday,sex,address)
values
<foreach collection="users" item="user" index="index" separator=",">
(#{user.username},#{user.birthday},#{user.sex},#{user.address})
</foreach>
</insert>
生成的sql語句如下
insert into
user(username,birthday,sex,address)
values
("趙一","2020-06-03 10:47:59","男","河北邯鄲"),
("錢一","2020-06-03 10:47:59","女","河北張家口"),
("孫一","2020-06-03 10:47:59","男","河北石家莊")
2.批量查詢用戶in語句
測試類代碼
@Test //用於測試批量查詢用戶
public void findInIds(){
List<Integer> ids = new ArrayList<Integer>();
ids.add(77);
ids.add(78);
List<User> users = userDao.findInIds(ids);
for(User user : users){
System.out.println(user);
}
}
IUserDao接口
//批量查詢用戶
List<User> findInIds(@Param(value = "ids") List<Integer> ids);
IUserDao.xml映射文件
<!--批量查詢用戶-->
<select id="findInIds" resultType="com.thinkcoder.domain.User">
select
id,
username,
birthday,
sex,
address
from
user
<where>
<if test="ids != null and ids.size() > 0">
<foreach collection="ids" open = "id in (" close=")" item="id" separator=",">
#{id}
</foreach>
</if>
</where>
</select>
foreach迭代過程
生成的sql語句
select
id,
username,
birthday,
sex,
address
from
user
where
id in (77,78)
3.2 格式化輸出
3.2.1 where標籤
作用
- 防止多餘關鍵字and 或 or 出現
舉例
where
1=1
<if test="username !=null and username != ''"> //判斷username值是否爲空
and username like #{username}
</if>
<if test="address != null"> //判斷address值是否爲空
and address like #{address}
</if>
此時1=1的作用就是去掉多餘的and或or
如果不用1=1的sql語句
where
and address like #{address}
where 和 and 關鍵字一起出現,此時sql語句報錯,因此就有了where標籤
where標籤例子
select
id,
username,
birthday,
sex,
address
from
user
<where>
<if test="username !=null and username != ''"> //判斷username值是否爲空
and username like #{username}
</if>
<if test="address != null"> //判斷address值是否爲空
and address like #{address}
</if>
</where>
除了where標籤,後面的trim標籤也可以實現
3.2.2 trim標籤
作用
- 1.去除sql語句中多餘的關鍵字(如,and,or),逗號
- 2.在sql語句前拼接"where"、“set”、以及"values(“等前綴,或者添加”)"等後綴
相關屬性
屬性 | 描述 |
---|---|
prefix | sql語句拼接的前綴 |
suffix | sql語句拼接的後綴 |
prefixOverrides | 去除sql語句前面的關鍵字 |
suffixOverrides | 去除sql語句後面的關鍵字 |
舉例
1.去除多餘的and關鍵字
select
id,
username,
birthday,
sex,
address
from
user
<trim prefix = "where" prefixOverrides = "and">
<if test="username !=null and username != ''"> //判斷username值是否爲空
and username like #{username}
</if>
<if test="address != null"> //判斷address值是否爲空
and address like #{address}
</if>
</where>
prefix:加上where的前綴
prefixOverrides = “and”:覆蓋where相連的and
2.去除多餘的逗號,
<update id="updateUser" parameterType="com.thinkcoder.domain.User">
update user
<trim prefix="set" suffixOverrides=",">
<if test="username != null and username != ''">
username = #{username},
</if>
<if test="sex != null and sex != ''">
sex = #{sex},
</if>
</trim>
where id=#{id}
</update>
如果sex爲空則sql語句爲
update user set username = #{username},where id=#{id}
此時suffixOverrides=","將set語句後的,去掉
3.2.3 Set標籤
作用
- set標籤將多餘逗號去掉,一般用於update語句中
<update id="updateUser" parameterType="com.thinkcoder.domain.User">
update user
<set>
<if test="username != null and username != ''">
username = #{username},
</if>
<if test="sex != null and sex != ''">
sex = #{sex},
</if>
</set>
where id=#{id}
</update>
3.3 sql片段複用
- sql標籤:重複的 sql 提取出來
- include標籤:使用sql標籤,將重複的sql片段引用起來
舉例
sql標籤
<!-- 抽取重複的語句代碼片段 -->
<sql id="defaultSql">
select * from user
</sql>
include標籤
<!-- 配置查詢所有操作 -->
<select id="findAll" resultType="user">
<include refid="defaultSql"></include>
</select>
<!-- 根據 id 查詢 -->
<select id="findById" resultType="com.thinkcoder.domain.User" parameterType="int">
<include refid="defaultSql"></include>
where id = #{uid}
</select>
四、總結
基本的內容就總結完畢了,重點在於之後的實踐,看完之後記得自己總結下哦,總結出來的東西纔是自己的,加油