hibernate05 HQL语句详解
2015-12-22 10:26
162 查看
一、 hibernate的查询方式
1、hql(hibernate query language) query
2、Criteria query
3、Native query(即SQL)
二、 HQL语句
0、domain中的类及关系
************************************************************************************
public class Classes implements Serializable {
private Long cid;
private String cname;
private String description;
private Set<Student> students;
public Classes(){}
public Classes(String cname, String description) {
super();
this.cname = cname;
this.description = description;
}
// set/get属性
}
public class ClassesView {
private String cname;
private String sname;
public ClassesView(String cname, String sname) {
super();
this.cname = cname;
this.sname = sname;
}
// set/get属性
}
public class Course implements Serializable {
private Long cid;
private String cname;
private String description;
private Set<Student> students;
// set/get属性
}
public class Student implements Serializable {
private Long sid;
private String sname;
private String description;
private Classes classes;
private Set<Course> courses;
// set/get属性
}
************************************************************************************
1、 单表查询
************************************************************************************
// 只有from POJO 的语句查询出的list泛型里面放的是POJO形式,是常用的对象的形式
public List<Classes> queryAllClasses(){
Session session = sessionFactory.openSession();
List<Classes> cList = session.createQuery("from Classes").list();
session.close();
return cList;
}
// 带有select查询的全部元素放在list中,在list的存在形式为数组
public List queryClasses_Properties(){
SessionFactory sessionfactory = HibernateUtils.getSessionFactory();
Session session = sessionfactory.openSession();
List cList = session.createQuery("select cid,cname from Classes").list();
session.close();
return cList;
}
// 如果想使用select查询,并且还不想让List泛型里面的结构为数组,让其为POJO形式,须使用带参的构造函数HQL语句
// 注: 一般使用带构造函数的查询; order by, group by, sum, min, max, avg, having等都适用
public List<Classes> queryClasses_Constructor(){
SessionFactory sessionfactory = HibernateUtils.getSessionFactory();
Session session = sessionfactory.openSession();
List<Classes> cList = session.createQuery("select new cn.itcast.domain.Classes(cname,description) from Classes").list();
session.close();
return cList;
}
// 查询cid为1的班级 方式1
public Classes queryClasses_Condition(){
SessionFactory sessionfactory = HibernateUtils.getSessionFactory();
Session session = sessionfactory.openSession();
Query query = session.createQuery("select new cn.itcast.domain.Classes(cname,description) from Classes where cid=:cid");
query.setLong("cid", 1L);
Classes classes = (Classes) query.uniqueResult();
System.out.println(classes.getCname());
session.close();
return classes;
}
// 查询cid为1的班级 方式2 使用占位符
public Classes queryClasses_Condition_2(){
SessionFactory sessionfactory = HibernateUtils.getSessionFactory();
Session session = sessionfactory.openSession();
Query query = session.createQuery("select new cn.itcast.domain.Classes(cname,description) from Classes where cid=?");
query.setLong(0, 1L);
Classes classes = (Classes) query.uniqueResult();
System.out.println(classes.getCname());
session.close();
return classes;
}
// 子查询
public void queryClasses_SubSelect(){
SessionFactory sessionfactory = HibernateUtils.getSessionFactory();
Session session = sessionfactory.openSession();
List<Classes> cList = session.createQuery("from Classes where cid in(select cid from Classes where cid in(1,2,3))").list();
System.out.println(cList.size());
session.close();
}
************************************************************************************
2、 一对多
************************************************************************************
// 等值连接 查询出来放到list集合中的为数组,结构很差,少用
public List<Classes> queryClasses_Student_EQ(){
SessionFactory sessionfactory = HibernateUtils.getSessionFactory();
Session session = sessionfactory.openSession();
// 注意: s为类Student的别名,不是表,并无cid属性, 所以要先获取属性class,再获取cid属性
List<Classes> cList = session.createQuery("from Classes c,Student s where c.cid=s.classes.cid").list();
System.out.println(cList.size());
session.close();
return cList;
}
// 内链接 查询出来放到list集合中的为数组,结构很差,少用
public List<Classes> queryClasses_Student_INNER(){
SessionFactory sessionfactory = HibernateUtils.getSessionFactory();
Session session = sessionfactory.openSession();
// 注意: s为类Student的别名,不是表,并无cid属性, 所以要先获取属性class,再获取cid属性
List<Classes> cList = session.createQuery("from Classes c inner join c.students").list();
System.out.println(cList.size());
session.close();
return cList;
}
// 迫切内链接 此时的结构为正常的结构 cid=1, cname='s1'
public List<Classes> queryClasses_Student_INNER_FETCH(){
SessionFactory sessionfactory = HibernateUtils.getSessionFactory();
Session session = sessionfactory.openSession();
List<Classes> cList = session.createQuery("from Classes c inner join fetch c.students").list();
System.out.println(cList.size());
session.close();
return cList;
}
// 左外连接 查询出来放到list集合中的为数组,结构很差,少用
public List<Classes> queryClasses_Student_LeftJoin(){
SessionFactory sessionfactory = HibernateUtils.getSessionFactory();
Session session = sessionfactory.openSession();
List<Classes> cList = session.createQuery("from Classes c left join c.students").list();
System.out.println(cList.size());
session.close();
return cList;
}
// 迫切左外连接 此时的结构为正常的结构 cid=1, cname='s1'
public List<Classes> queryClasses_Student_LeftJoin_Fetch(){
SessionFactory sessionfactory = HibernateUtils.getSessionFactory();
Session session = sessionfactory.openSession();
// Classes在前,所以结构为Classes包含student
List<Classes> cList = session.createQuery("from Classes c left join fetch c.students").list();
System.out.println(cList.size());
session.close();
return cList;
}
// 带select的查询
public List<Classes> queryClasses_Student_Select(){
SessionFactory sessionfactory = HibernateUtils.getSessionFactory();
Session session = sessionfactory.openSession();
// 注: 此处创建了一个bean,ClassView,里面有cname和sname字段,及带字段的构造函数和set/get属性
// 因为迫切连接的结构和带构造函数的结构有冲突,所以两者只能选择其中一种,不能同时存在
String hql = "select new cn.itcast.domain.ClassesView(c.cname,s.sname)" +
"from Student s left outer join s.classes c";
List<Classes> cList = session.createQuery(hql).list();
System.out.println(cList.size());
session.close();
return cList;
}
************************************************************************************
3、多对多
************************************************************************************
public void queryCourse_Student(){
Session session = sessionFactory.openSession();
List<Student> studentList = session.createQuery("from Student s inner join fetch s.courses c").list();
System.out.println(studentList.size());
session.close();
}
// 一对多结合多对多
public void queryClasses_Student_Course_1(){
Session session = sessionFactory.openSession();
// 不同的主体,遍历方式不同,三张表,找中间表做主体,以第二条语句最好
String hql = "from Classes cs inner join fetch cs.students s inner join fetch s.courses c";
hql = "from Student s inner join fetch s.classes cs inner join fetch s.courses c";
hql = "from Classes cs left outer join fetch cs.students s left outer join fetch s.courses c";
List<Classes> cList = session.createQuery(hql).list();
System.out.println(cList.size());
// 去除list集合中重复元素的方式 先转换成set(set集合会自动去除重复元素),再将其转换为list
Set<Classes> cSet = new HashSet<Classes>(cList);
cList = new ArrayList<Classes>(cSet);
for (Classes classes : cList) {
System.out.println(classes.getCname());
Set<Student> students = classes.getStudents();
for (Student student : students) {
System.out.println(student.getSname());
Set<Course> courses = student.getCourses();
for (Course course : courses) {
System.out.println(course.getCname());
}
}
}
session.close();
}
// 三张表 以中间表为主体最好,在jsp中遍历
public List<Student> queryClasses_Student_Course_2(){
Session session = sessionFactory.openSession();
String hql = "from Student s inner join fetch s.classes cs inner join fetch s.courses c";
List<Student> sList = session.createQuery(hql).list();
System.out.println(sList.size());
session.close();
return sList;
}
************************************************************************************
4、JSP中的遍历
************************************************************************************
<!-- 迭代list<Classes> -->
<s:iterator value="#cList">
<s:property value="cname"/> <br/>
<s:property value="description"/> <br/>
</s:iterator>
<!-- 方式1:迭代 list<object[]> 当前迭代的元素在栈顶 -->
<s:iterator value="#cList">
<!-- 迭代Object[] [Long,String] -->
<s:iterator>
<s:property/>
</s:iterator>
</s:iterator>
<!-- 方式2:使用key -->
<s:iterator value="#cList">
<s:iterator var="aa">
<!-- aa代表当前正在迭代元素的key值,此时在map栈中,所以要加# -->
<s:property value="#aa"/>
</s:iterator>
</s:iterator>
<!-- 遍历: List<Student<Classes,Set<Course>>> -->
<!-- 先遍历list -->
<s:iterator value="#students">
<!-- 当前list集合中的元素student在栈顶 -->
<s:property value="sname"/> <br/>
<!-- 当前list集合中的key为classes,是一个POJO -->
<s:property value="classes.cname"/> <br/>
<!-- 遍历 当前list集合中的value为Set<Course> 此时set集合是对象栈中的一个属性 ,访问时不需加# -->
<s:iterator value="courses">
<!-- 当前遍历的courses元素在栈顶 -->
<s:property value="cname"/>
</s:iterator>
</s:iterator>
************************************************************************************
5、各条SQL语句的内存图
6、总结
1、如果页面上要显示的数据和数据库中的数据相差甚远,利用带select的构造器进行查询是比较好的方案
2、如果页面上要显示的数据和数据库中的数据相差不是甚远,这个时候用迫切连接
3、如果采用迫切连接,from后面跟的那个对象就是结构主体
4、如果多张表进行查询,找核心表
1、hql(hibernate query language) query
2、Criteria query
3、Native query(即SQL)
二、 HQL语句
0、domain中的类及关系
************************************************************************************
public class Classes implements Serializable {
private Long cid;
private String cname;
private String description;
private Set<Student> students;
public Classes(){}
public Classes(String cname, String description) {
super();
this.cname = cname;
this.description = description;
}
// set/get属性
}
public class ClassesView {
private String cname;
private String sname;
public ClassesView(String cname, String sname) {
super();
this.cname = cname;
this.sname = sname;
}
// set/get属性
}
public class Course implements Serializable {
private Long cid;
private String cname;
private String description;
private Set<Student> students;
// set/get属性
}
public class Student implements Serializable {
private Long sid;
private String sname;
private String description;
private Classes classes;
private Set<Course> courses;
// set/get属性
}
************************************************************************************
1、 单表查询
************************************************************************************
// 只有from POJO 的语句查询出的list泛型里面放的是POJO形式,是常用的对象的形式
public List<Classes> queryAllClasses(){
Session session = sessionFactory.openSession();
List<Classes> cList = session.createQuery("from Classes").list();
session.close();
return cList;
}
// 带有select查询的全部元素放在list中,在list的存在形式为数组
public List queryClasses_Properties(){
SessionFactory sessionfactory = HibernateUtils.getSessionFactory();
Session session = sessionfactory.openSession();
List cList = session.createQuery("select cid,cname from Classes").list();
session.close();
return cList;
}
// 如果想使用select查询,并且还不想让List泛型里面的结构为数组,让其为POJO形式,须使用带参的构造函数HQL语句
// 注: 一般使用带构造函数的查询; order by, group by, sum, min, max, avg, having等都适用
public List<Classes> queryClasses_Constructor(){
SessionFactory sessionfactory = HibernateUtils.getSessionFactory();
Session session = sessionfactory.openSession();
List<Classes> cList = session.createQuery("select new cn.itcast.domain.Classes(cname,description) from Classes").list();
session.close();
return cList;
}
// 查询cid为1的班级 方式1
public Classes queryClasses_Condition(){
SessionFactory sessionfactory = HibernateUtils.getSessionFactory();
Session session = sessionfactory.openSession();
Query query = session.createQuery("select new cn.itcast.domain.Classes(cname,description) from Classes where cid=:cid");
query.setLong("cid", 1L);
Classes classes = (Classes) query.uniqueResult();
System.out.println(classes.getCname());
session.close();
return classes;
}
// 查询cid为1的班级 方式2 使用占位符
public Classes queryClasses_Condition_2(){
SessionFactory sessionfactory = HibernateUtils.getSessionFactory();
Session session = sessionfactory.openSession();
Query query = session.createQuery("select new cn.itcast.domain.Classes(cname,description) from Classes where cid=?");
query.setLong(0, 1L);
Classes classes = (Classes) query.uniqueResult();
System.out.println(classes.getCname());
session.close();
return classes;
}
// 子查询
public void queryClasses_SubSelect(){
SessionFactory sessionfactory = HibernateUtils.getSessionFactory();
Session session = sessionfactory.openSession();
List<Classes> cList = session.createQuery("from Classes where cid in(select cid from Classes where cid in(1,2,3))").list();
System.out.println(cList.size());
session.close();
}
************************************************************************************
2、 一对多
************************************************************************************
// 等值连接 查询出来放到list集合中的为数组,结构很差,少用
public List<Classes> queryClasses_Student_EQ(){
SessionFactory sessionfactory = HibernateUtils.getSessionFactory();
Session session = sessionfactory.openSession();
// 注意: s为类Student的别名,不是表,并无cid属性, 所以要先获取属性class,再获取cid属性
List<Classes> cList = session.createQuery("from Classes c,Student s where c.cid=s.classes.cid").list();
System.out.println(cList.size());
session.close();
return cList;
}
// 内链接 查询出来放到list集合中的为数组,结构很差,少用
public List<Classes> queryClasses_Student_INNER(){
SessionFactory sessionfactory = HibernateUtils.getSessionFactory();
Session session = sessionfactory.openSession();
// 注意: s为类Student的别名,不是表,并无cid属性, 所以要先获取属性class,再获取cid属性
List<Classes> cList = session.createQuery("from Classes c inner join c.students").list();
System.out.println(cList.size());
session.close();
return cList;
}
// 迫切内链接 此时的结构为正常的结构 cid=1, cname='s1'
public List<Classes> queryClasses_Student_INNER_FETCH(){
SessionFactory sessionfactory = HibernateUtils.getSessionFactory();
Session session = sessionfactory.openSession();
List<Classes> cList = session.createQuery("from Classes c inner join fetch c.students").list();
System.out.println(cList.size());
session.close();
return cList;
}
// 左外连接 查询出来放到list集合中的为数组,结构很差,少用
public List<Classes> queryClasses_Student_LeftJoin(){
SessionFactory sessionfactory = HibernateUtils.getSessionFactory();
Session session = sessionfactory.openSession();
List<Classes> cList = session.createQuery("from Classes c left join c.students").list();
System.out.println(cList.size());
session.close();
return cList;
}
// 迫切左外连接 此时的结构为正常的结构 cid=1, cname='s1'
public List<Classes> queryClasses_Student_LeftJoin_Fetch(){
SessionFactory sessionfactory = HibernateUtils.getSessionFactory();
Session session = sessionfactory.openSession();
// Classes在前,所以结构为Classes包含student
List<Classes> cList = session.createQuery("from Classes c left join fetch c.students").list();
System.out.println(cList.size());
session.close();
return cList;
}
// 带select的查询
public List<Classes> queryClasses_Student_Select(){
SessionFactory sessionfactory = HibernateUtils.getSessionFactory();
Session session = sessionfactory.openSession();
// 注: 此处创建了一个bean,ClassView,里面有cname和sname字段,及带字段的构造函数和set/get属性
// 因为迫切连接的结构和带构造函数的结构有冲突,所以两者只能选择其中一种,不能同时存在
String hql = "select new cn.itcast.domain.ClassesView(c.cname,s.sname)" +
"from Student s left outer join s.classes c";
List<Classes> cList = session.createQuery(hql).list();
System.out.println(cList.size());
session.close();
return cList;
}
************************************************************************************
3、多对多
************************************************************************************
public void queryCourse_Student(){
Session session = sessionFactory.openSession();
List<Student> studentList = session.createQuery("from Student s inner join fetch s.courses c").list();
System.out.println(studentList.size());
session.close();
}
// 一对多结合多对多
public void queryClasses_Student_Course_1(){
Session session = sessionFactory.openSession();
// 不同的主体,遍历方式不同,三张表,找中间表做主体,以第二条语句最好
String hql = "from Classes cs inner join fetch cs.students s inner join fetch s.courses c";
hql = "from Student s inner join fetch s.classes cs inner join fetch s.courses c";
hql = "from Classes cs left outer join fetch cs.students s left outer join fetch s.courses c";
List<Classes> cList = session.createQuery(hql).list();
System.out.println(cList.size());
// 去除list集合中重复元素的方式 先转换成set(set集合会自动去除重复元素),再将其转换为list
Set<Classes> cSet = new HashSet<Classes>(cList);
cList = new ArrayList<Classes>(cSet);
for (Classes classes : cList) {
System.out.println(classes.getCname());
Set<Student> students = classes.getStudents();
for (Student student : students) {
System.out.println(student.getSname());
Set<Course> courses = student.getCourses();
for (Course course : courses) {
System.out.println(course.getCname());
}
}
}
session.close();
}
// 三张表 以中间表为主体最好,在jsp中遍历
public List<Student> queryClasses_Student_Course_2(){
Session session = sessionFactory.openSession();
String hql = "from Student s inner join fetch s.classes cs inner join fetch s.courses c";
List<Student> sList = session.createQuery(hql).list();
System.out.println(sList.size());
session.close();
return sList;
}
************************************************************************************
4、JSP中的遍历
************************************************************************************
<!-- 迭代list<Classes> -->
<s:iterator value="#cList">
<s:property value="cname"/> <br/>
<s:property value="description"/> <br/>
</s:iterator>
<!-- 方式1:迭代 list<object[]> 当前迭代的元素在栈顶 -->
<s:iterator value="#cList">
<!-- 迭代Object[] [Long,String] -->
<s:iterator>
<s:property/>
</s:iterator>
</s:iterator>
<!-- 方式2:使用key -->
<s:iterator value="#cList">
<s:iterator var="aa">
<!-- aa代表当前正在迭代元素的key值,此时在map栈中,所以要加# -->
<s:property value="#aa"/>
</s:iterator>
</s:iterator>
<!-- 遍历: List<Student<Classes,Set<Course>>> -->
<!-- 先遍历list -->
<s:iterator value="#students">
<!-- 当前list集合中的元素student在栈顶 -->
<s:property value="sname"/> <br/>
<!-- 当前list集合中的key为classes,是一个POJO -->
<s:property value="classes.cname"/> <br/>
<!-- 遍历 当前list集合中的value为Set<Course> 此时set集合是对象栈中的一个属性 ,访问时不需加# -->
<s:iterator value="courses">
<!-- 当前遍历的courses元素在栈顶 -->
<s:property value="cname"/>
</s:iterator>
</s:iterator>
************************************************************************************
5、各条SQL语句的内存图
6、总结
1、如果页面上要显示的数据和数据库中的数据相差甚远,利用带select的构造器进行查询是比较好的方案
2、如果页面上要显示的数据和数据库中的数据相差不是甚远,这个时候用迫切连接
3、如果采用迫切连接,from后面跟的那个对象就是结构主体
4、如果多张表进行查询,找核心表
相关文章推荐
- Windows系统下安装Beautiful Soup4的步骤和方法
- svn clean up 失败解决方法
- IOS 图片压缩保存
- 数字签名原理简介(附数字证书)
- Unity3d模仿龙之谷的Camare
- wps两张表格合并
- spring mvc使用Maven配置Velocity
- 实践中学习css3(二级导航条制作)
- C++标准转换运算符 :reinterpret_cast <new_type> (expression)
- Python控制流语句(if,while,for)
- Linux 查看系统硬件信息(实例详解)
- Fingerprint 已经被使用 Fingerprint cannot be generated
- 11月移动设备品牌占比TOP10:小米第三 涨幅最大
- 正则表达式 整数
- 取余运算的Lyapunov指数
- UV动画贴图——更换表情
- 复制Android Studio 工程到其它电脑后遇到The SDK directory 'XXXX‘ does not exist.问题的解决方法
- Spring整合Quartz(JobDetailBean方式)
- Java中apache下面FTPClient主动模式和被动模式
- Linux命令中使用正则表达式