Getting Started with
JOOQ and Flyway
Wiring up your Java app with DB
JUG.LV 08.05.2014 RIGA
DMITRY LEBEDEV & RUSTAM ARSLAN...
About
Dmitry - developer
Rustam - DevOps guy
Customer - finances
Project - set of
microservices
http://www.28stone.com
Motivation
Use simple tools
Try something new
Keep codebase maintainable
Flyway
SQL scripts for migration
Java beans for complex logic
Simple commands
JOOQ
Java API corresponds to SQL semantics
ActiveRecord & JPA beans generation
Strict typing in Java
Simple Tool: Flyway
flyway:clear
flyway:init
flyway:migrate
Simple Tool: JOOQ
List<BookRecord> list = create.select(field("BOOK.TITLE"), field("AUTHOR.
FIRST_NAME"), field("AUTHOR.LA...
Flyway
migrate
V1_1__create_book_table.sql
V1_2__create_author_table.sql
V1_3__alter_book_table.sql DB
Database
DB
book
author
schema_version
Database
DB
schema_version
JOOQ
generate
DB
book
author
SchemaImpl
Tables
BOOK
AUTHOR
BookRecord
AuthorRecord
JOOQ
SchemaImpl
Tables
BOOK
AUTHOR
domain-objects_<version>.jar
BookRecord
AuthorRecord
component_1
domain-objects-version...
Build systems support
Flyway:
command line (java)
java API
ant
maven 2,3
gradle
sbt
Jooq:
command line (java)
java API
mav...
domain-objects build workflow (gradle)
clean
resource
preparation
deployflyway
generated
compilation
jar
main
compilation
...
domain-objects deploy workflow (gradle)
clean deployflyway
get
dependencies
clean
init
repair
validate
info
migrate
... .....
Flyway in CI (jenkins)
Flyway versioning
One or more numeric parts
Separated by a dot (.) or an underscore (_)
Underscores are replaced by dots a...
Let’s Do Some Programming!
Building queries / SQL generation
Fetching results
Updating records
Not covering:
● Lazy fetch
● Transaction management
● Constraints & Relationships
DSLContext - starting point
DSLContext create = DSL.using(conn, SQLDialect.MYSQL);
Result<Record> result = create.select()...
Building queries
create.select(field("BOOK.TITLE"), field("AUTHOR.FIRST_NAME"), field
("AUTHOR.LAST_NAME"))
.from(table("B...
Building queries
create.select(BOOK.TITLE, AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME)
.from(BOOK)
.join(AUTHOR)
.on(BOOK.AUTHOR_...
Building queries
create.select(BOOK.TITLE, AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME)
.from(BOOK)
.join(AUTHOR)
.on(BOOK.AUTHOR_...
Building queries
create.select(BOOK.TITLE, AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME)
.from(BOOK)
.join(AUTHOR)
.on(BOOK.AUTHOR_...
SQL Generation
String sql = create.select(BOOK.TITLE, AUTHOR.FIRST_NAME, AUTHOR.
LAST_NAME)
.from(BOOK)
.join(AUTHOR)
.on(...
Fetching results: Record
create.select(BOOK.TITLE, AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME)
.from(BOOK)
.join(AUTHOR)
.on(BOOK...
Fetching results: TableRecord
create.selectFrom(BOOK)
.where(BOOK.PUBLISHED_IN.equal(1948))
.orderBy(BOOK.TITLE.asc()).lim...
List<BookRecord> result1 = create.selectFrom(BOOK)...
Result<Record> result2 = create.select().from(BOOK)...
// somewhere ...
Fetching results: CSV
create.selectFrom(BOOK)
.where(BOOK.PUBLISHED_IN.equal(1948))
.orderBy(BOOK.TITLE.asc()).limit(10).o...
Fetching results: JSON
create.selectFrom(BOOK)
.where(BOOK.PUBLISHED_IN.equal(1948))
.orderBy(BOOK.TITLE.asc()).limit(10)....
Fetching results: XML
create.selectFrom(BOOK)
.where(BOOK.PUBLISHED_IN.equal(1948))
.orderBy(BOOK.TITLE.asc()).limit(10).o...
Fetching results: HTML
create.selectFrom(BOOK)
.where(BOOK.PUBLISHED_IN.equal(1948))
.orderBy(BOOK.TITLE.asc()).limit(10)....
Fetching results: POJOs
create.select(BOOK.TITLE, AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME)
.from(BOOK)
.join(AUTHOR)
.on(BOOK....
Fetching results: Maps
create.select(BOOK.TITLE, AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME)
.from(BOOK)
.join(AUTHOR)
.on(BOOK.A...
Records: create
// Create a new record
BookRecord book1 = create.newRecord(BOOK);
// Insert the record: INSERT INTO BOOK (...
Records: update
BookRecord book2 = create.fetchOne(BOOK, BOOK.ID.equal(id));
// Update the record: UPDATE BOOK SET TITLE =...
Records: delete
BookRecord book = create.fetchOne(BOOK, BOOK.ID.equal(5));
// Delete the book
book.delete();
Records: batch changes
// Fetch a bunch of books
List<BookRecord> books = create.fetch(BOOK);
// Modify the above books, a...
Records: update using a query
create.update(BOOK)
.set(BOOK.IS_BESTSELLER, 1)
.where(BOOK.SELLED_COPIES.greater(100000))
....
Q&A!
any questions?!
JOOQ and Flyway
Upcoming SlideShare
Loading in …5
×

JOOQ and Flyway

1,633 views

Published on

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

No Downloads
Views
Total views
1,633
On SlideShare
0
From Embeds
0
Number of Embeds
12
Actions
Shares
0
Downloads
9
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

JOOQ and Flyway

  1. 1. Getting Started with JOOQ and Flyway Wiring up your Java app with DB JUG.LV 08.05.2014 RIGA DMITRY LEBEDEV & RUSTAM ARSLANOV @ 28STONE
  2. 2. About Dmitry - developer Rustam - DevOps guy Customer - finances Project - set of microservices http://www.28stone.com
  3. 3. Motivation Use simple tools Try something new Keep codebase maintainable
  4. 4. Flyway SQL scripts for migration Java beans for complex logic Simple commands
  5. 5. JOOQ Java API corresponds to SQL semantics ActiveRecord & JPA beans generation Strict typing in Java
  6. 6. Simple Tool: Flyway flyway:clear flyway:init flyway:migrate
  7. 7. Simple Tool: JOOQ List<BookRecord> list = create.select(field("BOOK.TITLE"), field("AUTHOR. FIRST_NAME"), field("AUTHOR.LAST_NAME")) .from(table("BOOK")) .join(table("AUTHOR")) .on(field("BOOK.AUTHOR_ID").equal(field("AUTHOR.ID"))) .where(field("BOOK.PUBLISHED_IN").equal(1948)) .fetchInto(BookRecord.class);
  8. 8. Flyway migrate V1_1__create_book_table.sql V1_2__create_author_table.sql V1_3__alter_book_table.sql DB
  9. 9. Database DB book author schema_version
  10. 10. Database DB schema_version
  11. 11. JOOQ generate DB book author SchemaImpl Tables BOOK AUTHOR BookRecord AuthorRecord
  12. 12. JOOQ SchemaImpl Tables BOOK AUTHOR domain-objects_<version>.jar BookRecord AuthorRecord component_1 domain-objects-version=1.1 component_2 domain-objects-version=1.1 component_3 domain-objects-version=1.2
  13. 13. Build systems support Flyway: command line (java) java API ant maven 2,3 gradle sbt Jooq: command line (java) java API maven 2,3 gradle (3d party)
  14. 14. domain-objects build workflow (gradle) clean resource preparation deployflyway generated compilation jar main compilation ● resources filtering clean init repair validate info migrate ● generated compile jooq generateJooq
  15. 15. domain-objects deploy workflow (gradle) clean deployflyway get dependencies clean init repair validate info migrate ... ... ... ● get domain- objects ● deploy or run application
  16. 16. Flyway in CI (jenkins)
  17. 17. Flyway versioning One or more numeric parts Separated by a dot (.) or an underscore (_) Underscores are replaced by dots at runtime Leading zeroes are ignored in each part 1 001 5.2 5_2 (5.2 at runtime) 1.2.3.4.5.6.7.8.9 205.68 20130115113556 2013.1.15.11.35.56 2013.01.15.11.35.56 1__CreateTable.sql 001__AlterTable.sql 5.2__InsertDate.sql 5_2__DeleteData.sql 1.2.3.4.5.6.7.8.9__AnotherScript.sql 205.68__Transform.sql 20130115113556__InsertView.sql 2013.1.15.11.35.56__AddService.sql 2013.01.15.11.35.56__Delete.sql
  18. 18. Let’s Do Some Programming! Building queries / SQL generation Fetching results Updating records
  19. 19. Not covering: ● Lazy fetch ● Transaction management ● Constraints & Relationships
  20. 20. DSLContext - starting point DSLContext create = DSL.using(conn, SQLDialect.MYSQL); Result<Record> result = create.select().from(AUTHOR).fetch();
  21. 21. Building queries create.select(field("BOOK.TITLE"), field("AUTHOR.FIRST_NAME"), field ("AUTHOR.LAST_NAME")) .from(table("BOOK")) .join(table("AUTHOR")) .on(field("BOOK.AUTHOR_ID").equal(field("AUTHOR.ID"))) .where(field("BOOK.PUBLISHED_IN").equal(1948)) .fetch();
  22. 22. Building queries create.select(BOOK.TITLE, AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME) .from(BOOK) .join(AUTHOR) .on(BOOK.AUTHOR_ID.equal(AUTHOR.ID)) .where(BOOK.PUBLISHED_IN.equal(1948)) .fetch();
  23. 23. Building queries create.select(BOOK.TITLE, AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME) .from(BOOK) .join(AUTHOR) .on(BOOK.AUTHOR_ID.equal(AUTHOR.ID)) .where(BOOK.PUBLISHED_IN.equal(1948)) .orderBy(BOOK.TITLE.asc()) .fetch();
  24. 24. Building queries create.select(BOOK.TITLE, AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME) .from(BOOK) .join(AUTHOR) .on(BOOK.AUTHOR_ID.equal(AUTHOR.ID)) .where(BOOK.PUBLISHED_IN.equal(1948)) .orderBy(BOOK.TITLE.asc()).limit(10).offset(100) .fetch();
  25. 25. SQL Generation String sql = create.select(BOOK.TITLE, AUTHOR.FIRST_NAME, AUTHOR. LAST_NAME) .from(BOOK) .join(AUTHOR) .on(BOOK.AUTHOR_ID.equal(AUTHOR.ID)) .where(BOOK.PUBLISHED_IN.equal(1948)) .orderBy(BOOK.TITLE.asc()).limit(10).offset(100) .getSQL();
  26. 26. Fetching results: Record create.select(BOOK.TITLE, AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME) .from(BOOK) .join(AUTHOR) .on(BOOK.AUTHOR_ID.equal(AUTHOR.ID)) .where(BOOK.PUBLISHED_IN.equal(1948)) .orderBy(BOOK.TITLE.asc()).limit(10).offset(100) .fetch();
  27. 27. Fetching results: TableRecord create.selectFrom(BOOK) .where(BOOK.PUBLISHED_IN.equal(1948)) .orderBy(BOOK.TITLE.asc()).limit(10).offset(100) .fetch();
  28. 28. List<BookRecord> result1 = create.selectFrom(BOOK)... Result<Record> result2 = create.select().from(BOOK)... // somewhere in iteration loop bookRecord.getTitle(); record.get(“title”); Record VS. TableRecord
  29. 29. Fetching results: CSV create.selectFrom(BOOK) .where(BOOK.PUBLISHED_IN.equal(1948)) .orderBy(BOOK.TITLE.asc()).limit(10).offset(100) .fetch().formatCSV(‘,’,””);
  30. 30. Fetching results: JSON create.selectFrom(BOOK) .where(BOOK.PUBLISHED_IN.equal(1948)) .orderBy(BOOK.TITLE.asc()).limit(10).offset(100) .fetch().formatJSON();
  31. 31. Fetching results: XML create.selectFrom(BOOK) .where(BOOK.PUBLISHED_IN.equal(1948)) .orderBy(BOOK.TITLE.asc()).limit(10).offset(100) .fetch().formatXML();
  32. 32. Fetching results: HTML create.selectFrom(BOOK) .where(BOOK.PUBLISHED_IN.equal(1948)) .orderBy(BOOK.TITLE.asc()).limit(10).offset(100) .fetch().formatHTML();
  33. 33. Fetching results: POJOs create.select(BOOK.TITLE, AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME) .from(BOOK) .join(AUTHOR) .on(BOOK.AUTHOR_ID.equal(AUTHOR.ID)) .where(BOOK.PUBLISHED_IN.equal(1948)) .orderBy(BOOK.TITLE.asc()).limit(10).offset(100) .fetchInto(BookDTO.class);
  34. 34. Fetching results: Maps create.select(BOOK.TITLE, AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME) .from(BOOK) .join(AUTHOR) .on(BOOK.AUTHOR_ID.equal(AUTHOR.ID)) .where(BOOK.PUBLISHED_IN.equal(1948)) .orderBy(BOOK.TITLE.asc()).limit(10).offset(100) .fetchMaps();
  35. 35. Records: create // Create a new record BookRecord book1 = create.newRecord(BOOK); // Insert the record: INSERT INTO BOOK (TITLE) VALUES ('1984'); book1.setTitle("1984"); book1.store();
  36. 36. Records: update BookRecord book2 = create.fetchOne(BOOK, BOOK.ID.equal(id)); // Update the record: UPDATE BOOK SET TITLE = 'Animal Farm' WHERE ID = [id] book2.setTitle("Animal Farm"); book2.store();
  37. 37. Records: delete BookRecord book = create.fetchOne(BOOK, BOOK.ID.equal(5)); // Delete the book book.delete();
  38. 38. Records: batch changes // Fetch a bunch of books List<BookRecord> books = create.fetch(BOOK); // Modify the above books, and add some new ones: modify(books); addMore(books); // Batch-update and/or insert all of the above books create.batchStore(books);
  39. 39. Records: update using a query create.update(BOOK) .set(BOOK.IS_BESTSELLER, 1) .where(BOOK.SELLED_COPIES.greater(100000)) .execute();
  40. 40. Q&A! any questions?!

×