使用Hibernate SQLQuery执行原生SQLWord下载.docx
- 文档编号:20376702
- 上传时间:2023-01-22
- 格式:DOCX
- 页数:7
- 大小:18.09KB
使用Hibernate SQLQuery执行原生SQLWord下载.docx
《使用Hibernate SQLQuery执行原生SQLWord下载.docx》由会员分享,可在线阅读,更多相关《使用Hibernate SQLQuery执行原生SQLWord下载.docx(7页珍藏版)》请在冰豆网上搜索。
SQLQuery提供了众多的接口来分别设置不同类型的参数,诸如setBigDecimal、setBinary、setDouble等,详参SQLQuery的JavaDoc,此处不再赘述。
这里仅重点说一下通用的SQL参数设置接口setParameter。
如下代码示范了如何使用SQLQuery执行预处理SQL:
SQLQueryquery=session.createSQLQuery("
select*fromnotewhereid=?
"
);
//设置第一个参数的值为12,即查询ID=12的note
query.setParameter(0,12);
Listlist=query.list();
...
这里需要注明一点,
无论是通过不同类型参数的设置接口来设置SQL参数,还是通过setParameter来设置参数,下标都是从0开始的,而不是从1开始的
!
使用自定义的结果转换器处理查询结果
SQLQuery接口预留了setResultTransformer接口以实现使用用户自定义的ResultTransformer结果集转换器处理查询结果。
ResultTransformer接口非常简单,只有两个方法,分别用来转换单行数据和所有结果数据。
经过自定义ResultTransformer生成的实体,并未加入Session,因此是非受管实体。
如下代码,示范了如何将单行数据装入LinkedHashMap对象中:
query.setResultTransformer(newResultTransformer(){
@Override
publicObjecttransformTuple(Object[]values,String[]columns){
Map&
lt;
String,Object&
gt;
map=newLinkedHashMap&
(1);
inti=0;
for(Stringcolumn:
columns){
map.put(column,values[i++]);
}
returnmap;
publicListtransformList(Listlist){
returnlist;
});
如果不设置自定义的ResultTransformer转换器,则Hibernate将每行返回结果的数据按照结果列的顺序装入Object数组中。
当然,也可以直接指定默认的MAP转换规则:
query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
这里介绍一个工具类:
Transformers
,它提供了一些常用的转换器,能够帮助我们快速转换结果集,如
Transformers.aliasToBean(Note.class)
能够将查询结果依别名注入到Note实体中。
使用标量
使用SQLQuery执行原生SQL时,Hibernate会使用ResultSetMetadata来判定返回的标量值的实际顺序和类型。
如果要避免过多的使用ResultSetMetadata,或者只是为了更加明确的指名返回值,可以使用addScalar()。
)
.addScalar("
id"
LongType.INSTANCE)
name"
StringType.INSTANCE)
createtime"
DateType.INSTANCE);
这个查询指定了SQL查询字符串,要返回的字段和类型.它仍然会返回Object数组,但是此时不再使用ResultSetMetdata,而是明确的将id,name和createtime按照Long,String和Date类型从resultset中取出。
同时,也指明了就算query是使用*来查询的,可能获得超过列出的这三个字段,也仅仅会返回这三个字段。
对全部或者部分的标量值不设置类型信息也是可以的:
没有被指定类型的字段将仍然使用ResultSetMetdata获取其类型。
注意
,字段不区分大小写,同时不能够指定不存在的字段
关于从ResultSetMetaData返回的java.sql.Types是如何映射到Hibernate类型,是由方言(Dialect)控制的。
假若某个指定的类型没有被映射,或者不是你所预期的类型,你可以通过Dialet的registerHibernateType调用自行定义。
如果仅指定了一个scalar,那么...
DatecreateTime=(Date)session.createSQLQuery("
DateType.INSTANCE)
.uniqueResult();
如果我们的SQL语句使用了聚合函数,如count、max、min、avg等,且返回结果仅一个字段,那么Hibernate提供的这种提取标量结果的方式就非常便捷了。
实体查询
上面的查询都是返回标量值的,也就是从resultset中返回的“裸”数据。
下面展示如何通过addEntity()让原生查询返回实体对象。
).addEntity(Note.class);
selectid,name,createtimefromnotewhereid=1"
这个查询指定SQL查询字符串,要返回的实体。
假设Note被映射为拥有id,name和createtime三个字段的类,以上的两个查询都返回一个List,每个元素都是一个Note实体。
假若实体在映射时有一个many-to-one的关联指向另外一个实体,在查询时必须也返回那个实体,否则会导致发生一个"
columnnotfound"
的数据库错误。
这些附加的字段可以使用*标注来自动返回,但我们希望还是明确指明,看下面这个具有指向Dog的many-to-one的例子:
selectid,note,createtime,authorfromnotewhereid=?
author字段即为Note实体和Author实体的关联字段,只需在查询时得到该字段的值,Hibernate即可使用该值找到对应的关联实体。
如上例中,note.getAuthor()即可返回当前Note所属的Author对象。
处理关联和集合类
通过提前抓取将Author连接获得,而避免初始化proxy带来的额外开销也是可能的。
这是通过addJoin()方法进行的,这个方法可以让你将关联或集合连接进来。
select{note.*},{author.*}fromnotenote,userauthorwherenote.author=author.id"
.addEntity("
note"
Note.class)
.addJoin("
author"
"
note.author"
上面的例子是多对一的关联查询,反过来做一对多的关联查询也是可以的。
如下的例子中,author.notes表示该用户发表的所有日记(Note),Set集合类型:
select{author.*},{note.*}fromnotenote,userauthorwhereauthor.id=?
andnote.author=author.id"
User.class)
author.notes"
:
join查询会在每行返回多个实体对象,处理时需要注意
。
别名和属性引用
假若SQL查询连接了多个表,同一个字段名可能在多个表中出现多次,这会导致SQL错误。
不过在我们可以通过使用占位符来完美地解决这一问题。
其实在上例中已经用到了占位符:
这个查询指明SQL查询语句,其中包含占位附来让Hibernate注入字段别名,查询并返回的实体。
上面使用的{note.*}和{author.*}标记是作为“所有属性”的简写形式出现的,当然你也可以明确地罗列出字段名。
但如下的范例代码中我们让Hibernate来为每个属性注入SQL字段别名,字段别名的占位符是表别名+.+属性名。
:
属性名区分大小写,而且不能够在where子句中使用占位符
selectnote.idas{note.id},noteas{note.note},createtimeas{note.createTime},authoras{note.author},{author.*}fromnote,userauthorwherenote.id=?
query.addEntity("
Note.class);
query.addJoin("
大多数情况下,上面的别名注入方式可以满足需要,但在使用更加复杂的映射,比如复合属性、通过标识符构造继承树,以及集合类等等情况下,则需要更加复杂的别名注入方式。
下表列出了使用别名注射参数的不同方式:
别名注入(aliasinjectionnames)描述
语法
示例
简单属性
{[aliasname].[propertyname]
A_NAMEas{item.name}
复合属性
{[aliasname].[componentname].[propertyname]}
CURRENCYas{item.amount.currency},VALUEas{item.amount.value}
实体辨别器
{[aliasname].class}
DISCas{item.class}
实体的所有属性
{[aliasname].*}
{item.*}
集合键(collectionkey)
{[aliasname].key}
ORGIDas{coll.key}
集合id
{[aliasname].id}
EMPIDas{coll.id}
集合元素
{[aliasname].element}
XIDas{coll.element}
集合元素的属性
{[aliasname].element.[propertyname]}
NAMEas{coll.element.name}
集合元素的所有属性
{[aliasname].element.*}
{coll.element.*}
集合的所有属性
{coll.*}
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 使用Hibernate SQLQuery执行原生SQL 使用 Hibernate SQLQuery 执行 原生 SQL