Hibernate--HQL的使用(包括表的連接)

有幾點需要注意的地方:

1  

//OK Query query=session.createQuery("from Special");
            //ERROR Query query=session.createQuery("select * from Special");select *不能使用
             Query query=session.createQuery("select spec from  Special spec");//OK
            List<Special> ls=query.list();

2 hibernate下標從0開始 jdbc從1

3 指定參數名稱 用 :name格式,

 Query query=session.createQuery("from Student where name like :name and sex=:sex");
            query.setParameter("name","%2%");
            query.setParameter("sex","女");
            List<Student> ls=query.list();

4 使用uniqueResult進行唯一的查詢  返回值爲Object 可以強轉爲long

Query query=session.createQuery("select count(*) from Student where name like :name and sex=:sex");
            query.setParameter("name","%2%");
            query.setParameter("sex","女");
            Long ls=(Long)query.uniqueResult();
5 基於投影的查詢 通過在列表中存儲一個對象數組

session=HibernateUtil.openSession();
            Query query=session.createQuery("select stu.sex,count(*) from Student stu group by stu.sex");
            List<Object[]> ls=query.list();
            for (Object[] objects : ls)
            {
                System.out.println(objects[0]+"  "+objects[1]);
            }
6 基於導航的查詢 表之間的連接用笛卡爾積 cross join 使用效率低  但是方便 可以直接寫 stu.classroom.name=?

Query query=session.createQuery("select stu from Student stu where stu.name like ? and stu.classroom.name=?");
            List<Student> ls=query.setParameter(0,"%張%").setParameter(1,"軟件1班").list();
            for (Student stu : ls)
            {
                System.out.println(stu.getName());
            }

7可以使用in類來設置基於列表的查詢 此處查詢要使用別名進行查詢
   特別注意 使用的in查詢必須在其他查詢之後

Query query=session.createQuery("select stu from Student stu where stu.name like ? and stu.classroom.id in(:clas)");
            List<Student> ls=query.setParameter(0,"%張%").setParameterList("clas",new Integer[]{1,3}).list();
            for (Student stu : ls)
            {
                System.out.println(stu.getName());
            }

8使用setFirstResult和setMaxResult可以完成分頁的offset和pageSize的設置

 Query query=session.createQuery("select stu from Student stu where  stu.classroom.id in(:clas)");
            List<Student> ls=query.setParameterList("clas",new Integer[]{1,3})
                                    .setFirstResult(0).setMaxResults(2).list();
            for (Student stu : ls)
            {
                System.out.println(stu.getName());
            }

9可以使用is null 查詢 外鍵爲空的對象 使用關聯對象爲空判斷

session=HibernateUtil.openSession();
            Query query=session.createQuery("select stu from Student stu where  stu.classroom is null");
            List<Student> ls=query.list();
            for (Student stu : ls)
            {
                System.out.println(stu.getName());
            }

10使用對象的導航可以完成連接,但是基於cross join(笛卡爾積),
     效率不高 可以直接使用join{left join ,inner join(=join),right join}

Query query=session.createQuery("select stu.id,stu.name,stu.sex,cla.name,spe.name from"
                + " Student stu left join stu.classroom cla left join cla.special spe");
            List<Object[]> ls=query.list();
            for (Object[] stu : ls)
            {
                System.out.print(stu[0]+","+stu[1]+","+stu[2]+","+stu[3]+","+stu[4]+"\n");
            }

11 構造一個新的傳輸對象

         *1 直接使用new XXObject來新建一個傳輸對象來接住查詢的東西
         * 2 注意一定要加上XXObject的完整包名
         * 3 這裏使用New 要加入相應的構造方法
         * 4 記得使用as

 Query query=session.createQuery("select new com.itany.model."
                + "StudentDto(stu.id as sid,stu.name as sname,stu.sex as sex,cla.name as cname,spe.name as specname) "
                + "from Student stu left join stu.classroom cla left join cla.special spe");
            List<StudentDto> ls=query.list();
            for (StudentDto stu : ls)
            {
                System.out.print(stu.getSid()+","+stu.getSname()+","+stu.getSex()+","+stu.getCname()+","+stu.getSpecname()+"\n");
            }


廢話不說,直接上代碼:

涉及到幾個表的關係:

專業表--班級表--學生表  都是多對一的關係

下面是xml文件配置,annotation有關的配置 會單獨開篇文章說明:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.itany.model">

	<class name="Student" table="t_stu">
		<!--  <cache usage="read-only" /> -->
		<id name="id">
			<generator class="native"></generator>
		</id>
		<!-- 注意:version 一定要加在ID後面 property前面 -->
		<version name="version" />
		<property name="name" />
		<property name="sex" />
		<many-to-one name="classroom" column="cid" fetch="join" />
	</class>

</hibernate-mapping>

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.itany.model">

<!-- 注意:多對一時候 從多端懶加載一對象(目的是爲了全部加載多端對象)
           在一端加batch-size=3 表示3個一端對象對應的所有多端對象全部加載 比如3個班的所有學生加載  減少發出的SQL
	 同理: 一對多時候 從一端延遲加載多端對象 在一端set中batch-size="3"表示3個一端對象對應的所有多端對象全部延遲加載-->
	<class name="Classroom" table="t_cla" batch-size="3">
		<id name="id" >
		 <generator class="native"></generator>
		</id>
		<property name="name" />
		<property name="grade" />
		<!-- 表示一次加載2個classroom的所有學生 -->
		<set name="students" inverse="true" lazy="extra" fetch="subselect" batch-size="2">
			<key column="cid" />
			<one-to-many class="Student"/>
		</set>
		<many-to-one name="special"  column="spec_id" fetch="join"/>
	 
	</class>

</hibernate-mapping>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.itany.model">

	<class name="Special" table="t_spec">
		<id name="id" >
		 <generator class="native"></generator>
		</id>
		<property name="name" />
		<property name="type" />
		<set name="clas" inverse="true" lazy="extra">
			<key column="spec_id" />
			<one-to-many class="Classroom" />
		</set>
	 
	</class>

</hibernate-mapping>

下面使用幾個junit的測試用例說明:

public class TestHQL
{
    @SuppressWarnings("unchecked")
    @Test
    public void test01()
    {
        Session session=null;
        Transaction trans=null;
        try
        {
            session=HibernateUtil.openSession();
            trans=session.beginTransaction();
            
            //OK Query query=session.createQuery("from Special");
            //ERROR Query query=session.createQuery("select * from Special");select *不能使用
             Query query=session.createQuery("select spec from  Special spec");//OK
            List<Special> ls=query.list();
            for (Special special : ls)
            {
                System.out.println(special.getName());
            }
            trans.commit();
        }
        catch (HibernateException e)
        {
            e.printStackTrace();
            if(null!=session)
                trans.rollback();
        }
        finally
        {
            if(null!=session)
                HibernateUtil.closeSession(session);
        }
            
    }
    @Test
    public void test02()
    {
        //hibernate下標從0開始 jdbc從1
        Session session=null;
        Transaction trans=null;
        try
        {
            session=HibernateUtil.openSession();
            Query query=session.createQuery("from Student where name like ?");//name like '%1%'可能引起SQL注入
            query.setParameter(0,"%1%");
            List<Student> ls=query.list();
            for (Student stu : ls)
            {
                System.out.println(stu.getName());
            }
        }
        catch (HibernateException e)
        {
            e.printStackTrace();
        }
        finally
        {
            if(null!=session)
                HibernateUtil.closeSession(session);
        }
    }

