4、hibernate检索策略
1):立即检索(加载);session.get();query.list();缺点:sql语句太多。
2): 延迟检索(加载);session.load();query.iterate();<set lazy = “true”>
3): 在多对一关联级别中,默认情况下是使用左外连接检索策略。如果对Order.hbm.xml
文件中的<many-to-one outer-join=”true”>表示总是使用左外连接。
当使用代码:
Order order = (Order)session.get(Order.class,new Long(1));
则hibernate产生的sql有:缺点:如果连接数据表很复杂,将会导致查询的深度很深,从而影响其查询性能,在hibernate可以配置检索的深度。
Select * from order left outer join customer on order.customer_id = customer.id where order.id = 1;
配置检索深度,需要在主配置文件中配置。 <property name = “max_fetch_depth”>1</property>
5、Hibernate查询排序
1):数据库排序(推荐)
在进行数据查询时就对数据进行排序。
需要在hbm.xml文件中进行属性order-by属性的配置,其值为要进行排序的数据库字段进行asc desc进行排序。(可以同时进行多个字段的排序,相互之间用;隔开,<list>没有order-by属性)
2):内存排序
利用程序中的排序规则对数据进行排序
需要在hbm.xml文件中进行属性sort属性的配置。
Sort可以使用hibernate提供的值进行排序,也可以自定义排序规则。
如何自定义排序规则,如何引用?---需实现compare接口 /** * 自定义比较器 */ public class MyCompare implements Comparator<String> { @Override public int compare(String o1, String o2) { /** * 两者相等,返回0 * 前面的大,返回1 * 后面的大,返回-1 */ if(o1.equals(o2)) { return 0; } return 0; } } 然后在hbm.xml文件中指定属性sort = “比较器类的全称”
10、Hibernate 联合主键配置
利用hibernate生成联合主键
1):一种方式为在域模型中添加多个字段来映射成联合主键
要求:作为联合主键的域模型必须实现serializable;
必须重写该类的equals();与hashcode()方法,用于比较两个对象相等
的条件。
Public class Student implements Serializable{ Private String cardId;//联合主键之一 Private String name;//联合主键之一 Private int age; Public int hashCode(){ //将作为联合主键的属性进行hashcode比较 } Public boolean equals(Object obj){ //将作为联合主键的属性进行equals比较 } }
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name = "com.liusheng.models.Student7" table="student7"> <!-- 配置联合主键,不适用hibernate提供的主键 --> <composite-id> <key-property name="cardId" column="cardId" type="string"></key-property> <key-property name="name" column="name" type="string"></key-property> </composite-id> <!-- 配置普通属性 --> <property name="age" column="age" type="integer"></property> </class> </hibernate-mapping>
当在对作为联合主键的对象进行保存时,如何联合主键是相同的,只会进行一次(第一次)数据库保存。
11、hibernate检索方式
1):导航对象图检索方式;
2):根据OID进行检索;(session.get();session.load();)
3):HQL检索方式;
Query query = session.createQuery(“from Customer as c where c.name =:customerName and c.age =:customerAge”); //动态绑定参数--使用命名参数的方式(原子类型) query.setString(“customerName”,”Tom”); query.setInteger(“customerAge”,12); 说明:其中在HQL语句中的=:后面的为自定义的名字,等同于一个占位符一样 而后面的则是给自定义的名字动态的附上值。
如果是除原子类型外的参数传入??--Student、Team对象 Team t = (Team)session.get(Team.class,new Long(1)); Query query = session.createQuery(“from Student s where s.team = :team and s.age = :age”); //动态绑定原子类型 query.setInteger(“age”,12); //绑定其他类型(一种方式) query.setParameter(“team”,t,Hiberante.entity(Team.class)); //绑定其他类型(第二种方式) query.setEntity(“team”,t);
如果是除原子类型外的参数传入??--Student、Team对象 Team t = (Team)session.get(Team.class,new Long(1)); Query query = session.createFilter(t.getStudents,”where age =:age”); query.setInteger(“age”,23);
对查询出结果对象的解说:
1):返回的结果是完整的数据对象
Query query = session.createQuery(“from Customer”); List list = query.list(); For(int i =0;i<list.size();i++){ //得到的是一个个完整的数据对象 }
2):返回的结果不是完整数据对象(部分属性)
第一种方式: Query query = session.createQuery(“select c.name, c.age from Customer c”); /* * 通过该条件返回的只有对象中的部分属性,那么他查询数据并不是 * 一个个的对象,而是一个个游离的数据,也就是说以前通过list返回的 * 一行记录构成一个完整的数据对象,list存放的一个个对象就是 * 一个完整的对象。所以直接遍历然后类型转换即可。 * 而对于查询的数据只是部分的数据就无法构成一个完成的对象,Hibernate处理是 * 将查询出的一行数据(无法构成完整对象)将每一个字段包装成一个个object然后将整行 * 对象放置在一个Object[]中。 * 因此返回的一个个对象实际上是一个个Object[] */ List list = query.list(); For(int i=0;i<list.size();i++){ Object[]objs = (Object[])list.get(i); For(int j=0;j<objs.length;i++){ //得到的是一个个属性字段的内容对象 } }
第二种方式:前提是必须重载构造函数(提供对应查询字段的构造函数) /* * 希望即使是返回部分字段也是以完整对象的形式返回 * 他将离散的值构成一个完整的对象返回. * 这种方式是需要模型类提供一个与查询部分字段相对应的构造函数。 */ Query query = session.createQuery(“select new Coustomer(c.name,c.age) from Customer c”); List<Customer> list = (List<Customer)query.list(); for(Customer cc:list){ //得到的是一个完整的对象,除查询属性外,其他的属性都是为默认值。 }
连接查询: (两张表以上的查询Team表,Student表)
1):内连接查询(inner... join...on 或 join...on):
Select * from Team t inner join student s on t.id = s.id; 查询两表中符合条件的记录,可能两表的数据都有“丢失”现象
Hibernate会自动附上on 后面的查询条件 Query query = session.createQuery(“from Team t join t.student”);
2):左外连接(left ...join...on 或 left outter ...join ...on)
Select * from Team t left outter join Student on t.id = s.id; 已左表为基准,会将左表所有的记录查出来,如果右表有符合条件的就查询,如果没有就用将对应的字段赋值为Null
3):右外连接(right..join...on 或 right outter...join...on)与左外连接相反
4):QBC检索方式
这种检索方式主要由:Criteria接口、Criterion接口、Expression类组成,支持在运行时动态生成查询语句。 Criteria c = session.createCriteria(Customer.class);//Criteria是针对模型进行查询 List list = c.list(); //增加查询条件 Criterion cn= Expression.like(“name”,”T%”); Criterion cn2 = Expresion.eq(“age”,new Integer(21)); c = c.add(cn).add(cn2); List result = c.list(); -产生的对应的sql-- Select * from Customer c where c.name like “T%” and c.age = 21;