【MyBatis】如何让用resultMap表示一张大表——多表查询

理解思路

之前学习的MyBatis查询中,查询的如果是单个实体/实体集合,那么就把结果类型resultType写为com.samarua.domain.User/user;查询的如果是某个单一的属性值,那么就把结果类型resultType写为java.lang.Integer/int…那么,如果是多表的联合查询,结果集是一大张联合后的表(大表的字段是Users和Orders的结合),结果类型resultType该怎么写呢?

通过两处巧妙的设计思路,就能优雅的转化掉这个问题:

(1)实体类的属性编写

假设一个Order订单只属于一个用户User,Orders表中的uid字段对应Users表的id字段,这就是一对一的关系。那么,我们在设计实体类Order时,不要这样写:

public class Order {

    private int id;
    private String ordertime;
    private double total;
	// 一个订单对应一个uid
    private int uid;

	//...
}

而是这样编写:

public class Order {

    private int id;
    private String ordertime;
    private double total;
	// 一个订单对应一个User
    private User user;

	//...
}

这样有一个好处,那就是我们可以将resultType改为resultMap并将值写为Order,那另一半联合表(即User)呢?正是Order实体的一个属性!!!

(2)表字段与实体属性的匹配

我们使用resultType时,表字段和实体属性是根据名称进行自动匹配的;而当我们使用resultMap时,需要我们手动将表字段(column)和实体属性(property)进行对应匹配——这种要求是合理的,因为多表联合成的大表,字段名众多,很难保证在sql与java二者中保持名称完全一致。

下面这个例子说明了如何包装出一个resultMap,并进行字段与属性的名称匹配:

<resultMap id="orderMap" type="order">
	<!-- column为查询结果的字段名,property为实体的属性名 -->
	<!-- id只是比result多了主键语义,不用过多纠结 -->
	<id column="id" property="id"/>
	<result column="ordertime" property="ordertime"/>
	<result column="total" property="total"/>
	<result column="uid" property="user.id"/>
	<result column="username" property="user.username"/>
	<result column="password" property="user.password"/>
	<result column="birthday" property="user.birthday"/>
</resultMap>

<select id="findAll" resultMap="orderMap">
	select * from orders o, users u where o.uid = u.id
</select>

或许在配置名称匹配时你会无从下手,这里有一个屡试不爽的技巧,即先在mysql中进行查询得到这张表的结构,再对照着这张大表的字段名,对应上实体属性名:

在这里插入图片描述

 
 
 

一对一查询

Demo:一个订单只属于一个用户
在这里插入图片描述

SQL查询及其结果:

select * from orders o, users u where o.uid = u.id

在这里插入图片描述

代码编写:

public class Order {

    private int id;
    private String ordertime;
    private double total;
	// 一个订单对应一个User
    private User user;

	//...
}
<!-- 写法1 -->
<resultMap id="orderMap" type="order">
	<id column="id" property="id"/>
	<result column="ordertime" property="ordertime"/>
	<result column="total" property="total"/>
	<result column="uid" property="user.id"/>-->
	<result column="username" property="user.username"/>
	<result column="password" property="user.password"/>
	<result column="birthday" property="user.birthday"/>
</resultMap>

<!-- 写法2 -->
<resultMap id="orderMap" type="order">
	<id column="id" property="id"/>
	<result column="ordertime" property="ordertime"/>
	<result column="total" property="total"/>
	<association property="user" javaType="user">
    	<result column="uid" property="id"/>
    	<result column="username" property="username"/>
   		<result column="password" property="password"/>
	    <result column="birthday" property="birthday"/>
    </association>
</resultMap>

<select id="findAll" resultMap="orderMap">
	select * from orders o, users u where o.uid = u.id
</select>

在这里插入图片描述

 
 
 

一对多查询

Demo:一个用户同时拥有多个订单
在这里插入图片描述

SQL查询及其结果:

select *, o.id oid from users u left join orders o on o.uid = u.id

在这里插入图片描述

代码编写:

public class User {

    private int id;
    private String username;
    private String password;
    private String birthday;

    // 一个用户拥有多个订单
    private List<Order> orderList;

	//...
}
<resultMap id="userMap" type="user">
	<id column="id" property="id"/>
	<result column="username" property="username"/>
	<result column="password" property="password"/>
	<result column="birthday" property="birthday"/>
	<collection property="orderList" ofType="order">
		<result column="oid" property="id"/>
		<result column="ordertime" property="ordertime"/>
		<result column="total" property="total"/>
	</collection>
</resultMap>
    
<select id="findAll" resultMap="userMap">
	select *, o.id oid from users u left join orders o on o.uid = u.id
</select>

在这里插入图片描述

 
 
 

多对多查询

Demo:一个用户拥有多个角色,多个用户也可能是同一个角色

在这里插入图片描述

SQL查询及其结果:

select * from users u, roles r, user_role_relation ur where ur.userid = u.id and ur.roleid = r.id

在这里插入图片描述

代码编写:

public class User {

    private int id;
    private String username;
    private String password;
    private String birthday;

    // 一个用户拥有多个角色
    private List<Role> roleList;

	//...
}
<resultMap id="userRoleMap" type="user">
	<id column="userid" property="id"/>
	<result column="username" property="username"/>
	<result column="password" property="password"/>
	<result column="birthday" property="birthday"/>
	<collection property="roleList" ofType="role">
		<id column="roleid" property="id"/>
		<result column="rolename" property="rolename"/>
		<result column="roledesc" property="roledesc"/>
	</collection>
</resultMap>

<select id="findUserRole" resultMap="userRoleMap">
	select * from users u, roles r, user_role_relation ur where ur.userid = u.id and ur.roleid = r.id
</select>

在这里插入图片描述

 
 
 

总结

一对一<resultMap>+<association>
一对多<resultMap>+<collection>
多对多<resultMap>+<collection>

 
 
 
 

 
 
 
 

 
 
 
 

More >_<

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值