Hibernat的HQL语句查询(十六)

东家蝴蝶西家飞,白骑少年今日归。 愿,所有迷茫的人,都不再迷茫的,愿,所有努力工作的人,都可以得到应有的回报,愿,所有的人,都可以找到回家的方向,愿,再无苦痛,再无离别。

上一章简单介绍了 Hibernate的复合主键映射(十五),如果没有看过,请观看上一章

一. Hibernate的HQL语句

hql,全称是 Hibernate Query Language ,即Hibernate 查询语言。 是Hibernate对SQL语句的相应的封装,试图用ORM的思想重新构造生成数据表查询。 其中,实体类对应数据表,实体类对应视图,实体属性对应表的字段,类名对应表名。 session. get() ,session.load() 只是最简单的查询形式。

二. 只讲单表的查询

创建一个单表User ,其中只有简单的属性,id,name,sex,age,具体详情可查看以前的文章。 这里插入四条数据:
Hibernat的HQL语句查询(十六)

三.各种各样的查询

三.一 全量查

/**
	 * 查询全部的普通测试
	 */
	@Test
	public void Test1(){
		Session session=HibernateUtil.getSession();
		String hql="From User"; //User是类名,并不是数据表名。 
		Query hqlQuery=session.createQuery(hql);
		List<User> userList=hqlQuery.list();
		userList.forEach(n -> System.out.println(n));
		session.close();
	}

Hibernat的HQL语句查询(十六)
这里,并不能将其小写, from user,
Hibernat的HQL语句查询(十六)
也不能select * from User。
Hibernat的HQL语句查询(十六)

三.二 条件不传值查询

@Test
	public void Test2(){
		Session session=HibernateUtil.getSession();
		String hql="From User u where u.name='两个蝴蝶飞' and u.age=24 order by u.id";
		Query hqlQuery=session.createQuery(hql);
		List<User> userList=hqlQuery.list();
		userList.forEach(n -> System.out.println(n));
		session.close();
	}

可以放置正常的参数,也可以进行排序 order by .
Hibernat的HQL语句查询(十六)
均可以正确的查询,不再继续贴查询结果了。

三.三 ?形式传值

@Test
	public void Test3(){
		Session session=HibernateUtil.getSession();
		String hql="From User u where u.name=? and u.age=?";
		Query hqlQuery=session.createQuery(hql);
		//如果知道确切的类型,可以用具体的类型  已经过时了。		
		hqlQuery.setString(0,"两个蝴蝶飞"); hqlQuery.setInteger(1,24);
		List<User> userList=hqlQuery.list();
		userList.forEach(n -> System.out.println(n));
		session.close();
	}

可以直接用setString, setInteger 进行赋值。 从0开始,注意起始位置 。但是这种方式已经不建议使用了。 统一用setParameter() 进行设置.

@Test
	public void Test3(){
		Session session=HibernateUtil.getSession();
		String hql="From User u where u.name=? and u.age=?";
		Query hqlQuery=session.createQuery(hql);
		//强烈建议用 setParameter() 来设置值。
		hqlQuery.setParameter(0,"两个蝴蝶飞");
		hqlQuery.setParameter(1,24);
		List<User> userList=hqlQuery.list();
		userList.forEach(n -> System.out.println(n));
		session.close();
	}

三.四 :形式传值

@Test
	public void Test4(){
		Session session=HibernateUtil.getSession();
		// 使用属性值,建议用属性名称
		String hql="From User u where u.name=:name and u.age=:age";
		Query hqlQuery=session.createQuery(hql);
		hqlQuery.setParameter("name","两个蝴蝶飞");
		hqlQuery.setParameter("age",24);
		List<User> userList=hqlQuery.list();
		userList.forEach(n -> System.out.println(n));
		session.close();
	}

当然,也可以使用普通的字符串,如 a,b等。

@Test
	public void Test4(){
		Session session=HibernateUtil.getSession();
		// 不建议使用无意义的 a,b 
		String hql="From User u where u.name=:a and u.age=:b";
		Query hqlQuery=session.createQuery(hql);
		hqlQuery.setParameter("a","两个蝴蝶飞");
		hqlQuery.setParameter("b",24);
		List<User> userList=hqlQuery.list();
		userList.forEach(n -> System.out.println(n));
		session.close();
	}

如果传入的是属性的值,那么也可以传入对象进行查询。

@Test
	public void Test5(){
		Session session=HibernateUtil.getSession();
		// 使用属性值,用对象进行查询。
		String hql="From User u where u.name=:name and u.age=:age";
		Query hqlQuery=session.createQuery(hql);
		User user=new User();
		user.setName("两个蝴蝶飞");
		user.setAge(24);
		//利用setProperties 传入对象,进行相应的查询
		hqlQuery.setProperties(user);  //也可支持Map形式。
		List<User> userList=hqlQuery.list();
		userList.forEach(n -> System.out.println(n));
		session.close();
	}

建议使用 : 的形式,且参数名与属性名相同。

三.五 like 形式的使用

