Hibernate 与 HQL

Hibernate 与 HQL

HQL:Hibernate Query Language:hibernate查询语言;

Sql:语句针对的是数据库中的表的查询,而Hql是对类中的对象进行查询;

HQL的介绍最好是在代码中去解释:

Hql查询案例:查询所有的 list( ) 方法

	
	@Test
	public void test01() {
		//由于session是使用的getCurrentSession()获取的到的,必须在事务的环境下执行
		//获取session
		Session session = HbnUtil.getSession();//HbnUtil是一个工具类
		//开启事务
		session.getTransaction().begin();
		//创建hql
		String hql="from Student";
		//获取query查询对象
		Query query = session.createQuery(hql,Student.class);
		//执行全部查询操作
		List <Student>list = query.list();
		//执行一项效果
		for (Student student : list) {
			System.out.println(student);
		}
		//提交事务
		session.getTransaction().commit();
	}
//原生态sql实现
	@Test
	public void test02() {
		//由于session是使用的getCurrentSession()获取的到的,必须在事务的环境下执行
		//获取session
		Session session = HbnUtil.getSession();
		//开启事务
		session.getTransaction().begin();
        //SQL是面向表的
		List<Student> list = session.createSQLQuery("select * from t_student").addEntity(Student.class).list();
		//执行一项效果
		for (Student student : list) {
			System.out.println(student);
		}
		//提交事务
		session.getTransaction().commit();
	}

Hql查询,查询一条记录uniqueResult()方法

@Test
	public void test03() {
		//由于session是使用的getCurrentSession()获取的到的,必须在事务的环境下执行
		//获取session
		Session session = HbnUtil.getSession();
		//开启事务
		session.getTransaction().begin();
		Student stu = session
					.createQuery("from Student as stu where stu.sid=:mysid",Student.class)
					.setParameter(“mysid”, 3)//绑定参数
					.uniqueResult();//执行唯一查询
		//提交事务
		session.getTransaction().commit();
	}

//原生sql
	@Test
	public void test0032() {
		//获取session
		Session session = HbnUtil.getSession();
		//开启事务
		session.getTransaction().begin();
		Student stu = (Student) session.createSQLQuery("select * from t_student where sid=?")
				.setParameter(1, 3)//第一个?,赋值
				.addEntity(Student.class)
				.uniqueResult();
		//展示一下情况
		System.out.println(stu);
		//提交事务
		session.getTransaction().commit();
	}

Hql查询,条件查询

  • 使用别名占位,setXxx ()绑定参数:setXxx (String name, Object value)。别名的命名。规则为,冒号后跟别名,别名可是任意名称。
	@Test
	public void test004() {
		//获取session
		Session session = HbnUtil.getSession();
		//开启事务
		session.getTransaction().begin();
		String hql="from Student as stu where stu.score>:score and stu.age>=:age";
		List<Student> list = session.createQuery(hql,Student.class)
				.setParameter("score", 95.0)
				.setParameter("age", 22)
				.list();
		//遍历一下
		for (Student stu : list) {
			//展示一下情况
			System.out.println(stu);
		}
		//提交事务
		session.getTransaction().commit();
	}
//原生sql
	@Test
	public void test0042() {
		//获取session
		Session session = HbnUtil.getSession();
		//开启事务
		session.getTransaction().begin();
		String hql="select * from t_student where score>? and age>=?";
		List<Student> list = session.createSQLQuery(hql)
				.addEntity(Student.class)
				.setParameter(1, 95.0)
				.setParameter(2, 22)
				.list();
		//遍历一下
		for (Student stu : list) {
			//展示一下情况
			System.out.println(stu);
		}
		//提交事务
		session.getTransaction().commit();
	}

Hql查询,之排序查询 order by  asc,升序,desc降序’;

	@Test
	public void test005() {//hql查询
		//获取session
		Session session = HbnUtil.getSession();
		//开启事务
		session.getTransaction().begin();
		String hql="from Student order by score asc";
		List<Student> list = session.createQuery(hql).list();
		//遍历一下
		for (Student stu : list) {
			//展示一下情况
			System.out.println(stu);
		}
		//提交事务
		session.getTransaction().commit();
	}

