您的位置:首页 > 其它

【MyBatis框架点滴】——MyBatis一对一查询

2016-06-03 16:40 591 查看
  前面介绍的都是对单表进行查询,但实际业务中肯定会涉及到多张表,下面开始总结在MyBatis中的一对一、一对多、多对多的高级查询。

  就根据最常见的订单业务来分析这几种情况:

    


  如上图订单和用户的关系,一个用户可以对应多个订单,但是一个订单只能属于一个用户,所以对于订单来说,它跟用户之间的关系就是一对一,也就是根据一个订单只能查询出一个对应的用户来。下面说一下MyBatis中的一对一查询。

用resultMap返回指定类型

  代码如下:

  User.java

public class User implements Serializable {
private int id;//用户id
private String username;//用户名
private int sex;//性别
private Date birthday;//出生日期
private String address;//地址
//getter、setter
}


  Orders.java

public class User implements Serializable {
private Integer id;//订单id
private Integer userId;//所属用户id
private String number;//订单号
private Date createtime;//创建时间
private String note;//订单备注
private User user;//所属用户
//getter、setter
}


  OrdersMapper.xml

<?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="com.danny.mybatis.mapper.OrdersMapper" >

<!-- 订单关联用户的resultMap-->
<resultMap type="com.danny.mybatis.po.Orders" id="OrdersUserResultMap">
<!-- 配置映射的订单信息 -->
<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="user" javaType="com.danny.mybatis.po.User">
<id column="user_id" property="id"/>
<result column="username" property="username"/>
<result column="sex" property="sex"/>
<result column="address" property="address"/>
</association>
</resultMap>

<select id="findOrdersUserResultMap" resultMap="OrdersUserResultMap" >
select
orders.*,
user.username,
user.sex,
user.address
from orders,user
where orders.user_id=user.id
</select>
</mapper>


  resultMap的配置是这种方式查询的关键部分。resultMap的type表示查询的主体,比如这里要查询的主体是订单(顺便把关联的用户信息也查出来)。association表示用于映射单个关联对象的信息,它的property属性值表示要将关联查询的实体(用户)映射到主体(订单)中哪个属性。

  mapper接口:

public interface OrdersMapper{
List<Orders> findOrdersUserResultMap() throws Exception;
}


  测试:

@Test
public void findOrdersUserResultMap(){

SqlSession sqlSession=sqlSessionFactory.openSession();
OrdersMapper ordersMapper=sqlSession.getMapper(OrdersMapper.class);
try {
List<Orders> list=ordersCustomMapper.findOrdersUserResultMap();
if (list!=null) {
System.out.println(list.size());
}
} catch (Exception e) {
e.printStackTrace();
}
}


用resultType返回指定类型

  用resultType返回指定类型,需要添加一个组合实体OrdersCustom.java,它要包含查询出的用户和订单的所有字段。为了减少代码重复,可以让它继承User.java或者Orders.java中字段较多的一个实体,这里让它继承Orders,如下:

public class OrdersCustom extends Orders{
//添加User的属性
private String username;
private int sex;
private String address;
//getter、setter
}


  映射文件:

<select id="findOrdersUser" resultType="com.danny.mybatis.po.OrdersCustom" >
select
orders.*,
user.username,
user.sex,
user.address
from orders,user
where orders.user_id=user.id
</select>


  mapper接口:

public interface OrdersMapperCustom {
List<OrdersCustom> findOrdersUser() throws Exception;
}


  测试:

@Test
public void findOrdersUser(){

SqlSession sqlSession=sqlSessionFactory.openSession();
OrdersMapperCustom ordersCustomMapper=sqlSession.getMapper(OrdersMapperCustom.class);
try {
List<OrdersCustom> list=ordersCustomMapper.findOrdersUser();
if (list!=null) {
System.out.println(list.size());
}
} catch (Exception e) {
e.printStackTrace();
}
}


总结

  上面两种方法中,个人认为使用resultType定义输出映射比较简单,只需要添加一个po即可,补充多出的属性,即可完成映射。

  相对于第二种方法,使用resultMap麻烦一些,需要定义配置resultMap来映射与之关联的实体机器属性。虽然麻烦,但它的好处就是可以实现延迟加载~当然,如果没有特殊要求,可以使用第二种方法~

【 转载请注明出处——胡玉洋《【MyBatis框架点滴】——MyBatis一对一查询》
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息