1. 程式人生 > >hibernate系列十六:分組查詢,子查詢,原生sql查詢,命名查詢

hibernate系列十六:分組查詢,子查詢,原生sql查詢,命名查詢

一  分組查詢

HQL查詢語句使用groupby子句進行分組查詢,使用having子句篩選分組結果。下面通過示例說明。

案例1.  按性別分組,查詢學生的平均年齡

package com.obtk.test;

import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;

import com.obtk.entitys.DeptEntity;
import com.obtk.entitys.StudentEntity;
import com.obtk.utils.HiberUtil;

public class GroupTest1 {
	public static void main(String[] args) {
		Session session=null;
		String hqlStr="select gender,avg(age) from StudentEntity group by gender";
		try {
			session=HiberUtil.getSession();
			Query qy=session.createQuery(hqlStr);
			List<Object[]> stuList=qy.list();
			Object[] theRow=null;
			for(int i=0;i<stuList.size();i++){
				theRow=stuList.get(i);
				System.out.println(theRow[0]+"\t"+theRow[1]);
			}
		} catch (HibernateException e) {
			e.printStackTrace();
		}finally{
			HiberUtil.closeSession();
		}
	}
}

案例二.   按照系名分組,查詢每個系的學生的最高年齡,最低年齡,平均年齡,並且平均年齡要大於20歲
package com.obtk.test;

import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;

import com.obtk.entitys.DeptEntity;
import com.obtk.entitys.StudentEntity;
import com.obtk.utils.HiberUtil;

public class GroupJoinTest2 {
	public static void main(String[] args) {
		Session session=null;
		String hqlStr="SELECT d.departName,MAX(s.age),MIN(s.age),AVG(s.age) "
					+" FROM StudentEntity s INNER JOIN s.dept d"
					+" GROUP BY d.departName"
					+" having avg(s.age)>20";
		try {
			session=HiberUtil.getSession();
			Query qy=session.createQuery(hqlStr);
			List<Object[]> stuList=qy.list();
			Object[] theRow=null;
			for(int i=0;i<stuList.size();i++){
				theRow=stuList.get(i);
				System.out.println(theRow[0]+"\t"+theRow[1]+"\t"+theRow[2]+"\t"+theRow[3]);
			}
		} catch (HibernateException e) {
			e.printStackTrace();
		}finally{
			HiberUtil.closeSession();
		}
	}
}
二  子查詢

案例1   查年齡高於平均年齡的學生

package com.obtk.test;

import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;

import com.obtk.entitys.StudentEntity;
import com.obtk.utils.HiberUtil;

public class ChildQuery1 {
	public static void main(String[] args) {
		Session session=null;
		//查年齡高於平均年齡的學生
		String hqlStr="from StudentEntity s where s.age>(select avg(age) from StudentEntity)"; 
		try {
			session=HiberUtil.getSession();
			Query qy=session.createQuery(hqlStr);
			List<StudentEntity> stuList=qy.list();
			StudentEntity stu=null;
			for(int i=0;i<stuList.size();i++){
				stu=stuList.get(i);
				System.out.println(stu.getStuName()+"\t"+stu.getAge()+"\t"+stu.getGender());
			}
		} catch (HibernateException e) {
			e.printStackTrace();
		}finally{
			HiberUtil.closeSession();
		}
	}
}
案例2  所有學生年齡都大於21的系
package com.obtk.test;

import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;

import com.obtk.entitys.DeptEntity;
import com.obtk.entitys.StudentEntity;
import com.obtk.utils.HiberUtil;

public class ChildQuery2 {
	public static void main(String[] args) {
		Session session=null;
		//所有學生年齡都大於21的系
		String hqlStr="from DeptEntity d where 21<all(select s.age from d.stuList s) and d.stuList.size>0"; 
		try {
			session=HiberUtil.getSession();
			Query qy=session.createQuery(hqlStr);
			List<DeptEntity> deptList=qy.list();
			DeptEntity stu=null;
			for(int i=0;i<deptList.size();i++){
				stu=deptList.get(i);
				System.out.println(stu.getDepartName()+"\t"+stu.getAddress());
			}
		} catch (HibernateException e) {
			e.printStackTrace();
		}finally{
			HiberUtil.closeSession();
		}
	}
}

案例3   查學生的個數要大於3的系
package com.obtk.test;

import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;

import com.obtk.entitys.DeptEntity;
import com.obtk.entitys.StudentEntity;
import com.obtk.utils.HiberUtil;

public class ChildQuery3 {
	public static void main(String[] args) {
		Session session=null;
		//查學生的個數要大於3的系
		String hqlStr="from DeptEntity d where d.stuList.size>3"; 
		try {
			session=HiberUtil.getSession();
			Query qy=session.createQuery(hqlStr);
			List<DeptEntity> deptList=qy.list();
			DeptEntity stu=null;
			for(int i=0;i<deptList.size();i++){
				stu=deptList.get(i);
				System.out.println(stu.getDepartName()+"\t"+stu.getAddress());
			}
		} catch (HibernateException e) {
			e.printStackTrace();
		}finally{
			HiberUtil.closeSession();
		}
	}
}