Hql查询,之分页查询

  • Query 接口中具有 setFirstResult()方法,用于设置从总查询结果集的第几条记录作为本查询结果子集的开始,即本页的开始。总查询结果集从 0 开始记数。而 setMaxResults()方法用于设置该页所包含的记录数。
  • 分页查询的 SQL 语句:select * from … where …limit startIndex, pageSize;
  • startIndex 为开始索引,设置从总查询结果集的第几条记录作为本查询结果子集的开始,即本页的开始。总查询结果集从 0 开始记数。
  • pageSize 为该页所包含的记录数。
	@Test
	public void test006() {
		//获取session
		Session session = HbnUtil.getSession();
		//开启事务
		session.getTransaction().begin();
		String hql="from Student";
		List<Student> list = session.createQuery(hql)
									.setFirstResult(1)
									.setMaxResults(2)
									.list();
		//遍历一下
		for (Student stu : list) {
			//展示一下情况
			System.out.println(stu);
		}
		//提交事务
		session.getTransaction().commit();
	}
//原生态 查询
	@Test
	public void test0062() {
		//获取session
		Session session = HbnUtil.getSession();
		//开启事务
		session.getTransaction().begin();
		String hql="select * from t_student limit ?,?";
		List<Student> list = session.createSQLQuery(hql)
				.setParameter(1, 0)
				.setParameter(2, 2)
				.addEntity(Student.class)
				.list();
		//遍历一下
		for (Student stu : list) {
			//展示一下情况
			System.out.println(stu);
		}
		//提交事务
		session.getTransaction().commit();

模糊查询 like

  • 通过like后面使用占位符,:sname,冒号固定,后面的字符随意,但是兼顾见名知意;
	@Test
	public void test007() {
		//获取session
		Session session = HbnUtil.getSession();
		//开启事务
		session.getTransaction().begin();
		String hql="from Student as stu where stu.sname like:sname";
		List<Student> list = session.createQuery(hql)
					.setParameter("sname", "%哈%")
					.list();
		//遍历一下
		for (Student stu : list) {
			//展示一下情况
			System.out.println(stu);
		}
		//提交事务
		session.getTransaction().commit();
	}
//原生态的模糊查询
@SuppressWarnings("unchecked")
	@Test
	public void test0072() {
		//获取session
		Session session = HbnUtil.getSession();
		//开启事务
		session.getTransaction().begin();
		String hql="select * from t_student where sname like ?";
		List<Student> list = session.createSQLQuery(hql)
			  .addEntity(Student.class)
			  .setParameter(1, "%哈%")
			  .list();
		//遍历一下
		for (Student stu : list) {
			//展示一下情况
			System.out.println(stu);
		}
		//提交事务
		session.getTransaction().commit();
	}

BQL查询,Critertie 查询,不需要sql语句,只需要记住Restrictions添加条件,单词”Restrictions”约束,管制的意思;

	@Test
	public void test008() {
		//获取session
		Session session = HbnUtil.getSession();
		//开启事务
		session.getTransaction().begin();
		List<Student> list = session.createCriteria(Student.class)
				.add(Restrictions.like("sname", "%哈%"))
				.list();
		//遍历一下
		for (Student stu : list) {
			//展示一下情况
			System.out.println(stu);
		}
		//提交事务
		session.getTransaction().commit();
	}	

聚合函数查询,注意区分 count(*)与 count(name)的不同。count(*)与 count(id)等价,均表示未空记录数。而 count(name)则表示字段 name 的非空记录数。

	@Test
	public void test009() {
		//获取session
		Session session = HbnUtil.getSession();
		//开启事务
		session.getTransaction().begin();
		String hql="select count(sid) from Student";
		Object x = session.createQuery(hql).uniqueResult();
		//遍历一下
		System.out.println(x);
		System.out.println("count(sid) vs count(*)");
		
		String hql1="select count(*) from Student";
		Object y = session.createQuery(hql1).uniqueResult();
		System.out.println(y);
		//提交事务
		session.getTransaction().commit();
	}

通过QBC查询实现聚合函数查询,投影查询

Projection,中文意思:投影。Projections 中包含很多聚合函数的静态方法。

//投影查询
	@Test
	public void test0010() {
		//获取session
		Session session = HbnUtil.getSession();
		//开启事务
		session.getTransaction().begin();
		Object y = session.createCriteria(Student.class)
			   .setProjection(Projections.count("sid"))
			   .uniqueResult();
		System.out.println(y);
		//提交事务
		session.getTransaction().commit();
	}

投影查询

(1 )SQL 查询

要求查询的字段的别名要与实体类的属性名相同,这样才能将结果转换为相应类的对象。

(2)HQL 查询

该查询要求实体类中具有相同投影作为参数的带参构造器。所以,首先要在 Student 类中添加相应的带参构造器

	public Student(String sname, int age) {
		this.sname = sname;
		this.age = age;
	}
	@Test
	public void test0012() {
		//获取session
		Session session = HbnUtil.getSession();
		//开启事务
		session.getTransaction().begin();
		String hql="select new Student(sname,age) from Student";
		List<Student> list = session.createQuery(hql).list();
		//遍历集合
		for (Student stu : list) {
			System.out.println(stu);
		}
		//提交事务
		session.getTransaction().commit();
	}

Hql:分组查询,select * from student group by age having ?

(1 )SQL 查询

having,对分组结果进行筛选。下面代码实现的功能是,查询出所有年龄段,及人数多于 1 人的年龄段。

	@Test
	public void test0013() {//查询出来的是年龄段
		//获取session
		Session session = HbnUtil.getSession();
		//开启事务
		session.getTransaction().begin();
		String hql="select age from Student group by age";
		List<Integer> list = session.createQuery(hql)
									.list();
		//遍历
		for (Integer i : list) {
			System.out.println(i);
		}
		String hql2="select age from Student group by age having count(age)>:age";
		List list2 = session.createQuery(hql2)
		.setParameter("age", 1L)
		.list();
		//遍历
		for (Object o : list2) {
			System.out.println(o);
		}
		//提交事务
		session.getTransaction().commit();
	}

(2)QBC,hibernate不支持having操作:

	@Test
	public void test0014() {//查询出来的是年龄段
		//获取session
		Session session = HbnUtil.getSession();
		//开启事务
		session.getTransaction().begin();
		List list = session.createCriteria(Student.class)
				.setProjection(Projections.groupProperty("age"))
				.list();
		for (Object object : list) {
			System.out.println(object);
		}
		//提交事务
		session.getTransaction().commit();
	}

Query中list() vs iterate区别它们的区别:

使用 Query 接口的 list()与 iterate()进行查询,查看其控制台的 SQL 语句的输出情况,可以看到它们的区别主要有两点:

​ A、使用 list(),会一次性将所有符合条件的记录查询出来;而使用 iterate(),则首先会查询出所有符合条件的记录的 id,然后再根据这些 id 逐个查询出记录的具体内容。

​ B、使用 list(),不会使用缓存机制,即每执行一次查询代码,控制台均会执行一次 SQL查询语句;而使用 iterate(),则会使用缓存机制,只有第一次会执行 SQL 查询,再往后的查询会直接从缓存中读取。

public void test0015() {
		//获取session
		Session session = HbnUtil.getSession();
		//开启事务
		session.getTransaction().begin();
		String hql="from Student";
		//执行查询
		//第一次查询
		System.out.println("第一次查询");
		List<Student> list = session.createQuery(hql).list();
		for (Student stu : list) {
			System.out.println(stu);
		}
		//第二次查询
		System.out.println("第二次查询");
		List<Student> list2 = session.createQuery(hql).list();
		for (Student stu : list2) {
			System.out.println(stu);
		}
		//提交事务
		session.getTransaction().commit();
	}

	@Test
	@SuppressWarnings({ "unchecked", "deprecation" })
	public void test0016() {
		//获取session
		Session session = HbnUtil.getSession();
		//开启事务
		session.getTransaction().begin();
		String hql="from Student";
		//执行查询
		//第一次查询
		System.out.println("第一次查询");
		Iterator<Student> it = session.createQuery(hql).iterate();
		while(it.hasNext()) {
			Student stu = it.next();
			System.out.println(stu);
		}
		//第二次查询
		System.out.println("第二次查询");
		Iterator<Student> it1 = session.createQuery(hql).iterate();
		while(it1.hasNext()) {
			Student stu = it1.next();
			System.out.println(stu);
		}
		//提交事务
		session.getTransaction().commit();
	}

猜你喜欢

转载自blog.csdn.net/weixin_43650254/article/details/85553935