分享

14、Hibernate的HQL与QBC检索

 昵称10087950 2016-08-17

Hibernate检索对象的方式

- HQL检索方式

- QBC检索方式

1、Hibernate提供的检索对象的方式

- 导航图对象检索方式

根据已经加载的对象,导航到其他对象。例如,对于已经加载的Customer对象,调用它的getOrders().iterator()方法就可以导航到所有关联的Order对象,假如在关联级别使用了延迟家在检索策略,那么首次执行此方法时,hibernate会从数据库中加载关联的Order对象,否则就从缓存中取得Order对象。

- OID检索方式

    按照对象的OID来检索对象。Session的get()和load()方法提供了这种功能。如果在应用程序中事先知道了OID,就可以使用这种检索对象的方式。

HQL检索方式

    HIbernate提供了Query接口,它是Hibernate提供的专门的HQL查询接口,能够执行各种复杂的HQL查询语句。

- QBC检索方式

    使用QBC(Query By Criteria)API来检索对象。这种API封装了基于字符串形式的查询语句,提供了更加面向对象的接口。

2、HQL检索方式

HQL(Hibernate Query Language)是面向对象的查询语言,他和SQL查询语言有些相似。在Hibernate提供的各种检索方式中,HQL是使用最广的一种检索方式。它具有以下功能:

    - 在查询语句中设定各种查询条件
    - 支持投影查询,即仅检索出对象的部分属性
    - 支持分页查询
    - 支持连接查询
    - 支持分组查询,允许使用having和group by关键字
    - 提供内置聚集函数,如sum()、min()、和max()
    - 支持子查询,即嵌入式查询
    - 支持动态绑定参数

HQL检索步骤:

//创建一个Query

Query query = session.createQuery("from Customer as c where " + "c.name =: customerName" + "and c.age =: customerAge");

//这里c.name =: customerName,c.name是指出Customer的属性name,=:是一个动态赋值的符号,后面的customerName是任意起名的,是我们要动态付值得一个临时变量。c.age =: customerAge同理

//动态绑定参数

query.setString("customerName","tom");

query.setInteger("customerAge",20);

//执行查询语句,返回查询结果

List result = query.list();

Query提供了大量的setXXX方法,来为其提供设定参数。

(1)通过Session的createQuery()方法创建一个Query对象,它包含一个HQL查询语句。HQL查询语句可以包含命名参数,如”customerName“和”customerAge“都是命名参数。

(2)动态绑定参数。Query接口提供了各种类型的命名参数赋值的方法,例如setString()方法用于为字符串类型的customerName命名参数赋值。

(3)调用Query的list()方法执行查询语句。该方法返回List类型的查询结果,在List集合中存放了符合查询条件的持久化对象。

对于Query支持方法链编程风格

List result = session.greateQuery("...").setString("customerName","Tom").setInteger("customerAge",21).list();

方法链编程风格能使程序代码更加简洁

3、QBC检索方式

采用HQL检索方式时,在应用程序中需要定义基于字符串形式的HQL查询语句。

QBC API提供了检索对象的另一种方式,它主要由Criteria接口、Criterion接口和Expression类组成,它支持在运行时动态生成查询语句。

Criteria是由Session创建的,Session的createCriteria()创建一个Criteria对象。Criterion是增加约束条件的,具体实现类Restrictions

//创建一个Criteria对象

Criteria criteria = session.createCriteria(Customer.clss);
//设定查询条件,然后把查询条件加入到Criteria中
Criterion criterion1 = Expression.like(”name“,”T%“);   //相当于where name like ‘T%’
Criterion criterion2 = Expression.eq("age",new Integer(21));
criteria = criteria.add(criterion1);
criteria = criteria.add(criterion2);
//执行查询语句,返回查询结果
List result = criteria.list();

使用QBC检索的步骤

-(1)调用Session的createCriteria()方法创建一个Criteria对象。
-(2)设定查询条件。Expression类提供了一系列用于设定查询条件的静态方法,这些静态方法都返回Criterion实例,每个Criterion实例代表一个查询条件。Criteria的add()方法用于加入查询条件。
-(3)调用Criteria的list()方法执行查询语句。该方法返回List类型的查询结果,在List集合中存放了符合查询条件的持久化对象。对于以上程序代码,当运行Criteria的list()方法时,Hibernate执行的SQL查询语句为:
select * from customers where name like 'T%' and age = 21;

方法链编程风格

List result = session.createCriteria(Customer.class).add(Expression.like("name","T%")).add(Expression.eq("age",new Integer(21))).list();

4、分页查询

