zoukankan      html  css  js  c++  java
  • 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>                                                                 
  • 相关阅读:
    python+selenium之页面元素截图
    selenium八大定位
    http概述之URL与资源
    数组中只出现一次的数字
    数字在排序数组中出现的次数
    把数组排成最小的数
    数组中出现次数超过一半的数字
    调整数组顺序使得奇数位于偶数的前面
    旋转数组的最小值
    二维数组的查找
  • 原文地址:https://www.cnblogs.com/qingyaxuan/p/6413453.html
Copyright © 2011-2022 走看看