hibernate的QBE和QBC

一、先介绍几个名词:
 Criteria:在线查询容器
 DetachedCriteria:离线查询容器
 Example:作为查询容器德参数,创建查询对象的模版
 Restrictions:作为查询容器的参数,设置封装限制条件、查询条件的模版,返回类型为Criterion
 Order:作为查询容器的参数,用于排序
 Projections:作为查询容器的参数,用于统计,对应数据库中的聚会函数

二、QBC、QBE查询方式介绍:
 1、QBE方式的在线查询:QBE 查询的关键就是样本对象的创建,样本对象中的所有非空属性均将作为查询条件
  Session session = HibernateSessionFactory.getSessionFactory().openSession();
  Transaction transaction = session.beginTransaction();  
   Criteria criteria = session.createCriteria(Student.class);//创建一个查询容器
   Student stu = new Student();
   stu.setName("Lily");
   Example example = Example.create(stu);//创建一个查询对象模版,模版中封装查询条件,stu解析的形式为key/value,参数可以是一个Map
   criteria.add(example);
   List list = criteria.list();
   transaction.commit(); 
   HibernateSessionFactory.closeSession();
 2、QBE方式的离线查询:
  DetachedCriteria dc = DetachedCriteria.forClass(Student.class);//获得离线查询器
  Student stu = new Student();
  stu.setName("Lily");
  Example e=Example.create(entity);//创建一个查询对象模版,模版中封装查询对象
  dc.add(e);
  Session session = HibernateSessionFactory.getSessionFactory().openSession();  
  Transaction ts = session.beginTransaction();//获得当前session,并开启事务
  Criteria criteria=dc.getExecutableCriteria(session);//session作为参数,通过离线查询器获得在线查询器
   List list = criteria.list();
   transaction.commit(); 
   HibernateSessionFactory.closeSession();

  对QBE的Example的一点使用介绍:
  example.excludeNone();  排除对属性值为null的过滤
  example.ignoreCase();   对String类型属性的过滤不区分大小写
  example.enableLike(MatchMode.ANYWHERE); 对String类型属性采用完全模糊过滤查询
  example.excludeZeroes();  排除对属性值为0的过滤
  example.excludeProperty("entityName"); 排除指定的属性名


 3、QBC方式的在线查询:
  Session session = HibernateSessionFactory.getSessionFactory().openSession();  
  Transaction ts = session.beginTransaction();  
  Criteria cri = session.createCriteria(Student.class);//创建查询容器 
  //Criterion cron = Restrictions.eq("name","Lily");
  //cri.add(cron);
  cri.add(Restrictions.gt("name","Lily"));//通过Restrictions添加、封装查询条件
  cri.addOrder(Order. desc("createtime" ));
  Iterator it = cusCriteria.list().iterator();
  ts.commit();  
  HibernateSessionFactory.closeSession();
 4、QBC方式的离线查询:
  DetachedCriteria dc = DetachedCriteria.forClass(Student.class);//获得离线查询器
  dc.addOrder(Order. desc("createtime" ));
  //Criterion cron = Restrictions.eq("name","Lily");
  //cri.add(cron); 
  dc.add(Restrictions.eq("name","Lily"));
  Session session = HibernateSessionFactory.getSessionFactory().openSession();
  Transaction ts = session.beginTransaction();//获得当前session,并开启事务
  Criteria criteria=dc.getExecutableCriteria(session);//session作为参数,通过离线查询器获得在线查询器
  List list = criteria.list();
  transaction.commit();
  HibernateSessionFactory.closeSession(); 
 解释:1、QBC与QBE本质上没有什么区别,只是使用方式上有所不同,QBE需要将查询条件封装到查询对象中,并由Example创建查询模版,QBE功能没有QBC功能强大,两者可以结合使用
       2、Criteria与DetachedCriteria,前者为在线查询,后者为离线查询,主要区别在于创建的形式不一样,Criteria是由 Hibernate Session 进行创建的;DetachedCriteria创建时无需session
   使用DetachedCriteria离线查询,获得session后,还要获得Criteria,已进行实际查询任务
   Criteria criteria=dc.getExecutableCriteria(session);
   List list = criteria.list();
   两者之间的区别参照:http://www.cnblogs.com/hqr9313/archive/2012/08/08/2627855.html

此处有个问题:在实际的项目中,当获得离线查询器向里面添加的实体有某个或者某些属性值发生了变化,则执行criteria.list();的时候,看到的sql首先会执行update,然后才执行select语句,这是什么原因呢??

