问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

hibernate:createSQLQuery方法中 加不加addEntity(Jxjhdmx.class)什么区别?

发布网友 发布时间:2022-04-07 18:05

我来回答

3个回答

懂视网 时间:2022-04-07 22:26

使用SQLQuery
对原生SQL查询执行的控制是通过SQLQuery接口进行的,通过执行Session.createSQLQuery()获取这个接口。最简单的情况下,我们可以采用以下形式:

List cats = sess.createSQLQuery( " select * from cats " ).addEntity(Cat. class ).list();

这个查询指定了:

SQL查询字符串

查询返回的实体

这里,结果集字段名被假设为与映射文件中指明的字段名相同。对于连接了多个表的查询,这就可能造成问题,因为可能在多个表中出现同样名字的字段。下面的方法就可以避免字段名重复的问题:

List cats = sess.createSQLQuery( " select {cat.*} from cats cat " ).addEntity( " cat " , Cat. class ).list();

这个查询指定了:

SQL查询语句,它带一个占位符,可以让Hibernate使用字段的别名.

查询返回的实体,和它的SQL表的别名.

addEntity()方法将SQL表的别名和实体类联系起来,并且确定查询结果集的形态。

addJoin()方法可以被用于载入其他的实体和集合的关联.

List cats = sess.createSQLQuery(
" select {cat.*}, {kitten.*} from cats cat, cats kitten where kitten.mother = cat.id " )
.addEntity( " cat " , Cat. class )
.addJoin( " kitten " , " cat.kittens " )
.list();

原生的SQL查询可能返回一个简单的标量值或者一个标量和实体的结合体。

Double max = (Double) sess.createSQLQuery( " select max(cat.weight) as maxWeight from cats cat " )
.addScalar( " maxWeight " , Hibernate.DOUBLE);
.uniqueResult();

除此之外,你还可以在你的hbm文件中描述结果集映射信息,在查询中使用。

List cats = sess.createSQLQuery(
" select {cat.*}, {kitten.*} from cats cat, cats kitten where kitten.mother = cat.id " )
.setResultSetMapping( " catAndKitten " )
.list();

命名SQL查询
可以在映射文档中定义查询的名字,然后就可以象调用一个命名的HQL查询一样直接调用命名SQL查询.在这种情况下,我们不 需要调用addEntity()方法.

< sql - query name = " persons " >
< return alias = " person " class = " eg.Person " />
Select person.NAME AS {person.name},person.AGE AS {person.age},person.SEX AS {person.sex} FROM PERSON person Where person.NAME LIKE :namePattern
</ sql - query >List people = sess.getNamedQuery( " persons " ).setString( " namePattern " , namePattern)
.setMaxResults( 50 )
.list();

 

2.

使用hibernate3的createSQLQuery遇到的问题

为了给访问加速,把DAO中的一些HQL的操作改成了SQL,其实最主要的原因是:操作的是多张表,返回的数据也来源于多个表的字段;
String sql = “select A.id ID, A.name NAME, B.salary SALARY from employee A , Salary B where.......”;
Query query =getSession().createSQLQuery(sql)
.setResultTransformer(Transformers.aliasToBean(ReturnEmployee.class));
由于返回的ID, NAME, SALARY 非一个和表对应的一个BEAN,所以自己需要建立一个ReturnEmployee的BEAN,属性包括ID, NAME, SALARY;在mysql下调试,成功。
但是在ORACLE环境下却报错:

org.hibernate.PropertyNotFoundException: Could not find setter for ID on class com.ReturnEmployee

经过几个小时的查错,调试,没有发现问题的所在,只能摆脱GOOGLE了,最后在国外的一个论坛上找到了答案:

this is actually a limitation of some databases which return alias all uppercase instead of using the casing you actually specified.

until then use .addScalar(..) to workaround it.

原来是Hibernate对ORALCE的支持有BUG,所以修改代码为:
Query query = getSession().createSQLQuery(sql).addScalar("ID")
.addScalar("NAME").addScalar("SALARY");
就可以了,需要注意的是
List employeeData = query.list();
返回的employeeData 中的数据是object[],这样取值:
List employeeBean = new ArrayList();
for (int i = 0; i < employeeData.size(); i++) {
Employee employee = new Employee();//把"裸"数据组装到自己的employee类

Object[] object = (Object[]) employeeData.get(i);
employee.setId(object[0].toString());
employee.setName(object[1].toString());
employee.setOrgType(object[2].toString());

employeeBean.add(employee);
}

另还可以返回一个Map对象,也就是说在在list里包含多个Map,代码如下
Query query = session.createSQLQuery("select id,name from Tree t where pid in (select id from Tree) ").setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP); //返回一个map,KEY:为DB中名称一致(大小写一致)遍历list时就可以

