进阶:高级映射
跳到导航
跳到搜索
关于
标签 | 说明 |
---|---|
association | 将关联查询信息映射到一个pojo对象中
|
collection | 将关联查询信息映射到一个list集合中
|
一对一
示例:查询所有订单信息,关联查询下单用户信息。
note:
- 订单->用户:一对一
- 用户->订单:一对多
使用resultType
使用resultType,专门的po类作为输出类型,此po类中包括了订单信息和用户信息:
OrdersCustom.java:
public class OrdersCustom extends Orders {
private String username;// 用户名称
private String address;// 用户地址
// get/set
}
OrdersMapperCustom.xml:
<!-- 查询所有订单信息 -->
<select id="findOrdersList" resultType="OrdersCustom">
SELECT orders.*, user.username, user.address
FROM orders, user
WHERE orders.user_id = user.id
</select>
OrdersMapperCustom.java:
public List<OrdersCustom> findOrdersList() throws Exception;
OrdersMapperCustomTest.java:
Public void testfindOrdersList()throws Exception{
//获取session
SqlSession session = sqlSessionFactory.openSession();
//获限mapper接口实例
UserMapper userMapper = session.getMapper(UserMapper.class);
//查询订单信息
List<OrdersCustom> list = userMapper.findOrdersList();
System.out.println(list);
//关闭session
session.close();
}
使用resultMap
使用resultMap,定义专门的resultMap用于映射一对一查询结果:
- 在resultMap中使用association完成关联查询,将关联查询信息映射到pojo对象中。
Orders.java:
public class Orders {
private Integer id;
private Integer userId;
private String number;
private Date createtime;
private String note;
//用户信息
private User user;
...
}
OrdersMapperCustom.xml:
<!-- 订单信息resultmap -->
<resultMap type="cn.itcast.mybatis.po.Orders" id="userordermap">
<!-- 这里的id,是mybatis在进行一对一查询时将user字段映射为user对象时要使用,必须写 -->
<id property="id" column="id"/>
<result property="user_id" column="user_id"/>
<result property="number" column="number"/>
<!-- 使用association进行一对一关联查询 -->
<association property="user" javaType="cn.itcast.mybatis.po.User">
<!-- 这里的id为user的id,如果写上表示给user的id属性赋值 -->
<id property="id" column="user_id"/>
<result property="username" column="username"/>
<result property="address" column="address"/>
</association>
</resultMap>
<!-- 查询所有订单信息 -->
<select id="findOrdersListResultMap" resultType="userordermap">
SELECT orders.*, user.username, user.address
FROM orders, user
WHERE orders.user_id = user.id
</select>
- association:表示进行关联查询单条记录;
- property:表示关联查询的结果存储在cn.itcast.mybatis.po.Orders的user属性中;
- javaType:表示关联查询的结果类型;
OrdersMapperCustom.java:
public List<Orders> findOrdersListResultMap() throws Exception;
OrdersMapperCustomTest.java:
Public void testfindOrdersListResultMap()throws Exception{
//获取session
SqlSession session = sqlSessionFactory.openSession();
//获限mapper接口实例
UserMapper userMapper = session.getMapper(UserMapper.class);
//查询订单信息
List<Orders> list = userMapper.findOrdersListResultMap();
System.out.println(list);
//关闭session
session.close();
}
一对多
示例:查询所有订单信息及订单下的订单明细信息。
- 使用resultMap实现
note:
- 订单->订单明细:一对多
Orders.java:
- 在Orders类中加入List<Orderdetail> orderdetails属性;
public class Orders {
private Integer id;
private Integer userId;
private String number;
private Date createtime;
private String note;
//用户信息
private User user;
//订单明细
private List<Orderdetail> orderdetails;
OrdersMapperCustom.xml:
- 不使用继承时:
<!-- 订单信息resultmap --> <resultMap type="cn.itcast.mybatis.po.Orders" id="userorderdetailmap"> <id property="id"column="id"/> <result property="user_id" column="user_id"/> <result property="number" column="number"/> <!-- 使用association进行一对一关联查询 --> <association property="user" javaType="cn.itcast.mybatis.po.User"> <id property="id" column="user_id"/> <result property="username" column="username"/> <result property="address" column="address"/> </association> <!-- 使用collection进行一对多关联查询 --> <collection property="orderdetails" ofType="cn.itcast.mybatis.po.Orderdetail"> <id property="id" column="orderdetail_id"/> <result property="items_id" column="items_id"/> <result property="items_num" column="items_num"/> </collection> </resultMap> <!-- 查询所有订单详情 --> <select id="findOrdersDetailList" resultMap="userorderdetailmap"> SELECT orders.*, user.username, user.address, orderdetail.id orderdetail_id, orderdetail.items_id, orderdetail.items_num FROM orders,user,orderdetail WHERE orders.user_id = user.id AND orders.id = orderdetail.orders_id </select>
- 使用继承,将collection写在单独的resultMap:
<!-- 订单信息resultmap:使用继承 --> <resultMap type="cn.itcast.mybatis.po.Orders" id="userorderdetailmap"> <id property="id"column="id"/> <result property="user_id" column="user_id"/> <result property="number" column="number"/> <!-- 使用association进行一对一关联查询 --> <association property="user" javaType="cn.itcast.mybatis.po.User"> <id property="id" column="user_id"/> <result property="username" column="username"/> <result property="address" column="address"/> </association> </resultMap> <!-- 使用collection进行一对多关联查询 --> <!-- 继承自:"userordermap" --> <resultMap type="cn.itcast.mybatis.po.Orders" id="userorderdetailmap" extends="userordermap"> <collection property="orderdetails" ofType="cn.itcast.mybatis.po.Orderdetail"> <id property="id" column="orderdetail_id"/> <result property="items_id" column="items_id"/> <result property="items_num" column="items_num"/> </collection> </resultMap> <!-- 查询所有订单详情 --> <select id="findOrdersDetailList" resultMap="userorderdetailmap"> SELECT orders.*, user.username, user.address, orderdetail.id orderdetail_id, orderdetail.items_id, orderdetail.items_num FROM orders,user,orderdetail WHERE orders.user_id = user.id AND orders.id = orderdetail.orders_id </select>
- extends:继承resultMap信息自userordermap;
- collection:表示关联查询结果集;
- property:关联查询的结果集存储在cn.itcast.mybatis.po.Orders上哪个属性。
- ofType:指定关联查询的结果集中的对象类型即List中的对象类型。
OrdersMapperCustom.java:
public List<Orders>findOrdersDetailList () throws Exception;
OrdersMapperCustom.java:
Public void testfindOrdersDetailList()throws Exception{
//获取session
SqlSession session = sqlSessionFactory.openSession();
//获限mapper接口实例
UserMapper userMapper = session.getMapper(UserMapper.class);
//查询订单信息
List<Orders> list = userMapper.findOrdersDetailList();
System.out.println(list);
//关闭session
session.close();
}
多对多
示例:查询用户购买的商品信息。
- 使用resultMap实现
- 一对多是多对多的特例
note:
- 用户->商品信息:多对多
- 需要查询所有用户信息,关联查询订单及订单明细信息,订单明细信息中关联查询商品信息
Orders.java:
- 在User中添加List<Orders> orders 属性;
public class User implements Serializable { private int id; private String username; private String sex; private Date birthday; private String address; //用户创建的订单列表 private List<Orders> ordersList;
- 在Orders类中加入List<Orderdetail> orderdetails属性
public class Orders { private Integer id; private Integer userId; private String number; private Date createtime; private String note; //用户信息 private User user; //订单明细 private List<Orderdetail> orderdetails;
OrdersMapperCustom.xml:
需要关联查询映射的信息是:订单、订单明细、商品信息:
- 订单:一个用户对应多个订单,使用collection映射到用户对象的订单列表属性中
- 订单明细:一个订单对应多个明细,使用collection映射到订单对象中的明细属性中
- 商品信息:一个订单明细对应一个商品,使用association映射到订单明细对象的商品属性中。
<!-- resultMap:查询用户购买的商品信息 -->
<resultMap type="cn.itcast.mybatis.po.User" id="userOrderListResultMap">
<id column="user_id" property="id"/>
<result column="username" property="username"/>
<!-- 一对多查询:用户-订单 -->
<collection property="orders" ofType="cn.itcast.mybatis.po.Orders">
<id column="id" property="id"/>
<result property="number" column="number"/>
<!-- 一对多查询:订单-订单明细 -->
<collection property="orderdetails" ofType="cn.itcast.mybatis.po.Orderdetail">
<id column="orderdetail_id" property="id"/>
<result property="ordersId" column="id"/>
<result property="itemsId" column="items_id"/>
<result property="itemsNum" column="items_num"/>
<!-- 一对一查询:订单明细-商品 -->
<association property="items" javaType="cn.itcast.mybatis.po.Items">
<id column="items_id" property="id"/>
<result column="items_name" property="name"/>
<result column="items_detail" property="detail"/>
</association>
</collection>
</collection>
</resultMap>
延迟加载
需要查询关联信息时,使用mybatis延迟加载特性可有效的减少数据库压力,首次查询只查询主要信息,关联信息等用户获取时再加载。
开启延迟加载
设置项 | 描述 | 允许值 | 默认值 |
---|---|---|---|
lazyLoadingEnabled | 全局性设置懒加载。如果设为‘false’,则所有相关联的都会被初始化加载。 | true | false | false |
aggressiveLazyLoading | 当设置为‘true’的时候,懒加载的对象可能被任何懒属性全部加载。否则,每个属性都按需加载。 | true | false | true |
在SqlMapConfig.xml中配置:
<settings>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
一对一延迟加载
示例:查询订单信息,关联查询用户信息:
- 默认只查询订单信息,当需要查询用户信息时再去查询用户信息。
Orders.java:
- 在Orders类中加入User属性;
public class Orders {
private Integer id;
private Integer userId;
private String number;
private Date createtime;
private String note;
//用户信息
private User user;
OrdersMapperCustom.xml:
<!-- 延迟加载的resultMap -->
<resultMap type="cn.itcast.mybatis.po.Orders" id="OrdersUserLazyLoadingResultMap">
<!--对订单信息进行映射配置 -->
<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="cn.itcast.mybatis.po.User"
select="cn.itcast.mybatis.mapper.UserMapper.findUserById" column="user_id">
</association>
</resultMap>
<!-- 查询订单关联查询用户,用户信息需要延迟加载 -->
<select id="findOrdersUserLazyLoading" resultMap="OrdersUserLazyLoadingResultMap">
SELECT * FROM orders
</select>
- select:指定延迟加载需要执行的statement的id“cn.itcast.mybatis.mapper.UserMapper.findUserById”;
<!-- 通过id查询用户表的记录 --> <select id="findUserById" parameterType="int" resultType="user"> SELECT * FROM USER WHERE id=#{value} </select>
- column:关联查询时,将“column”的值传入延迟关联的statement;
- 最后将关联查询结果映射至“cn.itcast.mybatis.po.User”;
- 关联查询的sql理解为:
SELECT orders.*, (SELECT username FROM USER WHERE orders.user_id = user.id)username, (SELECT sex FROM USER WHERE orders.user_id = user.id)sex FROM orders
OrdersMapperCustom.java:
public List<Orders> findOrdersUserLazyLoading()throws Exception;
OrdersMapperCustomTest.java:
public void testFindOrdersUserLazyLoading() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();// 创建代理对象
OrdersMapperCustom ordersMapperCustom = sqlSession.getMapper(OrdersMapperCustom.class);
// 查询订单信息(单表)
List<Orders> list = ordersMapperCustom.findOrdersUserLazyLoading();
// 遍历上边的订单列表
for (Orders orders : list) {
// 执行getUser()去查询用户信息,这里实现按需加载
User user = orders.getUser();
System.out.println(user);
}
}
一对多延迟加载
(略,同一对一延迟加载)