一、一对一映射查询 返回值为ResultType
例如上面的Dao层接口方法返回值为List,泛型为返回值类型
二、一对一映射查询 返回值为resultMap
例如:当查询所有订单时,并要求查询出当前订单的用户,此时返回值不是一个简单类型,这是需要使用resultMap
<!-- 1对1映射之 resultMap -->
<!-- ............................................................ -->
<resultMap type=*"com.aishang.domain.OrdersExtRstMap"* id=*"ordersAndUserRstMap"*>
<id column=*"oid"* property=*"oid"*/>
<result column=*"total"* property=*"total"*/>
<result column=*"ordertime"* property=*"ordertime"*/>
<result column=*"uid"* property=*"uid"*/>
<!-- 用户信息 (1个订单1个用户)-->
<!-- association标签:1对1关联映射
property:关联信息查询出的结果,将要映射的扩展类中对象的属性名称
OrdersExtRstMap扩展类中,user对象属性承接用户信息
-->
<association property=*"user"* javaType=*"com.aishang.domain.User"*>
<!-- id标签,建议在关联查询时必须写上,不写不会报错,但会影响性能
<id column="下面SQL查询出来的列名" property="映射到User类的属性"/>
-->
<id column=*"uid"* property=*"uid"*/>
<result column=*"username"* property=*"username"*/>
<result column=*"name"* property=*"name"*/>
</association>
</resultMap>
<!-- ............................................................ -->
<select id=*"findOrdersAndUserRstMap"* resultMap=*"ordersAndUserRstMap"*>
<!-- sql没有变化 -->
select
orders.oid,
orders.total,
orders.ordertime,
orders.uid,
user.username,
user.name
from orders inner join user
on orders.uid = user.uid
</select>
总结;
resultType:使用ResultType实现比较简单,如果查询结果比较简单,没有特殊的对象封装,建议直接使用resultMap。这是一种平铺式的映射
resultMap:实现起来比较麻烦,但是可以将复杂的查询结果映射到对应的pojo对象的属性中。这是以重层叠式的映射
resultMap可以实现延迟加载,resultType无法实现延时加载。
三、动态sql
通过Mybatis提供的各种动态标签实现动态拼接sql,使得mapper映射文件在编写SQL时更加灵活,方便。常用动态SQL标签有:if、where、foreach;
If标签:作为判断入参来使用的,如果符合条件,则把if标签体内的SQL拼接上。
注意:用if进行判断是否为空时,不仅要判断null,也要判断空字符串‘’;
Where标签:会去掉条件中的第一个and符号。
动态SQL举例:
<!-- 综合查询:用户列表,根据用户的账户和密码进行查询,动态SQL
查询条件由用户来输入来决定,用户名称可以为空,密码也是 -->
<select id="findUserList" parameterType="UserWapper" resultType="user">
select * from user
<!-- where标签,默认去掉后面第一个"and"字符,如果没有参数传入,则把自己干掉 -->
<where>
<!-- if标签:可以对输入的参数进行判断 -->
<if test="user !=null">
<if test="user.username != null and user.username !='' ">
and username like '%${user.username}%'
</if>
<if test="user.password != null and user.password != '' ">
and password= #{user.password}
</if>
</if>
</where>
</select>
Mapper接口:
l 测试代码:
@Test
public void testFindUserList() {
SqlSession sqlSession = MybatisUtil.getSqlSession();
//由mybatis通过sqlSession生成Dao接口的代理对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
UserWapper vo = new UserWapper();
User user = new User();
user.setUsername("tom");
user.setPassword("123456");
vo.setUser(user);
List<User> list = mapper.findUserList(vo);
for(User u:list){
System.out.println(u);
}
sqlSession.close();
}
SQL片段:
Sql片段可以让代码有更高的可重用性,Sql片段需要先定义后使用。
<!-- 定义SQL片段 -->
<!-- sql片段内,可以定义任何部分, 最好不要将where和select关键字声明在内-->
<sql id="whereNameAndSexClause">
<!-- if标签:可以对输入的参数进行判断 -->
<if test="user !=null">
<if test="user.username != null and user.username !='' ">
and username like '%${user.username}%'
</if>
<if test="user.password != null and user.password != '' ">
and password= #{user.password}
</if>
</if>
</sql>
<!-- 综合查询:用户总数,根据用户的名称和性别进行查询
-->
<select id="findUserCount" parameterType="UserWapper" resultType="int">
select count(*) from user
<!-- 引入sql片段 -->
<where>
<!-- 引入sql片段 -->
<include refid="whereNameAndSexClause"></include>
</where>
</select>
forEach:
<!-- 综合查询:根据用户id的集合查询用户,修改包装类 -->
<!-- 定义sql片段 -->
<sql id="whereIDList">
<if test="idList != null">
<!-- select * from user where uid in (1,16,22),需要关注的部分是: and uid in (1,16,22)-->
<!-- collection表示pojo中集合属性的名称 -->
<!-- item:遍历过程中的临时变量 -->
<!-- open开始时需要拼接的字符串 -->
<!-- close遍历结束时需要拼接的字符串 -->
<!-- separator:遍历中需要连接的字符串 -->
and uid in
<foreach collection="idList" item="id"
open="(" close=")" separator=",">
#{id}
</foreach>
<!— 生成:and uid in (#{id},#{id},#{id}) -->
</if>
</sql>
<select id="findUserByIdList" parameterType="UserWapper" resultType="user">
select * from user
<where>
<include refid="whereIDList"></include>
</where>
</select>