89-----hibernate的hql查询,原生SQL查询,命名查询,投影查询

HQL是Hibernate Query Language即Hibernate查询语言



HQL(Hibernate Query Language)是面向对象的查询语句
执行HQL语句可以采用两种方式:
list()方法
iterator()方法
HQL语句中绑定参数的形式有两种:
按参数位置绑定
按参数名字绑定
HQL支持投影查询、参数查询、分页查询等功能。




查询所有部门:from Dept



HQL语法举例:



from cn.jbit.hibernatdemo.entity.Dept


select dept from Dept as dept


from Dept where deptName = 'SALES' 


from Dept dept where dept.location is not null


from Emp order by hireDate,salary desc




执行HQL语句的步骤:

获取Session对象
编写HQL语句;
创建Query对象;
执行查询,得到查询结果。
session = sessionFactory.openSession();
String hql = "from Emp";
Query query = session.createQuery(hql);
List empList = query.list();



HQL查询语句

在HQL查询语句中绑定参数:String hql = "from User where name ='" + name + "'";
在HQL查询方法二:from Emp where  job like ? and  ename=:n
query.setParameter("n", name);query.setParameter(0, "%保洁%");




HQL投影查询是查询一个持久化类的一个或多个属性值

将每条查询结果封装成Object对象
将每条查询结果封装成Object数组
将每条查询结果通过构造函数封装成对象

//投影查询方法1:直接使用select 属性  from 类名的方式查询

public void list1(){
Session session = HibernateSessionFactory.getSessionFactory().getCurrentSession();
//开启事务
Transaction tx = session.beginTransaction();
Query query = session.createQuery("select name,title from Guestbook");
List list = query.list();
for(Object[] o:list){
System.out.println("姓名:"+o[0]);
}
tx.commit();
}

/*
 * 投影查询方法2  ---   使用select new 类名(属性名...) from 类名的方式,返回实体类
 * 注意:如何使用实体类的方式,那么必须在实体类中有这样的构造方法
 */

public void list2(){
Session session = HibernateSessionFactory.getSessionFactory().getCurrentSession();
//开启事务
Transaction tx = session.beginTransaction();
Query query = session.createQuery("select new Guestbook(id,name,title) from Guestbook");
List list = query.list();
for(Guestbook gb:list){
System.out.println("编号:"+gb.getId()+",姓名:"+gb.getName()+",标题:"+gb.getTitle());
}
tx.commit();
}

/*
 * 投影查询方法3  ---   使用select new Map(属性名...) from 类名的方式,返回Map集合,通过下标获取属性值
 * 注意:如何使用实体类的方式,那么必须在实体类中有这样的构造方法
 */

public void list3(){
Session session = HibernateSessionFactory.getSessionFactory().getCurrentSession();
//开启事务
Transaction tx = session.beginTransaction();
//在遍历Map是就可以根据编号获取属性值
//Query query = session.createQuery("select new Map(id,name,title) from Guestbook");
//使用属性的别名,在遍历Map是就可以根据名称获取属性值
Query query = session.createQuery("select new Map(gb.id as id,gb.name as name,gb.title as title) from Guestbook gb");
List list = query.list();
for(Map m:list){
//注意:这里的编号不是Integer类型,而是String类型
System.out.println("编号:"+m.get("id")+",姓名:"+m.get("name")+",标题:"+m.get("title"));
}
tx.commit();
}


分页查询:

uniqueResult()方法:获取唯一对象
setFirstResult()方法:设置从第几条开始
setMaxResults()方法:设置读取最大记录数


String countHQL = "select count(*) from Dept";
int count =  ((Long)session.createQuery(countHQL)
.uniqueResult()).intValue();
int totalpages = (count % pageSize == 0) 
? (count / pageSize) : (count / pageSize + 1);
int pageIndex = 1;
query.setFirstResult((pageIndex - 1) * pageSize);


query.setMaxResults(pageSize);




List deptList = query.list();



一、      子查询语句应用在HQL查询语句的where子句中

all 返回的所有记录
any 返回的任意一条记录
some 和“any”意思相同
in 与“=any”意思相同
exists 至少返回一条记录 



 查询工资高于平均工资的员工。

