- 浏览: 1214869 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
lankk:
lankk 写道事实上,在运行String s1=new St ...
理解String 及 String.intern() 在实际中的应用 -
lankk:
事实上,在运行String s1=new String(&qu ...
理解String 及 String.intern() 在实际中的应用 -
lankk:
同意1楼的说法http://docs.oracle.com/j ...
理解String 及 String.intern() 在实际中的应用 -
raoyutao:
...
jdk 线程池 ThreadPoolExecutor -
hongdanning:
理解了。之前困惑的一些明白了。谢谢分享。
理解String 及 String.intern() 在实际中的应用
hibernate 里面用sql查询时 在没有return scalar的情况下返回值的顺序是按照sql中的select,
有return scalar的情况下返回值的顺序是按照scalar的排列顺序
列子:
<sql-query name="xxx.vvv">
<return-scalar column="click" type="long"/>
<return-scalar column="ipClick" type="long"/>
<return-scalar column="view" type="long"/>
<return-scalar column="ipView" type="long"/>
select xxx,sum(view) as view,sum(IP_view) as ipView,sum(click) as click,sum(ip_click) as ipClick
from vvv
</sql-query>
最后实际上返回值 Object[] 中的顺序是按照scalar的排列顺序来的
第 17 章 Native SQL查询
你也可以使用你的数据库的Native SQL语言来查询数据。这对你在要使用数据库的某些特性的时候(比如说在查询提示或者Oracle中的 CONNECT 关键字),这是非常有用的。这就能够扫清你把原来直接使用SQL/JDBC 的程序迁移到基于 Hibernate应用的道路上的障碍。
Hibernate3允许你使用手写的sql来完成所有的create,update,delete,和load操作(包括存储过程)
SQL查询是通过SQLQuery 接口来控制的,它是通过调用Session.createSQLQuery()方法来获得
List cats = sess.createSQLQuery("select {cat.*} from cats cat") .addEntity("cat", Cat.class); .setMaxResults(50); .list();
这个查询指定了:
-
SQL查询语句,它带一个占位符,可以让Hibernate使用字段的别名.
-
查询返回的实体,和它的SQL表的别名.
addEntity() 方法将SQL表的别名和实体类联系起来,并且确定查询结果集的形态。
addJoin() 方法可以被用于载入其他的实体和集合的关联,TODO:examples!
原生的SQL查询可能返回一个简单的标量值或者一个标量和实体的结合体。
Double max = (Double) sess.createSQLQuery("select max(cat.weight) as maxWeight from cats cat") .addScalar("maxWeight", Hibernate.DOUBLE); .uniqueResult();
上面使用的{cat.*} 标记是 "所有属性" 的简写.你可以显式地列出需要的字段,但是你必须让Hibernate 为每一个属性注入字段的别名.这些字段的站位符是以字段别名为前导,再加上属性名.在下面的例子里,我们从一个其他的表(cat_log ) 中获取Cat 对象,而非Cat对象原本在映射元数据中声明的表.注意我们甚至在where子句中也可以使用属性别名. 对于命名查询,{}语法并不是必需的.你可以在第 17.3 节 “命名SQL查询” 得到更多的细节.
String sql = "select cat.originalId as {cat.id}, " + "cat.mateid as {cat.mate}, cat.sex as {cat.sex}, " + "cat.weight*10 as {cat.weight}, cat.name as {cat.name} " + "from cat_log cat where {cat.mate} = :catId" List loggedCats = sess.createSQLQuery(sql) .addEntity("cat", Cat.class) .setLong("catId", catId) .list();
注意: 如果你明确地列出了每个属性,你必须包含这个类和它的子类的属性 ! and its subclasses !
可以在映射文档中定义查询的名字,然后就可以象调用一个命名的HQL查询一样直接调用命名SQL查询.在这种情况下,我们不 需要调用addEntity() 方法.
<sql-query name="mySqlQuery"> <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 'Hiber%' </sql-query>
List people = sess.getNamedQuery("mySqlQuery") .setMaxResults(50) .list();
一个命名查询可能会返回一个标量值.你必须使用<return-scalar> 元素来指定字段的别名和 Hibernate类型
<sql-query name="mySqlQuery"> <return-scalar column="name" type="string"/> <return-scalar column="age" type="long"/> SELECT p.NAME AS name, p.AGE AS age, FROM PERSON p WHERE p.NAME LIKE 'Hiber%' </sql-query>
<return-join> 和<load-collection> 元素分别用作 外连接和定义那些初始化集合的查询
使用<return-property> 你可以明确的告诉Hibernate使用哪些字段,这和使用{} -语法 来让Hibernate注入它自己的别名是相反的.
<sql-query name="mySqlQuery"> <return alias="person" class="eg.Person"> <return-property name="name" column="myName"/> <return-property name="age" column="myAge"/> <return-property name="sex" column="mySex"/> </return> SELECT person.NAME AS myName, person.AGE AS myAge, person.SEX AS mySex, FROM PERSON person WHERE person.NAME LIKE :name </sql-query><return-property> 也可用于多个字段,它解决了使用{} -语法不能细粒度控制多个字段的限制
<sql-query name="organizationCurrentEmployments"> <return alias="emp" class="Employment"> <return-property name="salary"> <return-column name="VALUE"/> <return-column name="CURRENCY"/> </return-property> <return-property name="endDate" column="myEndDate"/> </return> SELECT EMPLOYEE AS {emp.employee}, EMPLOYER AS {emp.employer}, STARTDATE AS {emp.startDate}, ENDDATE AS {emp.endDate}, REGIONCODE as {emp.regionCode}, EID AS {emp.id}, VALUE, CURRENCY FROM EMPLOYMENT WHERE EMPLOYER = :id AND ENDDATE IS NULL ORDER BY STARTDATE ASC </sql-query>
注意在这个例子中,我们使用了<return-property> 结合{} 的注入语法. 允许用户来选择如何引用字段以及属性.
如果你映射一个识别器(discriminator),你必须使用<return-discriminator>来指定识别器字段
Hibernate 3引入了对存储过程查询的支持. 存储过程必须返回一个结果集,作为Hibernate能够使用的第一个外部参数. 下面是一个Oracle9和更高版本的存储过程例子.
CREATE OR REPLACE FUNCTION selectAllEmployments RETURN SYS_REFCURSOR AS st_cursor SYS_REFCURSOR; BEGIN OPEN st_cursor FOR SELECT EMPLOYEE, EMPLOYER, STARTDATE, ENDDATE, REGIONCODE, EID, VALUE, CURRENCY FROM EMPLOYMENT; RETURN st_cursor; END;
在Hibernate里要要使用这个查询,你需要通过命名查询来映射它.
<sql-query name="selectAllEmployees_SP" callable="true"> <return alias="emp" class="Employment"> <return-property name="employee" column="EMPLOYEE"/> <return-property name="employer" column="EMPLOYER"/> <return-property name="startDate" column="STARTDATE"/> <return-property name="endDate" column="ENDDATE"/> <return-property name="regionCode" column="REGIONCODE"/> <return-property name="id" column="EID"/> <return-property name="salary"> <return-column name="VALUE"/> <return-column name="CURRENCY"/> </return-property> </return> { ? = call selectAllEmployments() } </sql-query>
注意存储过程当前仅仅返回标量和实体.现在不支持<return-join> 和<load-collection>
为了在Hibernate中使用存储过程,你必须遵循一些规则.不遵循这些规则的存储过程将不可用.如果你仍然想要使用他们, 你必须通过session.connection() 来执行他们.这些规则针对于不同的数据库.因为数据库 提供商有各种不同的存储过程语法和语义.
对存储过程进行的查询无法使用setFirstResult()/setMaxResults() 进行分页。
对于Oracle有如下规则:
-
存储过程必须返回一个结果集.它通过返回SYS_REFCURSOR实现(在Oracle9或10),在Oracle里你需要定义一个REF CURSOR 类型
-
推荐的格式是 { ? = call procName(<parameters>) } 或 { ? = call procName } (这更像是Oracle规则而不是Hibernate规则)
对于Sybase或者MS SQL server有如下规则:
-
存储过程必须返回一个结果集。.注意这些servers可能返回多个结果集以及更新的数目.Hibernate将取出第一条结果集作为它的返回值, 其他将被丢弃。
-
如果你能够在存储过程里设定SET NOCOUNT ON ,这可能会效率更高,但这不是必需的。
Hibernate3能够使用定制的SQL语句来执行create,update和delete操作。在Hibernate中,持久化的类和集合已经 包含了一套配置期产生的语句(insertsql, deletesql, updatesql等等),这些映射标记 <sql-insert> , <sql-delete> , and <sql-update> 重载了 这些语句。
<class name="Person"> <id name="id"> <generator class="increment"/> </id> <property name="name" not-null="true"/> <sql-insert>INSERT INTO PERSON (NAME, ID) VALUES ( UPPER(?), ? )</sql-insert> <sql-update>UPDATE PERSON SET NAME=UPPER(?) WHERE ID=?</sql-update> <sql-delete>DELETE FROM PERSON WHERE ID=?</sql-delete> </class>
这些SQL直接在你的数据库里执行,所以你可以自由的使用你喜欢的任意语法。但如果你使用数据库特定的语法, 这当然会降低你映射的可移植性。
如果设定callable ,则能够支持存储过程了。
<class name="Person"> <id name="id"> <generator class="increment"/> </id> <property name="name" not-null="true"/> <sql-insert callable="true">{call createPerson (?, ?)}</sql-insert> <sql-delete callable="true">{? = call deletePerson (?)}</sql-delete> <sql-update callable="true">{? = call updatePerson (?, ?)}</sql-update> </class>
参数的位置顺序是非常重要的,他们必须和Hibernate所期待的顺序相同。
你能够通过设定日志调试级别为org.hiberante.persister.entity ,来查看Hibernate所期待的顺序。在这个级别下, Hibernate将会打印出create,update和delete实体的静态SQL。如果想看到预想中的顺序。记得不要将定制SQL包含在映射文件里, 因为他们会重载Hibernate生成的静态SQL。
在大多数情况下(最好这么做),存储过程需要返回插入/更新/删除的行数,因为Hibernate对语句的成功执行有些运行时的检查。 Hibernate常会把进行CUD操作的语句的第一个参数注册为一个数值型输出参数。
CREATE OR REPLACE FUNCTION updatePerson (uid IN NUMBER, uname IN VARCHAR2) RETURN NUMBER IS BEGIN update PERSON set NAME = uname, where ID = uid; return SQL%ROWCOUNT; END updatePerson;
你可能需要声明你自己的SQL(或HQL)来装载实体
<sql-query name="person"> <return alias="p" class="Person" lock-mode="upgrade"/> SELECT NAME AS {p.name}, ID AS {p.id} FROM PERSON WHERE ID=? FOR UPDATE </sql-query>
这只是一个前面讨论过的命名查询声明,你可以在类映射里引用这个命名查询。
<class name="Person"> <id name="id"> <generator class="increment"/> </id> <property name="name" not-null="true"/> <loader query-ref="person"/> </class>
这也可以用于存储过程
TODO: 未完成的例子
<sql-query name="organizationEmployments"> <load-collection alias="empcol" role="Organization.employments"/> SELECT {empcol.*} FROM EMPLOYMENT empcol WHERE EMPLOYER = :id ORDER BY STARTDATE ASC, EMPLOYEE ASC </sql-query> <sql-query name="organizationCurrentEmployments"> <return alias="emp" class="Employment"/> <synchronize table="EMPLOYMENT"/> SELECT EMPLOYEE AS {emp.employee}, EMPLOYER AS {emp.employer}, STARTDATE AS {emp.startDate}, ENDDATE AS {emp.endDate}, REGIONCODE as {emp.regionCode}, ID AS {emp.id} FROM EMPLOYMENT WHERE EMPLOYER = :id AND ENDDATE IS NULL ORDER BY STARTDATE ASC </sql-query>
发表评论
-
连接池exception GetConnectionTimeoutException get/close not same thread
2015-09-24 14:44 7070环境 hibernate 4.2.0.Final sp ... -
hibernate spring 整合 Annotation SessionFactory java.lang.NoSuchMethodError
2015-03-26 09:40 1167使用Annotation整合Spring2.5和Hiber ... -
hibernate 一对多 排序 set
2011-05-19 11:50 2382一个note对象下面有多个comment 显示的时候希望按c ... -
hibernate 懒加载问题的一个临时解决方案
2011-05-06 11:00 1732hibernate的懒加载问题时常会困扰着我们, 今天发现了h ... -
hql select where in
2010-10-28 19:19 856public List<User> getUser ... -
hibernate sql 放到 hbm.xml中
2010-06-09 14:25 5711<?xml version="1.0" ... -
hibernate update 不是马上发出
2010-04-22 21:10 1000有时要手动让他立刻发出 -
fix No Hibernate Session bound to thread
2010-04-09 12:34 1073@Transactional @TransactionCon ... -
查看hibernate 实际发出的sql语句
2010-03-18 17:24 2287平常的show_sql=true 最后的参数只能看到一个? ... -
hibernate 映射文件 schema catalog 参数 导致的问题
2010-01-26 14:12 2407<hibernate-mapping> &l ... -
Xdoclet 笔记
2009-12-11 18:46 1345xdoclet2的网址: http://xdoclet. ... -
Hibernate 抓取策略
2009-12-11 18:30 1175hibernate抓取策略(单端代理的批量抓取) 保持< ... -
Hibernate 查询
2009-12-11 18:23 1257在hql中关键字不区分大小写,属性和类名区分大小写 1、简单 ... -
Hibernate 继承 及 锁
2009-12-11 18:20 1177每个类继承树映射成 ... -
Hibernate 关联映射
2009-12-11 18:19 1949------------------------------- ... -
hibernate 笔记
2009-12-11 18:14 1156第一个hibernate项目 1、新建一个java项目 2 ... -
hibernate 缓存 笔记
2009-11-02 12:00 1268hibernate一级缓存 一级缓存生命周期很短,它sess ... -
hibernate 缓存 初试
2009-11-02 11:08 1078配置二级缓存 hibernate.cfg.xml < ... -
hibernate 缓存
2009-10-28 09:08 1139缓存可以简单的看成一个 Map ,通过 ...
相关推荐
16. Native SQL查询 16.1. 使用SQLQuery 16.1.1. 标量查询(Scalar queries) 16.1.2. 实体查询(Entity queries) 16.1.3. 处理关联和集合类(Handling associations and collections) 16.1.4. 返回多个实体...
16. Native SQL查询 16.1. 使用SQLQuery 16.1.1. 标量查询(Scalar queries) 16.1.2. 实体查询(Entity queries) 16.1.3. 处理关联和集合类(Handling associations and collections) 16.1.4. 返回多个实体...
Scalar Subquery Expressions 4-11 Scalar Subqueries: Examples 4-12 Correlated Subqueries 4-14 Using Correlated Subqueries 4-16 Using the EXISTS Operator 4-18 Using the NOT EXISTS Operator 4-20 ...
16. Native SQL查询 16.1. 使用SQLQuery 16.1.1. 标量查询(Scalar queries) 16.1.2. 实体查询(Entity queries) 16.1.3. 处理关联和集合类(Handling associations and collections) 16.1.4. 返回多个实体...
16. Native SQL查询 16.1. 使用SQLQuery 16.1.1. 标量查询(Scalar queries) 16.1.2. 实体查询(Entity queries) 16.1.3. 处理关联和集合类(Handling associations and collections) 16.1.4. 返回多个实体(Returning...
16. Native SQL查询 16.1. 使用SQLQuery 16.1.1. 标量查询(Scalar queries) 16.1.2. 实体查询(Entity queries) 16.1.3. 处理关联和集合类(Handling associations and collections) 16.1.4. 返回多个实体...
16. Native SQL查询 16.1. 创建一个基于SQL的Query 16.2. 别名和属性引用 16.3. 命名SQL查询 16.3.1. 使用return-property来明确地指定字段/别名 16.3.2. 使用存储过程来查询 16.3.2.1. 使用存储过程的规则和限制 ...
16. Native SQL查询 16.1. 使用SQLQuery 16.1.1. 标量查询(Scalar queries) 16.1.2. 实体查询(Entity queries) 16.1.3. 处理关联和集合类(Handling associations and collections) 16.1.4. 返回多个实体...
17. Native SQL查询 17.1. 创建一个基于SQL的Query 17.2. 别名和属性引用 17.3. 命名SQL查询 17.3.1. 使用return-property来明确地指定字段/别名 17.3.2. 使用存储过程来查询 17.3.2.1. 使用存储过程的规则和...
16. Native SQL查询 16.1. 使用SQLQuery 16.2. 别名和属性引用 16.3. 命名SQL查询 16.3.1. 使用return-property来明确地指定字段/别名 16.3.2. 使用存储过程来查询 16.3.2.1. 使用存储过程的规则和限制 16.4....
SQL 函数 SQL 拥有很多可用于计数和计算的内建函数。 SQL Aggregate 函数 SQL Aggregate 函数计算从列中...SQL Scalar 函数基于输入值,返回一个单一的值。 有用的 Scalar 函数: UCASE() – 将某个字段转换为大写
10.4.4. Queries in native SQL 10.5. Modifying persistent objects 10.6. Modifying detached objects 10.7. Automatic state detection 10.8. Deleting persistent objects 10.9. Replicating object between two...
第一章 整体介绍 2 ...5.2.2 标量函数(Scalar Functions) 40 5.2.3 表函数(Table Functions) 42 5.2.4 聚合函数(Aggregate Functions) 45 5.2.5 表聚合函数(Table Aggregate Functions) 47
标量查询(Scalar query) 9.3.2. 查询接口(Query interface) 9.3.3. 可滚动迭代(Scrollable iteration) 9.3.4. 过滤集合类(Filtering collections) 9.3.5. 条件查询 9.3.6. 使用本地SQL的查询...
SP-6939 : Code analysis no longer flags an EI003 if a non-scalar subquery is contained within a scalar function, such as ANY, ALL or SOME. See the full release notes for more information.
Scalar® i500 是一个智能磁带库平台,可以为增长之中的中端存储环境带来更快、 更简单和更可靠的数据保护。
Quantum 的Scalar:registered: 24 对自动加载机已不能满足数据增长需要的IT 部 门具有出色的价值。Scalar 24 是一款设计小巧的双驱动器磁带库,它结合 了企业级产品的特性、性能以及低端产品的支付能力和易用性。...
Quantum:registered: 的Scalar:registered: 10K 是一台整合企业级备份的SAN 磁带库,能 够使IT 部门将存储整合在易于管理的单一系统中。它是业界第一台按需提 供容量磁带库,提供内置的容量扩展空间,并能使用户在...
昆腾Scalar i6000技术研讨会
17. Native SQL查询 17.1. 创建一个基于SQL的Query 17.2. 别名和属性引用 17.3. 命名SQL查询 17.3.1. 使用return-property来明确地指定字段/别名 17.3.2. 使用存储过程来查询 17.3.2.1. 使用存储过程的规则和...