From abbf47ed61b07bd2e7a48ba52156052cd62f7afa Mon Sep 17 00:00:00 2001 From: Gavin King Date: Fri, 25 Mar 2005 05:18:45 +0000 Subject: [PATCH] documented use of unqualified property names in HQL fixed some of the problems in the SQL chapter git-svn-id: https://svn.jboss.org/repos/hibernate/trunk/Hibernate3/doc@6215 1b8cb986-b30d-0410-93ca-fae66ebed9b2 --- reference/en/modules/query_hql.xml | 169 ++++++++++---------- reference/en/modules/query_sql.xml | 237 ++++++++++++++++------------- 2 files changed, 224 insertions(+), 182 deletions(-) diff --git a/reference/en/modules/query_hql.xml b/reference/en/modules/query_hql.xml index 0ec63dd29a..e637c5ec4a 100644 --- a/reference/en/modules/query_hql.xml +++ b/reference/en/modules/query_hql.xml @@ -38,16 +38,20 @@ - which simply returns all instances of the class eg.Cat. + which simply returns all instances of the class eg.Cat. + We don't usually need to qualify the class name, since auto-import + is the default. So we almost always just write: + + Most of the time, you will need to assign an alias, since you will want to refer to the Cat in other parts of the query. - + This query assigns the alias cat to Cat @@ -55,7 +59,7 @@ keyword is optional; we could also write: - + Multiple classes may appear, resulting in a cartesian product or "cross" join. @@ -80,13 +84,13 @@ collection of values, using a join. - -from eg.Cat as cat left join cat.mate.kittens as kittens + -from Formula form full join form.parameter param]]> + The supported join types are borrowed from ANSI SQL @@ -120,7 +124,7 @@ from Formula form full join form.parameter param]]> right outer join constructs may be abbreviated. - @@ -132,7 +136,7 @@ from Formula form full join form.parameter param]]> for more information. - @@ -162,7 +166,7 @@ from Formula form full join form.parameter param]]> @@ -170,7 +174,7 @@ from eg.Cat as cat Actually, you may express this query more compactly as: - + Queries may return properties of any value type including properties of component type: - @@ -196,7 +200,7 @@ select cust.name.firstName from Customer as cust]]> @@ -205,7 +209,7 @@ from eg.DomesticCat as mother @@ -223,7 +227,7 @@ from eg.DomesticCat as mother +from Cat cat]]> @@ -262,9 +266,9 @@ from eg.Cat cat group by cat]]> the same semantics as in SQL. - +select count(distinct cat.name), count(cat) from Cat cat]]> @@ -275,7 +279,7 @@ select count(distinct cat.name), count(cat) from eg.Cat cat]]> A query like: - + returns instances not only of Cat, but also of subclasses like @@ -292,7 +296,7 @@ select count(distinct cat.name), count(cat) from eg.Cat cat]]> classes: - + Note that these last two queries will require more than one SQL SELECT. This @@ -307,16 +311,23 @@ select count(distinct cat.name), count(cat) from eg.Cat cat]]> The where clause allows you to narrow the list of instances returned. + If no alias exists, you may refer to properties by name: - + + + + If there is an alias, use a qualified property name: + + + returns instances of Cat named 'Fritz'. @@ -328,14 +339,14 @@ where foo.startDate = bar.date]]> where clause extremely powerful. Consider: - + This query translates to an SQL query with a table (inner) join. If you were to write something like - @@ -347,10 +358,10 @@ where foo.bar.baz.customer.address.city is not null]]> instances: - -select cat, mate -from eg.Cat cat, eg.Cat mate + @@ -358,9 +369,9 @@ where cat.mate = mate]]> unique identifier of an object. (You may also use its property name.) - +from Cat as cat where cat.mate.id = 69]]> The second query is efficient. No table join is required! @@ -374,9 +385,9 @@ from eg.Cat as cat where cat.mate.id = 69]]> -from bank.Account account + @@ -390,7 +401,7 @@ where account.owner.id.country = 'AU' where clause will be translated to its discriminator value. - + You may also specify properties of components or composite user types (and of components @@ -408,8 +419,8 @@ store.owner.address // error!]]> is a property mapped with <any>). - + Notice that log.item.class and payment.class @@ -513,17 +524,17 @@ where log.item.class = 'eg.Payment' and log.item.id = payment.id]]>in and between may be used as follows: - -from eg.DomesticCat cat where cat.name in ( 'Foo', 'Bar', 'Baz' )]]> + and the negated forms may be written - -from eg.DomesticCat cat where cat.name not in ( 'Foo', 'Bar', 'Baz' )]]> + Likewise, is null and is not null may be used to test @@ -542,16 +553,16 @@ from eg.DomesticCat cat where cat.name not in ( 'Foo', 'Bar', 'Baz' )]]>1 and 0 in the translated SQL from this HQL: - + You may test the size of a collection with the special property size, or the special size() function. - 0 + 0]]> -from eg.Cat cat where size(cat.kittens) > 0]]> + 0]]> For indexed collections, you may refer to the minimum and maximum indices using @@ -561,11 +572,11 @@ from eg.Cat cat where size(cat.kittens) > 0]]> functions. - current date + current date]]> -from Order order where maxindex(order.items) > 100 + 100]]> -from Order order where minelement(order.items) > 10000]]> + 10000]]> The SQL functions any, some, all, exists, in are supported when passed the element @@ -573,17 +584,17 @@ from Order order where minelement(order.items) > 10000]]> or the result of a subquery (see below). - -select p from eg.NameList list, eg.Person p -where p.name = some elements(list.names) + -from eg.Cat cat where exists elements(cat.kittens) + -from eg.Player p where 3 > all elements(p.scores) + all elements(p.scores)]]> -from eg.Show show where 'fizard' in indices(show.acts)]]> + Note that these constructs - size, elements, @@ -597,16 +608,16 @@ from eg.Show show where 'fizard' in indices(show.acts)]]> index (in a where clause only): - -select person from Person person, Calendar calendar + -select item from Item item, Order order -where order.items[ order.deliveredItemIndices[0] ] = item and order.id = 11 + -select item from Item item, Order order + @@ -629,7 +640,7 @@ where index(item) < 5]]> Scalar SQL functions supported by the underlying database may be used - + If you are not yet convinced by all this, think how much longer and less readable the @@ -675,7 +686,7 @@ WHERE prod.name = 'widget' The list returned by a query may be ordered by any property of a returned class or components: - @@ -692,11 +703,11 @@ order by cat.name asc, cat.weight desc, cat.birthdate]]> -select foo.id, avg(name), max(name) -from eg.Foo foo join foo.names name + @@ -704,18 +715,18 @@ group by foo.id]]> SQL functions and aggregate functions are allowed in the having - and order by clauses, if supported by the underlying database (eg. - not in MySQL). + and order by clauses, if supported by the underlying database + (eg. not in MySQL). 100 @@ -737,24 +748,24 @@ order by count(kitten) asc, sum(kitten.weight) desc]]> (subqueries that refer to an alias in the outer query) are allowed. - ( - select avg(cat.weight) from eg.DomesticCat cat -) + select avg(cat.weight) from DomesticCat cat +)]]> -from eg.DomesticCat as cat + -from eg.Cat as cat + -from eg.DomesticCat as cat + diff --git a/reference/en/modules/query_sql.xml b/reference/en/modules/query_sql.xml index e4c4a535d0..8d9fbf93fe 100644 --- a/reference/en/modules/query_sql.xml +++ b/reference/en/modules/query_sql.xml @@ -86,7 +86,7 @@ "from cat_log cat where {cat.mate} = :catId" List loggedCats = sess.createSQLQuery(sql) - .addEntity("cat", Cat.class) + .addEntity("cat", Cat.class) .setLong("catId", catId) .list();]]> @@ -138,14 +138,14 @@ List loggedCats = sess.createSQLQuery(sql) - Using property-result to explicitly specify column/alias names - - - With <property-result> you can explicitly tell Hibernate what columns - to use as opposed to use {}-syntax to let Hibernate inject its own aliases. - - - + Using property-result to explicitly specify column/alias names + + + With <property-result> you can explicitly tell Hibernate what columns + to use as opposed to use {}-syntax to let Hibernate inject its own aliases. + + + @@ -157,18 +157,18 @@ List loggedCats = sess.createSQLQuery(sql) FROM PERSON person WHERE person.NAME LIKE :name ]]> - - <property-result> also works with multiple columns. This solves a limitation with - the {}-syntax which can not allow fine grained control of multi-column properties. - - - + + <property-result> also works with multiple columns. This solves a limitation with + the {}-syntax which can not allow fine grained control of multi-column properties. + + + - - - - + + + + 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 @@ -176,29 +176,29 @@ List loggedCats = sess.createSQLQuery(sql) WHERE EMPLOYER = :id AND ENDDATE IS NULL ORDER BY STARTDATE ASC ]]> - - - Notice that in this example we used <property-result> in combination - with the {}-syntax for injection. Allowing users to choose - how they want to refer column and properties. - + + + Notice that in this example we used <property-result> in combination + with the {}-syntax for injection. Allowing users to choose + how they want to refer column and properties. + - - If your mapping has a discriminator you must use <discriminator-result> to specify the discriminators column. - + + If your mapping has a discriminator you must use <discriminator-result> to specify the discriminators column. + - Using stored procedures for querying - - - Hibernate 3 introduces support for queries via stored procedures. - - The stored procedures must return a resultset as the first out-parameter to be able to work with Hibernate. - - An example of such a stored procedure in Oracle 9 and higher is as follows: - - Using stored procedures for querying + + + Hibernate 3 introduces support for queries via stored procedures. + + The stored procedures must return a resultset as the first out-parameter to be able to work with Hibernate. + + An example of such a stored procedure in Oracle 9 and higher is as follows: + + - - To use this query in Hibernate you need to map it via a named query. - - - - - - - - - - - - - - - { ? = call selectAllEmployments() } - ]]> - - - - Notice stored procedures currently only return scalars and entities. >return-join< and - >load-collection< is not supported. - - - - TODO: make the "rules" visually nicer and understandable ,) - - - - Rules/Limitations for using stored procedures - - - To use stored procedures with Hibernate the procedures have to follow some rules. If they do not follow those - rules they are not usable with Hibernate. If you still want to use these procedures you have to execute them via session.connection(). - - The rules are different per database since database vendors have different stored procedure semantics/syntax. - - For Oracle the following rules applies: - - 1. It must return a result set. (This is done by returning a SYS_REFCURSOR in Oracle 9 & 10, in Oracle you need to define a REF CURSOR type) - 2. It should be on the form { ? = call procName() } or { ? = call procName} (this is more a Oracle rule than a Hibernate rule) - - For Sybase & MS SQL server the following rules applies: - - It must return a result set. Note that since these servers can/will return multiple result sets and update count Hibernate will iterate the results and take the first result that is a result set as its return value. Everything else will be discarded. - If you can enable SET NOCOUNT ON in your procedure it will probably be the most efficient, but it is not an requirement. - - + + To use this query in Hibernate you need to map it via a named query. + + + + + + + + + + + + + + + { ? = call selectAllEmployments() } +]]> + + + + Notice stored procedures currently only return scalars and entities. + <return-join> and <load-collection> + are not supported. + + + + TODO: make the "rules" visually nicer and understandable ,) + + + + Rules/Limitations for using stored procedures + + + To use stored procedures with Hibernate the procedures have to follow some rules. + If they do not follow those rules they are not usable with Hibernate. If you still + want to use these procedures you have to execute them via session.connection(). + The rules are different per database since database vendors have different stored procedure + semantics/syntax. + + + + For Oracle the following rules apply: + + + + + + It must return a result set. This is done by returning a SYS_REFCURSOR in Oracle 9 or 10. + In Oracle you need to define a REF CURSOR type. + + + + + It should be on the form { ? = call procName(<parameters>) } or + { ? = call procName } (This is more an Oracle rule than a Hibernate rule.) + + + + + + For Sybase or MS SQL server the following rules apply: + + + + + + It must return a result set. Note that since these servers can/will return multiple result + sets and update count Hibernate will iterate the results and take the first result that is + a result set as its return value. Everything else will be discarded. + + + + + If you can enable SET NOCOUNT ON in your procedure it will probably be the most efficient, but + it is not a requirement. + + + + @@ -304,16 +335,16 @@ BEGIN {? = call updatePerson (?, ?)} ]]> - - The order of the positional parameters are currently vital, as they must be in - the same sequence as Hibernate expects them. - - - - You can see the expected order by enabling debug logging for the org.hiberante.persister.entity - level. With this level enabled Hibernate will print out the static SQL that is used to create, update, delete etc. entities. - To see the expected sequence, remember to not include your custom SQL in the mapping files as that will override the Hibernate generated static sql. - + + The order of the positional parameters are currently vital, as they must be in + the same sequence as Hibernate expects them. + + + + You can see the expected order by enabling debug logging for the org.hiberante.persister.entity + level. With this level enabled Hibernate will print out the static SQL that is used to create, update, delete etc. entities. + To see the expected sequence, remember to not include your custom SQL in the mapping files as that will override the Hibernate generated static sql. + The stored procedures are in most cases (read: better do it than not) required to @@ -336,7 +367,7 @@ BEGIN END updatePerson;]]> - + @@ -363,10 +394,10 @@ END updatePerson;]]> ]]> - - - And this also works with stored procedures. - + + + And this also works with stored procedures. + TODO: Document the following example for collection loader.