博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Hibernate上路_18-Hibernate查询方式
阅读量:6818 次
发布时间:2019-06-26

本文共 8765 字,大约阅读时间需要 29 分钟。

hot3.png

1.导航对象图:

已经获得持久态对象,通过对象引用关系,执行关联对象的查询 

1)Query查询的链式写法:

public void testQuery(){		Session session = UtilGetSession.openSession();		Transaction transaction = session.beginTransaction();				/**原多行写法*//*		Query query = session.createQuery("from PojoUser where t_name= :xxx");		query.setParameter("xxx", "PapaRoach");		List list = query.list(); */		/**链式写法*/		List list = session.createQuery("from PojoUser where t_name= :xxx").setParameter("xxx", "PapaRoach").list();		System.out.println(list);		transaction.commit();		session.close();	}

2)绑定参数:

(1)绑定基本类型参数:

 

(2)绑定实体参数:

/**使用ID*//*		Query query = session.createQuery("from PojoOrder where user= ?");		query.setEntity(0, new PojoUser(1)); //构造方法传入ID创建托管对象		List list = query.list(); */		/**使用实体的属性Name*/		Query query = session.createQuery("from PojoOrder where user.name= ?");		query.setParameter(0, "PapaRoach");		List list = query.list();

2.OID检索方式:

根据OID检索get / load 

3.HQL检索方式:

根据HQL语句进行检索。session.createQuery(hql)

4.QBC检索方式:

QBC(Query By Criteria) 根据Criteria对象完成检索。session.createCriteria(domain.class) 

1)标准查询:

public void testQuery(){		Session session = UtilGetSession.openSession();		Transaction transaction = session.beginTransaction();				/** 1.查询全部 **//*		Criteria criteria = session.createCriteria(PojoUser.class);		List users = criteria.list();*/				/** 2.查询指定ID **//*		Criteria criteria = session.createCriteria(PojoOrder.class);		criteria.add(Restrictions.eq("user", new PojoUser(1)));	//必须ID */				/** 3.通过别名查询指定属性 **/		Criteria criteria = session.createCriteria(PojoOrder.class);		criteria.createAlias("user", "u");	//创建别名		criteria.add(Restrictions.eq("u.name", "PapaRoach"));	//必须别名.属性				List orders = criteria.list();		System.out.println(orders);				transaction.commit();		session.close();	}

2)QBC常用限定方法:

Restrictions.eq --> equal,等于

Restrictions.allEq --> 参数为Map对象,使用key/value进行多个等于的比对,相当于多个Restrictions.eq的效果
Restrictions.gt --> great-than > 大于
Restrictions.ge --> great-equal >= 大于等于
Restrictions.lt --> less-than, < 小于
Restrictions.le --> less-equal <= 小于等于
Restrictions.between --> 对应SQL的between子句
Restrictions.like --> SQLLIKE子句
Restrictions.in --> SQLin
Restrictions.and --> and 关系
Restrictions.or --> or 关系
Restrictions.isNull --> 判断属性是否为空,为空则返回true
Restrictions.isNotNull --> isNull相反
Restrictions.sqlRestriction --> SQL限定的查询
Order.asc --> 根据传入的字段进行升序排序
Order.desc --> 根据传入的字段进行降序排序
MatchMode.EXACT --> 字符串精确匹配。相当于"like 'value'"
MatchMode.ANYWHERE --> 字符串在中间匹配。相当于"like '%value%'"
MatchMode.START --> 字符串在最前面的位置。相当于"like 'value%'"
MatchMode.END --> 字符串在最后面的位置。相当于"like '%value'"

3)复杂查询:

早期hibernate版本进行条件查询时使用Expression,目前Expression已经过时,推荐使用父类Restrictions 

Criteria criteria = session.createCriteria(PojoOrder.class);	// 条件一:lt=id小于5。取值0-4	SimpleExpression expression1 = Restrictions.lt("id", 5);	// 条件二:like=name包含'ne'。ilike忽略大小写;like不忽略	SimpleExpression expression2 = Restrictions.like("name", "%球%");	// 并列传入两个条件	criteria.add(Restrictions.and(expression1, expression2));	List
orders = criteria.list(); System.out.println(orders);

5.本地SQL检索方式:

根据SQL语句完成检索。session.createSQLQuery(sql);主要用于企业对查询进行优化时

1)SQLQuery查询代码:

@Test	public void testSQLQuery(){		Session session = UtilGetSession.openSession();		Transaction transaction = session.beginTransaction();				String sql="select *   from tb_user, tb_order  where tb_order.t_user_id=tb_user.t_id    and tb_user.t_name=?";		SQLQuery sqlQuery = session.createSQLQuery(sql);		sqlQuery.setParameter(0, "Eminem");				List
list = sqlQuery.list(); for (Object[] object : list) { System.out.println(Arrays.toString(object)); } transaction.commit(); session.close(); }

错误: 

org.hibernate.loader.custom.NonUniqueDiscoveredSqlAliasException: Encountered a duplicated sql alias [t_id] during auto-discovery of a native-sql query  

解决:

问题出在 Query须要使用别名来区分相同名称的列。

String sql=  "SELECT u.t_id AS uid, u.t_address AS uadd, o.t_id AS oid, o.t_name AS oname "+			"FROM   tb_user AS u, tb_order AS o "+ 			"WHERE  o.t_user_id = u.t_id "+			"AND    u.t_name=?";

2)使用Bean封装返回数据:

public void testSQLQuery(){		Session session = UtilGetSession.openSession();		Transaction transaction = session.beginTransaction();				/* 别名不能和POJO中的变量名相同		 * 必须查询*,或指定全部字段		 */		String sql = "SELECT * "+					 "FROM   tb_user as userr, tb_order as ord "+ 					 "WHERE  ord.t_user_id = userr.t_id "+					 "AND   userr.t_name=? ";		SQLQuery sqlQuery = session.createSQLQuery(sql);		sqlQuery.setParameter(0, "Eminem");				sqlQuery.addEntity(PojoOrder.class);	//查询结果封装到一个PojoOrder对象,仅用于SqlQuery		List
list = sqlQuery.list(); System.out.println(list); transaction.commit(); session.close(); }

6.多态查询:

查询PO类的父类,可将对应表中全部子类数据查出 

public void testQuery(){		Session session = UtilGetSession.openSession();		Transaction transaction = session.beginTransaction();		//直接查询对象		//Query query = session.createQuery("from PojoOrder");		//多态查询,会将其子类全部查出。非POJO类需用全路径		Query query = session.createQuery("from java.lang.Object");		List list = query.list();		System.out.println(list);				transaction.commit();		session.close();	}

7.order_by查询结果排序:

1)HQL方式:

//hql=from Pojo order by 主键属性 顺序		List orders = session.createQuery("from PojoOrder order by id desc").list();

2)QBC方式:

//标准查询器(对象).addOrder(顺序=(hibernate的排序器(排序参照))).list();		List
orders =   session.createCriteria(PojoOrder.class)  .addOrder(org.hibernate.criterion.Order.desc("id"))  .list();
  

8.setFirstResult分页查询:

Query和Criteria都提供。setFirstResult开始记录索引,setMaxResults查询条数

1)HQL:

Query query = session.createQuery("from PojoOrder");		query.setFirstResult(3);	//索引值。从0开始		query.setMaxResults(3);	//查询条数		List list = query.list();		System.out.println(list);
  

2)QBC:

Criteria criteria = session.createCriteria(PojoOrder.class);		criteria.setFirstResult(3);		criteria.setMaxResults(3);		List list = criteria.list();		System.out.println(list);

9.uniqueResult单一结果:

主要用于count、sum、max 

//Query query = session.createQuery("select count(*) from PojoOrder"); //count返回long		//Query query = session.createQuery("select sum(totalprice) from PojoOrder");		Query query = session.createQuery("select max(totalprice) from PojoOrder");		Object value = query.list();		System.out.println(value);

10.NamedQuery命名查询(自定义HQL方法):

常用的HQL在java源代码不便于维护。可将这些语句写入配置文件并命名,以调用API的方式使用

1)在POJO.hbm.xml中配置Query方法:

  
  
  
  
    

2)测试:

  //直接调用方法名  Query query = session.getNamedQuery("findPojoOrdersByPojoUserName");  //仍需手动传入参数  query.setParameter(0, "Eminem");  List list = query.list();  System.out.println(list);

11.连接查询 

多表关联查询。hibernate提供的Oracle、MySql都支持的七种查询:

1)内连接inner join | join与隐式内连接:

返回两个表都存在的数据:

select * from 1 inner join 2 on 1.id = 2.id ; 

等价于使用
where
的隐式内连接:
select * from 
1, 
where 
1.id = 
2.id
 ; 

2)左外连接left outer join | left join :

用左表匹配右表,无论是否完全匹配,左表数据全部返回,右表没有匹配的数据填充null:

select * from 表left outer join  表2 on  表1.id =  表2 .id;  

3)右外连接right outer join | right join :

用左表匹配右表,无论是否完全匹配,右表数据全部返回,左表没有匹配的数据填充null:

select * from right outer join  2 on  1.id =  2 .id;  

4)迫切左外连接left outer join fetch | left join fetch :

迫切左外连接是hibernate中的hql方式,转为sql后仍然是左外链接。

//hibernate为实现数据完整性,用一方顾客匹配多方订单时,按多方返回的数据有重复		//Query query = session.createQuery("from PojoUser as u left outer join fetch u.orders");		//去重		Query query = session.createQuery("select distinct(u) from PojoUser as u left outer join fetch u.orders");		List list = query.list();		System.out.println(list.size());

12.投影查询:

查询数据表中一部分字段:

//指定查询一列,返回List;查询多列,返回List
Query query = session.createQuery("select u.id, u.name from PojoUser as u"); List
list = query.list(); for (int i = 0; i < list.size(); i++) { Object[] users = list.get(i); //须用Object封装而不是PojoUser for (int j = 0; j < users.length; j++) { System.out.println(users[j]); } }

1)将结果封装到List集合:

select new list(id,name) from POJO ; 

2)将结果封装到Map集合:

select new map(id,name) from POJO ;  

3)将结果封装到POJO对象:

select new POJO(id,name) from POJO ; 

这种封装需要POJO类提供对应构造器,POJO(id,name)构造方法。

4)QBC方式的投影:

13.离线条件查询DetachedCriteria(非常重要):

简单条件查询使用HQL,如果是组合条件,复杂查询则使用Criteria。

问题:在实际开发中业务层没有Session对象,无法session.createCriteria(POJO.class); ,需要使用DetachedCriteria封装查询,然后交给数据层使用以完成查询。

public void testQuery() {		//在业务层封装查询		//查询订单		DetachedCriteria criteria = DetachedCriteria.forClass(PojoOrder.class);		//须指定别名		criteria.createAlias("user", "u");		//添加条件		criteria.add(Restrictions.eq("u.name", "Eminem"));				Session session = UtilGetSession.openSession();		Transaction transaction = session.beginTransaction();		//在数据层执行查询		List
list = criteria.getExecutableCriteria(session).list(); for (PojoOrder order : list) { System.out.println(order); } transaction.commit(); session.close(); }

- end
 

转载于:https://my.oschina.net/vigiles/blog/177538

你可能感兴趣的文章