三  原生sql查詢

     使用HQL查詢時,Hibernate會生成標準的SQL查詢語句,適用於所有的資料庫平臺,因此HQL是跨資料庫平臺的。在實際開發中,有時很可能需要使用底層資料庫的SQL特性,來生成一些特殊的查詢語句。Hibernate提供了原生SQL的查詢方式來支援這一需要。

案例1   

package com.obtk.test;

import java.text.SimpleDateFormat;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;

import com.obtk.entitys.DeptEntity;
import com.obtk.entitys.StudentEntity;
import com.obtk.utils.HiberUtil;

public class SrcQueryTest1 {
	public static void main(String[] args) {
		Session session=null;
		String srcSql="select sysdate()";
		try {
			session=HiberUtil.getSession();
			Query qy=session.createSQLQuery(srcSql);
			SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			String dateStr=sdf.format(qy.uniqueResult());
			System.out.println(dateStr);
		} catch (HibernateException e) {
			e.printStackTrace();
		}finally{
			HiberUtil.closeSession();
		}
	}
}

案例2  
package com.obtk.test;

import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;

import com.obtk.entitys.DeptEntity;
import com.obtk.entitys.StudentEntity;
import com.obtk.utils.HiberUtil;

public class SrcQueryTest2 {
	public static void main(String[] args) {
		Session session=null;
		String hqlStr="SELECT table_name,create_time FROM information_schema.tables"
					+" WHERE table_schema='studentdb'";
		try {
			session=HiberUtil.getSession();
			Query qy=session.createSQLQuery(hqlStr);
			List<Object[]> stuList=qy.list();
			Object[] theRow=null;
			for(int i=0;i<stuList.size();i++){
				theRow=stuList.get(i);
				System.out.println(theRow[0]+"\t"+theRow[1]);
			}
		} catch (HibernateException e) {
			e.printStackTrace();
		}finally{
			HiberUtil.closeSession();
		}
	}
}
四  命名查詢

    Hibernate支援在對映檔案中定義字串形式的查詢語句,這樣的查詢語句稱為命名查詢語句。

===========================對映檔案==============================

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.obtk.entitys">
    <class name="StudentEntity" table="student">
    	<cache usage="read-write" region="stu"/>
        <id name="stuId" type="java.lang.Integer">
            <column name="stuId" />
            <generator class="native"></generator>
        </id>
        <property name="stuName" type="java.lang.String">
            <column name="stuName" length="20" />
        </property>
        <property name="gender" type="java.lang.String">
            <column name="gender" length="2" />
        </property>
        <property name="age" type="integer">
            <column name="age" />
        </property>
        <property name="address" type="java.lang.String">
            <column name="address" length="200" />
        </property>
        <many-to-one name="dept" class="DeptEntity"
        	column="deptIdd" lazy="proxy"></many-to-one>
    </class>
    <!-- 命名查詢 -->
    <query name="getDept1">
    	<![CDATA[
    		from DeptEntity d where d.stuList.size>?
    	]]>
    </query>
    <!-- 原生sql命名查詢 -->
    <sql-query name="srcNameQuery">
    	SELECT table_name,create_time FROM information_schema.tables
		WHERE table_schema='studentdb'
    </sql-query>
</hibernate-mapping>
案例1.  命名查詢
package com.obtk.test;

import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;

import com.obtk.entitys.DeptEntity;
import com.obtk.entitys.StudentEntity;
import com.obtk.utils.HiberUtil;

public class NamingQuery1 {
	public static void main(String[] args) {
		Session session=null;
		//查學生的個數要大於3的系
		try {
			session=HiberUtil.getSession();
			Query qy=session.getNamedQuery("getDept1");
			qy.setParameter(0, 3);
			List<DeptEntity> deptList=qy.list();
			DeptEntity stu=null;
			for(int i=0;i<deptList.size();i++){
				stu=deptList.get(i);
				System.out.println(stu.getDepartName()+"\t"+stu.getAddress());
			}
		} catch (HibernateException e) {
			e.printStackTrace();
		}finally{
			HiberUtil.closeSession();
		}
	}
}
案例2   原生sql命名查詢
package com.obtk.test;

import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;

import com.obtk.entitys.DeptEntity;
import com.obtk.entitys.StudentEntity;
import com.obtk.utils.HiberUtil;

public class SrcNameQueryTest2 {
	public static void main(String[] args) {
		Session session=null;
		try {
			session=HiberUtil.getSession();
			Query qy=session.getNamedQuery("srcNameQuery");
			List<Object[]> stuList=qy.list();
			Object[] theRow=null;
			for(int i=0;i<stuList.size();i++){
				theRow=stuList.get(i);
				System.out.println(theRow[0]+"\t"+theRow[1]);
			}
		} catch (HibernateException e) {
			e.printStackTrace();
		}finally{
			HiberUtil.closeSession();
		}
	}
}