【发布时间】:2011-03-20 17:09:01
【问题描述】:
我是 Hibernate 的新手。
我想创建一个公共Object getById(Class class,long id) 函数。我尝试创建如下查询:from :nameEntity where id= :id,但在为nameEntity 设置参数时遇到问题。 Hibernate 不将其识别为参数。
我使用了session.createQuery 函数。你能帮帮我吗?
【问题讨论】:
我是 Hibernate 的新手。
我想创建一个公共Object getById(Class class,long id) 函数。我尝试创建如下查询:from :nameEntity where id= :id,但在为nameEntity 设置参数时遇到问题。 Hibernate 不将其识别为参数。
我使用了session.createQuery 函数。你能帮帮我吗?
【问题讨论】:
您要么必须进行字符串连接才能实现此目的:
session.createQuery("from " + clazz.getName() " where id=:id").
setParameter("id", id).
uniqueResult();
或使用Criteria API:
session.createCriteria(clazz).
add(Expression.eq("id", id).
uniqueResult()
【讨论】:
我想创建一个公共
Object getById(Class class, long id)函数。我尝试创建查询,例如:“from :nameEntity where id=:id”,但是在为“nameEntity”设置参数时遇到了问题。 Hibernate 不将其识别为参数。
不要构建查询,请使用Session 中的load() 或get() 方法。它们实际上是重载的,允许将类作为Class 或String 传递,持久对象标识符,如果需要,还可以使用锁定选项(用于悲观锁定):
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
Session的load()方法 提供一种检索方式 持久实例,如果你知道它 标识符。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()命中数据库的方法 立即返回nullif 没有匹配的行。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。
【讨论】: