Your SlideShare is downloading. ×
0
08 Queries
08 Queries
08 Queries
08 Queries
08 Queries
08 Queries
08 Queries
08 Queries
08 Queries
08 Queries
08 Queries
08 Queries
08 Queries
08 Queries
08 Queries
08 Queries
08 Queries
08 Queries
08 Queries
08 Queries
08 Queries
08 Queries
08 Queries
08 Queries
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

08 Queries

610

Published on

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
610
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
1
Comments
0
Likes
0
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Queries The Hibernate object-oriented query facilities
  • 2. Hibernate query options <ul><li>The Hibernate Query Language (HQL): </li></ul><ul><li>The Criteria API for type-safe queries: </li></ul><ul><li>Direct SQL with Hibernate mapping: </li></ul>session. createQuery (&quot; from Category cat where cat.name like '%Flights' &quot;).list(); session. createCriteria (Category.class) .add( Expression.like(&quot;name&quot;, &quot;%Flights&quot;) ) .list(); session. createSQLQuery ( &quot; select {cat.*} from CATEGORY {cat} where NAME like '%Flights' &quot;, &quot;cat&quot;, Category.class) .list();
  • 3. Executing queries <ul><li>We execute queries with the </li></ul><ul><ul><li>Query object from createQuery() and createSQLQuery() </li></ul></ul><ul><ul><li>Criteria object from createCriteria() </li></ul></ul><ul><li>Pagination: </li></ul><ul><li>Getting a list or results, or a single result: </li></ul><ul><li>Iterating: </li></ul>Query q = session.createQuery(&quot;from User user order by user.name asc&quot;) .setFirstResult(30) .setMaxResults(10) .list(); List result = q. list (); Object o = q.setMaxResults(1). uniqueResult (); Iterator it = q. iterate ();
  • 4. Executing queries <ul><li>A ScrollableResults let’s us step through the query results, just like a JDBC scrollable ResultSet : </li></ul>ScrollableResults users = session.createQuery( &quot;from User user order by user.name asc&quot;) .scroll(); while ( users.next() ) { User user = results.get(0); … } users.close();
  • 5. Binding parameters <ul><li>We should never use String manipulation: </li></ul><ul><li>We use named parameter binding : </li></ul><ul><li>Positional parameters are not recommended: </li></ul>String queryString = &quot;from Item i where i.description like '&quot; + string + &quot;'&quot;; List result = session.createQuery(queryString).list(); String queryString = &quot;from Item item &quot; + &quot;where item.description like :searchString &quot; + &quot;and item.date > :minDate &quot;; List result = session.createQuery(queryString) . setString (&quot;searchString&quot;, searchString ) . setDate (&quot;minDate&quot;, minDate ) .list(); String queryString = &quot;from Item item where item.description like ? &quot;; Query q = session.createQuery(queryString). setString ( 0 , searchString);
  • 6. More parameter binding techniques <ul><li>Use setEntity() to bind a persistent entity: </li></ul><ul><li>Use setProperties() to bind properties of a JavaBean to several named parameters simultaneously: </li></ul><ul><li>Use setParameterList() to bind multiple values: </li></ul>session.createQuery(&quot;from Item item where item.seller = :seller&quot;) .setEntity(&quot;seller&quot;, seller) ; Item item = new Item(); item. setSeller (seller); item. setDescription (description); String queryString = &quot;from Item item &quot; + &quot;where item.seller = :seller and &quot; + &quot;item.description like :description &quot;; session.createQuery(queryString). setProperties (item).list(); session.createQuery(&quot;from Item item where item.id in (:idList)&quot;) .setParameterList(“idList&quot;, idList) ;
  • 7. Externalizing named queries <ul><li>We can execute a named query : </li></ul><ul><li>The query is defined in the mapping metadata: </li></ul><ul><li>We can also name SQL queries: </li></ul>Query q = session.getNamedQuery(&quot; findItemsByDescription &quot;) .setString(&quot;description&quot;, description); <query name=&quot; findItemsByDescription &quot;><![CDATA[ from Item item where item.description like :description ]]></query> <sql-query name=&quot; findItemsByDescription &quot;><![CDATA[ select {item.*} from item where description like :description ]]> <return alias=&quot;item&quot; class=&quot;Item&quot;/> </sql-query>
  • 8. Basic queries in HQL and with Criteria <ul><li>The simplest query: </li></ul><ul><li>Using an alias: </li></ul><ul><li>Polymorphic queries: </li></ul>from Bid from BillingDetails from CreditCard from java.lang.Object // Returns all persistent objects! from Bid as bid session.createCriteria(Bid.class) session.createCriteria(BillingDetails.class)
  • 9. Restriction <ul><li>Restriction with a where clause in HQL: </li></ul><ul><li>Using a Criterion : </li></ul><ul><li>All regular SQL operators are supported in expressions: </li></ul>from User user where user.email = 'foo@hibernate.org' Criterion emailEq = Expression.eq(&quot;email&quot;, &quot;foo@hibernate.org); Criteria crit = session.createCriteria(User.class); crit.add( emailEq ); User user = (User) crit.uniqueResult(); from User user where user.email = 'foo@hibernate.org' and user.firstname like 'Max%' and user.lastname is not null or user.signupDate < :mondayLastWeek
  • 10. String matching <ul><li>We can use wildcards for string pattern matching: </li></ul><ul><li>The Criteria API allows string matching without string manipulation: </li></ul><ul><li>We can also call arbitrary SQL functions in the where clause: </li></ul>from User user where user.firstname not like &quot; %Foo B% &quot; session.createCriteria(User.class) .add( Expression.like(&quot;firstname&quot;, &quot;G&quot;, MatchMode.START ) ); from User user where lower(user.email) = 'foo@hibernate.org' session.createCriteria(User.class) .add( Expression.eq(&quot;email&quot;, &quot;foo@hibernate.org&quot;). ignoreCase() ) );
  • 11. Ordering results <ul><li>The order by clause is used in HQL: </li></ul><ul><li>The Criteria API also supports ordering of results: </li></ul><ul><li>HQL and the Criteria API give you all the power of SQL </li></ul><ul><li>without falling back to table and column names. </li></ul>from User user order by user.username desc List results = session.createCriteria(User.class) .addOrder( Order.asc (&quot;lastname&quot;) ) .addOrder( Order.asc (&quot;firstname&quot;) ) .list(); from Item item order by item.successfulBid.amount desc, item.id asc
  • 12. Joining associations <ul><li>The join SQL operation combines the data from two tables: </li></ul>PRICE PRICE 3 Baz 1.00 NAME ITEM_ID 1 1 2 Foo Foo Bar 2.00 2.00 50.00 from ITEM I inner join BID B on I.ITEM_ID = B.ITEM_ID AMOUNT ITEM_ID BID_ID 1 2 3 1 1 2 10.00 20.00 55.00 NAME ITEM_ID 1 1 2 Foo Foo Bar 2.00 2.00 50.00 from ITEM I left outer join BID B on I.ITEM_ID = B.ITEM_ID AMOUNT ITEM_ID BID_ID 1 2 3 1 1 2 10.00 20.00 55.00 null null null
  • 13. Fetching associations in Hibernate <ul><li>We can fetch associated objects in HQL: </li></ul><ul><li>For all Item s returned, the item.bids collection is fully initialized, </li></ul><ul><li>all with a single SQL outer join query. We may only fetch one collection in one HQL query, preserving performance in SQL. </li></ul><ul><li>We can also use a Criteria: </li></ul>from Item item left join fetch item.bids where item.description like '%gc%' session.createCriteria(Item.class) .setFetchMode(&quot;bids&quot;, FetchMode.EAGER) .add( Expression.like(&quot;description&quot;, &quot;gc&quot;, MatchMode.ANYWHERE) )
  • 14. Fetching single-ended associations <ul><li>We can also initialize (fetch) single-ended associations: </li></ul><ul><li>IMPORTANT: HQL always ignores the outer-join setting in the mapping metadata, we have to use an explicit fetch join. The Criteria will not ignore the metadata, disable it with FetchMode.LAZY ! </li></ul>from Bid bid left join fetch bid.item left join fetch bid.bidder where bid.amount > 100 session.createCriteria(Bid.class) .setFetchMode(&quot;item&quot;, FetchMode.EAGER) .setFetchMode(&quot;bidder&quot;, FetchMode.EAGER) .add( Expression.gt(&quot;amount&quot;, new Float(100) ) )
  • 15. Using aliases with joins <ul><li>We need an alias to express restrictions on joined objects: </li></ul><ul><li>This query returns ordered pairs of Items and Bids: </li></ul><ul><li>The select clause is optional: </li></ul>from Item item join item.bids bid where item.description like '%gc%' and bid .amount > 100 Query q = session.createQuery(&quot; from Item item join item.bids bid &quot;); Iterator pairs = q.list().iterator(); while ( pairs.hasNext() ) { Object[] pair = (Object[]) pairs.next(); Item item = (Item) pair[0]; Bid bid = (Bid) pair[1]; } select item from Item item join item.bids bid where bid.amount > 100
  • 16. Using implicit association joins <ul><li>We can query components (dereference with a dot): </li></ul><ul><li>We can join single-ended associations implicitly: </li></ul><ul><li>We have to be careful (how many SQL joins is this?): </li></ul>from User user where user . address . city = 'Bangkok' from Bid bid where bid . item . description like '%gc%' from Bid bid where bid.item.category.name like 'Laptop%' from Bid bid where bid.item.category.name like 'Laptop%' and bid.item.successfulBid.amount > 100
  • 17. Theta-style joins <ul><li>First, we create a Cartesian Product: </li></ul><ul><li>Then, we add a join condition in the where clause: </li></ul><ul><li>Theta-style (inner) joins are used when related tables (classes) are not referenced with a foreign key relationship (no automatic joining). </li></ul>from User, LogRecord from User user, LogRecord log where user.username = log.username
  • 18. Report queries in HQL <ul><li>The select clause is used for projection: </li></ul><ul><li>The result may be an Object[] of non-transactional objects: </li></ul><ul><li>Dynamic instantiation is much easier to handle: </li></ul>select item from Item item join item.bids bid where bid.amount > 100 select item.id, item.description, bid.amount from Item item join item.bids bid where bid.amount > 100 select new ItemRow ( item.id, item.description, bid.amount ) from Item item join item.bids bid where bid.amount > 100
  • 19. Aggregation in HQL <ul><li>The aggregation functions are </li></ul><ul><ul><li>count() , min() , max() , sum() and avg() </li></ul></ul><ul><li>Count all items with a successful bid: </li></ul><ul><li>The total of all successful bids: </li></ul><ul><li>The result is an ordered pair of Float s: </li></ul>select count (item.successfulBid) from Item item select sum (item.successfulBid.amount) from Item item select min (bid.amount), max (bid.amount) from Bid bid where bid.item.id = 1
  • 20. Grouping in HQL <ul><li>If we aggregate, we have to group every property in the select : </li></ul><ul><li>We can further restrict the result on the group: </li></ul><ul><li>Use report queries (projection, aggregation, grouping, dynamic instantiation) to optimize performance, only retrieve required data. </li></ul>select bid.item.id , avg(bid.amount) from Bid bid group by bid.item.id select item.id , count(bid) ), avg(bid.amount) from Item item join item.bids bid where item.successfulBid is null group by item.id having count(bid) > 10
  • 21. Dynamic queries with Query By Example <ul><li>Complex searches are best expressed with a QBE query: </li></ul><ul><li>QBE can be combined with QBC: </li></ul>User exampleUser = new User(); exampleUser.setFirstname (&quot;Max&quot;); exampleUser.setEmail (&quot;@hibernate.org&quot;); List result = findUsers( exampleUser ); public List findUsers(User user) throws HibernateException { return getSession().createCriteria(User.class) .add( Example.create(user) .ignoreCase().enableLik (MatchMode.ANYWHERE) ) .list(); } createCriteria(User.class) .add( Example.create(user) .ignoreCase().enableLike(MatchMode.ANYWHERE) ) . createCriteria(&quot;items&quot;) .add( Expression.isNull(&quot;successfulBid&quot;) );
  • 22. Filtering persistent collections <ul><li>We can filter the collection of bids of an already loaded Item : </li></ul><ul><li>HQL filter queries have an implicit from and where clause: </li></ul><ul><li>A filter doesn't have to return objects from the collection: </li></ul>Query q = session.createFilter ( item.getBids() , &quot;order by this .amount asc&quot; ); Query q = session.createFilter( item.getBids(), &quot;&quot; ); // This is valid... List result = q.setFirstResult(50).setMaxResults(100).list() // and useful! List results = session.createFilter( item.getBids(), &quot;select elements (this.bidder.bids)&quot; ).list()
  • 23. Subqueries in HQL <ul><li>Correlated subquery, total items sold by users, if more than 10: </li></ul><ul><li>Uncorrelated subquery, all bids that are 1 within the maximum: </li></ul><ul><li>We can use SQL quantifiers, ANY / ALL / SOME / IN: </li></ul>from User user where 10 < ( select count(item) from user.items where item.successfulBid is not null ) from Bid bid where bid.amount + 1 >= ( select max(b.amount) from Bid b ) from Item item where 100 > all ( select b.amount from item.bids b ) from Item item where 100 < any ( select b.amount from item.bids b ) from Item item where 100 = some ( select b.amount from item.bids b ) from Item item where 100 in ( select b.amount from item.bids b )
  • 24. Native SQL queries <ul><li>Direct native SQL queries use Hibernate shortcuts: </li></ul><ul><li>We can return Object[] s (tuples): </li></ul><ul><li>We can externalize SQL queries to the mapping file: </li></ul>List results = session.createSQLQuery(&quot;select {uzer.*} from user uzer&quot;, &quot; uzer &quot;, User.class ).list(); List tuples = session.createSQLQuery( &quot;select {u.*}, {b.*} from user u inner join bid b where u.id = b.bidder_id&quot;, new String[] { &quot;u&quot;, &quot;b&quot; }, new Class[] {User.class, Bid.class} ).list(); <sql-query name=&quot;findUsersAndBids&quot;><![CDATA[ select {u.*}, {b.*} from user u inner join bid b where u.id = b.bidder_id ]]> <return alias=&quot;u&quot; class=&quot;User&quot;/> <return alias=&quot;b&quot; class=&quot;Bid&quot;/> </sql-query>

×