Hibernate上路_18-Hibernate查询方式

1.导航对象图:

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

1Query查询的链式写法:

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)绑定基本类型参数:

Hibernate上路_18-Hibernate查询方式 

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检索方式:

QBCQuery 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();
	}


2QBC常用限定方法

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<PojoOrder> orders = criteria.list();
	System.out.println(orders);


5.本地SQL检索方式:

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

1SQLQuery查询代码:

@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<Object[]> 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<PojoOrder> 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查询结果排序:

1HQL方式:

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


2QBC方式:

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

8.setFirstResult分页查询:

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

1HQL

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

2QBC

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


9.uniqueResult单一结果:

主要用于countsummax 

//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方法):

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

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

<hibernate-mapping package="cn.cvu.hibernate.domain">
  <class name="PojoOrder">
  <!-- 略 -->
  </class>
  <query name="findPojoOrdersByPojoUserName">
  <![CDATA[ from PojoOrder where user.name = ? ]]>
  </query>
</hibernate-mapping>


2)测试:

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

11.连接查询 

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

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<Object>;查询多列,返回List<Object[]>
		Query query = session.createQuery("select u.id, u.name from PojoUser as u");
		List<PojoUser[]> 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 ; 

Hibernate上路_18-Hibernate查询方式


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

select new map(id,name) from POJO ;  

Hibernate上路_18-Hibernate查询方式


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

select new POJO(id,name) from POJO ; 

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

Hibernate上路_18-Hibernate查询方式


4QBC方式的投影:

Hibernate上路_18-Hibernate查询方式


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<PojoOrder> list = criteria.getExecutableCriteria(session).list();
		for (PojoOrder order : list) {
			System.out.println(order);
		}

		transaction.commit();
		session.close();
	}

Hibernate上路_18-Hibernate查询方式

- end
 

你可能感兴趣的:(sql,Hibernate,jdbc,数据持久化,查询方式)