String sql = "select Band.band_id bandId from guest_band Band";
sessionFactory.getCurrentSession().createSQLQuery(sql)
.addScalar("bandId", Hibernate.LONG)
.list();
我知道addScalar()用于表示所选项的数据类型hibernate,在这种情况下为bandId。 但我的问题是,为什么我们需要指定要休眠的类型?它内部执行什么?其次,如果我们不添加标签(),这是一个例外吗?最后,有没有其他方法可以实现这一目标?
答案 0 :(得分:3)
这不是强制性的,但肯定有助于使用
来自https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/querysql.html
最基本的SQL查询是获取标量列表(值)。
sess.createSQLQuery("SELECT * FROM CATS").list();
sess.createSQLQuery("SELECT ID, NAME, BIRTHDATE FROM CATS").list();
这些将返回一个对象数组列表(Object []),其中包含CATS表中每列的标量值。 Hibernate将使用ResultSetMetadata来推断返回的标量值的实际顺序和类型。
为了避免使用ResultSetMetadata的开销,或者只是在返回的内容中更明确,可以使用addScalar():
sess.createSQLQuery("SELECT * FROM CATS")
.addScalar("ID", Hibernate.LONG)
.addScalar("NAME", Hibernate.STRING)
.addScalar("BIRTHDATE", Hibernate.DATE)
此查询指定:
SQL查询字符串 要返回的列和类型
这将返回Object数组,但现在它不会使用ResultSetMetadata,而是显式地将ID,NAME和BIRTHDATE列分别从底层结果集中获取Long,String和Short。
这也意味着只返回这三列 虽然查询使用*并且可以返回超过三个 列出的专栏。
可以省略所有或部分标量的类型信息。
sess.createSQLQuery("SELECT * FROM CATS")
.addScalar("ID", Hibernate.LONG)
.addScalar("NAME")
.addScalar("BIRTHDATE")
这与以前的查询基本相同,但现在ResultSetMetaData用于确定NAME和BIRTHDATE的类型,其中明确指定了ID类型。
如何将从ResultSetMetaData返回的java.sql.Types映射到Hibernate类型由Dialect控制。如果没有映射特定类型,或者没有产生预期类型,则可以通过调用Dialect中的registerHibernateType来自定义它。
答案 1 :(得分:1)
使用addScalar的简单示例:
public byte[] getFile(Integer id){
Query q = session
.createSQLQuery("select some_file from tbl_name where id=:id")
.addScalar("some_file", StandardBasicTypes.BINARY);
q.setInteger("id", id);
return (byte[]) q.uniqueResult();
}
例如,您的数据库中有blob数据类型,在这种情况下,您可以轻松地将结果转换为byte [],但如果您运行不带addScalar函数的查询,您将获得结果作为blob而不能直接将blob转换为byte [],需要编写转换代码:
try{
Blob blob =(Blob)q.uniqueResult();
int blobLength = (int) blob.length();
byte[] blobAsBytes = blob.getBytes(1, blobLength);
return blobAsBytes;
} catch (Exception e) {
return null;
}
在这个问题中,使用addScalar要容易得多。
答案 2 :(得分:0)
就我而言,没有必要。我从来没有用.addScalar
编写查询。
您可以简单地用以下内容替换它:
Query q = sessionFactory.getCurrentSession().createQuery(
"select b.band_id " +
"from guest_band as b "
);
List idList = q.list();
虽然这可能取决于您的实体的设置方式,但它应该有效。
或许.createSQLQuery
和.createQuery
以这种方式不同。
请参阅此帖子,了解.addScalar()
实际执行的操作:What does addScalar do?
编辑:我熟悉Java,我想我假设您使用Java作为帖子。如果使用C#,这可能会有所不同。