一、顶级标签

1、sql – 可被其他语句引用的可重用语句块

<sql id="valid"> where valid = 1 </sql>
<select id = 'queryUser'>select * from user <include refid = 'valid'></include></select>

2、insert – 映射插入语句

<insert id = "saveUser">insert into User (id,name,sex) values (#{id},#{name},#{sex})<insert>

3、update – 映射更新语句

<update id="updateUser">
update User set
name = #{name},
sex= #{sex}
where id = #{id}
</update>

4、delete – 映射删除语句

<delete id="deleteUser">
delete from User where id = #{id}
</delete>

二、动态sql标签

1、if

<select id="findUserByName"
     resultType="User">
  SELECT * FROM User
  WHERE valid = 1
  <if test="name!= null">
    AND name like #{name}
  </if>
</select>

2、choose (when, otherwise)

<select id="findUser"
     resultType="User">
  SELECT * FROM User WHERE age = 26
  <choose>
    <when test="name!= null">
      AND name like #{name}
    </when>
    <when test="sex!= null ">
      AND sex like #{sex}
    </when>
    <otherwise>
      AND valid = 1
    </otherwise>
  </choose>
</select>

3、trim (where, set)


//prefixOverrides 属性会忽略通过管道分隔的文本序列(注意此例中的空格也是必要的)。它的作用是移除所有指定在 prefixOverrides 属性中的内容,并且插入 prefix 属性中指定的内容。
<trim prefix="WHERE" prefixOverrides="AND |OR ">
  ...
</trim>
 
//set 元素会动态前置 SET 关键字,同时也会删掉无关的逗号
<trim prefix="SET" suffixOverrides=",">
  ...
</trim>

4、foreach

//collection="要遍历的集合" 
//item = "可以在元素体内使用的集合项"
//index = "索引"
//open = "开始字符串"
//separator = "分隔符"
//close = "结束字符串"
<select id="selectUser" resultType="User">
  SELECT *
  FROM User
  WHERE ID in
  <foreach item="item" index="index" collection="list" open="(" separator="," close=")">
        #{item}
  </foreach>
</select>

5、bind

//bind可以创建一个变量并将其绑定到上下文

<select id="selectUser" resultType="user">
  <bind name="pattern" value="'%' + _parameter.getTitle() + '%'" />
  SELECT * FROM User
  WHERE name LIKE #{pattern}
</select>

6、xml中的timestamp比较

第一种写法:

 

原符号       <        <=      >       >=       &        '        "

替换符号    &lt;    &lt;=   &gt;    &gt;=   &amp;   &apos;  &quot;

  

例如:sql如下:

create_date_time &gt;= #{startTime} and  create_date_time &lt;= #{endTime}

<select id="getUser" resultType="java.lang.String" >
select name from user 
where birthday &lt; TO_TIMESTAMP(#{start}, 'yyyy-mm-dd hh24:mi:ss') 
and birthday &gt;= TO_TIMESTAMP(#{end}, 'yyyy-mm-dd hh24:mi:ss') order by start desc LIMIT 1
</select>

7、where

<where></where>标签的作用:

  • 可以动态的添加where关键字

可以自动去掉第一个拼接条件的and关键字

 <where>
    <if test="username!=null and username!=''">
        and username like '%${username}%'
    </if>
    <if test="gender!=null and gender!=''">
        and gender='${gender}'
    </if>
  </where>

8、@Param

@Param是MyBatis所提供的(org.apache.ibatis.annotations.Param),作为Dao层的注解,作用是用于传递参数,从而可以与SQL中的的字段名相对应,一般在2=<参数数<=5时使用最佳。


(1)原始的方法


当只有一个参数时,没什么好说的,传进去一个值也只有一个参数可以匹配。当存在多个参数时,传进去的值就区分不开了,这时可以考虑用Map,例如接口

public List<Role> findRoleByMap(Map<String, Object> parameter);

<select id="findRoleByMap" parameterType="map" resultType="role">
    SELECT id,name FROM t_role
    WHERE roleName=#{roleName}
    AND note=#{note}
<select>

2) 使用@Param


很明显上面的缺点就在于可读性差,每次必须阅读他的键,才能明白其中的作用,并且不能限定其传递的数据类型,下面是使用@Param的情况,需要将接口改为

public List<Role> findRoleByAnnotation(@Param("roleName") String roleName, @Param("note") String note);

这样我们就可以直接传入对应的值了。

当然也可以使用Java Bean来传递多个参数,定义一个POJO

public class RoleParam {
   private String roleName;
   private String note;
   /*getter和setter*/
}

此时接口就变为

public List<Role> findRoleByBean(RoleParam role);

这样对应的xml文件与1处的区别就在于id和parameterType发生了变化,id对应的方法和parameterType对应该类的权限定名。


而使用更多的场景可能是这样的,对应多个POJO

public List<Role> findRoleByMix(@Param("roleP") RoleParam role, @Param("permissionP") PermissionParam permission);

这样就可以进行如下映射

<select id="findRoleByMix" resultType="role">
    SELECT id,name FROM t_role
    WHERE roleName=#{roleP.roleName}
    AND note=#{rolep.note}
    AND level=#{permissionP.level}
<select>

注意此时并不需要写出parameterType属性,Mybatis会进行自动搜索。

(3)总结

  1. 当你不使用@Param注解来声明参数时,必须使用 #{}方式;

  2. 便于传多个参数;

  3. 类似于别名之类的功能;

三、批量插入

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.center.manager.mapper.FundMapper">
 
  <insert id="insertForeach" parameterType="java.util.List" useGeneratedKeys="false">
    insert into fund
      ( id,fund_name,fund_code,date_x,data_y,create_by,create_date,update_by,update_date,remarks,del_flag)
    values
    <foreach collection="list" item="item" index="index" separator=",">
      (
    	 #{item.id},
    	 #{item.fundName},
    	 #{item.fundCode},
    	 #{item.dateX},
    	 #{item.dataY},
    	 #{item.createBy},
    	 #{item.createDate},
    	 #{item.updateBy},
    	 #{item.updateDate},
    	 #{item.remarks},
    	 #{item.delFlag}
      )
    </foreach>		
  </insert>    
</mapper>


四、useGeneratedKeys参数

1、在settings元素中设置useGeneratedKeys参数

对于支持自动生成记录主键的数据库,如:MySQL,SQL Server,此时设置useGeneratedKeys参数值为true,在执行添加记录之后可以获取到数据库自动生成的主键ID。

实际上,在settings元素中设置useGeneratedKeys是一个全局参数,但是只会对接口映射器产生影响,对xml映射器不起效。

<settings>
    <!-- 
    允许JDBC支持自动生成主键,需要驱动兼容。 
    如果设置为true则这个设置强制使用自动生成主键,尽管一些驱动不能兼容但仍可正常工作(比如 Derby)。 -->
    <setting name="useGeneratedKeys" value="true" />
</settings>

此时,在接口映射中添加记录之后将返回主键ID。

public interface UserMapper {
    // 受全局useGeneratedKeys参数控制,添加记录之后将返回主键id
    @Insert("insert into user(id,name,age) values(#{id},#{name},#{age})")
    Integer insertUser(User user);
}

另外,在settings元素中设置的全局useGeneratedKeys参数对于xml映射器无效。如果希望在xml映射器中执行添加记录之后返回主键ID,则必须在xml映射器中明确设置useGeneratedKeys参数值为true。



2、在xml映射器中配置useGeneratedKeys参数

<!-- 插入数据:返回记录的id值 -->
<insert id="insertUser" parameterType="com.guor.bean.User" useGeneratedKeys="true" keyProperty="id" keyColumn="id">
    insert into user(id,name,age) values(#{id},#{name},#{age})
</insert>

xml映射器中配置的useGeneratedKeys参数只会对xml映射器产生影响,且在settings元素中设置的全局useGeneratedKeys参数值对于xml映射器不产生任何作用。


3、在接口映射器中设置useGeneratedKeys参数

// 设置useGeneratedKeys为true,返回数据库自动生成的记录主键id
@Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
@Insert("insert into user(id,name,age) values(#{id},#{name},#{age})")
Integer insertUser(User user);

请注意如果此时在接口映射器中又明确设置了useGeneratedKeys参数,那么注解映射器中的useGeneratedKeys参数值将覆盖settings元素中设置的全局useGeneratedKeys参数值。

举个例子:先在settings元素中设置全局useGeneratedKeys参数值为true,再在接口映射器中设置useGeneratedKeys参数值为false,添加记录之后将不能返回注解ID。 

五、MyBatis xml文件中postgres数据库字符串转timestamp写法

<select id="getName" resultType="java.lang.String" >
	SELECT name 
	FROM user 
	WHERE birthdaey &lt; TO_TIMESTAMP(#{start}, 'yyyy-mm-dd hh24:mi:ss') 
	AND birthdaey &gt;= TO_TIMESTAMP(#{end}, 'yyyy-mm-dd hh24:mi:ss') 
	ORDER BY birthdaey DESC 
	LIMIT 1
</select>

六、鉴别器

<resultMap type="com.gong.mybatis.bean.Employee" id="MyEmpDis">
    <id column="id" property="id"/>
    <result column="last_name" property="lastName"/>
    <result column="gender" property="gender"/>
    <result column="email" property="email"/>
    <discriminator javaType="string" column="gender">
        <case value="0" resultType="com.gong.mybatis.bean.Employee">
            <association property="dept" select="com.gong.mybatis.dao.DepartmentMapper.getDeptById"
                column="d_id">
                </association>
        </case>
        <case value="1" resultType="com.gong.mybatis.bean.Employee">
            <id column="id" property="id"/>
            <result column="last_name" property="lastName"/>
            <result column="gender" property="gender"/>
            <result column="last_name" property="email"/>
        </case>
    </discriminator>
</resultMap>
<select id="getEmpByIdStep" resultMap="MyEmpDis">
    select * from tbl_employee where id=#{id}
</select>