Mybatis关联查询
Posted javajava
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mybatis关联查询相关的知识,希望对你有一定的参考价值。
mybatis实现表与表之间的查询,将查询的结果集进行映射(reslutType/resultMap高级映射)
1.首先分析表与表之间的关系.步骤如下:
1) 按模块去分析表,不要一次全部分析 2)了解每个表存储了什么业务数据 3)了解表中关键字段(主键/外键/索引字段/非空字段)
4) 了解表与表之间数据级别的关系(外键关系) 5)了解表与表之间的业务关系(一对一/一对多/多对多)
(一) 一对一查询
需求: 查询订单关联查询用户信息
1. resultType实现
1.1创建实体类继承orders
public class OrdersCustom extends Orders { //应该包括 订单及订单关联信息的属性 //由于继承订单类只需要添加一些关联属性 //用户信息 private String username; private String address; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; }
1.2 mapper.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">
<!-- namespace是mapper.java的全路径,底层是在类里selectOne("test.findBy..","张")-->
<mapper namespace="cn.itcast.mybatis.mapper.OrdersMapperCustom">
<!-- 查询订单关联查询用户 -->
<select id="findOrdersAndUserByResultType" resultType="cn.itcast.mybatis.po.OrdersCustom">
SELECT
orders.*,
user.username,
user.address
FROM
orders,
USER
WHERE orders.user_id = user.id
</select>
</mapper>
1.3 mapper.java
public interface OrdersMapperCustom { //一对一查询,查询订单关联查询用户 public List<OrdersCustom> findOrdersAndUserByResultType() throws Exception; }
2. resultMap实现
2.1实体类添加user对象
public class Orders { private Integer id; private Integer userId; private String number; private Date createtime; private String note; //创建订单的用户 private User user;
2.2 mapper.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="cn.itcast.mybatis.mapper.OrdersMapperCustom"> <!-- 查询订单及用户的resultMap type:查询结果集映射的java对象类型 --> <resultMap type="orders" id="ordersAndUserByResultMap"> <!-- 订单信息的映射配置 --> <!-- id:唯一标识 列 ,这里是订单信息的唯一标识 --> <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:将关联的用户信息映射到orders的哪个属性中 javaType:property对应的类型 --> <association property="user" javaType="cn.itcast.mybatis.po.User"> <!-- id:用户信息的唯一标识 result:用户信息列 property:将关联查询的列映射到user的哪个属性中 --> <id column="user_id" property="id"/> <result column="username" property="username"/> <result column="address" property="address"/> </association> </resultMap> <!-- 查询订单关联查询用户,使用resultMap --> <select id="findOrdersAndUserByResultMap" resultMap="ordersAndUserByResultMap"> SELECT orders.*, user.username, user.address FROM orders, USER WHERE orders.user_id = user.id </select> </mapper>
2.3 mapper.java
//一对一查询,使用resultMap public List<Orders> findOrdersAndUserByResultMap() throws Exception;
如果需要将关联查询的信息映射到pojo的pojo属性中, 为了获取数据方便,可以使用resultMap。
如果使用延迟加载,只能使用resultMap。
(二) 一对多查询
需求:查询订单关联查询明细信息
注意: association是映射到单个对象中,标签使用javaType映射对象类型
collection是映射到集合对象中,标签使用ofType映射对象类型.
1.1创建实体类继承orders
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;
1.2 mapper.xml
<!-- 查询订单关联查询明细resultMap extends:resultMap可以继承另一个resultMap,如果跨mapper,前边要加namespace --> <resultMap type="orders" id="ordersAndOrderDetailResultMap" extends="ordersAndUserByResultMap"> <!-- 映射订单信息和用户信息采用继承 --> <!-- 订单明细信息 collection:将关联信息映射到一个List集合对象中 property:要将关联信息映射到orders主对象中的哪个属性中 ofType:关联信息映射到一个List中对象类型 --> <collection property="orderdetails" ofType="cn.itcast.mybatis.po.Orderdetail"> <!-- id:订单明细的唯一标识 列 --> <id column="orderdetail_id" property="id"/> <result column="id" property="ordersId"/> <result column="items_id" property="itemsId"/> <result column="items_num" property="itemsNum"/> </collection> <!-- 一对多查询,查询订单关联查询明细 --> 注意:resultMap的值为上面的resultMap的id <select id="findOrdersAndOrderDetail" resultMap="ordersAndOrderDetailResultMap"> 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 orderdetail.orders_id = orders.id </select>
1.3 mapper.java
//一对多查询,查询订单及明细 public List<Orders> findOrdersAndOrderDetail()throws Exception;
(三) 多对多查询
需求: 查询用户信息及用户购买的商品信息
1.1 映射需求: 在user中设置一个List<Orders> orders属性,在order对象中设置List<Orderdetail> orderdeils 属性,在Orderdetail中设置Items属性。
最终查询出来的用户列表,用户信息映射到List<User>中.
1.2 mapper.xml
<!-- 查询用户及用户购买的商品信息 最终要将查询结果映射成List<User> --> <resultMap type="user" id="userAndItemsResultMap"> <!-- 用户信息 --> <id column="user_id" property="id"/> <result column="username" property="username"/> <result column="address" property="address"/> <!-- 订单信息 一个用户可以创建多个订单 --> <collection property="ordersList" ofType="cn.itcast.mybatis.po.Orders"> <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" /> <!-- 订单明细信息 一个订单包括多个明细信息 --> <collection property="orderdetails" ofType="cn.itcast.mybatis.po.Orderdetail"> <id column="orderdetail_id" property="id"/> <result column="id" property="ordersId"/> <result column="items_id" property="itemsId"/> <result column="items_num" property="itemsNum"/> <!-- 商品信息 一个明细对应一个商品 --> <association property="items" javaType="cn.itcast.mybatis.po.Items"> <id column="items_id" property="id"/> <result column="items_name" property="name"/> <result column="items_pic" property="pic"/> </association> </collection> </collection>
<!-- 多对多查询,查询用户及用户购买的商品信息 --> <select id="findUserAndItems" resultMap="userAndItemsResultMap"> SELECT orders.*, user.username, user.address, orderdetail.id orderdetail_id, orderdetail.items_id, orderdetail.items_num, items.name items_name, items.pic items_pic FROM orders, USER, orderdetail, items WHERE orders.user_id = user.id AND orderdetail.orders_id = orders.id AND items.id = orderdetail.items_id </select>
1.3 mapper.java
//多对多查询,查询用户及用户购买订单 public List<User> findUserAndItems()throws Exception;
(四) 延迟加载
1.1 需求:查询订单关联查询用户信息,对关联查询用户信息延迟加载:也就是只加载订单,点击查询用户是再加载用户信息.(尽量从单表中查询)
1.2 在SqlMapConfig.xml中.
<!-- 通过setting配置mybatis的运行参数 注意,设置运行参数会影响 mybatis的运行,一定要注意! --> <settings> <!-- 延迟加载的总开关 --> <setting name="lazyLoadingEnabled" value="true"/> <!-- 设置为false实现按需求加载 --> <setting name="aggressiveLazyLoading" value="false"/> </settings>
1.3 mapper.xml sql语句:单表查询:select*from orders
<!-- 查询订单延迟加载 用户--> <resultMap type="orders" id="ordersLazyLoadingUserResultMap"> <!-- 订单信息映射 --> <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" /> <!-- 一个订单只能由一个用户,延迟加载用户信息 select就是延迟加载的sql语句,指定sql所在statement的id userMapper.xml中sql,namespace.id column:关联查询的列,这里就是orders表中外键user_id(SELECT * FROM USER WHERE id=orders.user_id) --> <association property="user" javaType="cn.itcast.mybatis.po.User" select="cn.itcast.mybatis.mapper.UserMapper.findUserById" column="user_id"> </association> </resultMap> <!-- 查询订单关联查询用户实现延迟加载 --> <select id="findOrdersLazyLoadingUser" resultMap="ordersLazyLoadingUserResultMap"> <!-- 查询订单的sql --> select * from orders </select>
1.4 mapper.java
//查询订单延迟加载用户信息 public List<Orders> findOrdersLazyLoadingUser()throws Exception;
ResultMap提供延迟加载,通过association 可以延迟加载一个对象,collection可以延迟加载多个对象.即集合对象.
以上是关于Mybatis关联查询的主要内容,如果未能解决你的问题,请参考以下文章