三、总结网上查到的资料,细说QBC:
 QBC(Query By Criteria) 查询:这种方式比较面向对象方式,重点是有三个描述条件的对象:Restrictions,Order,Projections。使用QBC查询,一般需要以下三个步骤:
 1. 使用Session实例 的createCriteria()方法创建Criteria对象
 2. 使用工具类Restrictions的方法为Criteria对象设置查询条件,Order工具类的方法设置排序方式,Projections工具类的方法进行统计和分组。
 3. 使用Criteria对象的list()方法进行查询并返回结果

 Restrictions类的常用方法:返回类型为Criterion,作为查询容器的参数
 方法名称   描述     使用
 Restrictions.eq   等于     Restrictions.eq(String propertyName,Object value)
 Restrictions.allEq  使用Map,Key/Valu进行多个等于的比对 Restrictions.allEq(Map propertyNameValues)
 Restrictions.gt(greater than) 大于     Restrictions.gt(String propertyName, Object value)
 Restrictions.ge(greater equal) 大于等于    Restrictions.ge(String propertyName, Object value)
 Restrictions.lt(less than) 小于     Restrictions.It(String propertyName, Object value)
 Restrictions.le(less equal) 小于等于    Restrictions.Le(String propertyName, Object value)
 Restrictions.between  对应SQL的between   Restrictions.between(String propertyName, Object lo, Object hi)
 Restrictions.like  对应SQL的like    Restrictions.like(String propertyName, Object value)
 Restrictions.in   对应SQL的in    Restrictions.in(String propertyName, Collection value)
 Restrictions.and  and关系     Restrictions.and(Criterion lhs, Criterion rhs)
 Restrictions.or   or关系     Restrictions.or(Criterion lhs, Criterion rhs)
 Restrictions.sqlRestriction SQL限定查询    Restrictions.sqlRestriction(String sql,Object[] values,Type[] types)
 
 Order类的常用方法:作为查询容器的参数
 方法名称   描述     使用
 Order.asc   升序     Order.asc(String propertyName)
 Order.desc   降序     Order.desc(String propertyName)

 Projections类的常用方法:作为查询容器的参数
 方法名称   描述     使用
 Projections.avg   求平均值    Porjections.avg(String propertyName)
 Projections.count  统计某属性的数量   Projections.count(String propertyName)
 Projections.countDistinct 统计某属性不同值的数量   Projections.countDistinct(String propertyName)
 Projections.groupProperty 指定某个属性为分组属性   Projections.groupProperty(String propertyName)
 Projections.max   求最大值    Projections.max(String propertyName)
 Projections.min   求最小值    Projections.min(String propertyName)
 Projections.projectionList 创建一个ProjectionList对象  Projections.projectionList()
 Projections.rowCount  查询结果集中的记录条数   Projections.rowCount()
 Projections.sum   求某属性的合计    Projections.sum(String propertyName)

 
 QBC的普通查询:
 示例:
 Criteria实际上是一个容器,如果想要设定查询条件,则要使用add()方法加入Restrictions的条件限制,例如查询age大于20且小于40的资料:
  Criteria criteria = session.createCriteria(User.class);
  criteria.add(Restrictions.gt("age", new Integer(20)));
  criteria.add(Restrictions.lt("age", new Integer(40)));
  List users = criteria.list();


 您也可以使用逻辑作何查询数据,例如結合age等于(eq)20或(or)age为空(isNull)的条件:
  Criteria criteria = session.createCriteria(User.class);
  criteria.add(Restrictions.or(
       Restrictions.eq("age", new Integer(20)), Restrictions.isNull("age")
        ));
  List users = criteria.list();


 也可以使用sqlRestriction()方法來提供SQL语法作限定查詢,例如查询name以cater开头的资料:
  Criteria criteria = session.createCriteria(User.class);
  criteria.add(Restrictions.sqlRestriction("{alias}.name LIKE (?)", "cater%", Hibernate.STRING));
  List users = criteria.list();
 其中alias將被替换为与User类別关联的名称,而?將被替换为cater%,也就是第二个参数所提供的值,在SQL书写时,不必再写WHERE,如果有多个查询条件,
 例如BETWEEN子句的查询,则可以如下:
  Criteria criteria = session.createCriteria(User.class);
  Integer[] ages = {new Integer(20), new Integer(40)};
  Type[] types = {Hibernate.INTEGER, Hibernate.INTEGER};
  criteria.add(Restrictions.sqlRestriction("{alias}.age BETWEEN (?) AND (?)", ages, types));
  List users = criteria.list();

 QBC分页查询:
 分页查询主要是要指定两个参数:从第几条数据开始,取多少条数据。可以通过调用Query或者Criteria对象的setFirstResult()和setMaxResults()方法分别进行设定。
 示例:
    Session session = SessionFactory.getCurrentSession();
    List userList = null;
    Transaction ts = session.beginTransaction();
    try {
  Criteria criteria = session.createCriteria(User.class);
  criteria.setFirstResult(0);//从第一个数据开始
  criteria.setMaxResults(10);//取10条记录
  userList = (List) criterial.list();  
  session.commit();
   } catch (HibernateException ex) {
  ts.rollBack();
  ex.printStackTrace();
   }

 QBC复合查询:在原有查询的基础上再进行查询,可以调用Criteria对象的createCriteria()方法在这个Criteria对象的基础上再进行查询。
 示例:
    Session session = SessionFactory.getCurrentSession();
    User user = new User();
    Transaction ts = session.beginTransaction();
    try
    {
  Criteria criteria1 = session.createCriteria(Room.class);
  Criteria criteria2 =criteria1.createCriteria("User");  
  criteria2.add(Restrictions.eq("name",new String("ijse"));
  user= (User) criteria2.list().get(0); 
  session.commit();
   } catch (HibernateException ex) { 
  ts.rollBack(); 
  ex.printStackTrace();
   }
   QBC关联查询:
   示例:要求,通过客户查找销售员
  使用Criteria可以有两种方法:
  1:
  DetachedCriteria beautyCriteria = DetachedCriteria.forClass(Beauty.class).createCriteria("customers");
  beautyCriteria.add(Restrictions.eq("name", "Gates")):

  2:
  DetachedCriteria beautyCriteria = DetachedCriteria.forClass(Beauty.class).createAlias("customers", "c");
  beautyCriteria.add(Restrictions.eq("c.name", "Gates")):

  要求二:对销售员的年龄进行控制为20岁
  DetachedCriteria beautyCriteria = DetachedCriteria.forClass(Beauty.class, "b").;
  DetachedCriteria customerCriteria = beautyCriteria.createAlias("customers", c");
  beautyCriteria.add(Restrictions.le("b.age", new Long(20))):
  customerCriteria.add(Restrictions.eq("c.name", "Gates")):

你可能感兴趣的:(hibernate的QBE和QBC)