mybatis-6-动态sql

动态sql简介&OGNL了解

动态 SQL 元素和使用 JSTL 或其他类似基于 XML 的文本处 理器相似。

MyBatis 采用功能强大的基于 OGNL 的表达式来简化操作。

  • if
  • choose (when, otherwise)
  • trim (where, set)
  • foreach

注意xml中的转义字符的使用

使用XML转义序列表示这些特殊的字符,这5个特殊字符所对应XML转义序列为:
&  &
<  &lt;
>  &gt;
"  &quot;
'  &apos;

if标签使用

要求:查询员工,携带了哪个查询条件就带上这个字段的值

<resultMap id="EmployeeMap" type="Employee">
    <id column="id" property="id"/>
    <result column="last_name" property="lastName"/>
    <result column="gender" property="gender"/>
    <result column="email" property="email"/>
    <association property="department"
                 select="com.wang.Dao.DepartmentMapper.getDepartmentByDid"
                 column="d_id"/>
</resultMap>
    <!--if
        choose (when, otherwise)
        trim (where, set)
        foreach-->
<!--    //测试if语句-->
<!--if标签里的test属性放的就是OGNL表达式-->
<!--List<Employee> getEmployeeIf(HashMap<String, Object> map);-->
<select id="getEmployeeIf" parameterType="map" resultMap="EmployeeMap">
    select *
    from tbl_employee
    where
    <if test="id!=null">
        id = #{id}
    </if>
    <if test="lastName!=null and lastName !=''">
       and Last_name = #{lastName}
    </if>
    <if test="gender!=null and gender != ''">
        and gender = #{gender}
    </if>
    <if test="email!=null and email != ''">
        and email = #{email}
    </if>
</select>

where标签使用

在使用if时会发现我们在使用if语句时,会因为and无法自动去除而导致了后面的sql语法错误,使用where标签就可以帮助我们自动去除and

  • 解决方法1:

    在原本的sql语句的where后面加上1=1

    但if语句中必须是这样的,and + 字段

    <if test="email!=null and email != ''">
        and email = #{email}
    </if>
    
  • 解决方法2:

    把我们需要判断的所有语句全部放到where标签下,用以取代原来的where语句

    and任然需要放在sql语句的前面

    <select id="getEmployeeIf" parameterType="map" resultMap="EmployeeMap">
        select *
        from tbl_employee
        <where>
            <if test="id!=null">
                and id = #{id}
            </if>
            <if test="lastName!=null and lastName !=''">
                and Last_name = #{lastName}
            </if>
            <if test="gender!=null and gender != ''">
                and gender = #{gender}
            </if>
            <if test="email!=null and email != ''">
                and email = #{email}
            </if>
        </where>
    </select>
    

trim代替where标签

在使用where时会发现,where只能去除整句sql语句的前缀,但后缀不能去除,且不够灵活

使用trim可以自定义在整句sql语句上加上前缀和后缀,当发现整句话前或者后多了某个词也能帮助我们去除

属性:

  • prefix:整句sql语句前加上一个前缀

  • suffix:整句sql语句后加上一个后缀

  • prefixOverride:整句sql语句前多了指定的值就会被删除

  • subfixOverride:整句sql语句后多了指定的值就会被删除

<select id="getEmployeeIf" parameterType="map" resultMap="EmployeeMap">
    select *
    from tbl_employee
    <trim prefix="where" prefixOverrides="and" suffixOverrides="and">
        <if test="id!=null">
            and id = #{id}
        </if>
        <if test="lastName!=null and lastName !=''">
            and Last_name = #{lastName}
        </if>
        <if test="gender!=null and gender != ''">
            and gender = #{gender}
        </if>
        <if test="email!=null and email != ''">
            and email = #{email}
        </if>
    </trim>
</select>

choose分支查询

要求:如果带了id就用id查询,不再使用其他的查询了,如果带了last_name就用last_name查询

所以:choose-when类似于switch-case

注意点:当输入了大量值的时候,按照when的先后顺序排其次

<!--    //测试choose语句-->
<!--    List<Employee> getEmployeeChoose(HashMap<String, Object> map);-->
<select id="getEmployeeChoose" resultMap="EmployeeMap">
    select *
    from tbl_employee
    <trim prefix="where" prefixOverrides="and">
        <choose>
            <when test="id!=null">
                and id = #{id}
            </when>
            <when test="lastName!=null and lastName!=''">
                and last_name = #{lastName}
            </when>
            <when test="gender!=null and gender!=''">
                and gender = #{gender}
            </when>
            <when test="email!=null and email!=''">
                and email = #{email}
            </when>
        </choose>
    </trim>
