JDBC API提供了一种可滚动的结果集,它是利用数据库系统中的游标来实现的。游标用于定位查询结果集中的记录,应用程序可以通过任意移动游标来定位到特定记录。 

Query接口及Criteria接口的scroll()方法返回一个org.hibernate.ScrollableResults对象,它就代表可滚动的结果集。ScrollableResult接口包含一下用于移动游标的方法: 
first():使游标移动到第一行 
last():使游标移动到最后一行 
beforeFirst():使游标移动到结果集的开头 
afterLast():使游标移动到结果集的末尾 
previous():使游标从当前位置向上移动一行 
next():使游标从当前位置向下移动一行 
scroll(int n):使游标从当前位置移动n行。若n>0,就向下移动,否则就向上移动。当n=1,等价于调用next()方法;当n=-1,等价于调用previous()方法 
setRowNumber(int n):使游标移动到行号为n的行。参数n指定行号。结果集的行号从0开始编号。若n为0,使游标移动到第一行;若n为2,使游标移动到第三行;若n为-1,使游标移动到最后一行。 
除beforeFirst()和afterLast()方法返回void类型,其余方法都返回boolean类型,若游标移动到的目标位置具有记录,就返回true,否则返回false。 
final int PAGE_SIZE=3; 
List firstNameOfPages = new ArrayList(); 
List pageOfCustomers = new ArrayList(); 
ScrollableResults re = session.createQuery("select c.name,c from Customer c").scroll(); 

