目录
一、script
注解版下,使用动态SQL需要将sql语句包含在script标签里。
在 <script></script>内使用特殊符号,则使用java的转义字符,如 双引号 "" 使用"" 代替或者使用 \"\"
<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
用于动态更新语句的类似解决方案叫做 set。set 元素可以用于动态包含需要更新的列,忽略其它不更新的列。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() ;
}