@Test
	public void Test6(){
		Session session=HibernateUtil.getSession();
		// 使用属性名
		String hql="From User u where u.name like :name and u.age>:age";
		Query hqlQuery=session.createQuery(hql);
		//构建Map 进行传值
		Map<String,Object> map=new HashMap<String,Object>();
		map.put("name","%"+"蝴蝶飞"+"%"); //注意like的使用
		map.put("age",23);
		hqlQuery.setProperties(map); 
		List<User> userList=hqlQuery.list();
		userList.forEach(n -> System.out.println(n));
		session.close();
	}

三.六 ById 的查询单个对象,用uniqueResult

@Test
	public void Test7(){
		Session session=HibernateUtil.getSession();
		String hql="From User u where u.id=:id";
		Query hqlQuery=session.createQuery(hql);
		hqlQuery.setParameter("id",1);
		//确定查询的是单个对象,用uniqueResult(), 当多个时,只返回第一个值。
		User user=(User) hqlQuery.uniqueResult(); //进行强制转换
		System.out.println(user);
		session.close();
	}

三.七 投影查询,即只查询几列

@Test
	public void Test8(){
		Session session=HibernateUtil.getSession();
		// 只查询name和age
		String hql="SELECT u.name,u.age From User u";
		Query hqlQuery=session.createQuery(hql);
		//List<User> userList=hqlQuery.list();  //不支持直接转换成User
		List<Object []> userList=hqlQuery.list(); //查询出来的是List 对象数组
		for (Object[] objects : userList) { //二级循环,进行查询
			for (int i = 0; i < objects.length; i++) {
				Object object = objects[i];
				System.out.print(object+",");
			}
			System.out.println();
		}
		session.close();
	}

三.八 投影查询,返回对象

@Test
	public void Test9(){
		Session session=HibernateUtil.getSession();
		// 直接进行相应的构造。 其中,在user类中必须有这样的构造,还有一个空构造函数。
		String hql="SELECT new com.yjl.pojo.User(u.name,u.age) From User u";
		Query hqlQuery=session.createQuery(hql);
		List<User> userList=hqlQuery.list();
		userList.forEach(n -> System.out.println(n));
		session.close();
	}

User 类中必须存在这样的构造。

public User() {
		super();
	}
	public User(String name, Integer age) {
		super();
		this.name = name;
		this.age = age;
	}

三.九 统计函数,如count(),sum()

@Test
	public void Test10(){
		Session session=HibernateUtil.getSession();
		//String hql="SELECT count(*) From User u"; 
		String hql="SELECT max(u.age) From User u";
		Query hqlQuery=session.createQuery(hql);
		Object object=hqlQuery.uniqueResult(); //查询出的是单个值,用uniqueResult()
		System.out.println(object);
		session.close();
	}

三.十 分页查询

@Test
	public void Test11(){
		Session session=HibernateUtil.getSession();
		String hql="From User u";
		Query hqlQuery=session.createQuery(hql);
		hqlQuery.setMaxResults(2);  //每页显示的数目
		hqlQuery.setFirstResult((2-1)*2); //开始处的索引
		List<User> userList=hqlQuery.list();
		userList.forEach(n -> System.out.println(n));
		session.close();
	}

与条件组合的分页查询为:

public void Test12(){
		Session session=HibernateUtil.getSession();
		String hql="From User u where u.name like :name and u.age>:age order by u.id desc";
		Query hqlQuery=session.createQuery(hql);
		hqlQuery.setMaxResults(2);
		hqlQuery.setFirstResult((1-1)*2);  //2页时,查询不出来结果
		hqlQuery.setParameter("name","%蝴蝶飞%");
		hqlQuery.setParameter("age",22);
		List<User> userList=hqlQuery.list();
		userList.forEach(n -> System.out.println(n));
		session.close();
	}

三.十一 批量ids查询

@Test
	public void Test11(){
		Session session=HibernateUtil.getSession();
		String hql="From User u where u.id in :ids";
		Query hqlQuery=session.createQuery(hql);
		//用setParameterList, 支持数组和集合。
		hqlQuery.setParameterList("ids",new Object[]{1,2});
		List<User> userList=hqlQuery.list();
		userList.forEach(n -> System.out.println(n));
		session.close();
	}

三.十二 分组查询

@Test
	public void Test13(){
		Session session=HibernateUtil.getSession();
		// 按照性别查询,统计数组
		String hql="select u.sex,count(*) From User u where u.age >:age group by u.sex having count(*)>1 order by u.id desc";
		Query hqlQuery=session.createQuery(hql);
		hqlQuery.setParameter("age",22);
		List<Object []> userList=hqlQuery.list();
		for (Object[] objects : userList) {
			for (int i = 0; i < objects.length; i++) {
				Object object = objects[i];
				System.out.print(object+",");
			}
			System.out.println();
		}
		session.close();
	}

其中,排序可以直接写进HQL 语句中。

四.Query 接口

@Incubating
 public abstract interface Query<R>
 extends TypedQuery<R>, org.hibernate.Query<R>, CommonQueryContract
{
	
}

Hibernat的HQL语句查询(十六)
Hibernat的HQL语句查询(十六)
Hibernat的HQL语句查询(十六)
Hibernat的HQL语句查询(十六)
由于能力不足,Query 接口,暂时无法解析。 抱歉。

谢谢!!!