zoukankan      html  css  js  c++  java
  • Mybatis SQL语句查询

    MyBatis中使用in查询时的注意事项
    foreach的主要用在构建in条件中,它可以在SQL语句中进行迭代一个集合。

    foreach一共有三种类型,分别为List,[](array),Map三种。

    foreach元素的属性主要有 item,index,collection,open,separator,close。

    下面表格是我总结的各个属性的用途和注意点

    属性 描述
    item 循环体中的具体对象。支持属性的点路径访问,如item.age,item.info.details。
    具体说明:在list和数组中是其中的对象,在map中是value。
    该参数为必选。
    collection 要做foreach的对象,作为入参时,List<?>对象默认用list代替作为键,数组对象有array代替作为键,Map对象没有默认的键。
    当然在作为入参时可以使用@Param("keyName")来设置键,设置keyName后,list,array将会失效。 除了入参这种情况外,还有一种作为参数对象的某个字段的时候。举个例子:
    如果User有属性List ids。入参是User对象,那么这个collection = "ids"
    如果User有属性Ids ids;其中Ids是个对象,Ids有个属性List id;入参是User对象,那么collection = "ids.id"
    上面只是举例,具体collection等于什么,就看你想对那个元素做循环。
    该参数为必选。
    separator 元素之间的分隔符,例如在in()的时候,separator=","会自动在元素中间用“,“隔开,避免手动输入逗号导致sql错误,如in(1,2,)这样。该参数可选。
    open foreach代码的开始符号,一般是(和close=")"合用。常用在in(),values()时。该参数可选。
    close foreach代码的关闭符号,一般是)和open="("合用。常用在in(),values()时。该参数可选。
    index 在list和数组中,index是元素的序号,在map中,index是元素的key,该参数可选。
    
    

    在Mybatis的xml配置中使用集合,主要是用到了foreach动态语句。

    1. Mybatis生成select * from table where id in(1,2,...,n)语句的查询

    我们一般的做法是在方法的参数处指定传入的参数名称,在xml中使用的时候,集合的名称要和方法的Param的名称一致,这样便于阅读和理解,然后是在对应的xml文件中使用foreach循环。

    java代码如下:

    public abstract List<Model> findByIds(@Param("ids")List<Integer> ids);

    对应的xml代码如下:

    select * from table
    <where>
        id in <foreach collection="ids" item="item" index="index" 
    open="(" separator="," close=")">#{item}</foreach>
    </where>

    2.Mybatis保存多条记录

    我们同样是通过foreach的方法来实现,这里我们巧妙的利用了sql的语法规则用Mybatis的foreach动态语句来处理。

    java代码:

    public abstract void saves(@Param("tables")List<Model> tables);

    xml代码:

    insert into table(name,addtime) values
    <foreach collection="tables" item="item" index="index" separator=",">  
        (#{item.name},#{item.addtime})
    </foreach>

    以上方法Mybatis会帮我们进行sql注入拦截,Mybatis如果采用#{xxx}的形式设置参数,Mybatis会进行sql注入的过滤。如果采用的是${xxx},Mybatis不会进行sql注入过滤,而是直接将参入的内容输出为sql语句。

    在使用foreach的时候最关键的也是最容易出错的是collection属性,该属性是必须指定的,但是在不同的情况下,该属性的值是不一样的,主要分为三种情况

    1:如果传入的是单参数且参数类型

     <select id="findByIdsMap" resultMap="BaseResultMap">
             Select
             <include refid="Base_Column_List" />
             from jria where ID in
                      <foreach item="item" index="index" collection="list" 
                             open="(" separator="," close=")">
                            #{item}
                    </foreach>
      </select> 
     
     findByIds(Long[] ids)
     1.b 如果参数的类型是Array,则在使用时,collection属性要必须指定为 array
     
      <select id="findByIdsMap" resultMap="BaseResultMap">
                     select
                     <include refid="Base_Column_List" />
              from jria where ID in
                      <foreach item="item" index="index" collection="array" 
                             open="(" separator="," close=")">
                            #{item}
                    </foreach>
      </select> 
     
    2. 当查询的参数有多个时,例如 findByIds(String name, Long[] ids)
     这种情况需要特别注意,在传参数时,一定要改用Map方式, 这样在collection属性可以指定名称
             下面是一个示例
     
             Map<String, Object> params = new HashMap<String, Object>(2);
            params.put("name", name);
             params.put("ids", ids);
            mapper.findByIdsMap(params);
     
     <select id="findByIdsMap" resultMap="BaseResultMap">
                     select
                     <include refid="Base_Column_List" />
              from jria where ID in
                      <foreach item="item" index="index" collection="ids" 
                             open="(" separator="," close=")">
                            #{item}
                    </foreach>
       </select> 
     
     
    完整的示例如下:
    例如有一个查询功能,Mapper接口文件定义如下方法:
    List<Jria> findByIds(Long... ids);
    使用 in 查询的sql拼装方法如下:
     
     <select id="findbyIds" resultMap="BaseResultMap">
                     select
                     <include refid="Base_Column_List" />
              from jria where ID in
                      <foreach item="item" index="index" collection="array" 
                             open="(" separator="," close=")">
                            #{item}
                    </foreach>
      </select> 
     
     
    MyBatis动态多条件查询语句
     
    <select id="searchpeople" parameterClass="people" resultClass="people">
    select peopleid,peoplename,password,dept,peopletype,telephone,email,mphone,fax,description,allflag,vipid,vipname from people
      <dynamic prepend="WHERE">
           
           <isNotEmpty prepend="AND" property="peopleid">
           (peopleid like #peopleid#)
           </isNotEmpty>
           
           <isNotEmpty prepend="AND" property="peoplename">
           (peoplename like #peoplename#)
           </isNotEmpty>
         
           <isNotEmpty prepend="AND" property="dept">
           (dept like #dept#)
           </isNotEmpty>
           
           <isNotEmpty prepend="AND" property="peopletype">
           (peopletype like #peopletype#)
           </isNotEmpty>
           
           </dynamic>
           
            </select>
    <dynamic>内则是动态条件所相关的语句,里面填写的都是where相关的条件 对于这个动态的依赖于什么动词侧为 prepend="" 其中可以填写where也可以写group by和order by
    对于要动态的判定条件是否存在则用以下标签:
    <isNotEmpty>意思则为当次条件不为空时执行其中语句 prepend="" 依赖约束, 值可以是 AND 也可以是OR property="" 就是对于这个条件所判定的取值字段 例如"dept" 
    这样上述的select语句就可以实现一个判定<=4个条件的sql实现语句,在应用中,在页面此处就可以设计4个输入框,用户只输入其中条件,动态实现查询
    顺便提一句,mybaits一般导入的都是类的参数,所以要实现模糊查询,只需要在类->属性字段值的2边+上%就可以以 %字段值% 的形式传入实现模糊查询.
    对于动态语句中的判定条件除了上面的<isNotEmpty>不为空,还有下面一些常用到的:
    <isGreaterThan prepend="and" property="" compareValue="">
    字段大于某个值 compareValue 比较值
    <isGreateEqual> 大于等于比较 同上用法
    <isEqual> 是否相等 同上用法
    <isNotEqual> 是否不相等 同上用法
    <isLessThan> 小于比较 同上用法
    <isLessEqual> 小于等于比较 同上用法
    总结一下mybatis select基本格式用法:
                     
                  <select 导入导出参数>
                       SQL查询语句
                 <dynamic prepend="依赖条件">
                               <isNotEmpty prepend="下个条件的依赖值,and,or" property="判定字段">
                                                             //判定条件语句
                               (查询条件语句)
                               </isNotEmpty>
                               //另外一个判定条件语句
                        </dynamic>
                  </select>
     
     
     
     
     
    在MyBatis中当sql语句只需要一个String类型参数时,我们在sql语句中必须将参数改为_parameter才可以执行,不然会报错
    There is no getter for property named 'moduleCode' in 'class java.lang.String  这个错误!
     
    例如:
     <select id="selectFtpConfigName" resultType="com.jzl.entity.platFormEntity.FtpConfig">
            select * from ftpconfig where
            <if test="_parameter != null and _parameter !='' ">
                name like CONCAT('%',#{_parameter}, '%')
            </if>
     
        </select>

     

     
  • 相关阅读:
    mysql 递归查找菜单节点的所有子节点
    mapStruct笔记
    JavaBean映射工具dozer学习
    常见Bean映射工具分析评测及Orika介绍
    Java 实体-实体的映射框架
    实体类与实体DTO类之间的转换
    推荐一个 Java 实体映射工具 MapStruct
    java Web项目Service层通用接口和entityVo对象与entity对象转化问题的解决方案
    SpringData JPA进阶查询—JPQL/原生SQL查询、分页处理、部分字段映射查询
    JPA框架下使用纯粹的原生SQL
  • 原文地址:https://www.cnblogs.com/lhfyy/p/4076797.html
Copyright © 2011-2022 走看看