您的位置:首页 > 其它

hibernate分组查询

2013-07-22 15:32 162 查看
检索单个对象

Query和Criteria都提供了返回单个对象的方法uniqueResult().

先调用setMaxResult(1)方法,把最大检索数目设为1,在调用uniqueResult()方法。

Hx hx = (Hx)session.createQuery("from Hx")

.setMaxResults(1)

.uniqueResult();

Hx hx = (Hx)session.createCriteria(Hx.class)

.addOrder(Order.asc("name"))

.setMaxResults(1)

.uniqueResult();

与对象属性绑定

Hx hx = new Hx();

hx.setAge("33");

List list = session.createQuery("from Hx as c where c.age=:age")

.setProperties(hx)

.list();

SQL内连接

内连接就是传统的连接操作,用join连接关联表,on作为连接条件,where指定其他限定条件的查询

如:

select hx.name,hx.age,hxhome.home from hx join hxhome on hx.id=hxhome.hxid

SQL左外连接

在结果表中包含第一个表中满足的所有纪录,如果是在连接条件上匹配纪录,则第二个表返回相应的值,否则第二个表返回空值。

如:

select hx.name,hx.age,hxhome.home from hx  left join hxhome on hx.id=hxhome.hxid

SQL右外连接

在结果表中包含第二个表中满足的所有纪录,如果是在连接条件上匹配纪录,则第一个表返回相应的值,否则第一个表返回空值。

如:

select hx.name,hx.age,hxhome.home from hx  right outer join hxhome on hx.id=hxhome.hxid

Hibernate中各种连接

迫切左外连接

以下两种检索方式是等价的,它们都能同时迫切左外连接类B和类C:

//HQL迫切左外连接检索方式

from A a left join fetch a.b b left join fetch a.c c where b is not

null and c is not null

//QBC迫切左外连接检索方式

List result=session.createCriteria(A.class)

.setFetchMode("this.b",FetchMode.EAGER)

.setFetchMode("this.c",FetchMode.EAGER)

.add(Expression.isNotNull("this.b"))

.add(Expression.isNotNull("this.c"))

.list();

迫切左外连接

HQL:

Session session = HibernateSessionFactory.getSession();

List list = session.createQuery("from Hxhome c left join fetch c.hx h") .list();

for(int i=0;i<list.size();i++)

{

Hxhome hh = (Hxhome)list.get(i);

System.out.println("homeid="+hh.getHxid());

System.out.println("home="+hh.getHome());

System.out.println("hxname="+hh.getHx().getName());

}

迫切左外连接

QBC:

List list = session.createCriteria(Hxhome.class)

            .setFetchMode("hx", FetchMode.EAGER)

            .add(Expression.like("home","h%"))

            .list();

for(int i=0;i<list.size();i++)

{

Hxhome hh = (Hxhome)list.get(i);

System.out.println("homeid="+hh.getHxid());

System.out.println("home="+hh.getHome());

System.out.println("hxname="+hh.getHx().getName());

}

QBC中的FetchMode

FetchMode.DEFAULT:表示采用映射文件中配置的检索策略

FetchMode.EAGER:覆盖映射文件中配置的检索策略,在程序中显示指定迫切左外连接检索策略

FetchMode.LAZY:覆盖映射文件中配置的检索策略,在程序中显示指定延迟检索策略

左外连接

HQL:

List list = session.createQuery("from Hxhome c left join  c.hx ")

.list();

for(int i=0;i<list.size();i++)

{

Object[] zmx = (Object[])list.get(i);

Hx hx = (Hx)zmx[1];

Hxhome hh = (Hxhome)zmx[0];

System.out.println("hx="+hx.getName()+"---------hh="+hh.getHome());

}

左外连接

QBC不支持左外连接

内连接

HQL:

List list = session.createQuery("from Hxhome c  join  c.hx ")

.list();

for(int i=0;i<list.size();i++)

{

Object[] zmx = (Object[])list.get(i);

Hx hx = (Hx)zmx[1];

Hxhome hh = (Hxhome)zmx[0];

System.out.println("hx="+hx.getName()+"---------hh="+hh.getHome());

}

QBC:

List list =session.createCriteria(Hxhome.class)

           .createAlias("hx", "h")

           .add(Expression.like("home","h%"))

           .list();          

for(Iterator it=list.iterator();it.hasNext();)

{

Map map = (Map)it.next();

Hxhome hh = (Hxhome)map.get("this");

Hx hx = (Hx)map.get("h");

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

}

右外连接

HQL:

List list = session.createQuery("from Hxhome c right join c.hx h")

.list();          

for(Iterator it=list.iterator();it.hasNext();)

{

Object[] zmx = (Object[])it.next();

Hxhome hh = (Hxhome)zmx[0];

Hx hx = (Hx)zmx[1];

System.out.print(hh.getHome());

System.out.println(hx.getName());

}

右外连接

QBC:

不支持右外连接

HQL支持各种的连接查询

1、默认情况

from Hx c where c.name like ‘h%’

2、迫切左外连接

from Hx c left join fetch c.hxhome where c.name like ‘h%’

3、左连接

from Hx c left join c.hxhome where c.name like ‘h%’

4、迫切内连接