</select>

set标签

要求:更新数据库的时候,传入了什么数据就更新哪些数据类似于where属性,但是他主要用于uptate的sql语句

<update id="UpdateEmployee" parameterType="map">
    update tbl_employee
    <set>
        <if test="lastName!=null">
            last_name = #{lastName},
        </if>
        <if test="gender!=null">
            gender = #{gender},
        </if>
        <if test="email!=null">
            email = #{email},
        </if>
    </set>
    where id = #{id}
</update>

trim代替set标签

<update id="UpdateEmployee" parameterType="map">
    update tbl_employee
    <trim prefix="set" suffixOverrides=",">
        <if test="lastName!=null">
            last_name = #{lastName},
        </if>
        <if test="gender!=null">
            gender = #{gender},
        </if>
        <if test="email!=null">
            email = #{email},
        </if>
    </trim>
    where id = #{id}
</update>

foreach标签遍历传入参数给sql语句

<select id="getEmployeeForeach" parameterType="map" resultMap="EmployeeMap">
    select *
    from tbl_employee
    <!--
    collection:指定要遍历的集合
        list类型的参数会特殊处理封装在map中,map的key就叫list
        item:将当前遍历的元素赋值给指定的变量
        separator:遍历出来的每个元素的分割符
        open:该SQL语句拼接后在前面加上的字符
        close:该sql语句拼接后在后面加上的字符
        index:索引。遍历list的时候index就是索引,item就是当前值
                    遍历map时候index表示的就是map的key
    -->

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

foreach实现批量保存

<insert id="insertEmployeeForeach" parameterType="list">
    insert into tbl_employee
    (id,last_name,gender,email,d_id)
    <foreach collection="list" separator="," open="values" item="item">
        (#{item.id},#{item.lastName},#{item.gender},#{item.email},#{item.department.id})
    </foreach>
</insert>

mybatis的两个内置参数(提取可重用代码基础)

<select id="getEmployeeInnerParamter" parameterType="employee" resultMap="EmployeeMap">
    <!--两个内置参数:
        不只是方法传递过来的参数可以传递,取值。
        mybatis还有两个内置参数:
            _paramter:代表整个参数
                单个参数时:_paramter就是这个歌参数
                多个参数时:这些参数会被封装成一个map,_paramter就是封装好的map
            _databaseId:如果配置了databaseIdProvider标签,_databaseId就代表数据库的别名-->
    <!--这里使用databaseId参数来进行根据不同数据库,执行不同语句-->
    	<choose>
            <when test="_databaseId=='mysql'">
                <choose>
                    <when test="_parameter!=null">
                        select * from tbl_employee
                    </when>
                </choose>
            </when>
            <when test="_databaseId=='oracle'">
                <choose>
                    <when test="_parameter!=null">
                        select * from tbl_employee
                    </when>
                </choose>
            </when>
        </choose>
</select>

bind绑定OGNL值,便于后来调用

<select id="getEmployeeBind" resultMap="EmployeeMap">
    <!--bind:可以将OGNL表达式的值绑定到一个变量中,方便后来引用这个变量的值-->
    <!--帮助我们提前拼接好lastName以便于使用模糊查询-->
    <bind name="_lastName" value="'%'+lastName+'%'"/>
    select * from tbl_employee where last_name like #{_lastName};
</select>

sql标签和include标签结合使用实现sql语句复用

抽取可重复使用的sql片段,方便后期维护

1、sql抽取,经常将要查询的列名,或者插入用的列名抽取出来方便使用

2、include用来引用已经抽取的sql

3、include还可以自定义一些property,sql标签内部就能使用自定义的属性

​ include-property:取值的正确方式${prop},而不能是#{prop}

<sql id="insertColumn">
    id,last_name,gender,email,${testcolumn}
</sql>
<insert id="insertEmployee">
    insert into tbl_employee(
    <include refid="insertColumn">
    	<property name="testcolumn" value="abc"/>
    </include>
    )
    values(
    <include refid="insertColumn"/>
    )
</insert>
posted @ 2021-06-07 16:06  Coder-Wang  阅读(65)  评论(0编辑  收藏  举报