概述
说在前面
MyBatis在映射文件中加载关联关系对象主要通过两种方式:
嵌套查询和嵌套结果。
嵌套查询:
是指通过执行另外一条SQL映射语句来返回预期的复杂类型。
会执行多条sql语句
嵌套结果查询:
是使用嵌套结果映射来处理重复的联合结果的子集。
只会执行一条复杂的sql语句
简单来说:
嵌套查询是多条sql语句分开写并配置
嵌套结果是一条sql语句关联查询并配置
实质效果是一样的。
但嵌套查询会导致数据库访问次数不定,进而有可能影响到性能。
一对一查询
举例:人和身份证是一一对应的,满足一对一查询
pojo:
public class Person{
private String name;
private Integer id;
private String gender;
private Integer age;
private Card card;
//省略getter、setter
}
public class Card{
private Integer cid;
private String address; //住址
//省略getter、setter
}
- 数据库表字段与实体类属性对应,person表通过外键cid关联card表
需求:查询person时要求把card也查询出来
问题:数据库查询只能查询出card的字段,不能封装进person实体里的card属性
方法:编写resultMap,手动指定person表字段和实体属性的映射关系
1.嵌套结果查询
<resultMap id="personMap" type="Person"> <!-- type:实体类名,如不定义别名需写全类名 -->
<!--column是数据库表的字段名,property是实体的属性名-->
<id column="id" property="id"></id>
<result column="name" property="name"></result>
<result column="gender" property="gender"></result>
<result column="age" property="age"></result>
<!--封装card-->
<association property="card" javaType="Card"> <!--property:当前实体中的pojo属性 javaType:当前实体中的pojo属性的类型,此处已定义别名-->
<!--映射card属性-->
<id column="cid" property="cid"></id>
<result column="address" property="address"></result>
</association>
</resultMap>
<!--查询-->
<select id="findAll" resultMap="personMap">
select * from person p,card c where p.id = c.cid
</select>
2.还是嵌套结果查询,抽取出被映射的pojo,提高复用性
<resultMap type="Card" id="cardMap">
<id column="cid" property="cid"></id>
<result column="address" property="address"></result>
</resultMap>
<resultMap type="Person" id="personMap">
<id column="id" property="id"></id>
<result column="name" property="name"></result>
<result column="gender" property="gender"></result>
<result column="age" property="age"></result>
<association property="Card" resultMap="cardMap" /><!--association标签中通过resultMap="cardMap"引用-->
</result>
<!--嵌套结果:使用嵌套结果映射来处理重复的联合结果的子集-->
<select id="findAll" resultMap="personMap">
select * from person p,card c where p.id = c.cid
</select>
3.嵌套查询
<resultMap id="personMap" type="Person">
<id column="id" property="id"></id>
<result column="name" property="name"></result>
<result column="gender" property="gender"></result>
<result column="age" property="age"></result>
<!--association使用select属性引入另外一条SQL语句 -->
<association property="card"
javaType="Card"
column="cid" <!--引入另外定制sql的参数值,这里是person表里的外键cid-->
select="cn.wyu.mapper.CardMapper.findCardById"><!--通过findCardByPersonId方法查询出card映射到person实体中的card属性-->
</association>
</resultMap>
<select id="findAll" resultMap="personMap">
select * from person<!--因为在resultMap-->
</select>
一对多查询
举例:用户和订单,用户可以有多条订单,每条订单对应一个用户
pojo:
public class User{
private String username;
private Integer id;
private List<Order> orders; //一对多
//省略getter、setter
}
public class Order{
private Integer oid;
private Double money;
private private User user; //一条订单从属一个用户
//省略getter、setter
}
- 数据库表字段与实体类属性对应,order表通过外键uid关联user表
1.嵌套结果查询
userMapper.xml
<resultMap id="baseUserMapper" type="User"><!--User:别名-->
<id column = "id" property="id"/>
<result column = "username" property="usernmae"/>
</resultMap>
<resultMap id="userMapper" type="userMapper" extends="baseUserMapper"><!--extends:继承baseUserMapper,减少代码编写,利于维护-->
<!--一个用户有多条订单,使用collection标签-->
<collection property="orders" javaType="list" ofType="Order"><!--javaType:封装的是多条订单,是set类型 ofType:集合里的泛型,这里是Order-->
<id column="oid" property="oid"/>
<result column="money" property="money"/>
</collection>
</resultMap>
<!--查询-->
<select id="findAll" resultMap="userMapper">
select * from user left join order on user.id=order.uid
</select>
orderMapper.xml
<result id="baseOrderMapper" type="Order"><!--Order:别名-->
<id column="oid" property="oid">
<result column="money" property="money"/>
</result>
<result id="orderMapper" type="Order" extends="baseOrderMapper">
<!--一条订单从属一个用户,这里相当于是一对一查询-->
<association property="user" javaType="user">
<id column = "id" property="id"/>
<result column = "username" property="usernmae"/>
</association>
</result>
<!--查询-->
<select id="findAll" resultMap="orderMapper">
select * from order,user where order.uid = user.id
</select>
2.嵌套查询
userMapper.xml
<resultMap id="baseUserMapper" type="User"><!--User:别名-->
<id column = "id" property="id"/>
<result column = "username" property="usernmae"/>
</resultMap>
<resultMap id="userMapper" type="userMapper" extends="baseUserMapper">
<!--一个用户有多条订单,使用collection标签-->
<collection
property="orders"
javaType="list"
ofType="Order"
column="id" <!--这里是user表中的id-->
select="cn.wyu.mapper.OrderMapper.findOrderByUid">
</collection>
</resultMap>
<!--查询-->
<select id="findAll" resultMap="userMapper">
select * from user
</select>
orderMapper.xml
<result id="baseOrderMapper" type="Order"><!--Order:别名-->
<id column="oid" property="oid">
<result column="money" property="money"/>
</result>
<result id="orderMapper" type="Order" extends="baseOrderMapper">
<association
property="user"
javaType="user"
column="uid"
select="cn.wyu.mapper.userMapper.findUserByUid">
</association>
</result>
<!--查询-->
<select id="findAll" resultMap="orderMapper">
select * from order
</select>
多对多查询
举例:用户和角色,一个用户可以有多名角色,一个角色可以被多个用户使用
pojo:
public class User{
private Integer id;
private String username;
private List<Role> roles;
//省略getter、setter
}
public class Role{
private Integer id;
private String rolename;
private List<User> users ;
}
- 数据库表字段与实体类属性对应,还要一张维护user和role的中间表,字段是user和role的id,并且都是外键
由于用户和角色是多对多的关系,即它们是同一级别,这里只举出查询用户并对实体内部的角色属性实现映射的例子
userMapper.xml
1.嵌套结果查询
<resultMap id="baseUserMapper" type="User"><!--User是别名-->
<id column="id" property="id"/>
<result column="username" property="username"/>
</resultMap>
<resultMap id="userMapper" type="User" extends="baseUserMapper">
<collection property="roles" javaType="list" ofType="Role">
<id column="id" property="id">
<result column="rolename" property="rolename">
</collection>
</resultMap>
<select id="findAll" resultMaop="userMapper">
select * from (user u left join user_role ur on u.id=ur.uid) left join role r on r.id=ur.rid
</select>
2.嵌套查询
<resultMap id="baseUserMapper" type="User"><!--User是别名-->
<id column="id" property="id"/>
<result column="username" property="username"/>
</resultMap>
<resultMap id="baseRoleMapper" type="Role">
<id column="id" property="id">
<result column="rolename" property="rolename">
</resultMap>
<resultMap id="userMapper" type="User" extends="baseUserMapper">
<collection
property="roles"
javaType="list"
ofType="Role"
column="id" <!--同样是user表的id-->
select="cn.wyu.mapper.RoleMapper.findRoleListByUid">
</collection>
</resultMap>
<!--这里有必要贴一下findRoleListByUid方法的代码-->
<select id="findRoleListByUid" resultMap="baseRoleMapper" paramType="int">
select * from user_role ur,role r where ur.rid = r.id and ur.uid=#{uid}
</select>
<select id="findAll" resultMaop="userMapper">
select * from user
</select>
最后
以上就是怕黑电话为你收集整理的Mybatis基于xml的一对一、一对多、多对多嵌套结果查询和嵌套查询的全部内容,希望文章能够帮你解决Mybatis基于xml的一对一、一对多、多对多嵌套结果查询和嵌套查询所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复