from Hx c join fetch c.hxhome where c.name like ‘h%’

5、内连接

from Hx c join c.hxhome where c.name like ‘h%

6、右外连接

from Hx c right join c.hxhome where c.name like ‘h%

报表查询

1、投影查询

2、使用聚集函数

3、分组查询

投影查询

投影查询:指查询结果仅包含部分实体或实体的部分属性,通过select关键字来实现。

select关键字用于选择对象的部分属性,例如:

Session session = HibernateSessionFactory.getSession();

Transaction tx = session.beginTransaction();

Iterator it = session.createQuery("select c.name,c.age,h.home from Hx c join c.homes h where c.id>0 ")

              .list()

              .iterator();

while(it.hasNext())

{

Object[] row = (Object[])it.next();

String age = (String)row[1];

String home = (String)row[2];

System.out.println("|age="+age+"|home="+home);

}

tx.commit();

session.close();

投影查询

过滤结果中的重复数据—使用set

Iterator it = session.createQuery("select c.name from Hx c")

              .iterate();

Set set = new HashSet();

while(it.hasNext())

{

String it1 = set.iterator();

while(it1.hasNext())

{

String name1 = (String)it1.next();

System.out.println("name1="+name1);

}

投影查询

也可以使用distinct关键字来过滤重复记录

Session session = HibernateSessionFactory.getSession();

Transaction tx = session.beginTransaction();

Iterator it = session.createQuery("select distinct c.name from Hx c")

.iterate();

while(it.hasNext())

{

String c.ID,c.NAME,o.ORDER_NUMBER

from CUSTOMERS c inner join ORDERS o

on c.ID=o.CUSTOMER_ID where o.ORDER_NUMBER like 'T%';

以上查询语句的查询结果如下:

+----+------+--------------+

| ID | NAME | ORDER_NUMBER |

+----+------+--------------+

|  1 | Tom  | Tom_Order001 |

|  1 | Tom  | Tom_Order002 |

|  1 | Tom  | Tom_Order003 |

+----+------+--------------+

Query的list()方法返回的集合中包含三个对象数组类型的元素,每个对象数组代表以上查询结果的一条记录。

投影查询

使用聚集函数

在HQL中可以调用

Count:统计函数

Min:求最小值函数

Max:求最大值函数

Sum:求和函数

Avg:求平均数函数

 Count:统计函数

Session session = HibernateSessionFactory.getSession();

Transaction tx = session.beginTransaction();

Integer count = (Integer)session.createQuery("select count(*) from Hx")

.uniqueResult();

System.out.print(count);

tx.commit();

session.close();

Avg:求平均数函数

Session session = HibernateSessionFactory.getSession();

Transaction tx = session.beginTransaction();

Float count = (Float)session.createQuery("select avg(c.id) from Hx c")

 .uniqueResult();

System.out.print(count);

tx.commit();

session.close();

Sum:求和函数

Session session = HibernateSessionFactory.getSession();

Transaction tx = session.beginTransaction();

Integer count = (Integer)session.createQuery("select sum(c.id) from Hx c")

 .uniqueResult();

System.out.print(count);

tx.commit();

session.close();

Min:求最小值函数 Max:求最大值函数

Session session = HibernateSessionFactory.getSession();

Transaction tx = session.beginTransaction();

Object[] count = (Object[])session.createQuery("select min(c.age),max(c.age) from Hx c")

.uniqueResult();

String min = (String)count[0];

String max = (String)count[1];

System.out.print("min="+min+"|max="+max);

tx.commit();

session.close();

分组查询

Session session = HibernateSessionFactory.getSession();

Transaction tx = session.beginTransaction();

Iterator it = session.createQuery("select c.name,count(c) from Hx c group by c.name")

.iterate();

while(it.hasNext())

{

Object[] oc = (Object[])it.next();

String count = (Integer)oc[1];

System.out.println(name+":"+count);

}

tx.commit();

session.close();

private static final String LIST_COUNT = "select f.type as t,count(f.type) as c from Fetch as f group by type";

public void testCount(){  

  

   Query query = createQuery(LIST_COUNT);

  

   List list = query.list();  

   for(int i=0;i<list.size();i++){

   

    Object ob[]=(Object[]) list.get(i);

   

    System.out.println(ob[0].toString());

    System.out.println(ob[1].toString());

   }

}

另外:

在hibernate中,用hql语句查询实体类,采用list方法的返回结果为一个List,该List中封装的对象分为以下三种情况:

1.查询全部字段的情况下,如"from 实体类",list中封装的对象为实体类本身,各属性都将得到填充。

2.只查询一个字段,默认情况下,list中封装的是Object对象。

3.查询两个或两个以上的字段,默认情况下,list中封装的是Object[],长度与所查询的字段数一致。

对于后两种情况,用标签遍历时不太方便,因为无法直接转换成实体类的对象。比较简单的解决方法是:

在hql中使用 select new 包名.类名(属性1,属性2……) from 实体类,同时在实体类中添加带参的构造方法,参数的个数和顺序与(属性1,属性2……) 保持一致,这样我们得到的list中存放的依然是实体类的对象,所查询到的属性得到了填充,使用起来更为方便。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: