Mapper.xml映射文件定义了操作数据库的sql,每个sql都是一个statement,需要我们自己进行配置。映射文件是mybatis的灵魂。
首先我们来说说输入映射和输出映射。
输入映射:
parameterType:我们可以直接用占位符#{}或${}sql拼接来传递简单类型的参数。例如
<select id="findUserById" parameterType="Integer" resultType="User">
select * from user where id = #{id}
</select>
当我们需求比较复杂时,也可以通过pojo传递查询条件,pojo中可以定义另外的pojo,我们可以定义一个这样的pojo。
public class QueryVo {
// 包含其他的pojo
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
这样进行查询,
<select id="findUserByUsernameAndSex" parameterType="QueryVo"
resultType="User">
select * from user
<where>
<if test="user.sex !=null and user.sex !=''">
and sex = #{user.sex}
</if>
<if test="user.username!=null and user.username!=''">
and username like #{user.username}
</if>
</where>
</select>
调用pojo中的属性的属性,来进行参数传递。
输出映射:用来定义查询的结果是什么类型
resultType:配置一些基本类型。
例如:
<select id="findUserListByUsername" parameterType="QueryVo"
resultType="User">
select * from user where username like #{user.username}
</select>
通过这个映射我们可以返回一个user对象。
但是resultType有一个缺点,就是pojo属性名必须与sql查询的列名一致才能映射成功。我们只有通过别名修改列名或者使用另一个映射字段,resultMap。
resultMap可以实现查询结果映射成复杂类型的pojo,比如一对一查询和一对多查询。
例:配置order和user的一对一查询。
<resultMap type="Order" id="oneToOne">
<id column="id" property="id" />
<result column="user_id" property="userId" />
<result column="number" property="number" />
<result column="createtime" property="createtime" />
<result column="note" property="note" />
<!-- association :配置一对一属性 -->
<!-- property:order里面的User属性名 -->
<!-- javaType:属性类型 -->
<association property="user" javaType="User">
<id column="user_id" property="id" />
<result column="username" property="username" />
<result column="address" property="address" />
</association>
</resultMap>
<select id="findOrderAndUser" resultMap="oneToOne">
SELECT
o.id,
o.user_id,
o.number,
o.createtime,
o.note,
u.username,
u.address
FROM
`orders` o
LEFT JOIN `user` u ON o.user_id = u.id
</select>
动态sql:
我们也可以通过一些标签来替代sql语句,以及做判断和循环操作。
1.if标签
通过if标签我们可以来判断该条件字段是否有值,如果没有则可以不进行显示,这样可以提高效率。例如:
<select id="findUserByUsernameAndSex" parameterType="QueryVo"
resultType="User">
select * from user
<where>
<if test="user.sex !=null and user.sex !=''">
and sex = #{user.sex}
</if>
<if test="user.username!=null and user.username!=''">
and username like #{user.username}
</if>
</where>
</select>
2.where标签
where标签会自动把内部为空的条件中的and/or忽略掉。
3.sql片段
我们可以将可复用的sql抽取出来,单独放入一个标签中。
例如:
<sql id="selector">
select * from user
</sql>
使用时直接在想要的位置引入标签及id。
例如:
<select id="findUserById" parameterType="Integer" resultType="User">
<include refid="selector" />
where id = #{id}
</select>
4.foreach标签
当想sql传递数组或list。可以使用foreach标签进行解析。
例如根据多个id查询用户信息。
<!-- 根据ids查询用户 -->
<select id="queryUserByIds" parameterType="queryVo" resultType="user">
SELECT * FROM `user`
<where>
<!-- foreach标签,进行遍历 -->
<!-- collection:遍历的集合,这里是QueryVo的ids属性 -->
<!-- item:遍历的项目,可以随便写,,但是和后面的#{}里面要一致 -->
<!-- open:在前面添加的sql片段 -->
<!-- close:在结尾处添加的sql片段 -->
<!-- separator:指定遍历的元素之间使用的分隔符 -->
<foreach collection="ids" item="item" open="id IN (" close=")"
separator=",">
#{item}
</foreach>
</where>
</select>