Mybatis if else if условие для оценки значения и объединения выражения фрагмента SQL

предисловие

В последнее время при разработке проекта задействуются сложные динамические условные запросы, но mybaitsон не поддерживает i f elseif-подобные суждения, но мы можем косвенно chose when otherwiseреализовать его chooseв целом, то whenесть if otherwiseили else

быстрое использование

В прошлом, когда мы судили об условиях, мы использовали ifдля суждения ярлыки, и условия существовали бок о бок.

		    <if test="seat_no != null and seat_no != '' ">  
		        AND seat_no = #{seat_no}  
		    </if>   

Теперь chose when otherwise, пока установлено одно из условий использования, другие не будут оцениваться. Если никакие условия не выполняются, otherwiseвыполняемый контент будет выполняться по умолчанию.

		<choose>
		    <when test="……">
		    	……
		    </when>
		    <otherwise>
		    	……
		    </otherwise>
	    </choose>

Ниже приведен пример моего собственного реального использования, и он был протестирован только для справки:

Фильтровать и запрашивать информацию о пользователях на основе динамических условий

<select id="findUsersByUser" resultType="cn.soboys.kmall.sys.entity.User">
        select tu.USER_ID,tu.USERNAME,tu.SSEX,td.DEPT_NAME,tu.MOBILE,tu.EMAIL,tu.STATUS,tu.CREATE_TIME,
        td.DEPT_ID
        from t_user tu left join t_dept td on tu.DEPT_ID = td.DEPT_ID

        <where>
            <choose>
                <when test="userParams.adminType==4">
                    and tu.ADMIN_TYPE_ID in(2,3)
                </when>
                <otherwise>
                       <include refid="search"></include> 
                </otherwise>
            </choose>
            
        </where>

    </select>
 <sql id="search">
         <if test="userParams.adminType==null or userParams.adminType==''">
             and tu.ADMIN_TYPE_ID in(0,1)
         </if>

         <if test="userParams.adminType != null and userParams.adminType != ''">
             and tu.ADMIN_TYPE_ID=#{userParams.adminType}
         </if>


         <if test="userParams.roleId != null and userParams.roleId != ''">
             and (select group_concat(ur.ROLE_ID)
             from t_user u
             right join t_user_role ur on ur.USER_ID = u.USER_ID,
             t_role r
             where r.ROLE_ID = ur.ROLE_ID
             and u.USER_ID = tu.USER_ID and r.ROLE_ID=#{userParams.roleId})
         </if>


         <if test="userParams.mobile != null and userParams.mobile != ''">
             AND tu.MOBILE =#{userParams.mobile}
         </if>
         <if test="userParams.username != null and userParams.username != ''">
             AND tu.USERNAME   like CONCAT('%',#{userParams.username},'%')
         </if>
         <if test="userParams.ssex != null and userParams.ssex != ''">
             AND tu.SSEX  =#{userParams.ssex}
         </if>
         <if test="userParams.status != null and userParams.status != ''">
             AND tu.STATUS =#{userParams.status}
         </if>
         <if test="userParams.deptId != null and userParams.deptId != ''">
             AND td.DEPT_ID =#{userParams.deptId}
         </if>
         <if test="userParams.createTime != null and userParams.createTime != ''">
             AND DATE_FORMAT(tu.CREATE_TIME,'%Y%m%d') BETWEEN substring_index(#{userParams.createTime},'#',1) and substring_index(#{userParams.createTime},'#',-1)
         </if>
     </sql>

Вот где это происходит if else if. Как только условие chooseметки не установлено, условие в метке будет выполнено, и оператор суждения, который является условием фрагмента sql, которое я включил ниже中whenotherwise

Для получения более подробной информации об использовании ярлыка состояния, пожалуйста, обратитесь к моей статье, нажмите, чтобы войти

Сращивание фрагментов SQL

Когда мы пишем операторы sql, у нас часто возникают некоторые требования: мы не хотим писать повторяющиеся фрагменты операторов sql, поэтому мы можем извлечь их через фрагменты sql, а затем использовать общедоступный sql для цитирования там, где это необходимо.

MyBatisСредний <sql>элемент используется для определения SQLфрагмента, который используется для разделения некоторых общих операторов SQL, например: SELECTключевые слова и WHEREчасть между ключевыми словами. в:

id<include>: уникальный идентификатор для ссылок на теги , используемые в других местах ;

lang:Установить кодировку символов;

databaseId: укажите идентификатор базы данных для выполнения оператора SQL, и идентификатор базы данных настроен в mybatis-cfg.xml.

В то же время вы также можете видеть, что такие <sql>теги <include>、<trim>、<where>、<set>、<foreach>、<choose>、<if>、<bind>, как можно использовать для определения сложных фрагментов SQL.

Простое использование определяет фрагмент sql следующим образом:

<sql id="user_columns">
    `user_id`, `name`, `sex`, `age`
</sql>

<sql>Используйте тег в теге , чтобы <include>представить определенный фрагмент sql следующим образом:

<!-- 定义基础列 -->
<sql id="user_base_columns">
    `user_id`, `name`
</sql>
 
<!-- 定义一个SQL片段 -->
<sql id="user_columns">
    <include refid="user_base_columns"/>, `sex`, `age`
</sql>

Варианты использования сценария, такие как: запрос информации о пользователе

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
   "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hxstrive.mybatis.sql.demo1.UserMapper">
   <!-- 映射结果 -->
   <resultMap id="RESULT_MAP" type="com.hxstrive.mybatis.sql.demo1.UserBean">
      <id column="user_id" jdbcType="INTEGER" property="userId" />
      <result column="name" jdbcType="VARCHAR" property="name" />
      <result column="sex" jdbcType="VARCHAR" property="sex" />
      <result column="age" jdbcType="INTEGER" property="age" />
   </resultMap>
 
   <!-- 定义一个SQL片段 -->
   <sql id="user_columns">
      `user_id`, `name`, `sex`, `age`
   </sql>
 
   <!-- 查询所有用户信息 -->
   <select id="findAll" resultMap="RESULT_MAP">
      select <include refid="user_columns" /> from `user`
   </select>
 
</mapper>

Значения параметров SQL и выражения OGNL

#{params}См. выше, переданный параметр #{xx} является OGNLвыражением, используемым для обесценивания параметра таким образом.

В модуле «XML Mapping File» в официальном документе Mybatis он анализируется следующим образом:

Когда мы используем символ параметра типа #{}, мы фактически говорим Mybatis создать параметр подготовленного оператора.Через JDBC такой параметр будет идентифицирован знаком «?» в SQL и передан новому параметру подготовленного оператора.


То есть, когда мы используем выражение #{XX} OGNL, оно сначала поможет нам сгенерировать оператор SQL с заполнителем, а затем поможет нам установить этот параметр внизу: ps.setInt(1, id);

OGNL — это аббревиатура от Object-Graph Navigation Language, языка объектно-графовой навигации, синтаксис: #{}.
Вы немного запутались, не знаете, что это такое?
Роль OGNL заключается во взаимодействии с данными между объектами и представлениями.Он может получать доступ к свойствам объектов и вызывать методы объектов.Он может перебирать структурную диаграмму всего объекта с помощью выражений.

MyBatis обычно использует следующие выражения OGNL:

Приведенный выше контент представляет собой просто выражение OGNL, подходящее для использования в MyBatis, щелкните здесь, чтобы просмотреть полное выражение .

Есть два места, где OGNL можно использовать в MyBatis:

  1. SQLв динамическом выражении
  2. ${param}в параметрах

Следующий пример MySql-подобного запроса:

<select id="xxx" ...>
    select id,name,... from country
    <where>
        <if test="name != null and name != ''">
            name like concat('%', #{name}, '%')
        </if>
    </where>
</select>

Значение test в приведенном выше коде будет использовать OGNL для вычисления результата.

Пример 2, общий запрос:

<select id="xxx" ...>
    select id,name,... from country
    <bind name="nameLike" value="'%' + name + '%'"/>
    <where>
        <if test="name != null and name != ''">
            name like #{nameLike}
        </if>
    </where>
</select>

Значение здесь будет рассчитано с использованием OGNL.

Примечание. Вызов параметра <bind можно получить с помощью #{} или ${}, а #{} может предотвратить внедрение.

Первичный ключ UUID поддерживается в общем Mapper. Реализация в общем Mapper заключается в использовании метки. Эта метка вызывает статический метод. Примерный метод выглядит следующим образом:

<bind name="username_bind" 
      value='@java.util.UUID@randomUUID().toString().replace("-", "")' />

Хотя этот метод может автоматически вызывать статический метод, он не может записывать обратно соответствующее значение атрибута, поэтому при его использовании нужно быть внимательным.

  1. ${params}параметры в

В приведенном выше примере проще всего использовать следующий метод

<select id="xxx" ...>
    select id,name,... from country
    <where>
        <if test="name != null and name != ''">
            name like '${'%' + name + '%'}'
        </if>
    </where>
</select>

Обратите внимание, что результаты этих двух методов ${'%' + name + '%'},не %${name}%,совпадают, а различается процесс обработки.

MyBatisПри обработке в , ${}просто используйте OGNLрассчитанное значение результата, а затем замените соответствующее в SQL ${xxx}, OGNL обрабатывает только${这里的表达式}。

Выражение здесь может быть всеми выражениями, поддерживаемыми OGNL, и может быть написано очень сложно, и может вызывать возвращаемое значение статического метода или вызывать значение статического атрибута.

Например, условие для определения того, содержит ли значение атрибута входного параметра подстроку, можно напрямую использовать для containsопределения

<foreach collection="list" item="item" index="index" separator="AND" open="(" close=")">

    <choose>
        <when test='item.cname.contains("select") or item.cname.contains("checkbox") or item.cname.contains("date")'>
            <if test='item.cname.contains("select") or item.cname.contains("checkbox")'>
                find_in_set(#{item.value},base.${item.cname})
            </if>

            <if test='item.cname.contains("date")'>
                DATE_FORMAT(base.${item.cname},'%Y-%m-%d') = DATE_FORMAT(#{item.value},'%Y-%m-%d')
            </if>
        </when>
        <otherwise>
            base.${item.cname} = #{item.value}
        </otherwise>
    </choose>


</foreach>

Je suppose que tu aimes

Origine blog.csdn.net/u011738045/article/details/120483615
conseillé
Classement