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
- Hibernate--HQL的使用(包括表的连接)
- Hibernate HQL的使用
- Hibernate的HQL,QBC 查询语言(包括多表联合查询join)
- Hibernate的HQL,QBC 查询语言(包括多表联合查询join)
- hibernate HQl中不存在左连接和右连接/内连接(这里指的Hql不是Sql)
- Hibernate(4)hibernate的HQL详解
- hql语句使用时,参数中包括日期的处理
- 使用hibernate 的hql进行查询表名无效问题
- 框架hibernate的使用(数据库增删改查、hql)
- Hibernate hql ---in操作符的使用
- Hibernate中HQL语句的使用
- Hibernate中使用HQL的基础语法
- hibernate HQL的简单使用一
- Hibernate中HQL语句的使用
- hibernate,hql与sql的缓存使用
- Hibernate中HQL语句的使用
- Hibernate的Hql语句使用in关键字
- hibernate的hql不能使用insert语句
- 一个合格的程序员应该读过哪些书
- POJ 2451 Uyuw's Concert 半平面交求面积
- Linux忘记 root密码的解决办法
- 线性插值——如何根据两点确定一条线段
- HTML 分组无序列表和有序列表
- Hibernate--HQL的使用(包括表的连接)
- 应用层调用内核中的链表操作.
- NGUI FontMaker 简单使用,以及在文字源文件丢失的情况下,怎么根据UIFont预制获取全部文字
- 前端开发和设计必备的Chrome插件
- PHP之——PDO_MYSQL扩展安装步骤
- HexString类型的颜色的使用
- C语言学习之关键字第十讲
- JQuery前端插件的一些使用
- 阿里云CentOS6.5挂载数据盘以及搭建LAMP环境