【问题标题】:Hibernate setParamater a classHibernate setParamater 一个类
【发布时间】:2011-03-20 17:09:01
【问题描述】:

我是 Hibernate 的新手。

我想创建一个公共Object getById(Class class,long id) 函数。我尝试创建如下查询:from :nameEntity where id= :id,但在为nameEntity 设置参数时遇到问题。 Hibernate 不将其识别为参数。

我使用了session.createQuery 函数。你能帮帮我吗?

【问题讨论】:

    标签: java hibernate orm


    【解决方案1】:

    您要么必须进行字符串连接才能实现此目的:

    session.createQuery("from " + clazz.getName() " where id=:id").
            setParameter("id", id).
            uniqueResult();
    

    或使用Criteria API:

    session.createCriteria(clazz).
            add(Expression.eq("id", id).
            uniqueResult()
    

    【讨论】:

      【解决方案2】:

      我想创建一个公共Object getById(Class class, long id) 函数。我尝试创建查询,例如:“from :nameEntity where id=:id”,但是在为“nameEntity”设置参数时遇到了问题。 Hibernate 不将其识别为参数。

      不要构建查询,请使用Session 中的load()get() 方法。它们实际上是重载的,允许将类作为ClassString 传递,持久对象标识符,如果需要,还可以使用锁定选项(用于悲观锁定):

      get(Class clazz, Serializable id)
      
      load(Class theClass, Serializable id)
      
      get(Class clazz, Serializable id, LockOptions lockOptions)
      
      load(Class theClass, Serializable id, LockOptions lockOptions)
      
      get(String entityName, Serializable id)
      
      load(String entityName, Serializable id)
      
      get(String entityName, Serializable id, LockOptions lockOptions) 
      
      load(String entityName, Serializable id, LockOptions lockOptions)
      

      get()load() 有什么区别?参考文档中对此进行了解释:

      10.3. Loading an object

      Sessionload() 方法 提供一种检索方式 持久实例,如果你知道它 标识符。 load() 上课 对象并将状态加载到 新实例化的那个 类处于持久状态。

      Cat fritz = (Cat) sess.load(Cat.class, generatedId);
      
      // you need to wrap primitive identifiers
      long id = 1234;
      DomesticCat pk = (DomesticCat) sess.load( DomesticCat.class, new Long(id) );
      

      或者,您可以将状态加载到 给定实例:

      Cat cat = new DomesticCat();
      // load pk's state into cat
      sess.load( cat, new Long(pkId) );
      Set kittens = cat.getKittens();
      

      注意load() 会抛出一个 如果不存在不可恢复的异常 匹配的数据库行。如果班级是 使用代理映射,load() 只是 返回一个未初始化的代理和 实际上并没有命中数据库 直到您调用 代理。如果您愿意,这很有用 创建与对象的关联 没有实际从 数据库。它还允许多个 要作为批处理加载的实例,如果 为类定义批处理大小 映射。

      如果您不确定是否匹配 行存在,您应该使用get() 命中数据库的方法 立即返回null if 没有匹配的行。

      Cat cat = (Cat) sess.get(Cat.class, id);
      if (cat==null) {
          cat = new Cat();
          sess.save(cat, id);
      }
      return cat;
      

      您甚至可以使用 SQL SELECT ... FOR UPDATE,使用 锁定模式。请参阅 API 文档 了解更多信息。

      Cat cat = (Cat) sess.get(Cat.class, id, LockMode.UPGRADE);
      

      任何关联的实例或包含 不会选择收藏品 FOR 更新,除非您决定指定 锁定或全部作为级联样式 协会。

      可以重新加载对象 以及它的所有收藏品, 使用refresh() 方法。这是 使用数据库触发器时很有用 初始化一些属性 对象。

      sess.save(cat);
      sess.flush(); //force the SQL INSERT
      sess.refresh(cat); //re-read the state (after the trigger executes)
      

      Hibernate 从 数据库以及将有多少 SQL SELECT 它用吗?这取决于获取 战略。这在Section 20.1, “Fetching strategies” 中有解释。

      如何选择?

      get()load() 很简单:如果你确定 持久对象存在,并且 不存在将被视为 例外,load() 是一个不错的选择。 如果您不确定是否存在 具有给定的持久实例 标识符,使用get() 并测试 返回值看是不是null

      另见

      相关问题

      【讨论】:

      • @user198147:不客气。如果您认为此答案有帮助,请随时接受(左侧投票计数器下方的绿色勾号)。
      猜你喜欢
      • 1970-01-01
      • 2015-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多