Slick @ Confitura 2013

436 views

Published on

Slick @ Confitura 2013

Published in: Software
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
436
On SlideShare
0
From Embeds
0
Number of Embeds
6
Actions
Shares
0
Downloads
5
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Slick @ Confitura 2013

  1. 1. Maciek Próchniak
  2. 2. Jak udawać że nie mamy bazy danych
  3. 3. Oracle view
  4. 4. DDD/OOP view
  5. 5. Larry
  6. 6. Uncle Bob
  7. 7. Repozytorium? public interface Repository<T> { void save(T object); Collection<T> loadAll(); T load(Id id); }
  8. 8. Repozytorium? public interface Repository<Presentation> { Collection<Presentation> findByCategoryWithPopularityGreaterThan (String name, double popularity, int limit); ... }
  9. 9. Zapytania też mogą być logiką!
  10. 10. Dashboard
  11. 11. Kolekcje - Java Collection<Presentation> ret = new HashSet<Presentation>(); for (Presentation presentation : presentations) { if (presentation.getPopularity() > popularity) { for (Author author : authors) { if (author.getName().equals(name) && author.getId() == presentation.getAuthorId() ) { ret.add(presentation); } } } } return ret;
  12. 12. Techniki ● JDBC ● i(my??)Batis ● Hibernate/JPA ● Hades ● SpringData ● jOOQ ● OneWEBSQL
  13. 13. Object/Relational Mapping is the Vietnam of Computer Science - Ted Neward ORM - OMG - Rich Hickey
  14. 14. SQL? SELECT p.* from PRESENTATIONS p, AUTHORS a where p.authorId = a.id and p.popularity > :popularity and a.name = :name
  15. 15. SQL - kompozycja???
  16. 16. ???
  17. 17. .Net LINQ makes a query a first-class language construct in C# and Visual Basic. var results = from c in Suppliers where c.size < 1 select new {c.name, c.address};
  18. 18. JVM?
  19. 19. map
  20. 20. tasks :List[Task] convert :Task->View
  21. 21. tasks.map(convert) : List[View]
  22. 22. flatMap
  23. 23. tasks :List[Task] createSubtasks :Task->List[Task]
  24. 24. tasks.flatMap(createSubtasks) :List[Task]
  25. 25. Kolekcje - Scala! presentations.flatMap(presentation => authors .filter(author => author.id == presentation.authorId) .filter(author => author.name == name && presentation.popularity > popularity) .map(_ => presentation) )
  26. 26. Kolekcje - Scala! for { presentation <- presentations author <- authors if (author.id == presentation.authorId) if (author.name == name && presentation.popularity > popularity) } yield presentation
  27. 27. SQL - Scala SELECT p.* from PRESENTATIONS p for { p <- presentations } yield p
  28. 28. Filtrowanie SELECT p.* from PRESENTATIONS p WHERE p.rank > 5 for { p <- presentations if p.rank > 5 } yield p
  29. 29. Projekcja SELECT p.name from PRESENTATIONS p WHERE p.rank > 5 for { p <- presentations if p.rank > 5 } yield p.name
  30. 30. Join SELECT p.name,a.name from PRESENTATIONS p, AUTHORS a WHERE p.authorId = a.id for { p <- presentations a <- authors if (p.authorId==a.id) } yield (p.name,a.name)
  31. 31. InnerJoin SELECT p.name,a.name from PRESENTATIONS p, INNER JOIN AUTHORS a ON p.authorId = a.id for { p <- presentations a <- authors(p.authorId) } yield (p.name,a.name)
  32. 32. Order by, limit SELECT p.* from PRESENTATIONS p order by p.name limit 10 (for { p <- presentations } yield p) .sortBy(_.name) .take(10)
  33. 33. Deklaratywność w Scali tasks .map(_.name) .filter(_.priority > 4) .take(3)
  34. 34. ● Statyczne typowanie ● Deklaratywność ● Predykaty = wyrażenia Scali ● Standardowe API - (flat)Map
  35. 35. Logika DAO DB findByNameOrderByType findByTypeGroupByCategory ...
  36. 36. Logika DAO DB query
  37. 37. ???
  38. 38. Scala Language Integrated Connectivity Kit
  39. 39. Play! Akka Slick Scala Typesafe
  40. 40. Slick ● Obsługa różnych baz ● Łatwa konfiguracja ● DML ● Ochrona przed SQL injection ● bla ● bla ● bla
  41. 41. zapytania ~ operacje na kolekcjach Scali
  42. 42. SLICK - architektura AST H2MySQL Lifted
  43. 43. Lifted - predykaty for { speaker <- Query(Speakers) if (speaker.name startsWith "Maciek") } yield (speaker.twitter)
  44. 44. Lifted - metadane object Speakers extends Table[Speaker]("speakers") { def id = column[Long]("id") def name = column[String]("name") def twitter = column[TwitterId]("twitterId") def * = id ~ name ~ twitter <> ( Speaker.apply _, Speaker.unapply _) }
  45. 45. Lifted - predykaty for { speaker <- Query(Speakers) if (speaker.name startsWith "Maciek") } yield (speaker.twitter)
  46. 46. abstract class Query[+E, U] { def flatMap[F, T](f: E => Query[F, T]): Query[F, T] = ... def map[F, G, T](f: E => F) (implicit shape: Shape[F, T, G]): Query[G, T] = ... def filter[T](f: E => T) (implicit wt: CanBeQueryCondition[T]): Query[E, U] }
  47. 47. trait UnitInvoker[+R] extends Invoker[Unit, R] { final def list()(implicit session: JdbcBackend#Session): List[R] final def first()(implicit session: JdbcBackend#Session) : R final def foreach(f: R => Unit, maxRows: Int) (implicit session: JdbcBackend#Session): Unit .... }
  48. 48. Lifted - predykaty for { speaker <- Query(Speakers) if (speaker.name startsWith "Mac") } yield (speaker.twitter) === =!= notNull
  49. 49. Lifted - predykaty for { speaker <- Query(Speakers) if (speaker.name startsWith "Mac") } yield (speaker.twitter) Rep[String] Rep[TwitterId] Rep[String]
  50. 50. Lifted - Join for { (s,p) <- Query(Speakers) innerJoin Presentations on (_.id === _.authorId) } yield (s.twitter,p.abstr)
  51. 51. Lifted - własne typy case class TwitterId(id:String) extends AnyVal implicit val twitterId = MappedJdbcType.base[TwitterId,String] (_.id,TwitterId.apply) object Speakers extends Table[Speaker]("speakers") { def twitter = column[TwitterId]("twitterId") }
  52. 52. Lifted - kompozycja def filter(pred :Presentations=>Column[Boolean]) = { for { p <- Query(Presentations) if (pred(p)) } yield (p.id) }
  53. 53. Lifted - kompozycja for { presentation <- Query(Presentations) author <- presentation.author if author.name startsWith "Mac" } yield presentation.title
  54. 54. Lifted - kompozycja object Presentations extends Table[Presentation] { ... def author = foreignKey("author_fk", authorId, Speakers)(_.id) }
  55. 55. Lifted - podsumowanie
  56. 56. Czego brakuje lifted? for { speaker <- Query(Speakers) if (speaker.name === "Mac") } yield (speaker.twitter)
  57. 57. WIP - direct
  58. 58. Makra ● C - syntaktyczne ● Lisp - higieniczne ● Scala 2.10 - typowane
  59. 59. def filter(filter:T => Boolean) : Queryable[T] = macro QueryableMacros.filter[T]
  60. 60. def filter[T:c.WeakTypeTag] (c: scala.reflect.macros.Context) (projection: c.Expr[T => Boolean]) : c.Expr [scala.slick.direct.Queryable[T]] = ...
  61. 61. Makro - przykład .filter(s => s.name == "Henry") ("filter", Supplier, Function( List("s"), Apply( Select("s", "name"), "==", List(Literal(Constant("Henry"))))))
  62. 62. ("filter", Supplier, Function( List("s"), Apply( Select("s", "name"), "==", List(Literal(Constant("Henry")))))) Slick Query AST
  63. 63. SLICK - architektura AST H2MySQL Lifted Direct
  64. 64. Direct - metadane @table("presentation") case class Presentation(@column("id") id:Long, @column("authorId") authorId:Long, @column("title") title:String, @column("abstract")abstr:String)
  65. 65. Direct - przykład val query = for { speaker <- Queryable[Speaker] if speaker.name == "Kuba Nabrdalik" } yield speaker.bio
  66. 66. Direct - przykład val backend = new SlickBackend(profile, AnnotationMapper) def list[H](query:BaseQueryable[H]) : Iterable[H] = backend.result(query, session) dao.list(query) : List[Speaker]
  67. 67. Direct - typesafety :| for { presentation <- Queryable[Presentation] if (presentation.title.contains("scala")) } yield (presentation.id)
  68. 68. Direct - kompozycja?? def filter(pred:Presentation=>Boolean) = { for { p <- Queryable[Presentation] if (pred(p)) } yield (presentation.id) }
  69. 69. Slick - architektura AST H2MySQL Lifted Direct OrientDB
  70. 70. Slick OrientDB @table("presentation") case class Presentation(@column("id") id:Long, @column("title") title:String, @column("comments") comments:List[Comment]) case class Comment(@column("number") author:String, @column("rate") rate:Integer, @column("content") content:String)
  71. 71. Slick OrientDB for { presentation <- Queryable[Presentation] if (presentation.comments .filter(_.ratio > 5).size > 0) } yield (presentation.title)
  72. 72. SLICK - architektura AST H2MySQL Lifted Direct OrientDB Memory
  73. 73. SLICK - architektura AST H2 MySQL Lifted 18 faz kompilacji... OrientDBMemory Direct
  74. 74. there is no valid translation of arbitrary monadic Query expressions to SQL (whose semantics are stuck half-way between applicative functors and monads) - Stefan Zeiger
  75. 75. czy to się opłaca? ● Deklaratywne zapytania ● Znane API ● Brak magii ● ... oprócz odrobiny makr ● Skomplikowane :(
  76. 76. http://slick.typesafe.com https://github.com/slick/slick https://github.com/mproch/slick-orientdb
  77. 77. Takk/Tänan/Dzięki * we're hiring :)

×