JOOQ and Flyway
-
Upload
dmitry-buzdin -
Category
Software
-
view
341 -
download
19
description
Transcript of JOOQ and Flyway
Getting Started with JOOQ and Flyway
Wiring up your Java app with DB
JUG.LV 08.05.2014 RIGA
DMITRY LEBEDEV & RUSTAM ARSLANOV @ 28STONE
About
Dmitry - developerRustam - DevOps guyCustomer - financesProject - set of
microservices
http://www.28stone.com
Motivation
Use simple toolsTry something new
Keep codebase maintainable
Flyway
SQL scripts for migrationJava beans for complex logic
Simple commands
JOOQ
Java API corresponds to SQL semanticsActiveRecord & JPA beans generation
Strict typing in Java
Simple Tool: Flyway
flyway:clearflyway:init
flyway:migrate
Simple Tool: JOOQList<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);
Flyway
migrate
V1_1__create_book_table.sqlV1_2__create_author_table.sqlV1_3__alter_book_table.sql DB
Database
DB
book
author
schema_version
Database
DB
schema_version
JOOQ
generate
DB
bookauthor
SchemaImpl
Tables
BOOK
AUTHOR
BookRecord
AuthorRecord
JOOQ
SchemaImpl
TablesBOOK
AUTHOR
domain-objects_<version>.jar
BookRecord
AuthorRecord
component_1domain-objects-version=1.1
component_2domain-objects-version=1.1
component_3domain-objects-version=1.2
Build systems support
Flyway: command line (java)java APIantmaven 2,3gradlesbt
Jooq: command line (java)java APImaven 2,3gradle (3d party)
domain-objects build workflow (gradle)
clean resource preparation deployflyway generated
compilation jarmain compilation
● resources filtering
clean
init
repair
validate
info
migrate
● generated compile
jooq
generateJooq
domain-objects deploy workflow (gradle)
clean deployflywayget dependencies
clean
init
repair
validate
info
migrate
... ... ...
● get domain-objects
● deploy or run application
Flyway in CI (jenkins)
Flyway versioningOne 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
10015.25_2 (5.2 at runtime)1.2.3.4.5.6.7.8.9205.68201301151135562013.1.15.11.35.562013.01.15.11.35.56
1__CreateTable.sql001__AlterTable.sql5.2__InsertDate.sql5_2__DeleteData.sql1.2.3.4.5.6.7.8.9__AnotherScript.sql205.68__Transform.sql20130115113556__InsertView.sql2013.1.15.11.35.56__AddService.sql2013.01.15.11.35.56__Delete.sql
Let’s Do Some Programming!
Building queries / SQL generationFetching resultsUpdating records
Not covering:
● Lazy fetch● Transaction management● Constraints & Relationships
DSLContext - starting pointDSLContext create = DSL.using(conn, SQLDialect.MYSQL);
Result<Record> result = create.select().from(AUTHOR).fetch();
Building queriescreate.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();
Building queriescreate.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();
Building queriescreate.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();
Building queriescreate.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();
SQL GenerationString 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();
Fetching results: Recordcreate.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();
Fetching results: TableRecordcreate.selectFrom(BOOK)
.where(BOOK.PUBLISHED_IN.equal(1948))
.orderBy(BOOK.TITLE.asc()).limit(10).offset(100)
.fetch();
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
Fetching results: CSVcreate.selectFrom(BOOK)
.where(BOOK.PUBLISHED_IN.equal(1948))
.orderBy(BOOK.TITLE.asc()).limit(10).offset(100)
.fetch().formatCSV(‘,’,””);
Fetching results: JSONcreate.selectFrom(BOOK)
.where(BOOK.PUBLISHED_IN.equal(1948))
.orderBy(BOOK.TITLE.asc()).limit(10).offset(100)
.fetch().formatJSON();
Fetching results: XMLcreate.selectFrom(BOOK)
.where(BOOK.PUBLISHED_IN.equal(1948))
.orderBy(BOOK.TITLE.asc()).limit(10).offset(100)
.fetch().formatXML();
Fetching results: HTMLcreate.selectFrom(BOOK)
.where(BOOK.PUBLISHED_IN.equal(1948))
.orderBy(BOOK.TITLE.asc()).limit(10).offset(100)
.fetch().formatHTML();
Fetching results: POJOscreate.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);
Fetching results: Mapscreate.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();
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();
Records: updateBookRecord 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();
Records: deleteBookRecord 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, and add some new ones:
modify(books);
addMore(books);
// Batch-update and/or insert all of the above books
create.batchStore(books);
Records: update using a query
create.update(BOOK) .set(BOOK.IS_BESTSELLER, 1) .where(BOOK.SELLED_COPIES.greater(100000)) .execute();
Q&A!
any questions?!