Query和Criteria接口都提供了用于分页显示查询结果的方法:

- setFirstResult(int firstResult):设定从哪一个对象开始检索,参数firstResult表示这个对象在查询结果中的索引位置,索引位置的起始值为0.默认情况下,Query和Criteria接口从查询结果中的第一个对象,也就是索引位置为0的对象开始检索。

- seMaxResult(int maxResults):设定一次最多检索出的对象数目。默认情况下,Query和Criteria接口检索出查询结果中所有的对象。

分页查询:

//采用HQL检索方式
Query query = session.createQuery("from Customer c order by c.name asc");
query.setFirstResults(0);
query.setMaxResults(10);
List result = query.list();
//采用QBC检索方式
Criteria criteria=session.createCritia(Customer.class);
criteria.addOrder(Order.asc("name"));
criteria.setFirstResults(0);
criteria.setMaxResults(10);
List result = criteria.list();

5、查询检索方式举例:

使用Team、Student和Course三个类:

  1. import java.util.HashSet;  
  2. import java.util.Set;  
  3.   
  4. public class Team  
  5. {  
  6.     private String id;  
  7.       
  8.     private String teamName;  
  9.       
  10.     private Set students = new HashSet();  
  11.   
  12.     public String getId()  
  13.     {  
  14.         return id;  
  15.     }  
  16.   
  17.     public void setId(String id)  
  18.     {  
  19.         this.id = id;  
  20.     }  
  21.   
  22.       
  23.     public String getTeamName()  
  24.     {  
  25.         return teamName;  
  26.     }  
  27.   
  28.     public void setTeamName(String teamName)  
  29.     {  
  30.         this.teamName = teamName;  
  31.     }  
  32.   
  33.     public Set getStudents()  
  34.     {  
  35.         return students;  
  36.     }  
  37.   
  38.     public void setStudents(Set students)  
  39.     {  
  40.         this.students = students;  
  41.     }  
  42.   
  43. }  

  1. import java.util.Set;  
  2.   
  3. public class Student  
  4. {  
  5.     private String id;  
  6.       
  7.     private String cardId;  
  8.       
  9.     private String name;  
  10.       
  11.     private int age;  
  12.   
  13.     public String getCardId()  
  14.     {  
  15.         return cardId;  
  16.     }  
  17.   
  18.     public void setCardId(String cardId)  
  19.     {  
  20.         this.cardId = cardId;  
  21.     }  
  22.   
  23.     public int getAge()  
  24.     {  
  25.         return age;  
  26.     }  
  27.   
  28.     public void setAge(int age)  
  29.     {  
  30.         this.age = age;  
  31.     }  
  32.   
  33.     private Set<Course> courses;  
  34.   
  35.     public String getId()  
  36.     {  
  37.         return id;  
  38.     }  
  39.   
  40.     public void setId(String id)  
  41.     {  
  42.         this.id = id;  
  43.     }  
  44.   
  45.     public String getName()  
  46.     {  
  47.         return name;  
  48.     }  
  49.   
  50.     public void setName(String name)  
  51.     {  
  52.         this.name = name;  
  53.     }  
  54.   
  55.     public Set<Course> getCourses()  
  56.     {  
  57.         return courses;  
  58.     }  
  59.   
  60.     public void setCourses(Set<Course> courses)  
  61.     {  
  62.         this.courses = courses;  
  63.     }  
  64.       
  65. }  

  1. import java.util.Set;  
  2.   
  3. public class Course  
  4. {  
  5.     private String id;  
  6.       
  7.     private String name;  
  8.       
  9.     private Set<Student> students;  
  10.   
  11.     public String getId()  
  12.     {  
  13.         return id;  
  14.     }  
  15.   
  16.     public void setId(String id)  
  17.     {  
  18.         this.id = id;  
  19.     }  
  20.   
  21.     public String getName()  
  22.     {  
  23.         return name;  
  24.     }  
  25.   
  26.     public void setName(String name)  
  27.     {  
  28.         this.name = name;  
  29.     }  
  30.   
  31.     public Set<Student> getStudents()  
  32.     {  
  33.         return students;  
  34.     }  
  35.   
  36.     public void setStudents(Set<Student> students)  
  37.     {  
  38.         this.students = students;  
  39.     }  
  40.       
  41. }  

