zoukankan      html  css  js  c++  java
  • iBatis 中 Like 的写法实现模糊查询

    iBatis 开发指南告诉我们,当 Person 对象的 name 属性不为 null 时启用 name 查询条件在映射文件 person.xml 中的配置为 

    <select id="getPersonsByName" resultClass="com.unmi.Person">              
        select id as id,name as name,passwd as passwd from person                
    <dynamic prepend="WHERE">        
        <isNotNull prepend="AND" property="name">                          
            (name like #name#)                    
    </isNotNull>                
    </dynamic>        
    </select>     

       

    再用如下的代码调用 
    Person person = new Person();        

    person.setName("unmi");        
    List list = sqlMap.queryForList("getPersonsByName", person);      执行效果翻译成 sql 语句就是 
    select * from person where name like 'unmi'    

    select * from person where name like 'unmi'  
    这实际上是一个完全匹配的查询,与用等号写成如下语句是一致的 

    select * from person where name = 'unmi'    

    select * from person where name = 'unmi'  


    我们之所以要用 like 谓词,一般都想实现模糊查询,比如说 name 以 'unmi' 开始、结束或包含 'unmi' 的记录,

    如下 
    select * from person where name like 'unmi%';    

    select * from person where name like '%unmi';    

    select * from person where name like '%unmi%';    
    也就是如上的 like 语义在 person.xml中应该怎么表述呢?我曾经是想当然的尝试把 
    (name like #name#) 写成    (name like '%#name#%')    或 (name like %#name#%) ,都没法通过,分别报错 
    java.sql.SQLException: Invalid argument in JDBC call: parameter index out of range: 1 和 
    java.sql.SQLException: Unexpected token: % in statement [     select id...... 
    那么正确的写法是什么呢?在网上找到一个解答方法有两种: 
    1. 是把上面 (name like '%#name#%') 的 # 换成 $, 也就是 (name like '%$name$%') 

    2. 是用 || 连接字符串的方式,写成 (name like '%' || #name# || '%') 但却不能写成 (name like '%'||$name$||'%') ,不能又要出错 
    java.sql.SQLException: Column not found: UNMI in statement [select id...... 

    总结一下,在 iBatis 中用 like 的模糊查询的配置如下(两种方式) 

    <select id="getPersonsByName" resultClass="com.unmi.Person">         
    
    select id as id,name as name,passwd as passwd from person            
    
    <dynamic prepend="WHERE">   
                <isNotNull prepend="AND" property="name">                   
    
      (name like '%$name$%')    
                    <!-- (name like '%'||#name#||'%') -->  
    
    </isNotNull>      
     </dynamic>   
    </select>   

    不知细心的诸位注意到没有,这同时也是我在组织上面文字时产生的疑问: 
    1. 写成 (name like '%'||$name$||'%') 为什就不行呢?# 和 $ 有什么区别呢? 

    2. 还有明明是写成的 unmi,为什么报错的时候又是全大写的 UNMI 呢? 
    具体的异同我们可能还需从源代码中找,简单的只要知道,$name$ 是字面意义的替换,这种形式要注意 SQL 注入的漏洞;#name# 是带类型的替换。至于unmi被转换成大写,还需再研究研究,对于以上两个疑问必要时还可以发挥一下。也要权衡一下花那个时间值不值。 
    附: 
    为了防止SQL注入,iBatis模糊查询时也要避免使用$$来进行传值。下面是三个不同数据库的ibatis的模糊查询传值。 
    mysql: select * from stu where name like concat('%',#name #,'%')    

    oracle: select * from stu where name like '%'||#name #||'%'   SQL Server:

    select * from stu where name like '%'+#name #+'%  

  • 相关阅读:
    leetcode33. Search in Rotated Sorted Array
    pycharm 设置sublime text3 monokai主题
    django class Meta
    leetcode30, Substring With Concatenation Of All Words
    Sublime text3修改tab键为缩进为四个空格,
    sublime text3 python打开图像的问题
    安装上imesupport输入法依然不跟随的解决办法,
    sublime text3 的插件冲突弃用问题,
    sublime text3 BracketHighlighter括号匹配的设置
    windows 下wget的使用
  • 原文地址:https://www.cnblogs.com/zhangpengnike/p/4891805.html
Copyright © 2011-2022 走看看