mybatis.xml
mybatis3 官方文档
链接: (https://mybatis.org/mybatis-3/zh/).
初始映射文件
<?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="org.mybatis.example.BlogMapper">
</mapper>
以上是初始的xml文件, namespace: 指向相关的dao类。必须是完正的路径 底层会自动映射文件的实现类!
以下标签在 mapper标签内
标签 resultMap
<resultMap id="BaseResultMap" type="com.shan.dal.entity.approve.ApproveDiscussLog">
<result column="approve_id" property="approveId" jdbcType="VARCHAR"/>
<result column="user_id" property="userId"/>
<result column="body" property="body"/>
<result column="type" property="type"/>
<result column="shop_id" property="shopId"/>
</resultMap>
属性 | 含义 |
---|---|
作用 | 返回的结果集为一个map key为表字段映射实体类的属性,value对应数据库响应的值 |
id | 当前实体类映射的唯一的命名 |
type | 全限定类名,或系统别名 必须是完正的实体类路径 |
<result>中
属性 | 含义 |
---|---|
column | 数据库表中的字段名 |
property | 映射到实体类对应的属性名 |
jdbcType | 数据库表字段类型(可省略不写) |
标签 sql
<sql id="BaseColumnList">
approve_id,
user_id,
body,
type,
shop_id
</sql>
属性 | 含义 |
---|---|
sql | 自定义的sql语句,可以复用 |
id | 唯一id ,引用当前sql 语句的指向 |
标签 select 查询标签
<select id="select" resultMap="BaseResultMap">
select
<include refid="BaseColumnList"/>
from approve_discuss_log
</select>
返回的结果 为多条 会自动 转为list
属性 | 含义 |
---|---|
id | 唯一命名 指向mapper 层对应的方法名,也可以被用来引用这条语句 |
include | 引用定义的sql标签,refid 指向sql标签的id |
resultmap | 比较强大,适合使用返回值是自定义实体类的情况 |
resultType | 适合使用返回值得数据类型是非自定义的,即jdk的提供的类型可为 int String boolean 和 类名 map resultType 和 resultMap 之间只能同时使用一个。 |
parameterType | 传过来的参数类型注意和mapper层方法 的传参类型 对应。这个属性是可选的可以省略不写 |
标签 insert update delete
<insert id="insertAuthor">
insert into Author (id,username,password,email,bio)
values (#{id},#{username},#{password},#{email},#{bio})
</insert>
<update id="updateAuthor">
update Author set
username = #{username},
password = #{password},
email = #{email},
bio = #{bio}
where id = #{id}
</update>
<delete id="deleteAuthor">
delete from Author where id = #{id}
</delete>
生成并返回主键id
<insert id="insertAuthor" useGeneratedKeys="true"
keyProperty="id">
insert into Author (username, password, email, bio) values
(#{username}, #{password}, #{email}, #{bio})
</insert>
属性 | 含义 |
---|---|
useGeneratedKeys | 参数只针对 insert 语句生效,设置为 true 时,表示如果插入的表id以自增列为主键,则允许 JDBC 支持自动生成主键,并可将自动生成的主键id返回,默认为 false |
keyProperty | 中对应的值是实体类的属性,而不是数据库的字段,添加该属性之后并非改变insert方法的返回值,也就是说,该方法还是返回新增的结果。而如果需要获取新增行的主键ID,直接使用传入的实体对象的主键对应属性的值 |
动态sql
if
可以放在where子句过滤查询条件拼接
<select id="findActiveBlogWithTitleLike"
resultType="Blog">
SELECT * FROM BLOG
WHERE state = ‘ACTIVE’
<if test="title != null">
AND title like #{title}
</if>
// 双重判断可以用 and 拼接
<if test="author != null and author.name != null">
AND author_name like #{author.name}
</if>
</select>
也可在添加或者修改时做属性过滤
<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>
choose (when, otherwise)
<select id="findActiveBlogLike"
resultType="Blog">
SELECT * FROM BLOG WHERE state = ‘ACTIVE’
<choose>
<when test="title != null">
AND title like #{title}
</when>
<when test="author != null and author.name != null">
AND author_name like #{author.name}
</when>
<otherwise>
AND featured = 1
</otherwise>
</choose>
</select>
我们不想使用所有的条件,使用if标签时,只要test中的表达式为 true,就会执行 if 标签中的条件。MyBatis 提供了 choose 元素。if标签是与(and)的关系,而choose 是或(or)的关系。类似于Java 的 switch 语句,choose 为 switch,when 为 case,otherwise 则为 default。
属性 | 含义 |
---|---|
choose | choose标签是按顺序判断 |
when | when标签中的test条件出否成立,如果有一个成立,则 choose 结束 |
otherwise | 当 choose 中所有 when 的条件都不满则时,则执行 otherwise 中的sql |
trim (where, set)
<trim prefix="" suffix="" suffixOverrides="" prefixOverrides=""></trim>
属性 | 含义 |
---|---|
prefix | 在trim标签内sql语句加上前缀。 |
suffix | 在trim标签内sql语句加上后缀。 |
suffixOverrides | 指定去除多余的后缀内容,如:suffixOverrides=",",去除trim标签内sql语句多余的后缀","。 |
prefixOverrides | 指定去除多余的前缀内容 |
标签 where
<select id="findActiveBlogLike"
resultType="Blog">
SELECT * FROM BLOG
WHERE
<if test="state != null">
state = #{state}
</if>
<if test="title != null">
AND title like #{title}
</if>
<if test="author != null and author.name != null">
AND author_name like #{author.name}
</if>
</select>
以上sql语句如果where没有匹配的条件最终sql会是
SELECT * FROM BLOG
WHERE
这会导致查询失败,
如果第一个条件不匹配结果会是
SELECT * FROM BLOG
WHERE
AND title like ‘someTitle’
这种结果同样会失败
这样的情况可以使用where 标签
<select id="findActiveBlogLike"
resultType="Blog">
SELECT * FROM BLOG
<where>
<if test="state != null">
state = #{state}
</if>
<if test="title != null">
AND title like #{title}
</if>
<if test="author != null and author.name != null">
AND author_name like #{author.name}
</if>
</where>
</select>
where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除
也可用 trim 标签
<trim prefix="WHERE" prefixOverrides="AND |OR ">
...
</trim>
#
prefixOverrides 属性会忽略通过管道符分隔的文本序列(注意此例中的空格是必要的)。上述例子会移除所有 prefixOverrides 属性中指定的内容,并且插入 prefix 属性中指定的内容。
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>
这个例子中,set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)。
来看看与 set 元素等价的自定义 trim 元素吧:
<trim prefix="SET" suffixOverrides=",">
...
</trim>
注意,我们覆盖了后缀值设置,并且自定义了前缀值。
foreach
动态 SQL 的另一个常见使用场景是对集合进行遍历(尤其是在构建 IN 条件语句的时候)。比如:
<select id="selectPostIn" resultType="domain.blog.Post">
SELECT *
FROM POST P
WHERE ID in
<foreach item="item" index="index" collection="list"
open="(" separator="," close=")">
#{item}
</foreach>
</select>
foreach 元素的功能非常强大,它允许你指定一个集合,声明可以在元素体内使用的集合项(item)和索引(index)变量。它也允许你指定开头与结尾的字符串以及集合项迭代之间的分隔符。这个元素也不会错误地添加多余的分隔符,看它多智能!
提示 你可以将任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象作为集合参数传递给 foreach。当使用可迭代对象或者数组时,index 是当前迭代的序号,item 的值是本次迭代获取到的元素。当使用 Map 对象(或者 Map.Entry 对象的集合)时,index 是键,item 是值。
注意 collection属性与mapper层方法参数传入的参数一致,也可以在方法参数使用注解 @Param指向collection属性
script
要在带注解的映射器接口类中使用动态 SQL,可以使用 script 元素。比如:
@Update({"<script>",
"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}",
"</script>"})
void updateAuthorValues(Author author);
bind
bind 元素允许你在 OGNL 表达式以外创建一个变量,并将其绑定到当前的上下文。比如:
<select id="selectBlogsLike" resultType="Blog">
<bind name="pattern" value="'%' + _parameter.getTitle() + '%'" />
SELECT * FROM BLOG
WHERE title LIKE #{pattern}
</select>