对应的映射文件:

  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
  3. "http://hibernate./hibernate-mapping-3.0.dtd">  
  4.   
  5. <hibernate-mapping>  
  6.       
  7.     <class name="com.cdtax.hibernate.Team" table="team">  
  8.           
  9.         <id name="id" column="id" type="string">  
  10.             <generator class="uuid">  
  11.             </generator>  
  12.         </id>  
  13.           
  14.         <property name="teamName" column="teamname" type="string"></property>  
  15.           
  16.         <set name="students" lazy="false" cascade="all" inverse="true" fetch="select">  
  17.             <key column="team_id"></key>  
  18.             <one-to-many class="com.cdtax.hibernate.Student"/>  
  19.         </set>  
  20.            
  21.     </class>  
  22. </hibernate-mapping>  

  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
  3. "http://hibernate./hibernate-mapping-3.0.dtd">  
  4.   
  5. <hibernate-mapping>  
  6.       
  7.     <class name="com.cdtax.hibernate.Student" table="student">  
  8.       
  9.         <id name="id" column="id" type="string">  
  10.             <generator class="uuid"></generator>  
  11.         </id>  
  12.           
  13.         <property name="name" column="name" type="string"></property>  
  14.         <property name="cardId" column="cardid" type="string"></property>  
  15.         <property name="age" column="age" type="int"></property>  
  16.           
  17.           
  18.         <set name="courses" table="student_course" cascade="save-update">  
  19.         <!-- cascade不能使用all -->  
  20.             <key column="student_id"></key>  
  21.             <many-to-many class="com.cdtax.hibernate.Course" column="course_id"></many-to-many>  
  22.         </set>          
  23.     </class>  
  24. </hibernate-mapping>  

  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
  3. "http://hibernate./hibernate-mapping-3.0.dtd">  
  4.   
  5. <hibernate-mapping>  
  6.       
  7.     <class name="com.cdtax.hibernate.Course" table="course">  
  8.       
  9.         <id name="id" column="id" type="string">  
  10.             <generator class="uuid"></generator>  
  11.         </id>  
  12.           
  13.         <property name="name" column="name" type="string"></property>  
  14.           
  15.         <set name="students" table="student_course" cascade="save-update" inverse="true">  
  16.         <!-- cascade不能使用all -->  
  17.             <key column="course_id"></key>  
  18.             <many-to-many class="com.cdtax.hibernate.Student" column="student_id"></many-to-many>  
  19.         </set>          
  20.     </class>  
  21. </hibernate-mapping>  

产生数据库表:

create table course (id varchar(255) not null, name varchar(255), primary key (id))
create table student (id varchar(255) not null, name varchar(255), cardid varchar(255), age integer, team_id varchar(255), primary key (id))
create table student_course (student_id varchar(255) not null, course_id varchar(255) not null, primary key (student_id, course_id))
create table team (id varchar(255) not null, teamname varchar(255), primary key (id))
alter table student add index FK8FFE823BB04F9E7 (team_id), add constraint FK8FFE823BB04F9E7 foreign key (team_id) references team (id)
alter table student_course add index FKB0A3729F45A3E36D (student_id), add constraint FKB0A3729F45A3E36D foreign key (student_id) references student (id)
alter table student_course add index FKB0A3729FA31F19E7 (course_id), add constraint FKB0A3729FA31F19E7 foreign key (course_id) references course (id)

插入一些测试数据:

USE hibernate;


insert into `course`(`id`,`name`) values ('402881c04223208801422320897a0031','yy');
insert into `course`(`id`,`name`) values ('402881c04223208801422320897a0032','sx');
insert into `course`(`id`,`name`) values ('402881c04223208801422320897a0033','yw');


insert into `student`(`id`,`name`,`cardid`,`age`,`team_id`) values ('402881c04223208801422320897a0011','zhangsan','402881c04223208801422320897a0021',20,'402881c04223208801422320897a0001');
insert into `student`(`id`,`name`,`cardid`,`age`,`team_id`) values ('402881c04223208801422320897a0012','lisi','402881c04223208801422320897a0022',7,'402881c04223208801422320897a0001');
insert into `student`(`id`,`name`,`cardid`,`age`,`team_id`) values ('402881c04223208801422320897a0013','wangwu','402881c04223208801422320897a0023',45,'402881c04223208801422320897a0002');
insert into `student`(`id`,`name`,`cardid`,`age`,`team_id`) values ('402881c04223208801422320897a0014','zhaoliu','402881c04223208801422320897a0024',34,'402881c04223208801422320897a0002');
insert into `student`(`id`,`name`,`cardid`,`age`,`team_id`) values ('402881c04223208801422320897a0015','kklk','402881c04223208801422320897a0025',23,'402881c04223208801422320897a0003');


