MyBatis动态SQL(注解版)

目录

 

一、script

 

二、OGNL 的表达式

1.if 

2. choose

3.where

4.Set

5.bind

 6.foreach

扫描二维码关注公众号,回复: 12840766 查看本文章

三、关于JavaBean 的构造器问题

四、动态sql例子

五、在方法内编写sql

1、@InsertProvider实现批量插入数据

2、@SelectProvider  in List

六、Mybatis官方文档


一、script

注解版下,使用动态SQL需要将sql语句包含在script标签里。

在 <script></script>内使用特殊符号,则使用java的转义字符,如 双引号 "" 使用&quot;&quot; 代替或者使用 \"\" 

<script></script>

 

二、OGNL 的表达式

1.if 

通过判断动态拼接sql语句,一般用于判断查询条件

<if test=''>...</if>

2. choose

根据条件选择

<choose>
    <when test=''> ...
    </when>
    <when test=''> ...
    </when>
    <otherwise> ...
    </otherwise> 
</choose>

3.where

一般跟if 或choose 联合使用,这些标签或去掉多余的 关键字 或 符号。where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。如

<where>
    <if test="id != null "> 
        and t_id = #{id}
    </if>
</where>

4.Set

用于动态更新语句的类似解决方案叫做 setset 元素可以用于动态包含需要更新的列,忽略其它不更新的列。set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号。比如:

<update id="updateAuthorIfNecessary">
  update Author
    <set>
      <if test="username != null">username=#{username},</if>
      <if test="password != null">password=#{password},</if>
      <if test="email != null">email=#{email},</if>
      <if test="bio != null">bio=#{bio}</if>
    </set>
  where id=#{id}
</update>

5.bind

绑定一个值,可应用到查询语句中

<bind name="" value="" />

 6.foreach

循环,可对传入和集合进行遍历。一般用于批量更新和查询语句的 in

<foreach item="item" index="index" collection="list" open="(" separator="," close=")">
    #{item}
</foreach>

(1) item:集合的元素,访问元素的Filed 使用 #{item.Filed}

(2) index: 下标,从0开始计数

(3) collection:传入的集合参数

(4) open:以什么开始

(5) separator:以什么作为分隔符

(6) close:以什么结束

例如 传入的list 是一个 List<String>: ["a","b","c"],则上面的 foreach 结果是: ("a", "b", "c")。

三、关于JavaBean 的构造器问题

(1) bean 只有一个有参的构造方法,MyBatis 调用该构造器(参数按顺序),此时@results 注解无效。并有查询结果个数跟构造器不一致时,报异常。
(2) bean 有多个构造方法,且没有 无参构造器,MyBatis 调用跟查询字段数量相同的构造器;若没有数量相同的构造器,则报异常。
(3) bean 有多个构造方法,且有 无参构造器, MyBatis 调用无参数造器。
(4) 综上,一般情况下,bean 不要定义有参的构造器;若需要,请再定义一个无参的构造器。

四、动态sql例子

/**
     * if 对内容进行判断
     * concat函数:mysql拼接字符串的函数
     */
    @Select("<script>"
            + "select t_id, t_name, t_age                          "
            + "from sys_user                                       "
            + "<where>                                             "
            + "  <if test='id != null and id != ""'>     "
            + "    and t_id = #{id}                                "
            + "  </if>                                             "
            + "  <if test='name != null and name != ""'> "
            + "    and t_name like CONCAT('%', #{name}, '%')       "
            + "  </if>                                             "
            + "</where>                                            "
            + "</script>                                           ")
    @Results(id="userResults", value={
        @Result(property="id",   column="t_id"),
        @Result(property="name", column="t_name"),
        @Result(property="age",  column="t_age"),
    })
    List<User> selectUserWithIf(User user);
    
    /**
     * choose when otherwise 类似Java的Switch,选择某一项
     * when...when...otherwise... == if... if...else... 
     */
    @Select("<script>"
            + "select t_id, t_name, t_age                                     "
            + "from sys_user                                                  "
            + "<where>                                                        "
            + "  <choose>                                                     "
            + "      <when test='id != null and id != ""'>          "
            + "            and t_id = #{id}                                   "
            + "      </when>                                                  "
            + "      <otherwise test='name != null and name != ""'> "
            + "            and t_name like CONCAT('%', #{name}, '%')          "
            + "      </otherwise>                                             "
            + "  </choose>                                                    "
            + "</where>                                                       "
            + "</script>                                                      ")
    @ResultMap("userResults")
    List<User> selectUserWithChoose(User user);
    
    /**
     * set 动态更新语句,类似<where>
     */
    @Update("<script>                                           "
            + "update sys_user                                  "
            + "<set>                                            "
            + "  <if test='name != null'> t_name=#{name}, </if> "
            + "  <if test='age != null'> t_age=#{age},    </if> "
            + "</set>                                           "
            + "where t_id = #{id}                               "
            + "</script>                                        ")
    int updateUserWithSet(User user);
    
    /**
     * foreach 遍历一个集合,常用于批量更新和条件语句中的 IN
     * foreach 批量更新
     */
    @Insert("<script>                                  "
            + "insert into sys_user                    "
            + "(t_id, t_name, t_age)                   "
            + "values                                  "
            + "<foreach collection='list' item='item'  "
            + " index='index' separator=','>           "
            + "(#{item.id}, #{item.name}, #{item.age}) "
            + "</foreach>                              "
            + "</script>                               ")
    int insertUserListWithForeach(List<User> list);
    
    /**
     * foreach 条件语句中的 IN
     */
    @Select("<script>"
            + "select t_id, t_name, t_age                             "
            + "from sys_user                                          "
            + "where t_name in                                        "
            + "  <foreach collection='list' item='item' index='index' "
            + "    open='(' separator=',' close=')' >                 "
            + "    #{item}                                            "
            + "  </foreach>                                           "
            + "</script>                                              ")
    @ResultMap("userResults")
    List<User> selectUserByINName(List<String> list);
    
    /**
     * bind 创建一个变量,绑定到上下文中
     */
    @Select("<script>                                              "
            + "<bind name=\"lname\" value=\"'%' + name + '%'\"  /> "
            + "select t_id, t_name, t_age                          "
            + "from sys_user                                       "
            + "where t_name like #{lname}                          "
            + "</script>                                           ")
    @ResultMap("userResults")
    List<User> selectUserWithBind(@Param("name") String name);

