Blog of CodeJELLOW’S ENGINEERING NOTES
← 返回文章

Mybatis动态SQL

Mybatis动态SQL

本文目录 ⌄

    where

    如果我们想根据某个条件来查询,可以这样写:

    TEXT
     <select id="queryPersonByTag" resultType="Person">
            -- 这里的id是传进来的参数,MyBatis只能传递一个参数
            select * from Person
            <where>
                <if test="id">
                   and id=#{id}
                </if>
                <if test="name">
                   and name=#{name}
                </if>
            </where>
    
       </select>

    如果第一个标签为null,where标签会自动去除开头的And

    举例

    我们只根据name查询

    结果

    Person{id=3, name=’Chen’, age=20}

    只根据id查询

    可以看出通过动态SQL,我们实现了一个SQL语句完成多种情况的查询。

    For each

    迭代属性

    我们想通过属性来进行多个查询。

    首先创建一个类,在类中设定一个ArrayList,在这里我们通过list属性中的数值来进行查询。

    然后我们写SQL语句,首先写Mapper。返回值是多个,所以使用List。

    TEXT
        List<Person> queryPersonById(Id id);

    在XML文件中这样定义

    TEXT
     <select id="queryPersonById" resultType="com.cztcode.mybatis.Person">
            select * from Person
            <if test="list!=null and list.size>0">
                <foreach collection="list" open=" where id in (" close=")" item="item" separator=",">
                    #{item}
                </foreach>
            </if>
        </select>

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

    •     item表示集合中每一个元素进行迭代时的别名,
    •     index指 定一个名字,用于表示在迭代过程中,每次迭代到的位置,
    •     open表示该语句以什么开始,
    •     separator表示在每次进行迭代之间以什么符号作为分隔 符,
    •     close表示以什么结束。

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

    1. 如果传入的是单参数且参数类型是一个List的时候,collection属性值为list
    2. 如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array
    3. 如果是属性,则collection是属性名

    迭代List

    我们只需更改collection为list,并更改Mapper传递的参数即可

    TEXT
     List<Person> queryPersonById(ArrayList<Integer> id);

    使用Array同理。

    使用sql片段

    感觉没必要。

    定义形式

    使用形式

    返回布尔值类型

    0时为false,大于等于1时为true

    TEXT
     <select id="queryExistByName" resultType="java.lang.Boolean">
            <![CDATA[ select count(id) from jd_user where `name`=#{name} ]]>
      </select>

    利用Set去重

    图片暂不可用。

    匿名函数

    图片暂不可用。

    Dart基础之类型定义(typedef)

    在Dart 中,函数跟 string 和 number 一样都是对象。类型定义或函数类型别名,为函数类型提供了一个名称,你可以在声明字段和返回类型的时候使用该名称。 当将函数类型分配给变量时,typedef会保留类型的信息。

    下面的代码没使用类型定义:

    TEXT
    class SortedCollection {
      Function compare;
    
      SortedCollection(int f(Object a, Object b)) {
        compare = f;
      }
    }
    
    // 初始化,伪实现
    int sort(Object a, Object b) => 0;
    
    void main() {
      SortedCollection coll = SortedCollection(sort);
    
      // 我们都知道 compare 是一个函数
      // 那到底是什么类型的函数?
      assert(coll.compare is Function);
    }
    复制代码

    在给compage赋值f时,类型的信息丢失了。 f的类型是(Object, Object)->int(->表示返回), 然而compare的是函数类型。 如果我们将代码更改为使用显式名称并保留类型信息,那么开发人员和工具都可以使用该信息。

    TEXT
    typedef Compare = int Function(Object a, Object b);
    
    class SortedCollection {
      Compare compare;
    
      SortedCollection(this.compare);
    }
    
    int sort(Object a, Object b) => 0;
    
    void main() {
      SortedCollection coll = SortedCollection(sort);
      assert(coll.compare is Function);
      assert(coll.compare is Compare);
    }
    复制代码

    因为typedef只是简单的别名,所以它们提供了一种检查任何函数类型的方法。例如:

    TEXT
    typedef Compare<T> = int Function(T a, T b);
    
    int sort(int a, int b) => a - b;
    
    void main() {
      assert(sort is Compare<int>); // True!
    }
    通过 RSS 订阅更新 →