"fromEmp ewheree.salary>(selectavg(salary)fromEmp)"

查询所有员工工资都小于5000的部门。

"fromDept dwhere 5000>all(selecte.salary fromd.emps e) andd.emps.size>0"

查询至少有一位员工工资低于5000的部门。

"fromDept dwhere 5000>any(selecte.salary fromd.emps e)"

查询至少有一位员工的部门

"fromDept dwhere exists (fromd.emps)"

查询员工工资正好是5000元的部门

"fromDept dwhere 5000 in (selecte.salary fromd.emps e)"

"fromDept dwhere 5000=some(selecte.salary fromd.emps e)"

"fromDept dwhere 5000=any(selecte.salary fromd.emps e)"

查询指定员工所在部门

"fromDeptd where ? in (fromd.emps)"

"fromDeptd where ? in elements (d.emps)"

查询员工个数大于5的部门

"fromDeptd where d.emps.size>5"

"fromDeptd where  size(d.emps)>5"

二、      聚合函数

  count() 统计记录条数
sum() 求和
max() 求最大值
min() 求最小值
avg() 求平均值

 


按职位统计员工个数。select job,count(*)from Employee group by job

统计各个部门的平均工资  select e.dept.dname,avg(sal)from Employee egroup by e.dept.dname

 统计各个职位的最低工资和最高工资 selecte.job,max(sal),min(sal)from Employee e group by e.job

统计各个部门平均工资高于4000元的部门名称,打印部门名称、部门平均工资 

selecte.dept.dname,avg(sal)from Employee e group by e.dept.dname havingavg(sal)>2000

统计各个部门平均工资高于4000元的部门名称,打印部门名称、部门平均工资,使用JavaBean封装查询结果


 


三、      相关例子

    

查询有50条以上房屋信息的街道。

查询所有房屋信息的租金高于2000元的的街道。

查询至少有一条房屋信息的租金低于1000元的街道。

统计各个街道的房屋信息条数。

 

fromStreet s where 50<(select count(h) froms.houses h)

fromStreet s where 2000h.price froms.houses h) ands.houses.size>0

fromStreet s where 1000> any (selecth.price froms.houses h)

selects.name,s.houses.size from Street s 

 

四、      HQL的连接查询

 




使用隐式内连接查询某用户发布的房屋信息 (提示:from House h where h.user.uname = 'rose')




连接类型 HQL语法
内连接        inner join 或 join
迫切内连接 inner join fetch或 join fetch
左外连接 left outer join或 left join
迫切左外连接 left outer join fetch或 left join fetch
右外连接 right outer join 或right join


HQL使用group by关键字对数据分组,用having关键字对分组数据设定约束条件

Hibernate可以在映射文件中定义字符串形式的查询语句

Hibernate使用Session的createSQLQuery()方法创建SQLQuery对象,用来执行原生SQL语句

在持久化类中,二进制大对象可以声明为byte[]或java.sql.Blob类型;字符串大对象可以声明为java.lang.String或java.sql.Clob类型


 

五、      原生SQL查询

     
Query query = session
    .createSQLQuery(
       "select * from EMP where ENAME like :ename and JOB = :job")
    .addEntity(Emp.class).setString("ename", "%e%")
    .setString("job", "ENGINEER");
List list = query.list();

 

 

String sql = "select {e.*},{d.*} from EMP e join DEPT d on d.DEPTNO=e.DEPTNO"+ " where e.JOB = :job";
Query query = session.createSQLQuery(sql).addEntity("e", Emp.class).addJoin("d", "e.dept").setString("job", "ENGINEER");


   

    	

    	select {e.*} from EMP e where e.job = :job

    

    

    	

    	

    	select {e.*},{d.*} from EMP e join DEPT d on d.DEPTNO=e.DEPTNO where e.JOB = :job

    

六、      命名查询

    

    
        ......
    
    
            
        select {e.*} from EMP e where e.job = :job
    


 


    
        ......
    
    
    
    


 

原生sql查询

SQLQuerysession.createSQLQuery("sql");

命名查询

映射文件

根标签下

session.getNamedQuery("N");

原生sql命名查询

映射文件

根标签下sql

session.getNamedQuery("N");


 

 

八、      

 

 


你可能感兴趣的:(Java)