How does mybatis determine whether an list collection contains specified data

  • 2021-09-24 22:11:29
  • OfStack

Demand

1. In the mybatis script, you want to judge whether list contains a string.

2. Dynamically use the attributes in list and add them to the database crud field.

There is no similar case found on the Internet. Configuring choose function can make it convenient to write dynamic sql assembly, so record it.

Prepare

The most used list functions in previous scripts are size and traversal. So does the mybatis script include functions again? First of all, we need to know the type of list. Write a simple test case.


<select id="test" parameterType="java.util.Map" resultType="java.util.Map">
        select
          <if test="list.containsKey('0')">
              'yes' as a,
          </if>
          1
    </select>

list is followed by a method containsKey, which throws an exception after running:

Caused by: org.apache.ibatis.ognl.MethodFailedException: Method "containsKey" failed for object [0, 1] [java.lang.NoSuchMethodException: java.util.Arrays$ArrayList.containsKey(java.lang.Character)]

We can see that the type of list is ArrayList, and it doesn't have an containsKey method, but we know that List should have an contains () method, yes, that's right. However, when the script calculates the size, size does not need to add (), and it will throw an exception.

Details

One more detail in the above exception is containsKey (java. lang. Character). Character is character type in java, that is, if there is [0, 1] or ["0", "1"] in List, then there is no match. The comparison integer can only be contains (0), and the comparison string can only be double quotation marks, not single quotation marks, because java makes forced type comparison, while the double quotation marks in mybatis need escape characters & quot; So there must be such a way to compare strings:


 <if test="list.contains(&quot;0&quot;)">
              #{ Logic }
        </if>

Dynamic fetching from list

--Insert fields are fetched directly from list, via ${list [0]. retainDay}.

Of course, you can also encapsulate list into map, so you need to operate one more step in the code


<insert id="insert">
           insert ignore into ads_circle_user_retain
             (eventDate,${list[0].retainDay})
           VALUES
            <foreach collection="list" item="item" separator=",">
                (#{item.eventDate1},#{item.readNum})
            </foreach>
           on DUPLICATE KEY UPDATE ${list[0].retainDay} = values(${list[0].retainDay})
    </insert>

The set (list) determines whether a corresponding string or object exists

Judge whether there is a string object in the collection, and return true if there is one, and return false if there is no one


list.contains("str1")

Judge that there is an object with complete 1 sample in the collection (all attributes are 1 sample), and return true if there is one, and return false if there is no one


list.containsAll(Objcet obj)

Related articles: