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);
            }
    }
}


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