if(rs.first()){ 
   do{ 
        String name = rs.getString(0); 
        firstNamesOfPages.add(name); 
     }while(rs.sroll(PAGE_SIZE)); 

rs.beforeFirst(); 
int i = 0; 
while((PAGE_SIZE > i++) && rs.next()) 
  pageOfCustomers.add(rs.get(1)) ; 


rs.close(); 

for(int i = 0 ;i < firstNamesOfPages.size();i++) 
  System.out.println(firstNamesOfPages.get(i)); 

for(int i = 0 ;i < firstNamesOfPages.size();i++) 
  System.out.println((Customer)PageOfCustomers.get(i)).getName(); 

Query接口及Criteria接口的scroll()方法还可以包含一个用于设置滚动模式的参数: 
ScrollableResults rs = session.createCriteria(Customer.class).scroll(ScrollMode.FORWARD_ONLY); 

org.hibernate.ScrollModel类提供了一下表示结果集滚动模式的静态常量: 
ScrollMode.FORWORD_ONLY:游标只能从上到下移动,即结果集不能滚动,指示默认值 
ScrollMode.SCROLL_INSENSITIVE:游标可以上下移动,即结果集可以滚动。当程序对结果集的内容做了修改,游标对此不敏感 
ScrollMode.SCROLL_SENSITIVE:游标可以上下移动,结果集可以滚动。当程序对结果集的内容做了修改,游标对此敏感。 

Hibernate采用绑定机制来避免恶意输入的问题。Hibernate的绑定机制依赖于JDBC API中PrepareStatement的预定于SQL语句。有以下优点: 
非常安全,防止怀有恶意的用户非法调用数据库系统的存储过程 
能够利用底层数据库预编译SQL语句的功能,提高查询数据的性能。预编译是指底层数据库系统只需编译SQL一次,把编译出来的可执行代码保存在缓存中,若执行相同形式的SQL,则不需重新编译,直接从缓存中获得可执行代码即可。 

HQL的参数绑定有两种形式: 
按参数名绑定:在HQL查询语句中定义命名参数,命名参数以:开头 
Query query = session.createQuery("from Customer as c where c.name=: customerName and c.age =: customerAge"); 
query.setString("customerName",name); 
query.setInteger("customerAge",age); 

按参数位置绑定:在HQL查询语句中用个?来定义参数的位置 
Query query = session.createQuery("from Customer as c where c.name = ? and c.age = ?"); 
query.setString(0 , name); 
query.setInteger(1 , age); 

除了用于绑定特定映射类型的参数方法,Hibernate还提供了3个特殊的参数绑定方法: 
setEntity()方法:把参数与一个持久化类的实例绑定 
setParameter()方法:绑定任意类型的参数。 
//第三个参数显式指定Hibernate映射类型,有些参数值java可以推断出对应的映射类型,故可以不必显式指定。 
query.setParameter("customer",customer,Hibernate.entity(Customer.class)); 
setProperties()方法:用于把命名参数与一个对象的属性绑定 
Customer c = new Customer(); 
c.setName("Jack"); 
c.setAge(12); 
List result = session.createQuery("from Customer as c where c.name =: customerName and c.age =: customerAge").setProperties(c).list; 

在HQL检索方式或QBC检索方式来检索数据时,可以通过Query或Criteria接口的一些方法来设定查询附属事项: 
setFlushMode()方法:设置清理缓存的模式 
setCacheModel()方法:设置Session与第二级缓存的交互模式 
setTimeout()方法:设置执行查询数据库操作的超时间 
setFetchSize()方法:为JDBC驱动程序设置批量抓取的数目 
setLockMode()方法:设置锁定模式 
setComment()方法:为SQL日志设置注解 
setReadOnly()方法:设置查询结果是否只允许读,它还可以设置单个持久化对象的读写模式: 
setReadOnly(object,true); 
setReadOnly(object,false): 

Session的缓存有3种清理模式:分别用org.hibernate.FlushMode类的3个静态常量来表示:FlushMode.AUTO、FlushMode.NEVER 
                   3种清理模式 
清理缓存的模式 各种查询方法  Transaction的commit()方法  Session的flush()方法 
FlushMode.AUTO   清理               清理                         清理 
FlushMode.COMMIT  不清理            清理                         清理 
FlushMode.NEVER   不清理           不清理                        清理 

Query query = session.createQuery("from Customer c") 
                     .setFlushMode(FlushMode.COMMIT); 
Criteria criteria = session.createCriteria(Customer.class) 
                           .setFlushMode(FlushMode.COMMIT); 

Session与第二季缓存的5种交互模式及,分别用org.hibernate.CacheMode.NORMAL(正常模式)、CacheMode.IGNORAL(忽略模式)、CacheMode.GET(读取模式)、CacheMode.PUT(写入模式)、CacheMode.REFRESH(刷新模式) 
Query query = session.createQuery("from Customer c") 
                     .setCacheMode(CacheMode.GET) 
                     .setFlushMode(FlushMode.COMMIT); 
Criteria criteria = session.createCriteria(Customer.class) 
                           .setCacheMode(CacheMode.GET); 
                           .setFlushMode(FlushMode.COMMIT); 


设置注解 
在Hibernate配置文件中把hibernate.use_sql_comments属性设为true 
Java属性格式的配置文件: 
hibernate.use_sql_comments = true; 
XML格式的配置文件: 
<property name="use_sql_comments">true</property> 

Hibernate允许在映射文件中定义字符串形式的查询语句。 
<query name="findCustomerByName 
       cache-mode="get" 
       comment="My Comment.." 
       fetch-size="50" 
       read-only="true" 
       timeout="60" 
"> 
    <![CDATA[ 
          from Customer where c.name like :name 
    ]]> 
</query> 

Query query = session.getNamedQuery("findCustomersByName"); 
query.setString("name",name); 
List result = query.list(); 

字符串匹配模式:HQL用like关键字进行模糊查询,QBC用Restrictions类的like()方法进行模糊查询 
%匹配任意类型并且任意长度的字符串,若是中文,需两个百分号(%%) 
_匹配单个任意字符,常用来限制字符串表达式的长度 
session.createQuery("from Customer c where c.name like '%T'"); 

Criteria criteria = session.createCriteria(Customer.class); 
criteria.add(Restrictions.like("name","%T")); 

对于QBC检索方式,除了使用通配符,还可以使用org.hibernate.criterion.MatchMode类的各种静态常量实例来设定字符串模式。 
Criteria criteria = session.createCriteria(Customer.class); 
criteria.add(Restrictions.like("name","T",MatchMode.START)); 

             MatchMode类包含的各个静态常量实例 
匹配模式                        举例 
MatchMode.START    Restrictions.like("name","T",MatchMode.START) 以T开头 
MatchMode.END      Restrictions.like("name","T",MatchMode.END) 以T结尾 
MatchMode.ANYWHERE Restrictions.like("name","T",MacthMode.ANTWHERE) 包含T 
MatchMode.EXACT    Restrictions.like("name","Tom",MatchMode.EXACT) 精准匹配 

List result = session.createQuery("from Customer c where c.orders is empty").list(); 

List result = session.createCriteria(Customer.class).add(Restrictions.isEmpty("orders")).list(); 

              HQL与QBC支持的各种连接模型 
在程序中指定的连接查询类型              HQL               QBC             
内连接                      inner join 或 join     Criteria.createAlias() 
迫切内连接          inner join fetch 或 join fetch       不支持      
隐式内连接                            支持                    不支持   
左外连接              left outer join 或 left join       不支持 
迫切左外连接  left outer join fetch 或 left join fetch  FetchMode.JOIN 
右外连接              right outer join 或 right join      不支持 
以上适用于有关联关系的持久类,并且在映射文件中对这种关联关系做了映射 
交叉连接                   Class A, Class B                不支持 
适用于不存在关联关系的持久化类 

在使用left join fetch关键字表示迫切左外连接检索策略时,查询结果中可能会包含重复元素,可以通过一个HashSet来过滤重复元素。 
List result = session.createCriteria(Customer.class) 
                     .setFetchMode("orders",FetchMode.JOIN) 
                     .add(Restrictions.like("name","T",MetchMode.START)) 
                     .list(); 

HashSet set = new HashSet(result); 

for(Iterator it = set.iterator(); it.hasNext();){ 
  Customer customer = (Customer)it.next(); 
  .... 


迫切左外连接和左外连接的区别是前者实例化里关联和被关联对象,后者只是返回一个引用。