MyBatis動態SQL之where語句


針對模糊查詢的三種方式

業務層傳遞數據,在映射文件取值時where語句理論上應寫為where user_name like #{user_name}%,但實際上控制台會報錯。

### Error querying database.  Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '%' at line 1

提示的是數據庫Sql語句的錯誤,如果使用了log4j日志,控制台顯示:

DEBUG [main] - ==> Preparing: select * from web_user where user_name like ?% 
DEBUG [main] - ==> Parameters: 悟(String)

后面會解釋為什么會出錯。所以直接取值是不行的,可以使用下面的幾種方式。

一  在業務層進行處理

在業務層接收到數據時,首先對數據進行一次簡單的處理操作。

//接口中的方法為List<User> where01(String user_name);
//MyBatisUtil類詳見前面的MyBatis工具類整合
try {
    sqlSession = MyBatisUtil.getSqlSession();
    String user_name = "悟";
    List<User> list = sqlSession.getMapper(UserDao.class).where01(user_name + "%");
    logger.debug(list);
  } finally {
    MyBatisUtil.closeSqlSession(sqlSession);
  }

映射文件中的sql語句為:

<select id="where01" resultType="self.exercise.bean.User" parameterType="string">
  select * from web_user where user_name like #{user_name}
</select>

此時日志在控制台輸出

DEBUG [main] - ==>  Preparing: select * from web_user where user_name like ? 
DEBUG [main] - ==> Parameters: 悟%(String)

二  在映射文件取值時進行處理

在業務層不進行數據處理,在映射文件中不用#{}取值,改為${}方式取值。

<select id="where01" resultType="self.exercise.bean.User" parameterType="string">
  select * from web_user where user_name like '${_parameter}%'
</select>

控制台的信息:

DEBUG [main] - ==>  Preparing: select * from web_user where user_name like '悟%' 
DEBUG [main] - ==> Parameters: 

由此可以看出#和$的區別

#會將字符串進行預處理,用一對引號加在字符串外邊,再替代?如#{user_name}% -->'悟'%,所以直接用#{}接值控制台報錯的原因就在於此。

$將取到的數據直接替換掉,並不會進行預處理。如'${_parameter}%' -->'悟%'

三  在映射文件用方法進行拼接

在業務層不進行數據處理,在映射文件調用MySql的concat(param1,param2,...)進行拼接

<select id="where03" resultType="self.exercise.bean.User" parameterType="string">
  select * from web_user where user_name like concat(#{user_name},"%")
</select>

日志:

DEBUG [main] - ==>  Preparing: select * from web_user where user_name like concat(?,"%") 
DEBUG [main] - ==> Parameters: 悟(String)

針對多條件的where語句

當有多個查詢條件時,用if標簽進行條件篩選 

//接口中的方法為List<User> wheremore(@Param("userName") String user_name, @Param("account") String account);
try
{ sqlSession = MyBatisUtil.getSqlSession(); String user_name = "悟"; String account = "wukong"; List<User> list = sqlSession.getMapper(UserDao.class).wheremore(user_name, account); logger.debug(list);   } finally {     MyBatisUtil.closeSqlSession(sqlSession);   }

映射文件中的內容為:

<select id="wheremore" resultType="self.exercise.bean.User">
    select * from web_user where 1=1
    <if test="userName != null and userName != ''.trim()">
        and user_name like concat(#{userName},"%")
    </if>
    <if test="account != null and account != ''.trim()">
        and account = #{account}
    </if>
</select>

其中,test中的變量對應的為map中的key值、類中的屬性名或者接口中param方法映射出的屬性名

但是之前提到過,XML中有些運算符不能被識別,所以test中進行測試時一些運算符需要進行用轉義運算符替換,XML中有五個轉義字符:

      運算符   轉義字符
邏輯與    &    &amp;
大於號    >    &gt;
小於號    <    &lt;
雙引號    "    &quot;
單引號    '    &apos;

在讀取的時候,解析器會自動將其轉換回"&","<",">"等特殊字符,正常來說,只有"<" 字符和"&"字符對於XML來說是嚴格禁止使用的。 

需要注意的是: 
a. 轉義序列各字符間不能有空格; 
b. 轉義序列必須以";"結束; 
c. 單獨的&不被認為是轉義開始; 
d. 區分大小寫。

判斷一個字符串不為空串的幾種方式:

<if test="user_name != ''.trim()"></if>
<if test="user_name.lengh() != 0"></if>

以上的多條件查詢方法,where后面跟着 1=1,每次執行sql語句都會進行一次判斷(即使條件全部為空),當數據量很大時效率低下,可以where標簽進行改進。

<select id="wheremore02" resultType="self.exercise.bean.User">
  select * from web_user
  <where>
    <if test="userName != null and userName != ''.trim()">
      and user_name like concat(#{userName},"%")
    </if>
    <if test="account != null &amp;&amp; account.length() != 0">
      and account = #{account}   </if>   </where> </select>

where標簽會檢索語句,將where中的第一個and 或者or 去掉,這里的and 和or 都是sql中的關鍵字(注意關鍵字后的空格也會被去掉),如果名為and_user_name的屬性在最前面,則不會被檢索出來。

choose標簽,相當於Java中的switch分支語句,跟if標簽類似。 

但是這種方式不能使用,當最前邊的條件判斷正確后,會直接break;后面的條件不再判斷。

<select id="wheremore03" resultType="self.exercise.bean.User">            
    select * from web_user                                                
    <where>                                                               
        <choose>                                                          
            <when test="userName != null and userName != ''.trim()">      
                and user_name like concat(#{userName},"%")                
            </when>                                                       
            <when test="account != null &amp;&amp; account.length() != 0">
                and account = #{account}                                  
            </when>                                                       
        </choose>                                                         
    </where>                                                              
</select>                                                                 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM