MyBatis动态SQL

MyBatis动态SQL

mapper接口方法:

/**
 * mybatis动态SQL
 */
public interface EmployeeMapperDynamicSQL {
    List<Employee> getEmpByConditionIf(Employee e);

    List<Employee> getEmpByConditionChoose(Employee e);

    int updateEmployee(Employee e);

    List<Employee> selectEmpByConditionForEach(List<Integer> ids);

    void addEmps(@Param("emps") List<Employee> emps);
}

动态SQL之if

 <!--动态SQL之if-->
    <!--动态SQL之if-->
    <!--<if test="">
    test:判断表达式(OGNL)-->
    <!--为什么在where后加一个1=1的条件?避免某些条件为空的时候,sql直接拼接成where and ***的情况
    也有另外的解决办法,也是mybatis推荐的
   2. 使用<where></where>标签将所有的查询条件包裹上,这样mybatis会将where标签中拼装的sql,多出来的
    and 或or去掉,但是他只会去掉第一个条件

    3.使用trim标签包裹
    -->
    <select id="getEmpByConditionIf" resultType="com.gf.selfdemo.mybatis.bean.Employee">
        select * from employee
        where 1=1
        <if test="id != null">
            and id=#{id}
        </if>
        <if test="lastName != null and lastName != ''">
            and last_name like concat(concat('%',#{lastName}),'%')
        </if>
        <if test="email != null and email.trim() != ''">
            and email =#{email}
        </if>
        <if test="gender==0 or gender==1">
            and gender=#{gender}
        </if>
    </select>


    <!--用where标签包裹-->
    <select id="getEmpByConditionIf2" resultType="com.gf.selfdemo.mybatis.bean.Employee">
        select * from employee
        <where>
            <if test="id != null">
                id=#{id}
            </if>
            <if test="lastName != null and lastName != ''">
                and last_name like concat(concat('%',#{lastName}),'%')
            </if>
            <if test="email != null and email.trim() != ''">
                and email =#{email}
            </if>
            <if test="gender==0 or gender==1">
                and gender=#{gender}
            </if>
        </where>
    </select>
  <!--用trim标签包裹 trim属性:
    prefix:前缀:trim标签体中整个字符串拼接后的结果,即给字符串加一个前缀
    prefixOverrides:前缀覆盖,去掉整个字符串前面多余的字符
    suffix:后缀,给瓶装的字符串加上后缀
    suffixOverrides:去掉整个字符串后面多余的字符
    -->
    <select id="getEmpByConditionIf3" resultType="com.gf.selfdemo.mybatis.bean.Employee">
        select * from employee
        <trim prefix="where" suffixOverrides="and">
            <if test="id != null">
                id=#{id}
            </if>
            <if test="lastName != null and lastName != ''">
                and last_name like concat(concat('%',#{lastName}),'%')
            </if>
            <if test="email != null and email.trim() != ''">
                and email =#{email}
            </if>
            <if test="gender==0 or gender==1">
                and gender=#{gender}
            </if>
        </trim>
    </select>

动态SQL之choose

   <!--choose(when ,otherwise):分支选择:switch-case-->
    <!--场景:如果带了id就用id查,如果带了lastName就用lastName查,只会进入其中一个分支-->
    <select id="getEmpByConditionChoose" resultType="com.gf.selfdemo.mybatis.bean.Employee">
        select * from employee
        <where>
            /*如果带了id就用id查,如果带了lastName就用lastName查*/
            <choose>
                <when test="id != null">
                    id=#{id}
                </when>
                <when test="lastName != null and lastName != ''">
                    last_name=#{lastName}
                </when>

                <when test="email != null and email != ''">
                    email 3#{email}
                </when>
                <otherwise>
                    1=1
                </otherwise>

            </choose>
        </where>
    </select>

动态SQL之 set针对更新语句

 <!--更新时,除了最后一个字段外的所有字段都会有',',那么如果最后一个字段为空的话,会出现字符set字符串的最后
    会出现','的情况,<set>标签可以将多余的','去除掉-->

    <update id="updateEmployee">
        update employee
        <set>
            <if test="lastName != null">
                last_name=#{lastName},
            </if>
            <if test="email != null">
                email=#{email},
            </if>

            <if test="gender != null">
                gender=#{gender}
            </if>
        </set>
        <where>
            id=#{id}
        </where>
    </update>


    <!--set的功能也可以通过trim实现,trim指定字符串前缀为set,suffixOverrides指定如果
    字符串最后出现多余的','则去掉-->
    <update id="updateEmployee2">
        update employee
        <trim prefix="set" suffixOverrides=",">
            <if test="lastName != null">
                last_name=#{lastName},
            </if>
            <if test="email != null">
                email=#{email},
            </if>

            <if test="gender != null">
                gender=#{gender}
            </if>
        </trim>
        <where>
            id=#{id}
        </where>
    </update>

动态SQL之forEach

<!--forEach遍历list集合用于根据条件查询-->
<select id="selectEmpByConditionForEach" resultType="com.gf.selfdemo.mybatis.bean.Employee">

    select * from employee where id in

    /*
    forEach标签属性
    collection:指定要遍历的集合
    list类型的参数会特殊处理封装在map中,map的key就叫list
    item:将当前遍历出的元素赋值给指定的变量 #{变量名}就能取出变量的值也就是当前遍历的元素
    separator:指定每个元素之间的分隔符
    open:遍历出所有结果拼接一个开始字符
    close:遍历出所有结果拼接结束字符
    index:索引,遍历List的时候是索引,item就是当前值。如果遍历map的时候index表示的就是map的key,item就是map的值
    */
    <foreach collection="ids" index="index" item="item_id" separator="," open="(" close=")">
        #{item_id}
    </foreach>
</select>

<!--forEach遍历集合用于批量保存-->

<!--方式一:拼接为:insert into employee(last_name,email,gender,dept_id)values
(),(),()的形式-->
<insert id="addEmps">
    insert into employee (last_name,email,gender,dept_id)
    values
    <foreach collection="emps" item="emp"  separator=",">
        (#{emp.lastName},#{emp.email},#{emp.gender},#{emp.department.id})
    </foreach>
</insert>

<!--批量保存之方式二:拼接为
insert into employee(last_name,email,gender,dept_id)values(*,*,*);
 insert into employee(last_name,email,gender,dept_id)values(*,*,*);
 insert into employee(last_name,email,gender,dept_id)values(*,*,*);
 但是这种方式需要在数据库连接url指定支持多查询语句
 -->

<insert id="addEmps">
    <foreach collection="emps" item="item" separator=";">
        insert into employee (last_name,email,gender,dept_id)
        values
        (#{emp.lastName},#{emp.email},#{emp.gender},#{emp.department.id})
    </foreach>
</insert>

<!--oracle数据库批量保存方法:
oracle不支持values(),(),()的形式
oracle批量保存的方式为:
1.多个Insert放在begin-end里面
    begin
        insert into employee (last_name,email,gender,dept_id)
        values (#{emp.lastName},#{emp.email},#{emp.gender},#{emp.department.id});
        insert into employee (last_name,email,gender,dept_id)
        values (#{emp.lastName},#{emp.email},#{emp.gender},#{emp.department.id});
        insert into employee (last_name,email,gender,dept_id)
        values (#{emp.lastName},#{emp.email},#{emp.gender},#{emp.department.id});
    end;
 2.oracle支持中间表的形式
    insert into employee(employee_id,last_name,email)
    select employee_seq.nextval,lastName,email
    from (
        select 'test_1_last_name' lastName,'test_e_1_email' email from dual
        union
        select 'test_2_last_name' lastName,'test_e_2_mail' email from dual
    )
-->

<!--oracle批量保存-->
<insert id="addEmpss">
    begin
      <foreach collection="emps" item="item" >
          insert into employee(employee_id,last_name,email)
          values(employee_seq.nextval,#{emp.lastName},#{emp.email})
      </foreach>
    end;
</insert>

mybatis两个内置参数

不只是方法传递过来的参数可以被用来判断,取值,mybatis默认还有两个内置参数
_parameter:代表整个参数
    如果查询中只传过来一个参数,_parameter就代表这个参数
    如果查询传过来多个参数,参数会封装为一个map,_parameter就代表这个map

_databaseId:如果在mybatis-config.xml中配置了databaseIdProvider标签
    _databaseId就代表当前数据库的别名
-->

<select id="getEmpsTestInnerParameter" resultType="***">
    <if test="_databaseId=='mysql'">   /*去mysql查*/
        select * from employee
        <if test="_parameter != null">
            where last_name=#{lastName}
        </if>
    </if>
    <if test="_databaseId=='oracle'">  /*去oracle查*/
        select * from orac_employees
    </if>
</select>

bind绑定变量,可以对传入的变量做改变

<select id="selectByLastName" resultType="com.gf.selfdemo.mybatis.bean.Employee">
    <bind name="_lastName" value="'%'+lastName+'%'"/>
    select * from employee where last_name like #{_lastName}
</select>

公共代码片段

<!--与insert,select,delete,update等标签同级的标签sql,可以抽取出在mapper.xml中多处使用的公共语句
在调用的地方用<include>标签引入即可

抽取可宠用的sql片段,方便后面引用
1.sql:抽取,经常将要查询的列名,或者插入用的列名抽取出来方便应用
2.include 引用已经抽取出来的sql片段
3.include还可以自定义一些property,sql标签内部就能使用自定义的属性 ${property},不能用#{property}取
-->

<sql id="employee_column">
    last_name,email,gender
</sql>
<select id="testCommonSql" resultType="com.gf.selfdemo.mybatis.bean.Employee">
    select
      <include refid="employee_column"/>
    from employee where id=#{id}
</select>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值