五、在方法内编写sql

@InsertProvider 
@UpdateProvider 
@DeleteProvider 
@SelectProvider

1、@InsertProvider实现批量插入数据

mySql 批量插入数据库语句格式:

INSERT INTO 

[表名]([列名],[列名]) 

 VALUES

([列值],[列值])),

([列值],[列值])),

([列值],[列值]));

例如:

INSERT INTO 

items(name,city,price,number,picture) 

VALUES

('耐克运动鞋','广州',500,1000,'003.jpg'),

('耐克运动鞋2','广州2',500,1000,'002.jpg');

实体类:

public class WetSortVillage {
    
    private Integer id;
    
    private Integer areaId;
    
    private String areaName;
    
    private Integer streetId;
    
    private String village;
    
    private String street;
    
    private Integer villageId;
    
    private Integer households;//户数
    
    private Integer kegStationNum;//桶站数
    
    private Integer workerNum;//分类员数量
    
    private Integer status;//有效状态 1:开启 2关闭   默认添加就是开启
}

mapper:

public interface WetSortVillageMapper {

@InsertProvider(type=SQLProvider.class,method="insertSortVillagesByParam")
    public int insertSortVillagesByParam(List<WetSortVillage> list);
}

SQLProvider.java :

  public String insertSortVillagesByParam(Map map){
        StringBuilder sb = new StringBuilder();
        List<WetSortVillage> list = (List<WetSortVillage>) map.get("list");
        sb.append("INSERT INTO t_wet_sort_village ");
        sb.append("(area_id,street_id,village_id,households,");
        sb.append("keg_station_num,worker_num,status)");
        sb.append(" VALUES ");
        int length = list.size();
        MessageFormat mf = new MessageFormat("(#'{'list[{0}].areaId},#'{'list[{0}].streetId},#'{'list[{0}].villageId},#'{'list[{0}].households}"
                + ",#'{'list[{0}].kegStationNum},#'{'list[{0}].workerNum},#'{'list[{0}].status})");
        for(int i=0;i<length;i++){
             sb.append(mf.format(new Object[]{i}));  
             sb.append(StringUtils.join(valueArray, ","));
        }
    
        return sb.toString();
 }

2、@SelectProvider  in List

@Select({"<script>", +

"select ", +

"mysection ", +

"from test_my_table ", +

"where myNo in ", +

"<foreach collection='userDefParamName' item='yourselfItem' open='(' separator=',' close=')'>", +

"#{yourselfItem}", +

"</foreach>"

})

String getMysection (@Param("userDefParamName")List whateverName);

用<foreach>方式报错,有说版本低导致,使用3.5.1以上版本,可自行验证。

下面介绍此版本解决方法:

public String getMysection (@Param("userDefParamName")List whateverName){

    StringBuffer sql =new StringBuffer();

    sql.append("select mysection  from test_my_table ");

    sql.append(" where myNo IN ");

    if(userDefParamName.size()>0) {

    sql.append("(");

    for (int i =0; i < userDefParamName.size(); i++) {

    if(i>0){

        sql.append(",");

    }

    sql.append("#{userDefParamName[");

    sql.append(i);

    sql.append("]}");

    }

    sql.append(")");

    }

    return sql.toString() ;
}

六、Mybatis官方文档


https://mybatis.org/mybatis-3/zh/index.html

猜你喜欢

转载自blog.csdn.net/xiao__jia__jia/article/details/110975745