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 DDKK.COM 弟弟快看,程序员编程资料站
* @date 2022/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. 总结
对于对象导航查询来说:
从一方查询多方
默认:使用延迟加载
关联对象是一个集合,集合便说明里面可能有许多数据,如果不需要使用所有的数据,就会照成极大的浪费效率,所以需要使用延迟加载
从多方查询一方
默认:使用立即加载
只是需要查询一个数据,所以使用立即加载