Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1002453
  • 博文数量: 152
  • 博客积分: 4937
  • 博客等级: 上校
  • 技术积分: 1662
  • 用 户 组: 普通用户
  • 注册时间: 2007-10-05 16:55
文章分类

全部博文(152)

文章存档

2013年(12)

2012年(6)

2011年(58)

2010年(43)

2009年(1)

2008年(15)

2007年(17)

我的朋友

分类:

2010-06-24 17:36:00

hibernate2007-08-04(上午).avi
注意hql的大小写敏感性
下面所有测试用的都是one-to-many代码只是在student中加了一个Data createDate属性还有就是插入的内容不同
//可以省略select
Query q = createQuery("from Student");
//使用select关键字时,必须定义别名
//不支持这样select * from Student会出错。
Query q = createQuery("select s from Student s");
//忽略select 给表加别名
Query q = session.createQuery("from Student s");
---------------------------------------------------
  测试一(list()):
    /**
     * 将发出一条查询语句,获取Student的集合数据
     * select student0_.id as id1_, student0_.name as name1_,
     * student0_.createTime as createTime1_, student0_.classid as classid1_
     * from t_student student0_
     */
    List students = session.createQuery("from Student").list();
    for (Iterator iter = students.iterator();iter.hasNext();) {
     Student student = (Student)iter.next();
     System.out.println(student.getName());
    }
  测试二(iterate()会出现n+1问题):
   //会发出n+1 条语句
   //先发出查询id的列表语句
   //select student0_.id as col_0_0_ from t_student student0_
   //再依次发出查询对象的sql(根据id)
   //select student0_.id as id1_0_, student0_.name as name1_0_,
   //student0_.createTime as createTime1_0_, student0_.classid as classid1_0_
   //from t_student student0_ where student0_.id=?
   Query query = session.createQuery("from Student");
   Iterator students = query.iterate();    //先发出查询id的列表语句,不管缓存里有没有数据,都发
   while (students.hasNext()) {//如果缓存有数据就不发,如果没有数据就每次next都会发一条根据id查询的sql
    Student student = (Student)students.next();
    System.out.println(student.getName());
   }
Iterator query = session.createQuery("from Student").iterate();
List students = session.createQuery("from Student").list();
iterate()与list()不同区别是,如上面代码所示就在于发出的sql语句条数不同

Iterator it= session.createQuery("from Student").iterate();
//上面代码先从数据库查出所有id,再根据ID查数据,所以会有n+1问题,但查实体对象会先在一级缓存查找
Iterator it= session.createQuery("select s.name,s.id from Student s").iterate();
//上面代码不会查id而是一次性取出所有数据封装成对像数组返回,它不会从一级缓存里找,而是直接查数据库
 
测试三(解决n+1问题):
 List students = session.createQuery("from Student").list();//发一条取出所有数据并放到缓存里
 Query query = session.createQuery("from Student");//这里发一条sql取出所有ID,只取ID列
 Iterator students = query.iterate();  //iterate()这里不发了。Iterator会直接在缓存里取。
 
 这样便能解决n+1问题。因为第一句代码运行后会把数据放到缓存里,这样当query.iterator时会先在缓存里找数据

测试四(两个.list):
 Query q= session.createQuery("from Student");//发一条取出所有数据并放到缓存里 
 list students = q.list();//会发一条
 //这里是iterator代码
 students = q.list();//也会发一条。
 //这里是iterator代码
 
 hibernate默认配置了对象缓存(一级缓存)
 说明了在默认情况下list()每次都会向数据库发出查询语句取得所有结果,但如果配了二级缓存这里就不会再发sql了。
 
===============================================
单个属性查询:
   List students = session.createQuery("select name from Student").list();
   for (Iterator iter = students.iterator();iter.hasNext();) {
    String name = (String)iter.next();
    System.out.println(name);
   }

多个属性查询:
   //查询多个属性,其集合元素是对象数组
   //数组元素的类型,跟实体类的属性的类型相关
   //更常见的用法,给对象起个别名,然后通过别名来引用属性值
   //List students = session.createQuery("select s.id, s.name from Student s").list();
   List students = session.createQuery("select id, name from Student").list();
   for (Iterator iter = students.iterator();iter.hasNext();) {
    Object[] obj = (Object[])iter.next();
    System.out.println(obj[0] + ", " + obj[1]);
   }

简单属性查询
  * 单个属性查询,返回的结果集属性的列表,其元素和属性的类型一致
  * 多个属性查询,返回的结果集是数组类型,数组的长度和查询的属性数量相关,数组中元素的类型与相应的属性类型相同
  参见:SimplePropertyQueryTest.java
 
====================================================

   //条件查询,拼字符串
   List students = session.createQuery("SELECT s.id, s.name FROM Student s WHERE s.name LIKE '%1%'")
   .list();
   for (Iterator iter = students.iterator();iter.hasNext();) {
    Object[] obj = (Object[])iter.next();
    System.out.println(obj[0] + ", " + obj[1]);
   }

   ----------------------------------------------
   //条件查询,使用 ? 的方式传递参数
   Query query = session.createQuery("SELECT s.id, s.name FROM Student s WHERE s.name LIKE ?");
   
   //传递参数
   //参数的索引是从0开始的
   //传递的字符串,无需用''单引号括起来
   query.setParameter(0, "%1%");
   
   List students = query.list();
   
   for (Iterator iter = students.iterator();iter.hasNext();) {
    Object[] obj = (Object[])iter.next();
    System.out.println(obj[0] + ", " + obj[1]);
   }

   --------------------------------------
   //条件查询,使用 :参数名称 的方式传递参数
   Query query = session.createQuery("SELECT s.id, s.name FROM Student s WHERE s.name LIKE :myname");
   
   //传递参数
   query.setParameter("myname", "%1%");
   
   List students = query.list();

   -----------------------------------------
   //条件查询,因为setParameter方法返回Query接口,所以可以用省略的方式来查询
   List students = session.createQuery("SELECT s.id, s.name FROM Student s WHERE s.name LIKE :myname and    s.id = :myid")
   .setParameter("myname", "%1%")
   .setParameter("myid", 15)
   .list();
   --------------------------------------------
   //条件查询,支持in,需要用setParameterList()进行参数传递
   List students = session.createQuery("SELECT s.id, s.name FROM Student s WHERE s.id in(:myids)")
   .setParameterList("myids", new Object[]{1, 3, 5})
   .list();

   -------------------------------------------------
