MyBatis动态sql

动态sql

动态sql类似于jsp中的JSTL表达式,可以在sql中嵌套判断语句

环境搭建

员工类、部门类

public class Department {
    private Integer id;
    private String d_name;
    private List<Employee> emps;
}

public class Employee {
    private Integer id;
    private String lastName;
    private String gender;
    private String email;
    private Department department;
}
if标签

场景:根据提供的员工信息查找员工,举例:只给了id通过id查找,给了id和lastname根据两者一起查找

    <!--List<Employee> getEmpsDynamicForIf(Employee employee);-->
    <select id="getEmpsDynamicForIf" resultType="com.yellowstar.mybatis.bean.Employee">
        select * from employee
        <!--
			如果不使用where标签,当id为null时,sql语句会报错变成where and last_name....
			当然也可以通过在where后面加上1=1恒成立的语句解决
			where标签作用:可以剔除第一条判断语句前的and
		-->
        <where>
            <!--test中填写判断条件-->
            <if test="id!=null">
                id = #{id}
            </if>
            <if test="lastName!=null">
                and last_name like #{lastName}
            </if>
            <if test="gender!=null">
                and gender = #{gender}
            </if>
            <if test="email!=null">
                and email = #{email}
            </if>
        </where>
    </select>

有些同学就有一些自己独特的习惯,喜欢讲and放在语句后面,如下,当lastname存在,gender不存在时sql语句会报错

日志输出:select * from employee WHERE last_name like ? and

mybatis为我们提供了trim标签,可以自定义字符串截取

    <select id="getEmpsDynamicForTrim" resultType="com.yellowstar.mybatis.bean.Employee">
        select * from employee
        <where>
            <if test="id!=null">
                id = #{id} and
            </if>
            <if test="lastName!=null">
                last_name like #{lastName} and
            </if>
            <if test="gender!=null">
                gender = #{gender} and
            </if>
            <if test="email!=null">
                email = #{email}
            </if>
        </where>
    </select>
trim标签

trim标签有4个属性值

  • prefix:前缀,在拼接完成的语句前加上信息
  • prefixOverrides:去掉一个判断语句中的sql语句前面多余的内容
  • suffix:后缀,在拼接完成的语句后加上信息
  • suffixOverrides:去掉一个判断语句中的sql语句后面面多余的内容
<!--List<Employee> getEmpsDynamicForTrim(Employee employee);-->
<select id="getEmpsDynamicForTrim" resultType="com.yellowstar.mybatis.bean.Employee">
    select * from employee
    <trim prefix="where" suffixOverrides="and">
        <if test="id!=null">
            id = #{id} and
        </if>
        <if test="lastName!=null">
            last_name like #{lastName} and
        </if>
        <if test="gender!=null">
            gender = #{gender} and
        </if>
        <if test="email!=null">
            email like #{email}
        </if>
    </trim>
</select>
choose标签

场景:与上面场景不同的是,当我们查找员工信息时,如果给了id就根据id查找,没有id在判断有没有name,有的话根据name查找,一次类推,如果什么条件都没有,执行查找所有员工

这里使用到choose标签,个人理解为此标签有点像if…else if…else…

    <select id="getEmpsDynamicForChoose" resultType="com.yellowstar.mybatis.bean.Employee">
        select * from employee
        <where>
            <choose>
                <when test="id!=null">
                    id = #{id}
                </when>
                <when test="lastName!=null">
                    last_name like #{lastName}
                </when>
                <when test="gender!=null">
                    gender = #{gender}
                </when>
                <when test="email!=null">
                    email like #{email}
                </when>
                <otherwise>
                    <!--如果都不匹配-->
                </otherwise>
            </choose>
        </where>
    </select>
set标签

set用于更新数据,注意更新时要手动提交数据

场景:之前在更新一条员工信息时,使用的是全部更新,现在的需求是如果lastname传过来,就更新lastname,反之则不更新

    <!--void updateEmpForSet(Employee employee);-->
    <update id="updateEmpForSet">
        update 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>
foreach标签

foreach见名知意,是用来循环的

场景一:根据所提供的一个集合(集合中是id值),来查找符合id的员工