insert into `team`(`id`,`teamname`) values ('402881c04223208801422320897a0001','team1');
insert into `team`(`id`,`teamname`) values ('402881c04223208801422320897a0002','team2');
insert into `team`(`id`,`teamname`) values ('402881c04223208801422320897a0003','team3');


insert into `student_course`(`student_id`,`course_id`) values ('402881c04223208801422320897a0011','402881c04223208801422320897a0031');
insert into `student_course`(`student_id`,`course_id`) values ('402881c04223208801422320897a0011','402881c04223208801422320897a0032');
insert into `student_course`(`student_id`,`course_id`) values ('402881c04223208801422320897a0012','402881c04223208801422320897a0033');
insert into `student_course`(`student_id`,`course_id`) values ('402881c04223208801422320897a0013','402881c04223208801422320897a0032');

使用HQL查询学生的信息,如果是查询学生的所有信息,就用from Student这种写法,但是这里我们只是查询学生的name和age,写法要注意如下:

  1. import java.util.List;  
  2.   
  3. import org.hibernate.Query;  
  4. import org.hibernate.Session;  
  5. import org.hibernate.SessionFactory;  
  6. import org.hibernate.Transaction;  
  7. import org.hibernate.cfg.Configuration;  
  8.   
  9. public class HibernateTest  
  10. {  
  11.     private static SessionFactory sessionFactory;  
  12.       
  13.     static  
  14.     {  
  15.         try  
  16.         {  
  17.             sessionFactory = new Configuration().configure().buildSessionFactory();  
  18.         }  
  19.         catch(Exception ex)  
  20.         {  
  21.             ex.printStackTrace();  
  22.         }  
  23.     }  
  24.       
  25.     public static void main(String[] args)  
  26.     {  
  27.                   
  28.         Session session = sessionFactory.openSession();  
  29.         Transaction tx = null;  
  30.           
  31.         try  
  32.         {  
  33.             tx = session.beginTransaction();  
  34.               
  35.             Query query = session.createQuery("<span style="color:#ff0000;">select s.name,s.age from Student</span> s");  
  36.             <span style="color:#ff0000;">//对于以前查询学生的所有信息,就用from Student这种写法,现在是查询学生的name和age,写法就如上  
  37.             //对于查询出来的结果,如果是from Student,那么查询出来的就是Student对象,现在只是name和age,是游离的,跟Student看不出有任何关系  
  38.                           
  39.             List list = query.list();  
  40.             //对于list中的元素,如果是from Student方式,那么就是Student实例  
  41.             //但是现在就不是了,查看Query的list()方法说明:Return the query results as a List.If the query contains multiple results pre row  
  42.             //the results are returned in an instance of Object[].如果query每一行包含多个结果,那么结果就作为一个Objec[]数组返回。  
  43.             //对于我们这个程序list中的元素就是一个Object[]数组,其中Object[0]就是name,Object[1]就是age  
  44.             //所以我们要进行类型转换   </span>       
  45.             for(int i = 0; i < list.size(); i++)  
  46.             {  
  47.                 <span style="color:#ff0000;">Object[] obj = (Object[])list.get(i);</span>  
  48.                   
  49.                 System.out.println(<span style="color:#ff0000;">obj[0] + ", " + obj[1]</span>);  
  50.             }  
  51.               
  52.             tx.commit();  
  53.         }  
  54.         catch(Exception ex)  
  55.         {  
  56.             if(null != tx)  
  57.             {  
  58.                 tx.rollback();  
  59.             }  
  60.             ex.printStackTrace();  
  61.         }  
  62.         finally  
  63.         {  
  64.             session.close();  
  65.         }  
  66.     }  
  67. }  
看下面的对应关系图:

执行的结果:

Hibernate: select student0_.name as col_0_0_, student0_.age as col_1_0_ from student student0_
zhangsan, 20
lisi, 7
wangwu, 45
zhaoliu, 34
kklk, 23

Hibernate也提供了直接查询部分属性,而且返回也是相应类的查询方式,如下:

  1. try  
  2. {  
  3.     tx = session.beginTransaction();  
  4.       
  5.   
  6.       
  7.     Query query = session.createQuery("<span style="color:#ff0000;">select <strong><em>new Student(s.name,s.age)</em></strong> from Studnet s</span>");  
  8.       
  9.     List list = query.list();  
  10.       
  11.     for(int i = 0; i < list.size(); i++)  
  12.     {  
  13.         <span style="color:#ff0000;">Student student = (Student)list.get(i)</span>;  
  14.           
  15.         System.out.println(student.getName() + ", " + student.getAge());  
  16.     }  
  17.     tx.commit();  
  18. }  
这时list()返回的List元素就是Student。执行:结果出现异常了:

org.hibernate.hql.ast.QuerySyntaxException: Unable to locate appropriate constructor on class [com.cdtax.hibernate.Student] [select new Student(s.name,s.age) from com.cdtax.hibernate.Student s]
at org.hibernate.hql.ast.QuerySyntaxException.convert(QuerySyntaxException.java:54)
at org.hibernate.hql.ast.QuerySyntaxException.convert(QuerySyntaxException.java:47)
at org.hibernate.hql.ast.ErrorCounter.throwQueryException(ErrorCounter.java:82)
at org.hibernate.hql.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:261)
at org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:185)
at org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:136)
at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:101)
at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:80)
at org.hibernate.engine.query.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:94)
at org.hibernate.impl.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:156)
at org.hibernate.impl.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:135)
at org.hibernate.impl.SessionImpl.createQuery(SessionImpl.java:1651)
at com.cdtax.hibernate.HibernateTest.main(HibernateTest.java:54)
什么原因呢????原来Hibernate使用构造函数来生成list的元素,就是Student,而Student没有具有两个参数(String name,int age)的构造函数,所以修改一下Student类,增加相应的构造函数,一定要注意参数的顺序

  1. import java.util.Set;  
  2.   
  3. public class Student  
  4. {  
  5.     private String id;  
  6.       
  7.     private String cardId;  
  8.       
  9.     private String name;  
  10.       
  11.     private int age;  
  12.   
  13.     <span style="color:#ff0000;">public Student()  
  14.     {  
  15.           
  16.     }  
  17.       
  18.     public Student(String name, int age)  
  19.     {  
  20.         this.name = name;  
  21.         this.age = age;  
  22.     }  
  23. </span>  
  24.     public String getCardId()  
  25.     {  
  26.         return cardId;  
  27.     }  
  28.   
  29.     public void setCardId(String cardId)  
  30.     {  
  31.         this.cardId = cardId;  
  32.     }  
  33.   
  34.     public int getAge()  
  35.     {  
  36.         return age;  
  37.     }  
  38.   
  39.     public void setAge(int age)  
  40.     {  
  41.         this.age = age;  
  42.     }  
  43.   
  44.     private Set<Course> courses;  
  45.   
  46.     public String getId()  
  47.     {  
  48.         return id;  
  49.     }  
  50.   
  51.     public void setId(String id)  
  52.     {  
  53.         this.id = id;  
  54.     }  
  55.   
  56.     public String getName()  
  57.     {  
  58.         return name;  
  59.     }  
  60.   
  61.     public void setName(String name)  
  62.     {  
  63.         this.name = name;  
  64.     }  
  65.   
  66.     public Set<Course> getCourses()  
  67.     {  
  68.         return courses;  
  69.     }  
  70.   
  71.     public void setCourses(Set<Course> courses)  
  72.     {  
  73.         this.courses = courses;  
  74.     }  
  75.       
  76. }  