//   List students = session.createQuery("SELECT s.id, s.name FROM Student s WHERE " +
//     "date_format(s.createTime, '%Y-%m') =?")
//   .setParameter(0, "2007-01")
//   .list();
   ------------------------------------------------
   SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
   List students = session.createQuery("SELECT s.id, s.name FROM Student s WHERE " +
   "s.createTime between ? and ? ")
          .setParameter(0, format.parseObject("2007-01-01"))
          .setParameter(1, format.parseObject("2007-03-01"))
         .list();
   -----------------------------------------------
   //嵌入原生sql测试
   SQLQuery sqlQuery = session.createSQLQuery("select * from t_student");
   List students = sqlQuery.list();
   for (Iterator iter = students.iterator();iter.hasNext();) {
    Object[] obj = (Object[])iter.next();
    System.out.println(obj[0] + ", " + obj[1]);
   }
   -------------------------------------------------
   //* 外置的命名查询测试
   List students =  session.getNamedQuery("searchStudents")
                           .setParameter(0, 10)
                           .list();
   for (Iterator iter = students.iterator();iter.hasNext();) {
    Student student = (Student)iter.next();
    System.out.println(student.getName());
   }
类中配置:

 
  
   
  

  
  
  
  
 
   select s from Student s where s.id < ?
 ]]>
 
 
  
 


  外置的命名查询
  * 在映射文件中通过标签定义hql
  * 在程序中使用session.getNameQuery()方法获得这个查询
  参见:Student.hbm.xml,NameQueryTest.java
-----------------------------------------------------------------------------------------
6、查询过滤器
  * 定义过滤器参数
  * 在类映射文件中使用这些参数
  * 在session中启用过滤器
  参见:Student.hbm.xml,FilterQueryTest.java

   //通过下面的代码自动为本类的所有sql增加上where id   session.enableFilter("idfilter")
          .setParameter("myid", 10);
   
   List students = session.createQuery("from Student")
   .list();
   
   for (Iterator iter = students.iterator();iter.hasNext();) {
    
    Student student = (Student)iter.next();
    System.out.println(student.getName());
   }
类中配置:

 
  
   
  

  
  
  
  //这里就是条件id 
 
  
 

-------------------------------------------------
 
7、对象导航查询,在HQL语句中,可以使用.的方式进行对象导航【重要】
   参见:ObjectNavQueryTest.java
   //下面中的s.classes.id就是进行了对象的导航,由student对象导航到classes的对象
   List students = session.createQuery("select s.name from Student s where s.classes.id < 2").list();
   for (Iterator iter = students.iterator();iter.hasNext();) {
    String name = (String)iter.next(); 
    System.out.println(name);
   }
----------------------------------------------------
 

8、连接查询(在对象里可以直接导航)【重要】
  * 内连接
  * 外连接(左连接/右连接)  
   参见:JionQueryTest
 
 /**
  * 内连接,从Student连接到Classes
  *
  */
   List students = session.createQuery("select c.name, s.name from Student s join s.classes c ")
   .list();
   for (Iterator iter = students.iterator();iter.hasNext();) {
    Object[] obj = (Object[])iter.next();
    System.out.println(obj[0] + ", " + obj[1]);
   }
  //左外连接
   List students = session.createQuery("select c.name, s.name from Classes c left join c.students s ")
   .list();
  //右外连接
   List students = session.createQuery("select c.name, s.name from Classes c right join c.students s ")
   .list();
 
 /**
  * 内连接,从Classes连接到Student,代码省略,请自己写。
  *
  */

--------------------------------------------
   9、统计查询
     参见:StatQueryTest.java
   List students = session.createQuery("select count(*) from Student").list();
   Long count = (Long)students.get(0);
   System.out.println(count);
   int total = ((Integer)session.createQuery("select count(*) from student").uniqueResult).intValue();

   List students = session.createQuery("select c.id, c.name, count(s) from Student s join " +
     "s.classes c group by c.id, c.name").list();
   for (Iterator iter = students.iterator();iter.hasNext();) {
    Object[] obj = (Object[])iter.next();
    System.out.println(obj[0] + ",  " + obj[1] + ", " + obj[2]);
   }

----------------------------------------------------------
   
   10、分页查询【重要】
     * 通过query接口中的setFirstResult()和setMaxResults() 进行分页
     参见:PageQueryTest
   Query query = session.createQuery("from Student");
   query.setFirstResult(27);
   query.setMaxResults(5);
   List students = query.list();
------------------------------------------------------------
   11、DML风格的操作(尽量少用,因为它直接对数据库操作,而不是对缓存)
   /**
    * 使用这种风格的操作,将会造成内存中的对象与数据库中的数据不同步,所以
    * 建议尽量少使用
    */
   Query updateQuery =  session.createQuery("update Student a set a.name=? where a.id in(:ids)");
   updateQuery.setParameter(0, "张三");
   updateQuery.setParameterList("ids", new Object[]{1, 2});
   updateQuery.executeUpdate();
   session.getTransaction().commit();

 
阅读(828) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~