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

来源:互联网 发布:手机自动连接移动网络 编辑:程序博客网 时间:2024/05/21 09:46

有几点需要注意的地方:

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


0 0
原创粉丝点击