在执行结果正确显示:

Hibernate: select student0_.name as col_0_0_, student0_.age as col_1_0_ from student student0_
zhangsan, 20
lisi, 7
wangwu, 45
zhaoliu, 34
kklk, 23
我们在打印的时候增加一行:System.out.println(student.getCardId());结果:

Hibernate: select student0_.name as col_0_0_, student0_.age as col_1_0_ from student student0_
zhangsan, 20
null
lisi, 7
null
wangwu, 45
null
zhaoliu, 34
null
kklk, 23
null

cardid为null,因为我们没有查此字段。

6、连接操作

如下的查询:

  1. Query query = session.createQuery("from Team t join t.students");  
  2.               
  3. List list = query.list();  
产生的sql语句如下:

Hibernate: 
    select
        team0_.id as id3_0_,
        students1_.id as id0_1_,
        team0_.teamname as teamname3_0_,
        students1_.name as name0_1_,
        students1_.cardid as cardid0_1_,
        students1_.age as age0_1_ 
    from
        team team0_ 
    inner join
        student students1_ 
            on team0_.id=students1_.team_id
Hibernate: 
    select
        students0_.team_id as team5_1_,
        students0_.id as id1_,
        students0_.id as id0_0_,
        students0_.name as name0_0_,
        students0_.cardid as cardid0_0_,
        students0_.age as age0_0_ 
    from
        student students0_ 
    where
        students0_.team_id=?
Hibernate: 
    select
        students0_.team_id as team5_1_,
        students0_.id as id1_,
        students0_.id as id0_0_,
        students0_.name as name0_0_,
        students0_.cardid as cardid0_0_,
        students0_.age as age0_0_ 
    from
        student students0_ 
    where
        students0_.team_id=?
