本例模仿部门与员工之间来进行HQL的各种查询,一共有两张表,一张部门表,一张员工表,下面是具体查询代码:
1.Junit测试
package cn.itcast.a_query;
import org.hibernate.Query;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
import org.junit.Test;
public class App_hql {
private static SessionFactory sf;
static{
sf=new Configuration()
.configure()
.addClass(Dept.class)
.addClass(Employee.class)
.buildSessionFactory();
}
@Test
public void all() throws Exception{
Session session=sf.openSession();
session.beginTransaction();
//1.主键查询及区别
// Dept dept=(Dept) session.get(Dept.class, 3);
//1.对象导航查询
/* Dept dept=(Dept) session.get(Dept.class, 3);
System.out.println(dept.getDeptName());
System.out.println(dept.getEmps());*/
//HQL查询
//注意:使用HQL查询的时候auto-import="true",要设置true,
// 如果是false,写hql的时候,要指定类的全名
/*Query q=session.createQuery("from Dept");
System.out.println(q.list());*/
//a.查询全部列
// Query q = session.createQuery("from Dept"); //OK
// Query q = session.createQuery("select * from Dept"); //NOK, 错误,不支持*
// Query q = session.createQuery("select d from Dept d"); // OK
// System.out.println(q.list());
// b. 查询指定的列 【返回对象数据Object[] 】
// Query q = session.createQuery("select d.deptId,d.deptName from Dept d");
// System.out.println(q.list());
// c. 查询指定的列, 自动封装为对象 【必须要提供带参数构造器】
// Query q = session.createQuery("select new Dept(d.deptId,d.deptName) from Dept d");
// System.out.println(q.list());
// d. 条件查询: 一个条件/多个条件and or/between and/模糊查询
// 条件查询: 占位符
// Query q=session.createQuery("from Dept d where deptName=?");
// q.setString(0,"人事部");
// q.setParameter(0,"人事部");
// System.out.println(q.list());
// 条件查询: 命名参数
/* Query q=session.createQuery("from Dept d where deptId=:myid or deptName=:name");
q.setParameter("myid", 3);
q.setParameter("name", "人事部");
System.out.println(q.list());
*/
// 范围
// Query q = session.createQuery("from Dept d where deptId between ? and ?");
// q.setParameter(0, 1);
// q.setParameter(1, 20);
// System.out.println(q.list());
// 模糊
// Query q = session.createQuery("from Dept d where deptName like ?");
// q.setString(0, "%部%");
// System.out.println(q.list());
// e. 聚合函数统计
// Query q = session.createQuery("select count(*) from Dept");
// Long num = (Long) q.uniqueResult();
// System.out.println(num);
// f. 分组查询
//-- 统计t_employee表中,每个部门的人数
//数据库写法:SELECT dept_id,COUNT(*) FROM t_employee GROUP BY dept_id;
// HQL写法
// Query q = session.createQuery("select e.dept, count(*) from Employee e group by e.dept");
// System.out.println(q.list());
session.getTransaction().commit();
session.close();
}
//连接查询
@Test
public void join() throws Exception{
Session session=sf.openSession();
session.beginTransaction();
//1) 内连接 【映射已经配置好了关系,关联的时候,直接写对象的属性即可】
/* Query q = session.createQuery("from Dept d inner join d.emps");
System.out.println(q.list());*/
//2) 左外连接
// Query q = session.createQuery("from Dept d left join d.emps");
//3) 右外连接
/* Query q = session.createQuery("from Employee e right join e.dept");
q.list();*/
session.getTransaction().commit();
session.close();
}
// g. 连接查询 - 迫切连接
@Test
public void fetch() throws Exception{
Session session = sf.openSession();
session.beginTransaction();
//1) 迫切内连接 【使用fetch, 会把右表的数据,填充到左表对象中!】
/* Query q=session.createQuery("from Dept d inner join fetch d.emps");
q.list();*/
//2) 迫切左外连接
/* Query q = session.createQuery("from Dept d left join fetch d.emps");
q.list();*/
session.getTransaction().commit();
session.close();
}
// HQL查询优化
@Test
public void hql_other(){
Session session = sf.openSession();
session.beginTransaction();
// HQL写死
// Query q = session.createQuery("from Dept d where deptId < 10 ");
// HQL 放到映射文件中
Query q = session.getNamedQuery("getAllDept");
q.setParameter(0, 10);
System.out.println(q.list());
session.getTransaction().commit();
session.close();
}
}
2.Dept.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.itcast.a_query" auto-import="true">
<class name="Dept" table="t_dept" >
<id name="deptId">
<generator class="native"></generator>
</id>
<property name="deptName" length="20"></property>
<!--
集合属性,默认使用懒加载
lazy
true 懒加载
extra 懒加载(智能)
false 关闭懒加载
-->
<set name="emps" lazy="extra">
<key column="dept_id"></key>
<one-to-many class="Employee"/>
</set>
<!-- 存放sql语句 -->
<query name="getAllDept">
<![CDATA[
from Dept d where deptId < ?
]]>
</query>
</class>
</hibernate-mapping>
3.Dept
package cn.itcast.a_query;
import java.util.HashSet;
import java.util.Set;
public class Dept {
private int deptId;
private String deptName;
public Dept() {
super();
}
public Dept(int deptId, String deptName, Set<Employee> emps) {
super();
this.deptId = deptId;
this.deptName = deptName;
this.emps = emps;
}
public Dept(int deptId, String deptName) {
super();
this.deptId = deptId;
this.deptName = deptName;
}
// 【一对多】 部门对应的多个员工
private Set<Employee> emps = new HashSet<Employee>();
public int getDeptId() {
return deptId;
}
public void setDeptId(int deptId) {
this.deptId = deptId;
}
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}
public Set<Employee> getEmps() {
return emps;
}
public void setEmps(Set<Employee> emps) {
this.emps = emps;
}
}
其他的配置文件比较简单,这里没有列出来,主要是收藏hibernate的HQL查询语句,以及以后怎样使用HQL来查询