Hibernate查询

Hibernate查询技术

  1. HQL查询(最常用)
    Hibernate Query Language:Hibernate提供的独有的查询语法
  2. QBC查询
    Query By Criteria 完全面向对象的查询风格,无需写语句。
  3. 原生SQL

HQL查询

基本查询

  • 基础查询
	@Test //基础
	public void testQuery1() {
		
		Session session = HibernateSessionUtils.getSession();
		//String hql = "from Dept"; //类名区分大小写
		String hql = "select d from Dept d";
		Query query = session.createQuery(hql);
		List<Dept> list = query.list();
		for (Dept dept : list) {
			System.out.println(dept.getDeptno()+dept.getDname());
		}
		HibernateSessionUtils.closeSession();
	}
  • 属性查询
	@Test //属性查询
	public void testQuery2() {
		
		Session session = HibernateSessionUtils.getSession();

		String hql = "select e.ename,e.job,e.sal from Emp e";
		Query query = session.createQuery(hql);
		
		//Object[]表示每一行的记录的封装
		List<Object[]> list = query.list();
		for (Object[] row : list) {
			System.out.println(row[0]+","+row[1]+","+row[2]);
		}
		HibernateSessionUtils.closeSession();
	}
  • 聚合统计
	@Test //聚合统计查询:统计员工的最高工资,最低工资,平均工资
	public void testQuery3() {
		
		Session session = HibernateSessionUtils.getSession();

		String hql = "select max(e.sal),min(e.sal),avg(e.sal) from Emp e";
		Query query = session.createQuery(hql);
		
		//Object[]表示每一行的记录的封装
//		List<Object[]> list = query.list();
//		for (Object[] row : list) {
//			System.out.println(row[0]+","+row[1]+","+row[2]);
//		}
		Object[] row = (Object[]) query.uniqueResult(); //返回唯一行
		System.out.println(row[0]+","+row[1]+","+row[2]);
		HibernateSessionUtils.closeSession();
	}
  • 排序
	@Test //排序
	public void testQuery4() {
		
		Session session = HibernateSessionUtils.getSession();

		String hql = "select e from Emp e order by e.sal desc";
		Query query = session.createQuery(hql);
		
		List<Emp> list = query.list();
		for (Emp emp : list) {
			System.out.println(emp.getEname()+","+emp.getSal());
		}
		HibernateSessionUtils.closeSession();
	}
  • 参数绑定
	@Test //参数绑定  1. 索引值 ?  2.命名参数
	public void testQuery5() {
		
		Session session = HibernateSessionUtils.getSession();

		//String hql = "select e from Emp e where e.job=?  and e.sal>?";
		String hql = "select e from Emp e where e.job=:job and e.sal>:sal";
		Query query = session.createQuery(hql);
		
		//设置参数
//		query.setString(0, "CLERK");
//		query.setDouble(1, 2000D);
		query.setString("job", "CLERK");
		query.setDouble("sal", 2000D);
		
		List<Emp> list = query.list();
		for (Emp emp : list) {
			System.out.println(emp.getEname()+","+emp.getSal()+","+emp.getJob());
		}
		HibernateSessionUtils.closeSession();
	}
  • 分页查询
@Test //分页查询
	public void testQuery6() {
		
		Session session = HibernateSessionUtils.getSession();

		String hql = "select e from Emp e";
		//分页参数
		int pageNum = 2;
		int pageSize = 4;
		
		Query query = session.createQuery(hql);
		
		query.setFirstResult((pageNum-1)*pageSize);  //设置分页的开始位置
		query.setMaxResults(pageSize);   // 设置每页的查询数量
		
		List<Emp> list = query.list();
		for (Emp emp : list) {
			System.out.println(emp.getEname()+","+emp.getSal());
		}
		HibernateSessionUtils.closeSession();
	}

高级查询

按以下条件查询员工类 Emp
(1)统计现有员工的职位个数

	@Test //统计现有员工的职位个数
	public void testQuery7() {
		
		Session session = HibernateSessionUtils.getSession();

		String hql = "SELECT COUNT(DISTINCT e.job) FROM Emp e";
		
		Query query = session.createQuery(hql);
		
		Long counter = (Long) query.uniqueResult();
		System.out.println(counter);
		HibernateSessionUtils.closeSession();
	}

(2)按职位统计员工数 分组

	//按职位统计员工数  分组 输出  职位-->员工数
	//分组查询的结果必须是分组的条件和聚合函数的结果
	@Test 
	public void testQuery8() {
		
		Session session = HibernateSessionUtils.getSession();

		String hql = "select e.job,count(e)  FROM Emp e group by e.job";
		
		Query query = session.createQuery(hql);
		
		List<Object[]> list = query.list();
		for (Object[] row : list) {
			System.out.println(row[0] + ","+row[1]);
		}
		HibernateSessionUtils.closeSession();
	}

