• createSQLQuery与createQuery的区别


    本文原址 : http://stta04.javaeye.com/blog/377633hibernate 中createQuery与createSQLQuery

    昨晚帮同事看代码到凌晨2点多,今早6点醒来发现他发来信息说报空指针错误,实在无法入睡,起来自己测试了一下,控制台还真的报:

    2009-4-25 8:12:34 org.apache.catalina.core.ApplicationContext log
    信息: java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to com.miracle.dm.doc.catalog.model.DocCatalogInfo

    原来的查询语句:

    String sql = "select a.* from tb_doc_catalog a where a.cat_code like '"+catCode+"%'";
    Session session = this.getSession();
    try {
    List catNameList = session.createSQLQuery(sql).list();
    return catNameList ;
    } finally {
    releaseSession(session); //释放session
    }

    分析:原来是查询出来的字段并不能自动转换为bean对象。

    解决思路一(采用hql查询):

    String sql = "select a from DocCatalogInfo a where a.catCode like '"+catCode+"%'";
    List catNameList =getHibernateTemplate().find(sql);
    return catNameList ;
    ok,测试一下发现没问题,看来还是因为用原生sql查询的原因,网上搜一下:createsqlQuery返回对象,看到一篇文章才觉悟到:

    解决思路二(采用原生sql查询):

    String sql = "select a.* from tb_doc_catalog a where a.cat_code like '"+catCode+"%'";
    Session session = this.getSession();
    try {
    List catNameList = session.createSQLQuery(sql).addEntity(DocCatalogInfo.class).list();
    return catNameList ;
    } finally {
    releaseSession(session); //释放session
    }

    又ok了。

    该篇文章也贴上来:

    hibernate 中createQuery与createSQLQuery两者区别是:
    前者用的hql语句进行查询,后者可以用sql语句查询
    前者以hibernate生成的Bean为对象装入list返回
    后者则是以对象数组进行存储
    所以使用createSQLQuery有时候也想以hibernate生成的Bean为对象装入list返回,就不是很方便
    突然发现createSQLQuery有这样一个方法可以直接转换对象
    Query query = session.createSQLQuery(sql).addEntity(XXXXXXX.class);
    XXXXXXX 代表以hibernate生成的Bean的对象,也就是数据表映射出的Bean。
    呵呵以后多注意,还是时不时的要看看hibernate各个对象方法的使用。

    还有另外一个相关的小细节应注意:
    比如有这样一个po
    PO: User.class
    properties: userId,userName
    DDL: create table tuser (userid varchar(10),username varchar(20));
    当执行:
    session.createQuery("from User u").list()时生成的SQL:
      select userid,username from tuser;
    当执行:

    session.createQuery("from User u").iterator()时生成的SQL:
      
    select userid from tuser;
      
    可以看出list()一次将数据从数据库中读出直接填充到List中
      
    iterator()将数据的主键从数据库中读出,当循环这个Iterator时才添加执行:
      
    select userid,username from user where userid=?;把数据读出。
    在不同的应用范围使用不同的方法,具体在hibernate应用中应当注意。

    第二种解释

    今天想着做一个分页的DAO,用Hibernate从数据库的Question表中取5个数据,这个分页是每次都从数据库中取出一段数据,而不是一次性取所有的数据。

    一开始,我的DAO是这么写的:

    public List findallquestion(int num,int pagesize){
       int num2=(num-1)*5;
       Session session=getSession();
       String sql="select * from Question limit :num1,:size";
       Query query = session.createSQLQuery(sql);
       query.setParameter("num1",num2);
       query.setParameter("size", pagesize);
       List list=query.list();
       Question question=null;
        for(int i=0;i<list.size();i++)
       {
        question = (Question)list.get(i);
        System.out.print("ID"+question.getId());
        System.out.println("TITLE"+question.getTitle());
       }
       return list;
    }

    奇怪的事情就这么发生了,

    第一,出现了报错:

    java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to com.njcit.bbs.Question

    第二,question对象里面取不出值

    这我就奇怪了,我用list.size()发现长度的确是5,和我需要的长度是一致的,为什么会报错,而且取不出呢?

    问题应该是question = (Question)list.get(i);list里面不是存放的一条条记录么,为什么不能转成我需要的Bean呢

    网上找了很多资料,最后在这里找到了想要的东西:http://helloandy2009.javaeye.com/blog/614369

    我们一般在用Hibernate写增删查改的时候,有2中方式,一种是HQL,一种是SQL

    实例:

    我要执行的语句是:select * from Question

    HQL是这么写的:

    Session session = getSession();

    String hql="from Question";

    List list = (Question)session.createQuery(hql).list();

    System.out.println(list.getTitle());

    测试正常

    SQL写法:

    Session session=getSession();

    String sql="select * from Question"

    List list=(Question)session.createSQLQuery(sql).list();//会发生类型转换错误,就是文章开头的那个错误

    原因:
    HQL中

    String hql="from Question";

    List list = (Question)session.createQuery(hql).list();

    会根据你的hql语句,自动将session.createQuery(hql).list()的返回对象以hibernate生成的Bean为对象装入list返回

    SQL中

    String sql="select * from Question"

    List list=(Question)session.createSQLQuery(sql).list();

    则是以对象数组进行存储返回

    一句话:HQL:返回list装的是Bean SQL:返回对象就是一数组,数组在转为Question对象时,当然会报错。

    解决方法:

    第一种:直接老老实实用HQL去写吧= =参数化就百度“Hibernate 参数绑定”就行

    第二种:使用原生SQL,调用其中的一个方法addEntity()

    String sql="select * from Question";

    Query query = session.createSQLQuery(sql).addEntity(XXXXXXX.class);

    List list = (Question)query;

    这样 list中也就装的是Question这洋一个个Bean对象了,问题还是不知道如何参数化= =!

    找到方法了:

    Hibernate中的分页语句可以这么写

         session = HibernateUtils.getSession();
         session.beginTransaction();
         Query query = session.createQuery("from User");
         query.setFirstResult(0);//从第一条记录开始
         query.setMaxResults(4);//取出四条记录
         List userList = query.list();

  • 相关阅读:
    Java Learning (201108025)
    Java Learning (20110808)
    Negative numbers and binary representation
    “this” pointer
    NullPointerException
    Special Swiss Education
    Java Learning (20110802)
    More about Swiss keyboard
    About memory leak
    Application Verifier
  • 原文地址:https://www.cnblogs.com/toSeeMyDream/p/5539299.html
Copyright © 2020-2023  润新知