先来写一下sql语句(建议每次在mybatis中写sql之前,都先将sql写在数据库工具中试试看),其中的1,2,5就是传入的集合中的每一个参数,需要使用foreach标签遍历这个集合

select * from employee where id in (1,2,5)
    <!--List<Employee> getEmpsDynamicForeach(ArrayList<Integer> ids);-->
    <select id="getEmpsDynamicForeach" resultType="com.yellowstar.mybatis.bean.Employee">
        select * from employee where id in
            <!--
                 collection:传过来的集合对象,如果是list集合的话填list
                 item:当前遍历的对象
                 open:遍历拼接完成的语句前添加信息
                 close:遍历拼接完成的语句后添加信息
                 separator:分隔符,每一项之间用逗号分隔
            -->
            <foreach collection="list" item="emp_id" open="(" close=")" separator=",">
                #{emp_id}
            </foreach>
    </select>

场景二:批量插入员工数据

这里我们遍历map集合,如果是map集合,要在接口形参前标识@Param注解,设置map集合的参数名,collection要使用该参数名

    <!--void insertEmps(@Param("emps") Map<String,Object> emps);-->
    <!--  insert into employee (last_name,gender,email) VALUES (?,?,?) , (?,?,?)  -->
    <insert id="insertEmps">
        insert into employee (last_name,gender,email,d_id) VALUES
        <foreach collection="emps" item="emp" separator=",">
            (#{emp.lastName},#{emp.gender},#{emp.email},#{emp.department.id})
        </foreach>
    </insert>

mybatis也为我们提供了内置参数,可以不用设置注解,只需要使用_parameter参数即可

_parameter:

​ 如果是单个参数:代表整个参数

​ 如果参数被封装为一个map,_parameter就代表这个map

    <!--void insertEmps(@Param("emps") Map<String,Object> emps);-->
    <!--  insert into employee (last_name,gender,email) VALUES (?,?,?) , (?,?,?)  -->
    <insert id="insertEmps">
        insert into employee (last_name,gender,email,d_id) VALUES
        <foreach collection="_parameter" item="emp" separator=",">
            (#{emp.lastName},#{emp.gender},#{emp.email},#{emp.department.id})
        </foreach>
    </insert>

_databaseId

​ 如果在全局文件中设置了databaseIdProvider标签,_databaseId就代表当前数据库的别名

bind标签

bind 元素允许你在 OGNL 表达式以外创建一个变量,并将其绑定到当前的上下文。比如:

<select id="selectBlogsLike" resultType="Blog">
  <bind name="pattern" value="'%' + _parameter.getTitle() + '%'" />
  SELECT * FROM BLOG
  WHERE title LIKE #{pattern}
</select>
sql标签

在实际开发过程中,查询语句建议见每个字段的名称写出来,而不是用*代替,而有些语句使用的都是同一段字段名,这时候可以使用sql标签,使用的时候引用即可

原xml中如下配置,我们希望id,last_name,gender,email,d_id可以抽取出来,方便其他语句引用

<!--List<Employee> getEmpsDynamicForIf(Employee employee);-->
<select id="getEmpsDynamicForIf" resultType="com.yellowstar.mybatis.bean.Employee">
    select id,last_name,gender,email,d_id from employee
    <where>
        <if test="id!=null">
            id = #{id}
        </if>
        <if test="lastName!=null">
            and last_name like #{lastName}
        </if>
        <if test="gender!=null">
            and gender = #{gender}
        </if>
        <if test="email!=null">
            and email = #{email}
        </if>
    </where>
</select>

可以修改为以下这种写法

<!--List<Employee> getEmpsDynamicForIf(Employee employee);-->
<select id="getEmpsDynamicForIf" resultType="com.yellowstar.mybatis.bean.Employee">
    select 
    <include refid="column"></include>
    from employee
    <where>
        <if test="id!=null">
            id = #{id}
        </if>
        <if test="lastName!=null">
            and last_name like #{lastName}
        </if>
        <if test="gender!=null">
            and gender = #{gender}
        </if>
        <if test="email!=null">
            and email = #{email}
        </if>
    </where>
</select>

<sql id="column">
    id,last_name,gender,email,d_id
</sql>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值