hql关联和连接查询实例


 
  Hibernate 
  提供了强大的查询系统,使用Hibernate有多种查询方法可以选择:可以使用HibernateHQL查询,也可以使用条件查询,甚至可以使用原生的SQL查询语句。其中HQL查询时Hibernate配置的功能强大的查询语句。HQL是非常有意识的被设计为完全面向对象的查询,它可以理解如继承、多态 和关联之类的概念。 
  

       下面我们来看一下Hibernate中的关联查询的基本知识。

一、连接概念

外连接:把舍弃的元组也保存在结果关系中,而在其他属性上填写空值。

左外连接:返回那些存在于左表而右表中却没有的行,再加上内连接的行。

左连接特点:显示全部左边表中的所有项目,即使其中有些项中的数据未填写完全。

在使用的时候主要根据自己的需要选择时要保留join关键字右边的表中的属性还是要保留左边的表的属性

      内连接:内连接也叫连接,是最早的一种连接。还可以被称为普通连接或者自然连接,内连接是从结果表中删除与其他被连接表中没有匹配行的所有行,所以内连接可能会丢失信息。

当程序需要从多个数据表中获取数据时,Hibernate使用关联映射来处理底层数据表之间的连接,一旦我们提供了正确的关联映射后,当程序通过Hibernate进行持久化访问时,将可利用Hibernate的关联来进行连接。

         HQL支持两种关联join的形式:implicit(隐式) 与explicit(显式)

 

         显式form子句中明确给出了join关键字,而隐式使用英文点号(.)来连接关联实体。

         受支持的连接类型是从ANSI SQL中借鉴来的。

         inner join(内连接)

         left outer join(左外连接,outer 可以省略)

         right outer join(右外连接,outer 可以省略

         full join (全连接,并不常用)

         使用显式连接,可以通过with或者on关键字来提供额外的join条件

二、连接操作

下面来看我的表的结构:

user表

store表

goods表

order表

ordergoods表

表对应的model

public class User {
   private int userId;//用户ID
   private String userName;//用户名
   private String userPassword;//用户密码
   private Store store;
  private Set orderSet = new HashSet();

public class Store {
	private int storeId;// 主键
	private User user;// user的id是Store的外码
	private String storeName;
	private String storeAdress;
	private String storePhone;
        private Set goodsSet=new HashSet();
       //get和set方法省略
}

public class Orders {
	private int orderId;// 主键
	private User user;// User的主键作为Orders的外键。
	private String orderCount;
	private String totalPrice;
        private Set goodsSet = new HashSet();

}

public class Goods {
	
	private int goodsId;// 主键
	private Store store;// ID外键,来自Store
	private String goodsName;
	private String goodsPrice;
	private Set orderSet = new HashSet();
}

xml文件就省略了

1、user表和store表连接查询store表中的用户名为id的store表中的一行数据。使用的是内连接,当然也可使用其他连接方式。

    //store.user 连接操作用的是Store对象中的user,只能查找出指定userId的数据,内连接只会保存两张表中
    //有相同字段的数据。
    String hql="select store from Store store inner join store.user user on user.userId=:id";


2、左外连接 user表和store表连接查询store表中的用户名为id的store表中的一行数据。

     //hql1会查询出Store中的全部数据,因为使用的是左外连接,所以该连接将Store表所有的记录都保留了。
     String hql1="select store from Store store left join store.user user with user.userId=:id";

3、右外连接user和store表

    //但是如果循环打印store对象中的数据可能会抛出空引用的异常,因为查询出来的结果包含了user表中的所有数据,但是store的可能只有一条。
    String hql2="select store from Store store right join store.user user with user.userId=:id";

4、使用左外连接user和store表,查询某一个用户的订单,User类中有一个Orders的set集合对象,使用fetch将满足条件的订单读取到oederSet集合中,将该订单

对应的商品信息读取到goodSet中。

//hql3中的where user.userId=:id是将order表中的外码userId=id的选择出来连接。
//返回的User的对象中的属性,使用fetch连接抓取order对象中的的属性到SetOrder集合中
//同时也会去抓取order对象中关联的goodSet中的属性。
//把该订单中的商品信息保存在goodSet集合中。
String hql3="select distinct user from User user left join fetch user.orderSet where user.userId=:id";

5、使用左外连接查询Store对象选中的goodsSet集合,将商家的商品信息抓取到集合中。商家和商品一对多的关系。

//hql1会查询Goods表中的全部数据,根据我们的配置文件中的关联关系去抓取Goods对象中的goodsSet中的全部对象。
String hql1 = "select distinct store from Store store left join fetch store.goodsSet ";
//hql2会查询Goods表storeId=pk的全部数据。条件应该用where不能用with。
String hql2 = "select distinct store from Store store left join fetch store.goodsSet goods where store.storeId=:storeId";

6、使用隐式链接查询多对多中的orders和goods表,根据订单号查询订单,下面的查询语句会将关联的商品信息抓取到Orders类的goodsSet集合中。

String hql="select orders from Orders orders,Goods goods where orders.orderId=:orderId";

7、使用左外连接根据外码userId,查询某一个用户的订单,也就是Orders类中的user对象查询多对多关系中的orders和goods表,返回orders对象。下面查询语句会将关联的商品信息抓取到Orders类的goodsSet集合中,连接也可使用inner join,right join。

String hql = "select distinct orders from Orders orders left join fetch orders.goodsSet goods where orders.user.userId=:userId";



你可能感兴趣的:(Hibernate)