Hibernate: 
    select
        students0_.team_id as team5_1_,
        students0_.id as id1_,
        students0_.id as id0_0_,
        students0_.name as name0_0_,
        students0_.cardid as cardid0_0_,
        students0_.age as age0_0_ 
    from
        student students0_ 
    where
        students0_.team_id=?

简单地写join就是内连接:inner join

 inner join    student students1_      on team0_.id=students1_.team_id

等价于:select * from team team0_ ,student students1_ where team0_.id=students1_.team_id

左外连接,以连接左面的表为准(为参照表),查询结果一定包含左边表的全部和右边表匹配的记录。left  outer  join

同理,右外连接以右面的表为参照。

对于上面的查询,查询的是team和student中的所有字段,所以list结果是其元素是一个Object的数组,数组中是Team和Student对象。

  1. Query query = session.createQuery("from Team t join t.students");  
  2.               
  3.             List list = query.list();  
  4.               
  5.             for(int i = 0; i < list.size(); i++)  
  6.                 {  
  7.                     <span style="color:#ff0000;">Object[] obj = (Object[])list.get(i);  
  8.                       
  9.                     Team team = (Team)obj[0];  
  10.                     Student student = (Student)obj[1];</span>  
  11.                       
  12.                     System.out.println(team.getTeamName());  
  13.                     System.out.println(student.getName() + ", " + student.getAge());  
  14.                     System.out.println("====================");  
  15.                 }  
执行结果:

team1
zhangsan, 20
====================
team1
lisi, 7
====================
team2
wangwu, 45
====================
team2
zhaoliu, 34
====================
team3
kklk, 23
====================

7、将Team.hbm.xml中的set设为延迟加载,即lazy=”true“

修改测试程序:

  1. import java.util.List;  
  2.   
  3. import org.hibernate.Query;  
  4. import org.hibernate.Session;  
  5. import org.hibernate.SessionFactory;  
  6. import org.hibernate.Transaction;  
  7. import org.hibernate.cfg.Configuration;  
  8.   
  9. public class HibernateTest  
  10. {  
  11.     private static SessionFactory sessionFactory;  
  12.       
  13.     static  
  14.     {  
  15.         try  
  16.         {  
  17.             sessionFactory = new Configuration().configure().buildSessionFactory();  
  18.         }  
  19.         catch(Exception ex)  
  20.         {  
  21.             ex.printStackTrace();  
  22.         }  
  23.     }  
  24.       
  25.     public static void main(String[] args)  
  26.     {  
  27.                   
  28.         Session session = sessionFactory.openSession();  
  29.         Transaction tx = null;  
  30.         Query query = null;  
  31.           
  32.         List list = null;  
  33.         try  
  34.         {  
  35.             tx = session.beginTransaction();  
  36.   
  37.               
  38.             query = session.createQuery("from Team t join t.students");  
  39.               
  40.             list = query.list();  
  41.               
  42.             tx.commit();  
  43.         }  
  44.         catch(Exception ex)  
  45.         {  
  46.             if(null != tx)  
  47.             {  
  48.                 tx.rollback();  
  49.             }  
  50.             ex.printStackTrace();  
  51.         }  
  52.         finally  
  53.         {  
  54.             session.close();  
  55.         }  
  56.           
  57.         for(int i = 0; i < list.size(); i++)  
  58.         {  
  59.             Object[] obj = (Object[])list.get(i);  
  60.               
  61.             Team team = (Team)obj[0];  
  62.             Student student = (Student)obj[1];  
  63.               
  64.             System.out.println(team.getTeamName());  
  65.             System.out.println(student.getName() + ", " + student.getAge());  
  66.             System.out.println("====================");  
  67.         }  
  68.     }  
  69. }  

使用了join后,连同Student的信息就一并查询出来了,lazy延时加载就被覆盖了,变成了立即加载,所以在session关闭后,打印student也能出来结果,如果只查询team,而且又使用了延迟加载,那么在关系session后在打印student是打印不出来的。

8、使用实体命名参数查询

