今天遇到一個場景需要寫一個這樣的查詢語句:
用戶對象userInfo包含下面幾個字段:
userName phone email qqId weiboId wxId
歡迎訪問本人博客:http://wangnan.tech
現(xiàn)在新注冊用戶,傳過來一個注冊userInfo對象敞曹,現(xiàn)在要到數(shù)據(jù)庫中驗證狀態(tài)status=1 (表示激活的用戶)的用戶中瞎疼,是否存在一個用戶块蚌,只要它這些字段中至少有一個與新注冊的對象對應(yīng)的字段內(nèi)容相同显拳,那就說明重復(fù)注冊碉咆。
翻譯成sql語句表示一下的意思大概就是:
select * from tablename where
(
userName=”xxx”
or phone =”xxx”
or …
)
and status=1
一開始我是這樣寫的扮叨,在mybatis中的代碼就是這樣:
<select id="selectBySelective" resultType="xxx.UserInfo">
select
<include refid="Base_Column_List" />
from uc_user
<where>
(<if test="userName != null" >
user_name = #{userName}
</if>
<if test="email != null" >
or email = #{email}
</if>
<if test="phone != null" >
or phone = #{phone}
</if>
<if test="weiboId != null" >
or weibo_id = #{weiboId}
</if>
<if test="wxId != null" >
or wx_id = #{wxId}
</if>
<if test="qqId != null" >
or qq_id = #{qqId}
</if>)
</where>
and status = 1
</select>
這樣代碼看似沒有什么問題但是其實是有問題的沉桌。為什么呢藤树?
如果userName 為空浴滴,后面某字段不為空,最后的sql語言會成為這樣:
select * from uc_user where(or email = "xxx") and status = 1
使用mybatis < where > 標(biāo)簽就是為了防止這種情況岁钓,mybatis會在第一個
userName 為空的情況下升略,幫我們?nèi)サ艉竺娴恼Z句的第一個”or”
但是我加了where標(biāo)簽中加入()后微王,語句會報錯。因為自動去掉”or”會失效品嚣。
查看了mybatis官方文檔發(fā)現(xiàn)了另一個標(biāo)簽 < trim >可以通過自定義 trim 元素來定制我們想要的功能
trim標(biāo)簽包圍的內(nèi)容可以設(shè)置幾個屬性:
prefix :內(nèi)容之前加的前綴
suffix :內(nèi)容之后加的后綴
prefixOverrides: 屬性會忽略通過管道分隔的文本序列(注意此例中的空格也是必要的炕倘,多個忽略序列用“|”隔開)。它帶來的結(jié)果就是所有在 prefixOverrides 屬性中指定的內(nèi)容將被移除翰撑。
所以我修改后的代碼是:
<select id="selectBySelective" resultType="xxx.UserInfo">
select
<include refid="Base_Column_List" />
from uc_user
<trim prefix="WHERE (" suffix=")" prefixOverrides="AND |OR ">
<if test="userName != null" >
user_name = #{userName}
</if>
<if test="email != null" >
or email = #{email}
</if>
<if test="phone != null" >
or phone = #{phone}
</if>
<if test="weiboId != null" >
or weibo_id = #{weiboId}
</if>
<if test="wxId != null" >
or wx_id = #{wxId}
</if>
<if test="qqId != null" >
or qq_id = #{qqId}
</if>
</trim>
and status = 1
</select>