您的位置:首页 > 其它

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、如果多张表进行查询,找核心表
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: