五、级联查询
-
-
订单表orders:记录了用户所创建的订单(购买商品的订单)
-
订单明细表orderdetail:记录了订单的详细信息即购买商品的信息
-
注意:因为一个订单信息只会是一个人下的订单,所以从查询订单信息出发关联查询用户信息为一对一查询。如果从用户信息出发查询用户下的订单信息则为一对多查询,因为一个用户可以下多个订单。
使用association和collection 完成 订单<--->人一对一关联查询和订单<---->订单明细的一对多查询,将关联查询信息映射到pojo对象中。使用resultMap,定义专门的resultMap用于映射一对一查询结果。
/** * 订单信息 */ @Data @ToString public class Orders { private Integer id; private String number; private Date createtime; private String note; private User user; private List<OrderDetail> orderDetails; }
-
Mapper.xml
<!--一对一级联查询--> <resultMap id="userordermap" type="com.jdy.mybatis2020.bean.Orders"> <result property="number" column="number"/> <association property="user" javaType="com.jdy.mybatis2020.bean.User"> <id property="id" column="user_id"/> <result property="username" column="username"/> </association>
<!--一对多查询-->
<collection property="orderDetails" ofType="com.jdy.mybatis2020.bean.OrderDetail"> <association property="items" javaType="com.jdy.mybatis2020.bean.Items"> <result property="name" column="name"/> <result property="detail" column="detail"/> </association> </collection> </resultMap> <select id="findOrdersMap" resultMap="userordermap"> SELECT USER .id, USER .username, orders.number, items.name, items.detail FROM orders, USER, orderdetail, items WHERE orders.user_id = USER .id AND orders.id = orderdetail.orders_id AND orderdetail.items_id = items.id AND user.id = #{id} </select>
- association:表示进行关联查询单条记录
- property:表示关联查询的结果存储在Orders的user属性中。
- javaType:表示关联查询的结果类型
- collection:表示关联查询结果集
- property="orderDetails":关联查询的结果集存储在com.jdy.mybaties2020.bean.Orders上哪个属性。
- ofType="com.jdy.mybaties2020.bean.OrderDetail":指定关联查询的结果集中的对象类型即List中的对象类型。
测试
public class Test_02 { public static final String RESOURCE = "mybatis-config/mybatis-config_01.xml"; private SqlSessionFactory sqlSessionFactory; @Before public void createFactory() { sqlSessionFactory = SqlSessionFactoryUtil.createFactory(RESOURCE); } /** * association */ @Test public void test_Method00() { SqlSession sqlSession = sqlSessionFactory.openSession(); SelectMapperDao dao = sqlSession.getMapper(SelectMapperDao.class); List<Map<String, Object>> ordersMap = dao.findOrdersMap("3"); System.out.println("ordersMap = " + JSON.toJSONString(ordersMap)); } }
resultType:
-
-
作用:将查询结果按照sql列名pojo属性名一致性映射到pojo中。
-
场合:常见一些明细记录的展示,比如用户购买商品明细,将关联查询信息全部展示在页面时,此时可直接使用resultType将每一条记录映射到pojo中,在前端页面遍历list(list中是pojo)即可。
-
resultMap: 使用association和collection完成一对一和一对多高级映射(对结果有特殊的映射要求)。
association:
-
-
作用:将关联查询信息映射到一个pojo对象中。
-
场合:为了方便查询关联信息可以使用association将关联订单信息映射为用户对象的pojo属性中。
-
collection:
-
作用:将关联查询信息映射到一个list集合中。
-
场合:为了方便查询遍历关联信息可以使用collection将关联信息映射到list集合中。
三、分段查询&延迟加载&
3.1、分段查询
- select:调用目标的方法查询当前属性的值
- column:将指定列的值传入目标方法
mapper.xml
<!-- 订单信息resultmap --> <resultMap type="com.jdy.mybatis2020.bean.Orders" id="userordermap2"> <id property="id" column="id"/> <result property="number" column="number"/> <association property="user" javaType="com.jdy.mybatis2020.bean.User" select="user.findUserById" column="user_id"/> </resultMap> <select id="findOrdersList3" resultMap="userordermap2"> SELECT orders.* FROM orders where id = #{id}; </select>
分步查询的时候通过column指定,将对应的列的数据传递过去,我们有时需要传递多列数据。使用column ="{key1=column1,key2=column2…}"的形式。
3.1、打开延迟加载
resultMap可以实现高级映射(使用association、collection实现一对一及一对多映射),association、collection具备延迟加载功能。
在mybatis核心配置文件中配置: lazyLoadingEnabled、aggressiveLazyLoading
设置项 | 描述 | 允许值 | 默认值 |
---|---|---|---|
lazyLoadingEnabled | 全局性设置懒加载。如果设为‘false’,则所有相关联的都会被初始化加载。 | true/false | false |
aggressiveLazyLoading | 当设置为‘true’的时候,懒加载的对象可能被任何懒属性全部加载。否则,每个属性都按需加载。 | true/false | false |
mybatis-config_01.xml
<settings> <!-- 打开延迟加载 的开关 --> <setting name="lazyLoadingEnabled" value="true"/> <!-- 将积极加载改为消极加载即按需要加载 --> <setting name="aggressiveLazyLoading" value="false"/> </settings>
<!-- 订单信息resultmap --> <resultMap type="com.jdy.mybatis2020.bean.Orders" id="userordermap2"> <id property="id" column="id"/> <result property="number" column="number"/> <association fetchType="lazy" property="user" javaType="com.jdy.mybatis2020.bean.User" select="user.findUserById" column="user_id"/> </resultMap> <select id="findOrdersList3" resultMap="userordermap2"> SELECT orders.* FROM orders where id = #{id}; </select>
association或者collection标签的 fetchType=eager/lazy可以覆盖全局的延迟加载策略, 指定立即加载(eager)或者延迟加载(lazy)
延迟加载小结
作用:当需要查询关联信息时再去数据库查询,默认不去关联查询,提高数据库性能。 只有使用resultMap支持延迟加载设置。
场合:
当只有部分记录需要关联查询其它信息时,此时可按需延迟加载,需要关联查询时再向数据库发出sql,以提高数据库性能。
当全部需要关联查询信息时,此时不用延迟加载,直接将关联查询信息全部返回即可,可使用resultType或resultMap完成映射。