一、动态sql
- <where> 标签使用
一般涉及到多个动态查询条件,一般通过sql使用where 1 = 1来处理,mybatis提供了对应得标签,即 <where>
<where>
<if test="name != nulll">
and name like concat('%',trim(#{name,jdbcType=VARCHAR}),'%')
</if>
</where>
- <if> 标签使用
一般用于非空验证
<select id="queryByIdAndTitle"
resultType="Blog">
SELECT * FROM BLOG
WHERE 1=1
<if test="id!= null and title!=null">
AND id=#{id} and title=#{title}
</if>
</select>
上面的where可以使用where标签
- <choose>、<when>、<otherwise> 标签
choose(when,otherwise)标签相当于switch(case,default),当 when 中有条件满足的时候,就会跳出 choose,即所有的 when 和 otherwise 条件中,只有一个会输出,当所有的我很条件都不满足的时候就输出 otherwise 中的内容
<select id="dynamicChooseTest" parameterType="Blog" resultType="Blog">
select * from t_blog where 1 = 1
<choose>
<when test="title != null">
and title = #{title}
</when>
<when test="content != null">
and content = #{content}
</when>
<otherwise>
and owner = "owner1"
</otherwise>
</choose>
</select>
- <trim> 标签
trim标签的主要功能是可以在自己包含的内容前加上某些前缀,也可以在其后加上某些后缀,与之对应的属性是prefix和suffix;可以把包含内容的首部某些内容覆盖,即忽略,也可以把尾部的某些内容覆盖,对应的属性是prefixOverrides和suffixOverrides;正因为trim有这样的功能,所以我们也可以非常简单的利用trim来代替where元素的功能。
<select id="selectUsersTrim" resultMap="resultListUsers" parameterType="Users">
select * from users
<trim prefix="where" prefixOverrides="and | or">
<if test="name!=null">
and name=#{name}
</if>
<if test="address!=null">
and address=#{address}
</if>
</trim>
</select>
<insert id="insertSelective" parameterType="com.jyb.epm.api.model.AicInfo" >
insert into aic_info
<trim prefix="(" suffix=")" suffixOverrides="," >
<if test="id != null" >
id,
</if>
<if test="remark != null" >
remark,
</if>
<if test="createUserId != null" >
create_user_id,
</if>
<if test="modifyUserId != null" >
modify_user_id,
</if>
<if test="createTi != null" >
create_ti,
</if>
<if test="modifyTi != null" >
modify_ti,
</if>
<if test="version != null" >
version,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides="," >
<if test="id != null" >
#{id,jdbcType=INTEGER},
</if>
<if test="remark != null" >
#{remark,jdbcType=VARCHAR},
</if>
<if test="createUserId != null" >
#{createUserId,jdbcType=INTEGER},
</if>
<if test="modifyUserId != null" >
#{modifyUserId,jdbcType=INTEGER},
</if>
<if test="createTi != null" >
#{createTi,jdbcType=BIGINT},
</if>
<if test="modifyTi != null" >
#{modifyTi,jdbcType=BIGINT},
</if>
<if test="version != null" >
#{version,jdbcType=INTEGER},
</if>
</trim>
</insert>
- <foreach> 标签
<delete id="batchDelete" parameterType="java.lang.String">
delete from user
where id in
<foreach item="id" index="index" collection="list"
open="(" separator="," close=")">
#{id}
</foreach>
</delete >
foreach标签可迭代任何对象(如列表、集合等)和任何的字典或者数组对象传递给foreach作为集合参数,当使用可迭代对象或者数组时,index是当前迭代的次数,item的值是本次迭代获取的元素。当使用字典(或者Map.Entry对象的集合)时,index是键,item是值。collection标签可以填('list','array','map')。
foreach元素的属性主要有 item,index,collection,open,separator,close。
item表示集合中每一个元素进行迭代时的别名;
index指定一个名字,用于表示在迭代过程中,每次迭代到的位置;
open表示该语句以什么开始,
separator表示在每次进行迭代之间以什么符号作为分隔符;
close表示以什么结束。
- <bind> 标签
bind 元素可以从 OGNL 表达式中创建一个变量并将其绑定到上下文。比如:
<select id="selectBlogsLike" resultType="Blog">
<bind name="pattern" value="'%' + _parameter.getTitle() + '%'" />
SELECT * FROM BLOG
WHERE title LIKE #{pattern}
</select>
- Multi-db vendor support
一个配置了“_databaseId”变量的 databaseIdProvider 对于动态代码来说是可用的,这样就可以根据不同的数据库厂商构建特定的语句。比如下面的例子:
<insert id="insert">
<selectKey keyProperty="id" resultType="int" order="BEFORE">
<if test="_databaseId == 'oracle'">
select seq_users.nextval from dual
</if>
<if test="_databaseId == 'db2'">
select nextval for seq_users from sysibm.sysdummy1"
</if>
</selectKey>
insert into users values (#{id}, #{name})
</insert>
二、重复的sql片段
- 定义<sql>
<sql id="Base_Column_List" >
id, name, url, priority, logo, img
</sql>
- 引用
<include refid="Base_Column_List" />
三、插入时主键返回
<selectKey> 标签
<insert id="insert" parameterType="org.andy.shop.model.CourseInfo" >
insert into course_info (id, cname, caddress)
values (#{id,jdbcType=INTEGER}, #{cname,jdbcType=VARCHAR}, #{caddress,jdbcType=VARCHAR})
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
select last_insert_id()
</selectKey>
</insert>
或者
<insert id="insert" parameterType="org.andy.shop.model.CourseInfo" useGeneratedKeys="true" keyProperty="id">
insert into course_info (id, cname, caddress)
values (#{id,jdbcType=INTEGER}, #{cname,jdbcType=VARCHAR}, #{caddress,jdbcType=VARCHAR})
</insert>
非自增主键:但我们的ID为uuid字符类型的32为长度时,我们使用mysql的uuid()查询主键,是在查询之后在插入。
<insert id="insert" parameterType="org.andy.shop.model.CourseInfo" >
<selectKey keyProperty="id" order="BEFORE" resultType="java.lang.String">
select uuid()
</selectKey>
insert into course_info (id, cname, caddress)
values (#{id,jdbcType=VARCHAR}, #{cname,jdbcType=VARCHAR}, #{caddress,jdbcType=VARCHAR})
</insert>
使用oracle数据库时:使用 序列名.nextval()函数获取。
四、高级映射 collection和assiocation
区别: collection:1对多(比如博客和评论,一篇博客可能会有多个评论,这就是1对多,当你需要博客实体类的时候,可以使用collection)。 assiocation: 多对一(比如博客和作者,一篇博客只可能是一个作者,但是一个作者可以有多个博客,所以当你需要这种博客实体类的时候,可以使用assiocation)。
此单元会详细说明。