SpringDataJPA(16)多表查询:对象导航查询

1.概述

对象导航查询:查询一个对象的同时,通过此对象聋询他的关联对象

在这里,将使用一对多里面所使用的配置进行示例

2. 测试对象查询

2.1 从一方查询多方

默认使用延迟加载

2.1.1 测试

测试类:

package cn.yy.test;

import cn.yy.dao.ManyCustomerDao;
import cn.yy.dao.ManyLinkManDao;
import cn.yy.domain.Customer;
import cn.yy.domain.LinkMan;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;

import java.util.Set;

/**
 * @author Marston
 * @date 2021/12/5
 */
@RunWith(SpringJUnit4ClassRunner.class)//声明spring提供的单元测试环境
@ContextConfiguration(locations = "classpath:applicationContext.xml")//指定spring容器的配置信息
public class OneToManyTestQuery {
    @Autowired
    private ManyCustomerDao manyCustomerDao;
    @Autowired
    private ManyLinkManDao manyLinkManDao;

    /**
     * 测试对象导航查询(查询一个对象的时候,通过此对象查询所有的关联对象)
     */
    @Test
    @Transactional//解决java代码中报错:could not initialize proxy - no Session
    public void testQuery1(){
        //查询id为1的客户
        Customer customer = manyCustomerDao.getOne(1l);
        //对象导航查询,此客户下的所有联系人
        Set<LinkMan> linkMans = customer.getLinkMans();
        for (LinkMan linkMan:linkMans){
            System.out.println(linkMan);
        }
    }

}

运行结果:

cs_linkman数据库表内容:
在这里插入图片描述
cst_customer数据库表中的数据
在这里插入图片描述
运行结果:
在这里插入图片描述

2.1.1 延迟加载

默认使用的是延迟加载,如果想要修改加载方式的话,想要修改实体类中的注释,在本例中,想要修改加载方式的话就需要对实体类Customer中对注释进行修改

/*
        放弃外键维护权:
            mappedBy:对方配置关系的属性名称
        cascade :配置级联( 可以配置到设置多表的映射关系的注解上)
                CascadeType.all:所有
                            MERGE:更新
                            PERSIST:保存
                            REMOVE:删除
         fetch :配置关联对象的加载方式
                EAGER   :  立即加载
                LAZY    :   延迟加载
     */
    @OneToMany(mappedBy =  "customer" ,cascade = CascadeType.ALL,fetch = FetchType.EAGER)
    private Set<LinkMan> linkMans = new HashSet<LinkMan>();

测试方法,该方法在2中的测试类中

/**
     * 对象导航查询:
     *      默认使用的是延迟加载的形式查询的
     *          调用get方法并不会立即发送查询,而是在使用关联对象的时候才会查询,这叫做延迟加载!
     *
     *      修改配置,将延迟加载改为立即加载
     *          fetch,需要配置到多表映射关系的注解上面
     */
    @Test
    @Transactional//解决java代码中报错:could not initialize proxy - no Session
    public void testQuery2(){
        //查询id为1的客户
        //之前的情况下getOne默认使用延迟加载的方式,findOne是使用立即加载的方式进行查询
        //但是在对象查询中,默认使用的都是延迟加载方式
        Customer customer = manyCustomerDao.findOne(1l);
        //对象导航查询,此客户下的所有联系人
        Set<LinkMan> linkMans = customer.getLinkMans();//默认是延迟加载,调用
        System.out.println(linkMans);
        for (LinkMan linkMan:linkMans){
            System.out.println(linkMan);
        }
    }

运行结果:

2.2 从多一方查询一的一方

默认使用立即加载

2.2.1 测试

测试方法,该方法在2中的测试类中

/**
     * 从联系人对象导航查询他的所属客户
     *      从多的一方去查询少的一方:默认使用立即加载
     *      使用配置修改需要找到查询主体:在这里是联系人,与之前的fetch使用方法一样,修改其属性便可以修改加载方式
     */
    @Test
    @Transactional//解决java代码中报错:could not initialize proxy - no Session
    public void testQuery3(){
        //查询id为1的客户
        LinkMan linkMan = manyLinkManDao.findOne(2l);
        //对象导航查询所属用户
        Customer customer = linkMan.getCustomer();
        System.out.println(customer);
    }

3. 总结

对于对象导航查询来说:

从一方查询多方

  1. 默认:使用延迟加载
  2. 关联对象是一个集合,集合便说明里面可能有许多数据,如果不需要使用所有的数据,就会照成极大的浪费效率,所以需要使用延迟加载

从多方查询一方

  1. 默认:使用立即加载
  2. 只是需要查询一个数据,所以使用立即加载
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

?abc!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值