结果映射
resultMap
简单映射
<resultMap id="myResultMap" type="User">
<id property="id1" column="id1_column"/>
<id property="id2" column="id2_column"/>
<result property="name" column="name_column"/>
<result property="age" column="age_column"/>
</resultMap>
property
属性用于指定 Java 对象中对应的属性名,column
属性用于指定数据库表中对应的列名。通过使用多个 <id>
标签来映射复合主键。如果表中只有一个字段唯一,也可以直接用result标签完成映射。
关联查询映射
<resultMap id="BlogResultMap" type="Blog">
<id column="id" property="id"/>
<result column="title" property="title"/>
<result column="content" property="content"/>
<association property="author" javaType="Author">
<id column="author_id" property="id"/>
<result column="author_name" property="name"/>
</association>
</resultMap>
这里将查询结果的id、title、content映射到Blog对象的id、title、content属性上,将查询结果的author_id、author_name映射到Author对象的id、name属性上,并将Author对象作为Blog对象的属性进行关联映射。
集合映射
<resultMap id="AuthorResultMap" type="Author">
<id column="id" property="id"/>
<result column="name" property="name"/>
<collection property="blogs" ofType="Blog">
<id column="blog_id" property="id"/>
<result column="blog_title" property="title"/>
<result column="blog_content" property="content"/>
</collection>
</resultMap>
这里将查询结果的id、name映射到Author对象的id、name属性上,并将查询结果中Author对象关联的多个Blog对象映射到Author对象的blogs属性上,其中Blog对象的id、title、content属性分别映射到Blog对象的id、title、content属性上。
继承映射
<resultMap id="BaseResultMap" type="Base">
<id column="id" property="id"/>
<result column="name" property="name"/>
</resultMap>
<resultMap id="DerivedResultMap" type="Derived" extends="BaseResultMap">
<result column="age" property="age"/>
</resultMap>
这里将查询结果的id、name映射到Base对象的id、name属性上,并在Derived对象中继承了BaseResultMap,将查询结果的age映射到Derived对象的age属性上。
嵌套映射
<resultMap id="UserResultMap" type="User">
<id column="id" property="id"/>
<result column="username" property="username"/>
<result column="age" property="age"/>
<association property="department" resultMap="DepartmentResultMap"/>
</resultMap>
<resultMap id="DepartmentResultMap" type="Department">
<id column="id" property="id"/>
<result column="name" property="name"/>
</resultMap>
类似关联查询映射,但把内嵌的resultMap抽离出来
自动映射
<resultMap id="UserResultMap" type="User" autoMapping="true">
<id column="id" property="id"/>
</resultMap>
自动映射默认也开启,Mybatis会根据查询结果的列名自动将查询结果映射到Java对象的属性上,默认情况下会对驼峰命名规则和下划线命名规则进行转换,无需显式地定义映射关系。
枚举类型映射
<resultMap id="OrderResultMap" type="Order">
<id column="id" property="id"/>
<result column="status" property="status" typeHandler="org.apache.ibatis.type.EnumTypeHandler"/>
</resultMap>
这里将查询结果的id、status分别映射到Order对象的id、status属性上,并将status属性的映射类型指定为枚举类型,使用了Mybatis提供的EnumTypeHandler类型处理器。
格式化输出
where
<where>
标签用于动态生成WHERE子句,它会自动删除WHERE子句中的第一个AND或OR关键字。
<select id="findUsers" resultType="User">
SELECT * FROM users
<where>
<!-- 如果条件满足,则拼接SQL语句 -->
<if test="id != null">
AND id = #{id}
</if>
<if test="name != null">
AND name = #{name}
</if>
<if test="status != null">
AND status = #{status}
</if>
</where>
</select>
set
set
标签用于生成动态的 SET 语句。通常情况下,我们使用 update
语句来更新数据库中的数据,set
标签可以用来生成 SET 语句的动态部分。
<update id="updateUser" parameterType="User">
UPDATE users
<set>
<if test="name != null">name = #{name},</if>
<if test="age != null">age = #{age},</if>
</set>
WHERE id = #{id}
</update>
trim
<trim>
标签用于删除或添加SQL语句中的空格和其他不必要的字符。
<update id="updateUser" parameterType="User">
UPDATE users
<trim prefix="SET" suffixOverrides=",">
<if test="name != null">
name = #{name},
</if>
<if test="email != null">
email = #{email},
</if>
<if test="status != null">
status = #{status},
</if>
</trim>
WHERE id = #{id}
</update>
动态sql拼接
if
<if>
标签用于在SQL语句中嵌入条件判断语句。
<select id="findUsers" resultType="User">
SELECT * FROM users
<where>
<!-- 如果条件满足,则拼接SQL语句 -->
<if test="id != null">
AND id = #{id}
</if>
<if test="name != null">
AND name = #{name}
</if>
<if test="status != null">
AND status = #{status}
</if>
</where>
</select>
choose
<choose>
标签允许在多个条件分支中选择一个执行,类似于Java中的switch语句。
<select id="findUsers" resultType="User">
SELECT * FROM users
WHERE
<choose>
<when test="name != null and email != null">
name = #{name} AND email = #{email}
</when>
<when test="name != null">
name = #{name}
</when>
<when test="email != null">
email = #{email}
</when>
<otherwise>
status = 'ACTIVE'
</otherwise>
</choose>
</select>
foreach
<foreach>
标签可以用于循环一个集合,并将集合中的元素拼接到SQL语句中。主要用于构建in条件,可在sql中对集合进行迭代。也常用到批量删除、添加等操作中。
<insert id="batchInsertUsers" parameterType="java.util.List">
INSERT INTO users (id, name, email)
VALUES
<foreach collection="list" item="user" separator=",">
(#{user.id}, #{user.name}, #{user.email})
</foreach>
</insert>
- collection:如果直接传入集合,则用list、array、map三种,分别对应的参数类型为:List、数组、map集合。如果传入对象,使用其中的某个集合,则用该集合的名称。
- item :表示在迭代过程中每一个对象的别名
- index :表示在迭代过程中每次迭代到的位置(下标)的别名,可以用#{别名}来访问当前位置的值或者直接使用迭代的位置
- open :前缀
- close :后缀
- separator :分隔符,表示迭代时每个元素之间以什么分隔
定义常量
sql include
sql
标签可以用来定义 SQL 片段,这些 SQL 片段可以在其他 SQL 查询中被引用。通过使用 sql
标签,我们可以将一些常用的 SQL 代码片段定义为一个独立的模板,然后在其他 SQL 查询中使用include调用。sql标签可以继承其他sel标签,也可以进行嵌套。
<sql id="selectColumns">
id, name, age, email
</sql>
<sql id="userTable">
FROM users
</sql>
<select id="selectUsers" resultType="User">
SELECT
<include refid="selectColumns"/>
<include refid="userTable"/>
</select>
<sql id="commonColumns">
id, name, age, email
</sql>
<sql id="selectUsers">
SELECT
<include refid="commonColumns"/>
FROM users
WHERE 1 = 1
<if test="name != null">AND name = #{name}</if>
<if test="age != null">AND age = #{age}</if>
</sql>
<sql id="selectAdmins" extends="selectUsers">
AND role = 'admin'
</sql>
bind
<bind>
标签用于将 SQL 语句中的一个值绑定到一个参数中,可以避免在 SQL 语句中多次使用相同的值而造成代码的冗余。可以放在sql标签内顶部或者mapper标签内
<bind name="参数名" value="参数值" />
<select id="getUsersByName" parameterType="String" resultType="User">
<bind name="nameLike" value="'%' + name + '%'" />
SELECT * FROM user WHERE name LIKE #{nameLike}
</select>