关联查询

1.查询关联实体:

   (1)在一对一关连查询中,可以直接通过引用其关联属性来查询:

   select c.address from Customer c

   JPA实现者会根据实体映射的关系自动关联所对应的实体。

 

   (2)在一对多中,可以通过IN

    select c.name,o from Customer c, in (c.orders) o

    其中o为集合的别名。

 

2.内连接:

   查询所有客户和他所属的订单(若客户无订单是查询不到的):

   select c,order from Customer c (inner) join c.orders order

    inner可以不写,默认inner。

等价于:

   select c,order from Customer c,in (c.orders) order

 

3.左连接:

   即左外连接,客户无订单是可以查到的,但其订单为null值:

  select c,order from Customer c left (outer) join c.orders order

 

4.抓取连接(在join后面加上fetch),针对延迟加载

   select c,order from Customer c join fetch c.orders order

  select c,order from Customer c left join fetch c.orders order

 

  例如:customer的order为延迟加载

@OneToMany(mappedBy="customer",fetch=FetchType.LAZY)
public Set<Order> getOrders(){
  return orders;
}

在关联查询中,若使用

select c from customer c join c.orders o

返回的customer对象并没有加载所关联的orders属性,此时在客户端调用getOrders方法时会抛出异常。因此改为: 

select c from customer c join fetch c.orders o

此时返回的customer对象加载了所关联的orders属性。

 

-------------------------------------------------------------------------------------------------------------------------------------

这里的join fetch 跟下面的代码是什么关系?---上面的是通过Query,下面这个则是通过find。

两者什么区别和联系?

 

及时加载和延迟加载

@PersistenceContext
protected EntityManager em;

public Customer findCustomerById(Integer customerId){
     Customer customer=em.find(Customer.class,customerId);
     return customer;
    
}
 
由于customer和address为一对一关系,默认为及时加载,所以在find customer的时候,
其实select语句是左连接address,同时取出关联address的。 
如果改为延迟加载:
 
@OneToOne(cascade=CascadeType.PERSIST,fetch=FetchType.LAZY)
@JoinColumn(name="address_id")
public Address getAddress(){
  return this.address;
} 则在session bean中的find方法:@PersistenceContext
protected EntityManager em;

public Customer findCustomerById(Integer customerId){
     Customer customer=em.find(Customer.class,customerId);
   //通过调用延迟加载关联的address
     customer.getAddress();
     return customer;
    
} 

其实分两个select语句来实行,一个是先select customer,第二个是通过where address_id来select关联的address
如果客户端要使用customer的getAddress()方法,则必须在session bean中延迟加载customer.getAddress(),否则
客户端调用时会报错。延迟加载只能在持久化上下文(session bean)中执行。

转载于:https://www.cnblogs.com/cxccbv/archive/2009/01/23/1380505.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值