(3)统计各个部门的平均工资: 输出某个 “部门名称–>工资”

	//统计各个部门的平均工资: 输出某个 "部门名称-->平均工资"
	@Test 
	public void testQuery9() {
		
		Session session = HibernateSessionUtils.getSession();

		String hql = "select e.dept.dname,avg(e.sal) FROM Emp e group by e.dept.dname";
		
		Query query = session.createQuery(hql);
		
		List<Object[]> list = query.list();
		for (Object[] row : list) {
			System.out.println(row[0] + ","+row[1]);
		}
		HibernateSessionUtils.closeSession();
	}

(4)统计各个职位的最高工资 和最低工资

	//统计各个职位的最高工资 和最低工资
	@Test 
	public void testQuery10() {
		
		Session session = HibernateSessionUtils.getSession();

		String hql = "select e.job, max(e.sal),min(e.sal) FROM Emp e group by e.job";
		
		Query query = session.createQuery(hql);
		
		List<Object[]> list = query.list();
		for (Object[] row : list) {
			System.out.println(row[0] + ","+row[1]+","+row[2]);
		}
		HibernateSessionUtils.closeSession();
	}

(5)统计各个部门平均工资高于3000元的部门的名称 ,输出部门名和部门的平均工资 having

	//统计各个部门平均工资高于3000元的部门的名称 ,输出部门名和部门的平均工资  having+聚合函数
	@Test 
	public void testQuery11() {
		
		Session session = HibernateSessionUtils.getSession();

		String hql = "select e.dept.dname, avg(e.sal) FROM Emp e group by e.dept.dname having avg(e.sal)>5000";
		
		Query query = session.createQuery(hql);
		
		List<Object[]> list = query.list();
		for (Object[] row : list) {
			System.out.println(row[0] + ","+row[1]);
		}
		HibernateSessionUtils.closeSession();
	}

连接查询

  • 内连接
	//内连接: 所有的员工和员工部门的名称。
	@Test
	public void testQuery12() {
		
		Session session = HibernateSessionUtils.getSession();

		String hql = "from Emp e inner join e.dept";
		
		Query query = session.createQuery(hql);
		
		List<Object[]> list = query.list();
		for (Object[] row : list) {
			Emp e = (Emp) row[0];
			Dept d = (Dept) row[1];
			System.out.println(e.getEname()+","+e.getJob()+","+e.getSal()+","+d.getDname());
		}
		HibernateSessionUtils.closeSession();
	}
  • 迫切内连接
	//迫切内连接
	@Test
	public void testQuery14() {
		
		Session session = HibernateSessionUtils.getSession();

		String hql = "from Emp e inner join fetch e.dept";
		
		Query query = session.createQuery(hql);
		
		List<Emp> list = query.list();
		for (Emp e : list) {
			System.out.println(e.getEname()+","+e.getJob()+","+e.getSal()+","+e.getDept().getDname());
		}
		HibernateSessionUtils.closeSession();
	}
  • 左外连
	//左外连: 查询所有的部门信息,以及该部门中所有的员工,如果该部门没有员工,提示“无员工”
	@Test  
	public void testQuery15() {
		
		Session session = HibernateSessionUtils.getSession();

		String hql = "from Dept d left outer join d.emps";
		
		Query query = session.createQuery(hql);
		
		List<Object[]> list = query.list();
		for (Object[] row : list) {
			
			Dept d = (Dept) row[0];
			Emp e = (Emp) row[1];
			System.out.println(d.getDname());
			if (e!=null) {
				System.out.println("\t"+e.getEname()+","+e.getJob()+","+e.getSal());
			} else {
				System.out.println("\t无员工");
			}
			
		}
		HibernateSessionUtils.closeSession();
	}
  • 迫切左外连
	//迫切左外连: 查询所有的部门信息,以及该部门中所有的员工,如果该部门没有员工,提示“无员工”
	@Test  
	public void testQuery16() {
		
		Session session = HibernateSessionUtils.getSession();

		String hql = "select distinct d from Dept d left outer join fetch d.emps";
		
		Query query = session.createQuery(hql);
		
		List<Dept> list = query.list();
		for (Dept dept : list) {
			System.out.println(dept.getDname());
			Set<Emp> emps = dept.getEmps();
			if (emps!=null && emps.size()>0) {
				for (Emp e : emps) {
					System.out.println("\t"+e.getEname()+","+e.getJob()+","+e.getSal());
				}
			} else {
				System.out.println("\t无员工");
			}
		}
		HibernateSessionUtils.closeSession();
	}

Criteria查询

特点:

  • 以完全面向对象的编程风格
  • 无需写语句
  • 多条件的组合查询使用较多
  • 也可以做分组,统计查询,多对象的连接查询,但是比较少用。(投影查询)
public class TestQBC {

	
	@Test
	public void testQuery1() {
		Session session = HibernateSessionUtils.getSession();
		Criteria criteria = session.createCriteria(Emp.class);
		int pageNum = 3;
		int pageSize=5;
		criteria.setFirstResult((pageNum - 1)*pageSize);
		criteria.setMaxResults(pageSize);
		List<Emp> list = criteria.list();
		for (Emp emp : list) {
			System.out.println(emp.getEname()+"," + emp.getJob());
		}
		HibernateSessionUtils.closeSession();
	}
	
