Mybatis深入学习
一、resultMap
1.1 resultMap作用
resultType可以指定pojo将查询结果映射为pojo,但需要pojo的属性名和sql查询的列名一致方可映射成功。
如果sql查询字段名和pojo的属性名不一致,可以通过resultMap将字段名和属性名作一个对应关系 ,resultMap实质上还需要将查询结果映射到pojo对象中。
resultMap可以实现将查询结果映射为复杂类型的pojo,比如在查询结果映射对象中包括pojo和list实现一对一查询和一对多查询。
1.2 定义resultMap
id :此属性表示查询结果集的唯一标识,非常重要。如果是多个字段为复合唯一约束则定义多个<id />。也即主键约束。
Property:表示User类的属性。
Column:表示sql查询出来的字段名。
Column和property放在一块儿表示将sql查询出来的字段映射到指定的pojo类属性上。
<result />:普通结果,即pojo的属性
<resultMap id="BaseResultMap" type="cn.lx.crm.po.BaseDict" >
<id column="dict_id" property="dictId" jdbcType="VARCHAR" />
<result column="dict_type_code" property="dictTypeCode" jdbcType="VARCHAR" />
<result column="dict_type_name" property="dictTypeName" jdbcType="VARCHAR" />
<result column="dict_item_name" property="dictItemName" jdbcType="VARCHAR" />
</resultMap>
二、动态SQL
2.1 if
if一般用于添加条件,根据不同的选择,拼接不同的sql语句,注意要进行非空判断
<if test="dictEnable != null" >
adn dict_enable = #{dictEnable,jdbcType=CHAR}
</if>
<if test="dictMemo != null " >
adn dict_memo = #{dictMemo,jdbcType=VARCHAR}
</if>
2.2 where
where的也是用于添加条件,可以自动处理第一个and,一般where要和if一起使用
<!--
where 动态sql语句类似于 where 1=1 可以自动处理第一个and
if 条件判断,可以判断传进来的参数是否符合 -->
<where>
<if test="dictEnable != null" >
adn dict_enable = #{dictEnable,jdbcType=CHAR}
</if>
<if test="dictMemo != null " >
adn dict_memo = #{dictMemo,jdbcType=VARCHAR}
</if>
</where>
2.3 foreach
向sql传递数组或List,mybatis使用foreach解析、
SELECT * FROM USERS WHERE username LIKE ‘%张%’ id IN (10,89,16)
select * from user
<!--
where 动态sql语句类似于 where 1=1 可以自动处理第一个and
if 条件判断,可以判断传进来的参数是否符合
foreach 用于遍历集合,如果传进来的参数是集合的形式的话
open 表示开始 close 表示结束 集合中的参数写在中间
item用于表示参数
separator表示参数之间的分隔符
-->
<where>
<if test="ids!=null and ids.size>0">
<foreach collection="ids" open="and id in (" close=")" item="id"
separator=",">
#{id}
</foreach>
</if>
</where>
2.3 choose when otherwise
这个的作用类似于switch,表示只能选择一个,只能有一个成立
<choose >
<when test="criterion.noValue" >
and ${criterion.condition}
</when>
<when test="criterion.singleValue" >
and ${criterion.condition} #{criterion.value}
</when>
<otherwise>
${criterion.condition}
</otherwise>
</choose>
2.3 sql片段
Sql中可将重复的sql提取出来,使用时用include引用即可,最终达到sql重用的目的,如下:
<!-- 传递pojo综合查询用户信息 -->
<select id="findUserList" parameterType="user" resultType="user">
select * from user
<where>
<if test="id!=null and id!=''">
and id=#{id}
</if>
<if test="username!=null and username!=''">
and username like '%${username}%'
</if>
</where>
</select>
将where条件抽取出来:
<sql id="query_user_where">
<if test="id!=null and id!=''">
and id=#{id}
</if>
<if test="username!=null and username!=''">
and username like '%${username}%'
</if>
</sql>
使用include引用:
<select id="findUserList" parameterType="user" resultType="user">
select * from user
<where>
<include refid="query_user_where"/>
</where>
</select>
注意:如果引用其它mapper.xml的sql片段,则在引用时需要加上namespace,如下:
<include refid="namespace.sql片段”/>
3 关联查询
3.1 一对一关联
一个订单对应一个用户(也相当与多对一的关系)
PO类Orders中有一个 private User user;成员变量
1、传统方法
定义一个po类,接收所有的返回结果
SELECT
orders.*,
user.username,
userss.address
FROM
orders,
user
WHERE orders.user_id = user.id
<!-- 查询所有订单信息 -->
<select id="findOrdersList" resultType="cn.itcast.mybatis.po.OrdersCustom">
SELECT
orders.*,
user.username,
user.address
FROM
orders, user
WHERE orders.user_id = user.id
</select>
2、使用resultMap的方式
association:表示进行关联查询单条记录
property:表示关联查询的结果存储在cn.itcast.mybatis.po.Orders的user属性中
javaType:表示关联查询的结果类型
<id property="id" column="user_id"/>:查询结果的user_id列对应关联对象的id属性,这里是<id />表示user_id是关联查询对象的唯一标识。
<result property="username" column="username"/>:查询结果的username列对应关联对象的username属性。
<!-- 查询订单关联用户信息使用resultmap -->
<resultMap type="Orders" id="orderUserResultMap">
<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"/>
<!-- 一对一关联映射 -->
<!--
property:Orders对象的user属性
javaType:user属性对应 的类型
-->
<association property="user" javaType="cn.itcast.po.User">
<!-- column:user表的主键对应的列 property:user对象中id属性-->
<id column="id" property="id"/>
<result column="username" property="username"/>
<result column="address" property="address"/>
</association>
</resultMap>
<select id="findOrdersWithUserResultMap" resultMap="orderUserResultMap">
SELECT
o.id,
o.user_id,
o.number,
o.createtime,
o.note,
u.username,
u.address
FROM
orders o
JOIN `user` u ON u.id = o.user_id
</select>
3.2 多对一关联
一个用户对应多个订单,在User PO类中private List orders = new ArrayList();//一对多关系配置
<resultMap type="user" id="userOrderResultMap">
<!-- 用户信息映射 -->
<id property="id" column="id"/>
<result property="username" column="username"/>
<result property="birthday" column="birthday"/>
<result property="sex" column="sex"/>
<result property="address" column="address"/>
<!-- 一对多关联映射 -->
<collection property="orders" ofType="orders">
<id property="id" column="oid"/>
<!--用户id已经在user对象中存在,此处可以不设置-->
<result property="userId" column="user_id"/>
<result property="number" column="number"/>
<result property="createtime" column="createtime"/>
<result property="note" column="note"/>
</collection>
</resultMap>
<select id="getUserOrderList" resultMap="userOrderResultMap">
SELECT
u.*, o.id oid,
o.number,
o.createtime,
o.note
FROM
`user` u
LEFT JOIN orders o ON u.id = o.user_id
</select>
collection部分定义了用户关联的订单信息。表示关联查询结果集
property="orders":关联查询的结果集存储在User对象的上哪个属性。
ofType="orders":指定关联查询的结果集中的对象类型即List中的对象类型。此处可以使用别名,也可以使用全限定名。
<id />及<result/>的意义同一对一查询。