修改Student,增加一个Team成员变量:

  1. import java.util.Set;  
  2.   
  3. public class Student  
  4. {  
  5.     private String id;  
  6.       
  7.     private String cardId;  
  8.       
  9.     private String name;  
  10.       
  11.     private int age;  
  12.       
  13.     private Team team;  
  14.   
  15.     public Team getTeam()  
  16.     {  
  17.         return team;  
  18.     }  
  19.   
  20.     public void setTeam(Team team)  
  21.     {  
  22.         this.team = team;  
  23.     }  
  24.   
  25.     public Student()  
  26.     {  
  27.           
  28.     }  
  29.       
  30.     public Student(String name, int age)  
  31.     {  
  32.         this.name = name;  
  33.         this.age = age;  
  34.     }  
  35.   
  36.     public String getCardId()  
  37.     {  
  38.         return cardId;  
  39.     }  
  40.   
  41.     public void setCardId(String cardId)  
  42.     {  
  43.         this.cardId = cardId;  
  44.     }  
  45.   
  46.     public int getAge()  
  47.     {  
  48.         return age;  
  49.     }  
  50.   
  51.     public void setAge(int age)  
  52.     {  
  53.         this.age = age;  
  54.     }  
  55.   
  56.     private Set<Course> courses;  
  57.   
  58.     public String getId()  
  59.     {  
  60.         return id;  
  61.     }  
  62.   
  63.     public void setId(String id)  
  64.     {  
  65.         this.id = id;  
  66.     }  
  67.   
  68.     public String getName()  
  69.     {  
  70.         return name;  
  71.     }  
  72.   
  73.     public void setName(String name)  
  74.     {  
  75.         this.name = name;  
  76.     }  
  77.   
  78.     public Set<Course> getCourses()  
  79.     {  
  80.         return courses;  
  81.     }  
  82.   
  83.     public void setCourses(Set<Course> courses)  
  84.     {  
  85.         this.courses = courses;  
  86.     }  
  87.       
  88. }  

修改HBM文件:

  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
  3. "http://hibernate./hibernate-mapping-3.0.dtd">  
  4.   
  5. <hibernate-mapping>  
  6.       
  7.     <class name="com.cdtax.hibernate.Student" table="student">  
  8.       
  9.         <id name="id" column="id" type="string">  
  10.             <generator class="uuid"></generator>  
  11.         </id>  
  12.           
  13.         <property name="name" column="name" type="string"></property>  
  14.         <property name="cardId" column="cardid" type="string"></property>  
  15.         <property name="age" column="age" type="int"></property>  
  16.           
  17.           
  18.         <set name="courses" table="student_course" cascade="save-update">  
  19.         <!-- cascade不能使用all -->  
  20.             <key column="student_id"></key>  
  21.             <many-to-many class="com.cdtax.hibernate.Course" column="course_id"></many-to-many>  
  22.         </set>          
  23.           
  24.         <span style="color:#ff6666;"><many-to-one name="team" class="com.cdtax.hibernate.Team" fetch="select" column="team_id"></many-to-one></span>  
  25.     </class>  
  26. </hibernate-mapping>  
增加了many-to-one

