Hibernate HQL

原创
2016/10/20 20:44
阅读数 105

4、HQL

    1、基本查询

        1、不带条件的查询

			session = HibernateUtil.openSession();
			//对于HQL而言,都是基于对象进行查询的
			Query<Special> query = session.createQuery("from Special",Special.class);
			List<Special> spes = query.getResultList();
			for(Special spe:spes) {
				System.out.println(spe.getName());
			}
		try {
			session = HibernateUtil.openSession();
			//对于HQL而言,都是基于对象进行查询的
			//不能使用select * 进行查询
//			Query<Special> query = session.createQuery("select * from Special",Special.class);
			//可以使用链式查询的方式
			List<Special> spes = session.createQuery("select spe from Special spe", 
									Special.class)
									.getResultList();
			for(Special spe:spes) {
				System.out.println(spe.getName());
			}

    2、带条件的查询

			session = HibernateUtil.openSession();
			/**
			 * 带条件的查询
			 * 如果直接在代码中加条件可能存在SQL注入攻击,一般不使用这种方式传条件
			 * 和sql差不多,也是使用where加条件
			 */
			List<Student> stus = session.createQuery("from Student where name like '%王%'", 
									Student.class)
									.getResultList();
			for(Student stu:stus) {
				System.out.println(stu.getName());
			}

    3、通过参数进行查询

			session = HibernateUtil.openSession();
			/**
			 * 使用参数进行查询
			 * 基于?的条件的查询,特别注意:jdbc设置参数的最小下标是1,Hibernate是0
			 * 查询方法和JDBC类似,特别注意下标从0开始
			 */
			List<Student> stus = session.createQuery("from Student where name like ?", 
									Student.class)
									.setParameter(0, "%张%")
									.getResultList();
			for(Student stu:stus) {
				System.out.println(stu.getName());
			}

    4、通过命名参数进行查询

			session = HibernateUtil.openSession();
			/**
			 * 还可以基于别名进行查询,使用:xxx来说明别名的名称
			 * HQL支持链操作
			 */
			List<Student> stus = session.createQuery("from Student where name like :name and sex=:sex", 
									Student.class)
									.setParameter("name", "%张%")
									.setParameter("sex", "男")
									.getResultList();
			for(Student stu:stus) {
				System.out.println(stu.getName());
			}

    5、查询空(null)元素

			session = HibernateUtil.openSession();
			/**
			 * 查询null元素,最好使用is null,(虽然可以使用=null,但是不建议使用)
			 */
			List<Student> stus = session.createQuery("from Student where classroom is null", 
									Student.class)
									.getResultList();
			for(Student stu:stus) {
				System.out.println(stu.getName());
			}

2、常用查询

    1、列表查询(in ())

			session = HibernateUtil.openSession();
			/**
			 * 在HQL中也支持in查询,正常的查询一般都是会传递一个列表或者数组
             * 此时就必须使用参数命名查询
             * 这种方式在权限控制中是经常使用的
             * 特别注意:参数设置是setParameterList,参数值new Integer[]{1,2}必须是一个Collection或者Object[]
			 */
			List<Student> stus = session.createQuery("select stu from Student stu where stu.classroom.id in (:clas)",
										Student.class)
									.setParameterList("clas", new Integer[]{1,2})
									.getResultList();
			for(Student stu:stus) {
				System.out.println(stu.getName());
			}

    2、投影查询

			session = HibernateUtil.openSession();
			/**
			 * 基于投影的查询,通过在列表中存储一个对象的数组
			 * 对象数组的第一个元素就是第一个投影的值...
			 */
			List<Object[]> stus = session.createQuery("select stu.sex,count(*) from Student stu group by stu.sex",
										Object[].class)
									.getResultList();
			for(Object[] obj:stus) {
				System.out.println(obj[0]+":"+obj[1]);
			}

    3、投影一个元素查询(注意:不能使用select * 来查询)

		Session session = null;
		try {
			session = HibernateUtil.openSession();
			/**
			 * 使用getSingleResult()可以返回唯一的一个值
			 * 查询count(*),只有一个元素时就不是对象数组了,如果是count就是Long类型的值
			 */
			Long stus = session.createQuery("select count(*) from Student where classroom is null", 
									Long.class)
									.getSingleResult();
			System.out.println(stus);

    4、投影其它类型

			session = HibernateUtil.openSession();
			/**
			 * 使用getSingleResult()可以返回唯一的一个值
			 * 查询一个投影,一个投影也不是对象数组
			 * stu是Student类型的值
			 */
			Student stu = session.createQuery("select stu from Student stu where id=:id", 
									Student.class)
									.setParameter("id", 1)
									.getSingleResult();
			System.out.println(stu.getName());

    5、单个元素查询(getSingleResult())

			session = HibernateUtil.openSession();
			/**
			 * 如果查询出来的数据只有一条记录可以使用getSingleResult()来查询
			 * 特别注意不能使用select * 
			 */
			Student stu = session.createQuery("select stu from Student stu where id=:id", 
									Student.class)
									.setParameter("id", 1)
									.getSingleResult();
			System.out.println(stu.getName());


			session = HibernateUtil.openSession();
			/**
			 * 如果要查询count也可以使用getSingleResult()
			 */
			Long stus = session.createQuery("select count(*) from Student where classroom is null", 
									Long.class)
									.getSingleResult();
			System.out.println(stus);

    6、分页查询

			session = HibernateUtil.openSession();
			/**
			 * 使用setFirstResult和setMaxResults可以完成分页的offset和pageSize的设置
			 */
			List<Student> stus = session.createQuery("select stu from Student stu where stu.classroom.id in (:clas)",
										Student.class)
									.setParameterList("clas", new Integer[]{1,2})
									.setFirstResult(0).setMaxResults(15)
									.getResultList();
			for(Student stu:stus) {
				System.out.println(stu.getName());
			}

    7、导航查询(详见3.2:对象导航连接)

			/**
			 * 如果对象中存在相应的导航对象,可以直接导航完成查询
			 */
			List<Student> stus = session.createQuery("select stu from Student stu where stu.classroom.name=? and stu.name like ?",
										Student.class)
									.setParameter(0, "计算机教育班").setParameter(1, "%张%")
									.getResultList();
			for(Student stu:stus) {
				System.out.println(stu.getName());
			}

3、连接查询

    3.1、基于SQL的查询

    连接的三种方式:

        1、内连接(连接的两张表都有数据的连接)

SELECT * FROM t_stu t1 JOIN t_classroom t2 ON(t1.cid=t2.id)

        以上得到的数据是t_stu和t_classroom中都有的数据。       

        2、左外连接

SELECT * FROM t_classroom t1 LEFT JOIN t_stu t2 ON(t1.id=t2.cid)

        以上得到的结果是左边这张表的所有数据来连接右边这张表的数据,如果右表没有数据,会直接使用
        null来填充,这种在做统计时非常有用。

SELECT t1.name,COUNT(t2.id) FROM t_classroom t1 LEFT JOIN t_stu t2 ON (t1.id=t2.cid) GROUP BY t1.id
/*
 * COUNT(t2.id):必须是第二张表单的id,此时为null的值就会统计出0
 * 根据t1.id进行分组,其实也就等于根据班级进行分组
 * 以上实现了某一个班的人数的统计
*/

        3、右外连接

SELECT * FROM t_classroom t1 RIGHT JOIN t_stu t2 ON(t1.id=t2.cid)

    以上得到的是右表的所有数据,如果左表没有,就使用null来填充。

    3.2、基于Hibernate的连接查询

    1、使用对象导航连接(比较方便的一种操作方式),局限:只是内连接。

			/**
			 * 在Hibernate中可以直接使用对象的导航语句来完成查询
             * 这种方式称为内部连接查询。
             * 使用的是内连接。
             * stu.classroom.name=?:使用对象导航来完成连接,此时等于内连接
             * 
			 */
			List<Student> stus = session.createQuery("select stu from Student stu where stu.classroom.name=? and stu.name like ?",
										Student.class)
									.setParameter(0, "计算机教育班").setParameter(1, "%张%")
									.getResultList();
			for(Student stu:stus) {
				System.out.println(stu.getName());
			}

    2、使用连接操作方式

			session = HibernateUtil.openSession();
			/**
			 * 在Hibernate中也可以直接使用join来查询
			 * 这种方式可以直接选择是使用left join还是right join或者join
			 * 以下方式使用的内连接
			 * 此处如果不写投影(stu),默认会将两个对象都查询出来,得到的结果就是Object[]
			 * 如果希望查询某个对象,需要指明投影
			 * stu:必须指明投影对象,不然就是所有连接对象的投影数组
			 * join stu.classroom cla:不使用on,直接连接导航对象
			 */
			List<Student> stus = session.createQuery("select stu from Student stu join stu.classroom cla where cla.id=2",
										Student.class)
									.setFirstResult(0).setMaxResults(15)
									.getResultList();
			for(Student stu:stus) {
				System.out.println(stu.getName());
			}

    3、使用左连接(和sql完全一致)

			session = HibernateUtil.openSession();
			/**
			 * 在Hibernate中也可以直接使用join来查询
			 * 这种方式可以直接选择是使用left join还是right join或者join
			 * 使用left join
			 */
			List<Student> stus = session.createQuery("select stu from Student stu left join stu.classroom cla where cla.id=2",
										Student.class)
									.setFirstResult(0).setMaxResults(15)
									.getResultList();
			for(Student stu:stus) {
				System.out.println(stu.getName());
			}

    4、使用右连接

			session = HibernateUtil.openSession();
			/**
			 * 在Hibernate中也可以直接使用join来查询
			 * 这种方式可以直接选择是使用left join还是right join或者join
			 * 使用right join
			 */
			List<Object[]> stus = session.createQuery("select cla.name,count(stu.classroom.id) from Student stu right join stu.classroom cla group by cla.id",
										Object[].class)
									.getResultList();
			for(Object[] stu:stus) {
				System.out.println(stu[0]+","+stu[1]);
			}

    5、使用DTO对象连接查询

        创建DTO对象:

/**
 * DTO对象没有存储的意义,仅仅是用来进行数据的传输的
 * @author PM
 *
 */
public class StudentDto {
	private int sid;
	private String sname;
	private String sex;
	private String cname;
	private String spename;
	
	public int getSid() {
		return sid;
	}
	public void setSid(int sid) {
		this.sid = sid;
	}
	public String getSname() {
		return sname;
	}
	public void setSname(String sname) {
		this.sname = sname;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public String getCname() {
		return cname;
	}
	public void setCname(String cname) {
		this.cname = cname;
	}
	public String getSpename() {
		return spename;
	}
	public void setSpename(String spename) {
		this.spename = spename;
	}
	
	public StudentDto(int sid, String sname, String sex, String cname, String spename) {
		super();
		this.sid = sid;
		this.sname = sname;
		this.sex = sex;
		this.cname = cname;
		this.spename = spename;
	}
	
	public StudentDto() {
	}

        使用new XXXObject完成查询:

			session = HibernateUtil.openSession();
			/**
			 * 直接可以使用new XXXObject完成查询,注意,一定要加上Object的完整包名
			 * 这里使用的new XXX,必须在对象中加入相应的构造函数
			 */
			List<StudentDto> stus = session.createQuery("select new org.pm.hibernate.model.StudentDto "
					+ "(stu.id as sid,stu.name as sname,stu.sex as sex,cla.name as cname,spe.name as spename) "
					+ "from Student stu left join stu.classroom cla left join cla.special spe",
										StudentDto.class)
									.getResultList();
			for(StudentDto stu:stus) {
				System.out.println(stu.getSid()+","+stu.getSname()+","+stu.getSex()+","+stu.getCname()+","+stu.getSpename());
			}

    6、分组查询

			session = HibernateUtil.openSession();
			/**
			 * having是为group来设置条件的
			 */
			List<Object[]> stus = session.createQuery("select spe.name,count(stu.classroom.special.id) from "
					+ "Student stu right join stu.classroom.special spe "
					+ "group by spe having count(stu.classroom.special.id)>150",
										Object[].class)
									.getResultList();
			for(Object[] stu:stus) {
				System.out.println(stu[0]+","+stu[1]);
			}
			session = HibernateUtil.openSession();
			/**
			 * 分组查询
			 */
			List<Object[]> stus = session.createQuery("select stu.sex,spe.name,count(stu.classroom.special.id) from "
					+ "Student stu right join stu.classroom.special spe "
					+ "group by spe,stu.sex",
										Object[].class)
									.getResultList();
			for(Object[] stu:stus) {
				System.out.println(stu[0]+","+stu[1]+","+stu[2]);
			}

 

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
OSCHINA
登录后可查看更多优质内容
返回顶部
顶部