Map map = (Map)list.get[i];

map.get("id");map.get("name");来取值。按你的SQL语句select后的字段名来作为map的Key,但这个key必须与数据库中的字段名一模一样。


还可以用作函数方面的。如
Query query = session.createSQLQuery("select sum(id) SUMID from Tree t where pid in (select id from Tree)
.addScalar("SUMID",Hibernate.INTEGER) //转换类型,按DB中的type转
.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP); //返回一个map,KEY:为DB中名称一致(大小写一致)

直接就map.get("SUMID")可以取值了

还有一点就是这个方法在Hibernate3.2版本上才能正常运行。

 

查到现在,有了一些眉目,小结如下:

1,oracle的char字段在hibernate里映射为character类型,是varchar的子集。

2,复杂SQL用createSQLQuery方法查询没问题,如果查询多个字段,遍历用object[]造型,下标从0开始输出值,不需要映射文件;如果愿意可以写一个映射bean,方便取用。

3,如果查询SQL中是只有一个字段,那就不能用object[]数组接收,只能用object类接收,直接输出object.toString(),即是这个字段的值。

4,可以用addScalar(String arg,Type type)方法定义要返回的字段类型,如

s.createSQLQuery(shuiQingHQL).addScalar("STCD",Hibernate.STRING).addScalar("STNM");

这样就解决了CHAR字段类型只出一位字符的问题。

但是需要把其他字段也addScalar()进来!

5,addScalar(String arg)里的参数是需要大写的!

hibernate里createSQLQuery的addEntity()和setResultTran

标签:

热心网友 时间:2022-04-07 19:34

一个是自动帮你判断,
另外一个是直接找到,
当然自己判断的会稍微慢些追问你是说只有性能上的区别么?跟sql语句中jxjhdmx 的大小写有没有关系?这种在hibernate中执行sql算不算映射?

热心网友 时间:2022-04-07 20:52

。。不是hql语句吗 jxjhdmx 用类名追问createSQLQuery方法

追答额 Jxjhdmx.class Jxjhdmx 代表以hibernate生成的Bean的对象,也就是数据表映射出的Bean。

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
手机导航地图语音怎么下载 如何分别真金和仿金首饰 怎样区分真金和仿金首饰呢 小学生新年晚会主持人的串词!!(不要太多)急 大大后天就需要了!!!_百度... 周年晚会策划公司 奥格瑞玛传送门大厅在哪 奥格瑞玛传送门大厅怎么走 锻炼颈椎的几个动作 水多久能结冰 冰能在多长时间内形成 请问水低于0度会结冰吗? 如何防止脱发严重 我今年50岁了交自由职业养老保险一年,继续交划算吗? 50岁男性可以交养老保险合算吗 我妈今年50岁了,现在买养老保险合适吗,如果买要多少钱呢 50买养老保险合算吗? 50岁的人应该怎么买养老保险比较合算? 有小伙伴用过理房通装修贷款的吗?好用吗? 到了50岁了才交社保,还划算吗? 打算通过理房通申请装修贷款15万,还款方式和分期有限制吗? 50岁开始交社保还划算吗? 做了贝壳装修贷还能把房子抵押给银行吗? 50岁开始交社保合算吗 现在装修贷款的利率是多少,贷十万,五年还款 50岁社保合适吗 50岁开始交社保合算吗? 两位老人50岁左右补交养老保险得20万,划算吗 移动9元大王卡怎么样 boss直聘这软件怎么样? 现在的QQ怎么才能把人移除黑名单。 华为手机联系人不见了怎么恢复?难受 boss直聘好么? 为什么白头发总比黑头发要长得快 头上有一些白头发了,我发现白头发好象比黑头发长得快?为什么会这样? 为什么白头发长得不黑头发快? 为什么白头发比黑头发长的快 头上有白头发,为什么白头发比黑头发粗,看着长得壮 白发是不是比黑发长得快呢?推平头发之后总是白发先露头,是不是有这么个现象? 为什么人的白头发比黑头发长的了快? 为什么我的白头发比黑头发长的还好? 白头发是黑色头发变白的还是直接长出来就是白色的? 白头发别长得太快有什么办法? 头发长的很快,可是白发,为什么 我为何有那么多的白发 章鱼输入法怎样恢复彩色 章鱼输入法能打蓝色荧光字体吗 oppo a72的手机忘记密码了怎么办? 电脑蓝牙打不开了怎么回事 电脑显示此设备上的蓝牙无法使用? 一个男的评价一个女的跟他聊天有内涵,内涵这个词怎么理解在这个情况下,还说给他上了一课。(不要说什么 梦见在清澈的湖上和爱人泛舟是何意? 为什么用了章鱼输入法就把整个手机的屏幕和人物变成黑色的了?