Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

ITB2019 Faster DB Development with QB - Andrew Davis

23 views

Published on

Create object-oriented abstractions around SQL patterns. Explore new ways of organizing your code by passing around a query builder object that will compile down to the right SQL without you having to keep track of the order, whitespace, or other SQL gotchas!

Published in: Technology
  • Be the first to comment

  • Be the first to like this

ITB2019 Faster DB Development with QB - Andrew Davis

  1. 1. Faster DB Development with qb
  2. 2. Who are you? I am Andrew Davis - @blusol850 2
  3. 3. What is qb anyway? ✖ A fluent, chainable syntax for building SQL ✖ An abstraction around different DB engines ✖ An abstraction around queryExecute ✖ Heavily inspired by Eloquent From Laravel ✖ Written by Eric Peterson from Ortus Solutions 3
  4. 4. What is qb anyway? QueryBuilder@qb ✖ Queries your data 4 SchemaBuilder@qb ✖ Helps build DB schema ✖ Great for migrations
  5. 5. What is qb anyway? QB is the core backbone of Quick. Quick is an ORM (Object Relational Mapper) 5
  6. 6. Why qb? ✖ Reduce Typoz ✖ Bridge Database Engine Idiosyncrasies ✖ Stop Concatenating SQL Strings ✖ Object-Oriented Patterns with SQL Statements 6
  7. 7. Installation 7 EASY INSTALL VIA CommandBox Welcome to CommandBox! CommandBox> install qb
  8. 8. CONFIGURATION 8 EASY CONFIGURATION VIA moduleSettings struct in config/ColdBox.cfc moduleSettings = { qb = { defaultGrammar = "MSSQLGrammar", returnFormat = "array" // or query }
  9. 9. Que Problemo? function loadPosts() { return queryExecute(“SELECT * FROM `posts` limit 5”); } 9
  10. 10. Que Problemo? function loadPosts() { return queryExecute(‘SELECT TOP(5) * FROM [posts]’); } 10
  11. 11. DATABASE ENGINE SPECIFIC! 11
  12. 12. How can QB help?? //using take function loadPosts() { return query.from(“posts”).take(5).get(); } //using limit function loadPosts() { return query.from(“posts”).limit(5).get(); } 12
  13. 13. Bundled Grammars Include: 13 (Help is appreciated to add more)
  14. 14. select query.select( “id”); ✖ Default Is * ✖ Takes a Single Value, List, or Array ✖ Overwrites any Existing Selected Columns 14
  15. 15. addselect query.addSelect( “id”); ✖ Adds a column to the select list ✖ If the selection is currently *, then the added column will be the only column selected 15
  16. 16. join query.from( “posts”) .join( “users”, “posts.user_id”, “=”, “users.id” ); ✖ Add a join statement to the query ✖ Simple syntax for simple joins ✖ Complex joins can be specified using a callback 16
  17. 17. where() whereBetween() whereColumn() whereExists() whereIn() whereNotBetween() whereNotExists() whereNotIn() whereNotNull() whereNull() whereRaw() Where on Earth? and? andWhere() andWhereBetween() Etc… or? orWhere() orWhereBetween() Etc… 17
  18. 18. Where query.where( “title”, “=”, “My Title” ); ✖ Adds a where statement to the query ✖ AUTOMATICALLY params the value passed ✖ Accepts any SQL operator like <=, <>, OR like 18
  19. 19. Where magic query.where( “title”, “My Title” ); ✖ Can skip the second parameter if using = operator 19
  20. 20. Where magic query.whereTitle( “My Title” ); ✖ Thanks to onMissingMethod 20
  21. 21. Nested Where query.from( “users” ) .where( “email”, “foo” ) .orWhere( function( q ) { q.where( “name”, “bar” ) .where( “age”, “>=”, “21” ) } ); 21
  22. 22. Nested Where SQL SELECT * FROM `users` WHERE `email` = ? OR ( `name` = ? AND `age` >= ? ) 22
  23. 23. whereColumn query.whereColumn( "updated_date", ">", "created_date" ); ✖ Compares two columns ✖ Accepts any SQL operator like <=, <>, or LIKE 23
  24. 24. whereIn query.whereIn( "id", "[ 1, 2, 3, 5, 8, 13, 21, 34 ]" ); ✖ Adds a where in statement to the query ✖ Automatically params the values passed 24
  25. 25. More Where query.whereBetween( "createdDate", startDate, endDate); query.whereNull( "deletedDate"); query.whereExists( function( q ) { q.select( q.raw( 1 ) ) .from( "products" ) .where( "products.id", "=", q.raw( ‘"orders"."id"’) ); } ); 25
  26. 26. where() whereBetween() whereColumn() whereExists() whereIn() whereNotBetween() whereNotExists() whereNotIn() whereNotNull() whereNull() whereRaw() Where on Earth? and? andWhere() andWhereBetween() Etc… or? orWhere() orWhereBetween() Etc… 26
  27. 27. groupBy query.groupBy( "id" ); ✖ Adds a group by statement ✖ Further calls add to any existing groupings ✖ Takes a single value, list, or array 27
  28. 28. Having query.from( "users" ) .groupBy( "email" ) .having( builder.raw( "COUNT(email)" ), ">", 1 ); ✖ Adds a having statement ✖ Works pretty much like a where statement 28
  29. 29. Limit & Offset query.limit( 1 ) .offset( 10 ); ✖ Adds a limit and offset to the query ✖ This one is a great example where normalizing database engines is super nice. 29
  30. 30. mySQL LIMIT SELECT * FROM `users` LIMIT 3 LIMIT & OFFSET LIMIT & OFFSET SELECT * FROM `users` LIMIT 15 OFFSET 30 30
  31. 31. MSSQL LIMIT SELECT TOP (3) * FROM [users] LIMIT & OFFSET SELECT * FROM [users] ORDER BY 1 OFFSET 30 ROWS FETCH NEXT 15 ROWS ONLY 31
  32. 32. ORACLE LIMIT SELECT * FROM ( SELECT results.*, ROWNUM AS "QB_RN" FROM (SELECT * FROM "USERS") results ) WHERE "QB_RN" <= 3 LIMIT & OFFSET SELECT * FROM ( SELECT results.*, ROWNUM AS "QB_RN" FROM (SELECT * FROM "USERS") results ) WHERE "QB_RN" > 30 AND "QB_RN" <= 45 32
  33. 33. raw query.select( query.raw( "COUNT(*) AS post_count" ) ); ✖ The qb escape hatch ✖ Outputs exactly the text you give it 33
  34. 34. When Var temp = query.when( rc.isActive, function( q ) { q.where( "is_active", 1 ); }, function( q ) { q.whereNull( "is_active" ); } ); ✖ Control flow for chainable methods 34
  35. 35. toSQL query.from(“users”).toSQL() ✖ Builds the query into a SQL statement ✖ Bindings will be available in the getBindings method 35
  36. 36. get query.from( "users" ).get(); ✖ Builds and executes the current query ✖ Can accept columns as a shortcut ✖ Also accepts any options that can be passed to queryExecute 36
  37. 37. find query.from( "users" ).find(1, ‘idcolumn’); ✖ Shortcut method for retrieving records by primary key ✖ Default idColumn is id ✖ idColumn can be specified as second argument 37
  38. 38. find query.from( "users" ).find(1); ✖ Shortcut method for retrieving records by primary key ✖ Default idColumn is id ✖ idColumn can be specified as second argument 38
  39. 39. first query.from( "users" ).first(); ✖ Adds a limit( 1 ) to your query ✖ Also returns the struct value, not an array of one ✖ Returns an empty struct if nothing is found 39
  40. 40. exists query.from( "logins" ) .where( "user_id", user.getId() ) .exists(); ✖ Returns a boolean ✖ Works with any configured query ✖ Just call exists instead of get 40
  41. 41. Thanks! Any questions? You can find me at: @blusol850 41
  42. 42. Credits Special thanks to all the people who made and released these awesome resources for free: ✖ Presentation template by SlidesCarnival ✖ Photographs by Unsplash 42

×