查询测试:

  1. try  
  2.         {  
  3.             tx = session.beginTransaction();  
  4.               
  5.             Team team = (Team)session.get(Team.class, "402881c04223208801422320897a0002");  
  6.               
  7.             Query query = session.createQuery("<span style="color:#ff0000;">from Student s where s.team = :team and s.age > 20</span>");  
  8.               
  9.             query.<span style="color:#ff0000;">setParameter</span>("team", team,Hibernate.entity(Team.class));  
  10.               
  11.             List<Student> list = query.list();  
  12.               
  13.             System.out.println(list.size());  
  14.             tx.commit();  
  15.         }  

这里要注意,使用命名参数=:与命名参数之间不能有空格=和:之间可以有空格,query的setParameter方法,第一个参数是命名参数,第二个是参数的值,第三个是type,是Hibernate要求的type值,这个值的获取是使用org.hibrenate.Hibernate类提供的静态方法entity()来获得的。

第二种设定实体查询的命名参数的方法

  1. try  
  2.         {  
  3.             tx = session.beginTransaction();  
  4.               
  5.             Team team = (Team)session.get(Team.class, "402881c04223208801422320897a0002");  
  6.               
  7.             Query query = session.createQuery("from Student s where s.team = :team and s.age > 20");  
  8.               
  9. //          query.setParameter("team", team,Hibernate.entity(Team.class));  
  10.               
  11.             <span style="color:#ff0000;">query.setEntity("team", team);</span>  
  12.               
  13.             List<Student> list = query.list();  
  14.               
  15.             System.out.println(list.size());  
  16.             tx.commit();  
  17.         }  
query的setEntity()方法更简单。


session提供的过滤功能,createFilter(Object collection,String queryString) 

  1. try  
  2.         {  
  3.             tx = session.beginTransaction();  
  4.               
  5.             Team team = (Team)session.get(Team.class, "402881c04223208801422320897a0002");  
  6.               
  7. //          Query query = session.createQuery("from Student s where s.team = :team and s.age > 20");  
  8.               
  9. //          query.setParameter("team", team,Hibernate.entity(Team.class));  
  10.               
  11. //          query.setEntity("team", team);  
  12.               
  13.             <span style="color:#ff0000;">Query query = session.createFilter(team.getStudents(), "where age > 20");</span>  
  14.   
  15.             List<Student> list = query.list();  
  16.               
  17.             System.out.println(list.size());  
  18.             tx.commit();  
  19.         }  

9、QBC查询

between:

  1. try  
  2.         {  
  3.             tx = session.beginTransaction();  
  4.               
  5.             <span style="color:#ff0000;">Criteria criteria = session.createCriteria(Student.class)  
  6.                                 .add(Restrictions.between("age", new Integer(10), new Integer(30)));</span>  
  7.               
  8.             List<Student> list = criteria.list();  
  9.               
  10.             for(Student student : list)  
  11.             {  
  12.                 System.out.println(student.getName());  
  13.             }  
  14.             tx.commit();  
  15.         }  

like:

  1. try  
  2.         {  
  3.             tx = session.beginTransaction();  
  4.               
  5. //          Criteria criteria = session.createCriteria(Student.class)  
  6. //                              .add(Restrictions.between("age", new Integer(10), new Integer(30)));  
  7.               
  8.             Criteria criteria = session.createCriteria(Student.class)  
  9.                                 .add(Restrictions.<span style="color:#ff0000;">like</span>("name", "k%"));  
  10.             List<Student> list = criteria.list();  
  11.               
  12.             for(Student student : list)  
  13.             {  
  14.                 System.out.println(student.getName());  
  15.             }  
  16.             tx.commit();  
  17.         }  
in:

  1.     try  
  2.         {  
  3.             tx = session.beginTransaction();  
  4.               
  5. //          Criteria criteria = session.createCriteria(Student.class)  
  6. //                              .add(Restrictions.between("age", new Integer(10), new Integer(30)));  
  7.               
  8. //          Criteria criteria = session.createCriteria(Student.class)  
  9. //                              .add(Restrictions.like("name", "k%"));  
  10.           
  11.             String[] names = {"zhangsan","lisi","wangwu"};  
  12.               
  13.             Criteria criteria = session.createCriteria(Student.class)  
  14.                                 .add(Restrictions.<span style="color:#ff0000;">in</span>("name",names));  
  15.               
  16.             List<Student> list = criteria.list();  
  17.               
  18.             for(Student student : list)  
  19.             {  
  20.                 System.out.println(student.getName());  
  21.             }  
  22.             tx.commit();  
  23.         }  

排序:addOrder

  1. try  
  2.         {  
  3.             tx = session.beginTransaction();  
  4.               
  5. //          Criteria criteria = session.createCriteria(Student.class)  
  6. //                              .add(Restrictions.between("age", new Integer(10), new Integer(30)));  
  7.               
  8. //          Criteria criteria = session.createCriteria(Student.class)  
  9. //                              .add(Restrictions.like("name", "k%"));  
  10.           
  11. //          String[] names = {"zhangsan","lisi","wangwu"};  
  12. //            
  13. //          Criteria criteria = session.createCriteria(Student.class)  
  14. //                              .add(Restrictions.in("name",names));  
  15.               
  16.             Criteria criteria = session.createCriteria(Student.class)  
  17.                                 .addOrder(Order.asc("age")).addOrder(Order.desc("cardId"));  
  18.               
  19.             List<Student> list = criteria.list();  
  20.               
  21.             for(Student student : list)  
  22.             {  
  23.                 System.out.println(student.getName()+","+ student.getAge() + ","+ student.getCardId());  
  24.                 System.out.println("-----------------");  
  25.             }  
  26.             tx.commit();  
  27.         }  

执行结果:

Hibernate: 
    select
        this_.id as id0_0_,
        this_.name as name0_0_,
        this_.cardid as cardid0_0_,
        this_.age as age0_0_,
        this_.team_id as team5_0_0_ 
    from
        student this_ 
    order by
        this_.age asc,
        this_.cardid desc
lisi,7,402881c04223208801422320897a0022
-----------------
zhangsan,20,402881c04223208801422320897a0021
-----------------
kklk,23,402881c04223208801422320897a0025
-----------------
zhaoliu,34,402881c04223208801422320897a0024
-----------------
wangwu,45,402881c04223208801422320897a0023
-----------------

推荐使用HQL




    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多