    @Test
    public void test03()
    {
        /*
         * 指定參數名稱
         */
        Session session=null;
        Transaction trans=null;
        try
        {
            session=HibernateUtil.openSession();
            Query query=session.createQuery("from Student where name like :name and sex=:sex");
            query.setParameter("name","%2%");
            query.setParameter("sex","女");
            List<Student> ls=query.list();
            for (Student stu : ls)
            {
                System.out.println(stu.getName());
            }
        }
        catch (HibernateException e)
        {
            e.printStackTrace();
        }
        finally
        {
            if(null!=session)
                HibernateUtil.closeSession(session);
        }
    }
    @Test
    public void test04()
    {
        /*
         * 使用uniqueResult進行唯一的查詢
         */
        Session session=null;
        Transaction trans=null;
        try
        {
            session=HibernateUtil.openSession();
            Query query=session.createQuery("select count(*) from Student where name like :name and sex=:sex");
            query.setParameter("name","%2%");
            query.setParameter("sex","女");
            Long ls=(Long)query.uniqueResult();
            System.out.println(ls);
        }
        catch (HibernateException e)
        {
            e.printStackTrace();
        }
        finally
        {
            if(null!=session)
                HibernateUtil.closeSession(session);
        }
    }
    @Test
    public void test05()
    {
        /*
         * 使用uniqueResult進行唯一的查詢
         */
        Session session=null;
        Transaction trans=null;
        try
        {
            session=HibernateUtil.openSession();
            Query query=session.createQuery("select stu from Student stu where id=:id");
            query.setParameter("id",1);
            Student ls=(Student)query.uniqueResult();
            System.out.println(ls.getName());
        }
        catch (HibernateException e)
        {
            e.printStackTrace();
        }
        finally
        {
            if(null!=session)
                HibernateUtil.closeSession(session);
        }
    }
    @Test
    public void test06()
    {
        /*
         * 基於投影的查詢 通過在列表中存儲一個對象數組
         */
        Session session=null;
        Transaction trans=null;
        try
        {
            session=HibernateUtil.openSession();
            Query query=session.createQuery("select stu.sex,count(*) from Student stu group by stu.sex");
            List<Object[]> ls=query.list();
            for (Object[] objects : ls)
            {
                System.out.println(objects[0]+"  "+objects[1]);
            }
        }
        catch (HibernateException e)
        {
            e.printStackTrace();
        }
        finally
        {
            if(null!=session)
                HibernateUtil.closeSession(session);
        }
    }
    @Test
    public void test07()
    {
        /*
         * 普通查詢
         */
        Session session=null;
        Transaction trans=null;
        try
        {
            session=HibernateUtil.openSession();
            Query query=session.createQuery("select stu from Student stu where cid=?");
            List<Student> ls=query.setParameter(0, 1).list();
            for (Student stu : ls)
            {
                System.out.println(stu.getName());
            }
        }
        catch (HibernateException e)
        {
            e.printStackTrace();
        }
        finally
        {
            if(null!=session)
                HibernateUtil.closeSession(session);
        }
    }
    @Test
    public void test08()
    {
        /*
         * 基於導航的查詢 表之間的連接用笛卡爾積 cross join 使用效率低  但是方便 可以直接寫
         * stu.classroom.name=?
         */
        Session session=null;
        Transaction trans=null;
        try
        {
            session=HibernateUtil.openSession();
            Query query=session.createQuery("select stu from Student stu where stu.name like ? and stu.classroom.name=?");
            List<Student> ls=query.setParameter(0,"%張%").setParameter(1,"軟件1班").list();
            for (Student stu : ls)
            {
                System.out.println(stu.getName());
            }
        }
        catch (HibernateException e)
        {
            e.printStackTrace();
        }
        finally
        {
            if(null!=session)
                HibernateUtil.closeSession(session);
        }
    }
    @Test
    public void test09()
    {
        /*
         * 可以使用in類來設置基於列表的查詢 此處查詢要使用別名進行查詢
         * 特別注意 使用的in查詢必須在其他查詢之後
         */
        Session session=null;
        Transaction trans=null;
        try 
        {
            session=HibernateUtil.openSession();
            Query query=session.createQuery("select stu from Student stu where stu.name like ? and stu.classroom.id in(:clas)");
            List<Student> ls=query.setParameter(0,"%張%").setParameterList("clas",new Integer[]{1,3}).list();
            for (Student stu : ls)
            {
                System.out.println(stu.getName());
            }
        }
        catch (HibernateException e)
        {
            e.printStackTrace();
        }
        finally
        {
            if(null!=session)
                HibernateUtil.closeSession(session);
        }
    }
    @Test
    public void test10()
    {
        /*
         * 使用setFirstResult和setMaxResult可以完成分頁的offset和pageSize的設置
         */
        Session session=null;
        Transaction trans=null;
        try 
        {
            session=HibernateUtil.openSession();
            Query query=session.createQuery("select stu from Student stu where  stu.classroom.id in(:clas)");
            List<Student> ls=query.setParameterList("clas",new Integer[]{1,3})
                                    .setFirstResult(0).setMaxResults(2).list();
            for (Student stu : ls)
            {
                System.out.println(stu.getName());
            }
        }
        catch (HibernateException e)
        {
            e.printStackTrace();
        }
        finally
        {
            if(null!=session)
                HibernateUtil.closeSession(session);
        }
    }
    @Test
    public void test11()
    {
        /*
         * 可以使用is null 查詢 外鍵爲空的對象 使用關聯對象爲空判斷
         */
        Session session=null;
        Transaction trans=null;
        try 
        {
            session=HibernateUtil.openSession();
            Query query=session.createQuery("select stu from Student stu where  stu.classroom is null");
            List<Student> ls=query.list();
            for (Student stu : ls)
            {
                System.out.println(stu.getName());
            }
        }
        catch (HibernateException e)
        {
            e.printStackTrace();
        }
        finally
        {
            if(null!=session)
                HibernateUtil.closeSession(session);
        }
    }
    @Test
    public void test12()
    {
        /*
         * 使用對象的導航可以完成連接,但是基於cross join(笛卡爾積),
         * 效率不高 可以直接使用join{left join ,inner join(=join),right join}
         */
        Session session=null;
        Transaction trans=null;
        try 
        {
            session=HibernateUtil.openSession();
            Query query=session.createQuery("select stu.id,stu.name,stu.sex,cla.name,spe.name from"
                + " Student stu left join stu.classroom cla left join cla.special spe");
            List<Object[]> ls=query.list();
            for (Object[] stu : ls)
            {
                System.out.print(stu[0]+","+stu[1]+","+stu[2]+","+stu[3]+","+stu[4]+"\n");
            }
        }
        catch (HibernateException e)
        {
            e.printStackTrace();
        }
        finally
        {
            if(null!=session)
                HibernateUtil.closeSession(session);
        }
    }
    @Test
    public void test13()
    {
        /*
         * 1 直接使用new XXObject來新建一個傳輸對象來接住查詢的東西
         * 2 注意一定要加上XXObject的完整包名
         * 3 這裏使用New 要加入相應的構造方法
         * 4 記得使用as
         */
        Session session=null;
        Transaction trans=null;
        try 
        {
            session=HibernateUtil.openSession();
            Query query=session.createQuery("select new com.itany.model."
                + "StudentDto(stu.id as sid,stu.name as sname,stu.sex as sex,cla.name as cname,spe.name as specname) "
                + "from Student stu left join stu.classroom cla left join cla.special spe");
            List<StudentDto> ls=query.list();
            for (StudentDto stu : ls)
            {
                System.out.print(stu.getSid()+","+stu.getSname()+","+stu.getSex()+","+stu.getCname()+","+stu.getSpecname()+"\n");
            }
        }
        catch (HibernateException e)
        {
            e.printStackTrace();
        }
        finally
        {
            if(null!=session)
                HibernateUtil.closeSession(session);
        }
    }
        @Test
        public void test14()
        {
            /*
             * 統計不同專業的人數>3的(注意對專業需要進行外連接)
             * 可以寫一個連接 一下子連接2張表 中間隔了一個classroom
             * Student stu right join stu.classroom.special spe
             * 
             * 注意是 count(stu.id)
             */
            Session session=null;
            Transaction trans=null;
            try 
            {
                session=HibernateUtil.openSession();
                Query query=session.createQuery("select spe.name,count(stu.id)  from "
                    + "Student stu right join stu.classroom.special spe group by spe having count(stu.id)>3");
                List<Object[]> ls=query.list();
                for (Object[] stu : ls)
                {
                    System.out.print(stu[0]+","+stu[1]+"\n");
                }
            }
            catch (HibernateException e)
            {
                e.printStackTrace();
            }
            finally
            {
                if(null!=session)
                    HibernateUtil.closeSession(session);
            }
    }
        @Test
        public void test15()
        {
            /*
             * 統計不同專業不同性別的人數(注意對專業需要進行外連接)
             * 可以寫一個連接 一下子連接2張表 中間隔了一個classroom
             * Student stu right join stu.classroom.special spe
             * 
             * 注意是 count(stu.id)
             */
            Session session=null;
            Transaction trans=null;
            try 
            {
                session=HibernateUtil.openSession();
                Query query=session.createQuery("select spe.name,stu.sex,count(stu.id)  from "
                    + "Student stu right join stu.classroom.special spe group by spe.id,stu.sex");
                List<Object[]> ls=query.list();
                for (Object[] stu : ls)
                {
                    System.out.print(stu[0]+","+stu[1]+","+stu[2]+"\n");
                }
            }
            catch (HibernateException e)
            {
                e.printStackTrace();
            }
            finally
            {
                if(null!=session)
                    HibernateUtil.closeSession(session);
            }
    }
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章