Mybatis框架动态SQL

一、概念和使用场景
        使用MyBatis进行数据持久化的过程中,除了基于基本的纯SQL语句查询外,动态SQL也是MyBatis的强大特性之一。许多情况下,我们需要根据不同的条件动态的组装SQL语句,这时候就需要用到动态SQL。

        动态SQL一般是根据用户输入或者外部条件动态组合的SQL语句块,能够灵活的发挥SQL强大的功能、方便解决一些其他方法难以解决或解决方法繁琐的问题。动态SQL常用的标签如下:

标签    作用    备注
if    判断语句    单条件判断
choose、when、otherwise

相当于java中的switch、case、default    多条件判断
thrim、where    辅助元素    用于处理一些SQL拼装问题
foreach    循环    用于批量插入、删除,或者in语句
二、标签用法
1、if标签:条件判断
用于根据条件判断是否执行对应的sql。

示例如下,可用于多字段筛选,只筛选有值的条件。

<select id="getList" parameterType="java.util.Map" resultType="com.simon.model.baseModel.ADAccount">
    select * from ADAccount where 1=1
    <where>
        <if test="map.corp != null and map.corp!=''">
            and corp=#{map.corp}
        </if>
        <if test="map.account != null and map.account != ''">
            and account=#{map.account}
        </if>
        <if test="map.name != null and map.name != ''">
            and name=#{map.name}
        </if>
        <if test="map.departmentTrace != null and map.departmentTrace != ''">
            and departmentTrace=#{map.departmentTrace}
        </if>
        <if test="map.email != null and map.email != ''">
            and email=#{map.email}
        </if>
        <if test="map.mobile !=null and map.mobile != ''">
            and mobile=#{map.mobile}
        </if>
        <if test="map.status != null and map.status != ''">
            and status=#{map.status}
        </if>
    </where>
</select>

2、where标签
用于where语句,上述示例已有它的用法

3、set标签
用于update更新语句。常与if标签连用,根据条件更新对应字段

示例如下,根据字段是否为空,判断是否更新该字段。

<update id="updateUser">
    update user
    <set>
        <if test="name != null">name=#{name},</if>
        <if test="phone != null">phone=#{phone},</if>
    account=#{account}
    </set>
    where id=#{id}
</update>
4、choose、when、otherwise标签
用于选择多个条件中的某一个条件执行。

示例如下,根据条件选择id、username、phone、account中的一个字段进行筛选。依次判断when语句中的条件是否成立,若成立,则只执行当前语句;否则继续判断下一个。

<select id="getUserList" resultType="java.util.Map" parameterType="com.simon.model.baseModel.ADAccount">
  select * from user
  <where>
      <choose>
          <when test="id !='' and id != null">
              id=#{id}
          </when>
          <when test="username !='' and username != null">
              and username=#{username}
          </when>
          <when test="phone  !='' and phone  != null">
              and phone =#{phone }
          </when>
          <otherwise>
              and account=#{account}
          </otherwise>
      </choose>
  </where>
</select>

5、trim标签
用于在增加或删除语句的前后缀。有四个属性,分别为:

prefix:为语句增加指定前缀。

prefixOverrides:为语句去除指定前缀。

suffix:为语句增加指定后缀。

suffixOverrides:为语句去除指定后缀。

例如,可将1中的语句改成如下语句,在语句中增加指定前缀“where”,同时去除第一条语句的前缀“and”。同理3中的语句也可以改为增加指定前缀“set”,同时去除最后一条语句的后缀“,”。

<select id="getList" parameterType="java.util.Map" resultType="com.simon.model.baseModel.ADAccount">
    select * from ADAccount
    <trim prefix="where" prefixOverrides="and">
        <if test="map.corp != null and map.corp!=''">
            and corp=#{map.corp}
        </if>
        <if test="map.account != null and map.account != ''">
            and account=#{map.account}
        </if>
        <if test="map.name != null and map.name != ''">
            and name=#{map.name}
        </if>
        <if test="map.departmentTrace != null and map.departmentTrace != ''">
            and departmentTrace=#{map.departmentTrace}
        </if>
        <if test="map.email != null and map.email != ''">
            and email=#{map.email}
        </if>
        <if test="map.mobile !=null and map.mobile != ''">
            and mobile=#{map.mobile}
        </if>
        <if test="map.status != null and map.status != ''">
            and status=#{map.status}
        </if>
    </where>
</select>

6、foreach标签
用于遍历集合,同时可以设置对遍历的每条语句之前增加分隔符,也可以对整体遍历的结果增加前后缀。有如下属性:

collection:需要遍历的集合。

item:当前遍历出的元素所赋值的变量。

index:当前遍历出的元素的索引。

open:最终遍历结果所需增加的前缀。

close:最终遍历结果所需增加的后缀。

separator:遍历出的每条语句之间的分隔符。

示例如下:

<select id="findAll" resultType="Student" parameterType="Integer">
    <include refid="selectvp"/> WHERE sid in
    <foreach item="ids" collection="array"  open="(" separator="," close=")">
        #{ids}
    </foreach>
</select>
7、sql和include标签
sql标签主要用于设置公共的语句,而include标签则用于引用sql标签所定义的语句。

开发过程中总会重复编写一些相同的sql语句,而这就可以用sql标签来统一定义;而之后在需要的地方用include标签来引用即可,避免重复编码相同语句。

示例如下:

<sql id="Base_Column_List">
    ID, AZID, EID, badge, Name, Joindate, WorkBeginDate, BalType, Term, TakeDate, ExpiredDate, 
    TotalBal, TotalDec, Bal, xUnit, SeqID, totalbal2, totalbal3, hjbadge
</sql>
<select id="selectByExample" parameterType="com.simon.model.ehrModel.AbalanceExample" resultMap="BaseResultMap">
    select
    <if test="distinct">
      distinct
    </if>
    'true' as QUERYID,
    <include refid="Base_Column_List" />
    from aBalance
    <if test="_parameter != null">
      <include refid="Example_Where_Clause" />
    </if>
    <if test="orderByClause != null">
      order by ${orderByClause}
    </if>
</select>

如果要在不同的文件中引用sql标签,则需要在include标签的refid属性中填写sql标签的具体路径,例如:

<include refid="com.xxx.dao.xxMapper.Base_Column_List"></include>
三、关联查询
        一般情况下的关联查询,只需要使用对应关联sql语句就可以。但如果遇到一对多的情况,在使用对应的sql语句之外,还需用到mybatis的关联查询的结果映射。如下:

<resultMap id="BaseResultMap" type="com.simon.model.ehrModel.Abalance">
    <id column="ID" jdbcType="INTEGER" property="id" />
    <result column="AZID" jdbcType="INTEGER" property="azid" />
    <result column="EID" jdbcType="INTEGER" property="eid" />
    <result column="badge" jdbcType="VARCHAR" property="badge" />
    <result column="Name" jdbcType="NVARCHAR" property="name" />
    <result column="Joindate" jdbcType="TIMESTAMP" property="joindate" />
    <collection property="list" ofType="workInfo">
        <result property="company" column="company"/>
        <result property="startDate" column="startDate"/>
        <result property="endDate" column="endDate"/>
    </collection>
</resultMap>
四、注意
        当然,动态SQL虽然可以根据条件动态的调整sql语句,从而增加代码开发的便利,但有时候并不能增加执行性能,而如果使用不当的话,更有可能存在sql注入的风险。需要谨慎使用。
————————————————

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值