	@Test
	public void testQuery2() {
		Session session = HibernateSessionUtils.getSession();
		Criteria criteria = session.createCriteria(Emp.class);
		
		//拼接查询条件 
		criteria.add(Restrictions.like("ename", "%n%"))
				.add(Restrictions.gt("sal", 2000D))
				.add(Restrictions.eq("job", "CLERK"));
		
		List<Emp> list = criteria.list();
		for (Emp emp : list) {
			System.out.println(emp.getEname()+"," + emp.getJob());
		}
		HibernateSessionUtils.closeSession();
	}
	
	//实例查询
	@Test
	public void testQuery3() {
		Session session = HibernateSessionUtils.getSession();
		Criteria criteria = session.createCriteria(Emp.class);
		
		Emp emp = new Emp();
		emp.setEname("zhansan");
		//emp.setSal(5000D);
		
		criteria.add(Example.create(emp));   // select * from emp where ename='zhangsan' and sal=5000
		
		List<Emp> list = criteria.list();
		for (Emp e : list) {
			System.out.println(e.getEname()+"," + e.getJob());
		}
		HibernateSessionUtils.closeSession();
	}
 }

原生sql

@Test
	public void testSql() {
		Session session = HibernateSessionUtils.getSession();
		String sql = "select * from dept";
		SQLQuery query = session.createSQLQuery(sql);
		query.addEntity(Dept.class);
//		List<Object[]> list = query.list();
//		for (Object[] row : list) {
//			System.out.println(row[0]+","+row[1]+","+row[2]);
//		}
		List<Dept> list = query.list();
		for (Dept dept : list) {
			System.out.println(dept.getDname());
		}
	}

DAO封装

  • UserDao接口定义
public interface UserDao {

	//增删改
	public boolean addUser(Users user);
	public boolean updateUser(Users user);
	public boolean deleteUser(Users user);
	//查询
	//根据唯一标识查询单个实体
	public Users findUsersById(Integer id);
	//根据实体的条件查询多个实体
	public List<Users> findUsersByExample(Users user);
}
  • UserDaoImpl实现类
package com.gec.hiber.dao.impl;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Example;

import com.gec.hiber.dao.UserDao;
import com.gec.hiber.entity.Users;
import com.gec.hiber.utils.HibernateSessionUtils;

public class UserDaoImpl implements UserDao {

	@Override
	public boolean addUser(Users user) {
		try {
			Session session = HibernateSessionUtils.getSession();
			Transaction tx = session.beginTransaction();
			session.save(user);
			tx.commit();
			return true;
		} catch (HibernateException e) {
			e.printStackTrace();
			return false;
		} finally {
			HibernateSessionUtils.closeSession();
		}
	}

	@Override
	public boolean updateUser(Users user) {
		try {
			Session session = HibernateSessionUtils.getSession();
			Transaction tx = session.beginTransaction();
			session.update(user);
			tx.commit();
			return true;
		} catch (HibernateException e) {
			e.printStackTrace();
			return false;
		} finally {
			HibernateSessionUtils.closeSession();
		}
	}

	@Override
	public boolean deleteUser(Users user) {
		try {
			Session session = HibernateSessionUtils.getSession();
			Transaction tx = session.beginTransaction();
			session.delete(user);
			tx.commit();
			return true;
		} catch (HibernateException e) {
			e.printStackTrace();
			return false;
		} finally {
			HibernateSessionUtils.closeSession();
		}
	}

	@Override
	public Users findUsersById(Integer id) {
		Session session = HibernateSessionUtils.getSession();
		Users user = (Users) session.get(Users.class, id);
		HibernateSessionUtils.closeSession();
		return user;
	}

	@Override
	public List<Users> findUsersByExample(Users user) {
		Session session = HibernateSessionUtils.getSession();
		Criteria criteria = session.createCriteria(Users.class);
		criteria.add(Example.create(user));
		List<Users> list = criteria.list();
		HibernateSessionUtils.closeSession();
		return list;
	}
}

对hibernate性能的调优:数据加载方式

Hibernate中数据的加载方式默认都是”懒加载“(延时加载)

  • 类级别
<class name="com.gec.hiber.entity.Users" table="users" catalog="hiberdb" lazy="false">

仅对 session.load() 起作用,把load方法变成即时加载。

  • 关联级别 双向一对多
    一方 <set lazy="true|false|extra">
    true : 延时加载
    false: 即时加载 关联数据
    extra:增强的延时加载

例如:
在这里插入图片描述
结果:
在这里插入图片描述
多方 <many-to-one name="district" lazy="false|no-proxy|proxy">

  • false: 即时加载
  • no-proxy: 延时 非代理对象的方式
  • proxy: 延时 生成代理对象

数据抓取策略
一方的配置:
<set>设置 fetch=join,select,subselect

  • fetch=join,select
    仅对load()或get()起作用 但hql查询不起作用(sql有n+1条)
    join 表示连表查询

  • fetch=subselect子查询
    仅对hql查询起作用,load,get不起作用,
    使用子查询来优化关联方数据的获取,否则会出现n+1条数据!

  • batch-size="" 对hql查询起作用

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值