From 32f4eeef0207f19f217c6c92b78e906fb6b65ed6 Mon Sep 17 00:00:00 2001 From: Krzysztof Majewski Date: Fri, 25 Sep 2020 23:39:32 +0200 Subject: [PATCH] BAEL-4520 Getting Started with jOOQ (#10086) * BAEL-4520 Getting Started with jOOQ * add generated sources * remove maven files * create tests Co-authored-by: Krzysztof Majewski --- persistence-modules/jooq/pom.xml | 46 ++++ .../src/main/java/com/baeldung/jooq/Crud.java | 57 ++++ .../java/com/baeldung/jooq/CrudExamples.java | 117 ++++++++ .../baeldung/jooq/model/DefaultCatalog.java | 44 +++ .../java/com/baeldung/jooq/model/Keys.java | 48 ++++ .../java/com/baeldung/jooq/model/Public.java | 59 ++++ .../java/com/baeldung/jooq/model/Tables.java | 25 ++ .../baeldung/jooq/model/tables/Article.java | 159 +++++++++++ .../baeldung/jooq/model/tables/Author.java | 149 ++++++++++ .../model/tables/records/ArticleRecord.java | 218 +++++++++++++++ .../model/tables/records/AuthorRecord.java | 217 +++++++++++++++ .../java/com/baeldung/jooq/CrudLiveTest.java | 257 ++++++++++++++++++ persistence-modules/pom.xml | 1 + 13 files changed, 1397 insertions(+) create mode 100644 persistence-modules/jooq/pom.xml create mode 100644 persistence-modules/jooq/src/main/java/com/baeldung/jooq/Crud.java create mode 100644 persistence-modules/jooq/src/main/java/com/baeldung/jooq/CrudExamples.java create mode 100644 persistence-modules/jooq/src/main/java/com/baeldung/jooq/model/DefaultCatalog.java create mode 100644 persistence-modules/jooq/src/main/java/com/baeldung/jooq/model/Keys.java create mode 100644 persistence-modules/jooq/src/main/java/com/baeldung/jooq/model/Public.java create mode 100644 persistence-modules/jooq/src/main/java/com/baeldung/jooq/model/Tables.java create mode 100644 persistence-modules/jooq/src/main/java/com/baeldung/jooq/model/tables/Article.java create mode 100644 persistence-modules/jooq/src/main/java/com/baeldung/jooq/model/tables/Author.java create mode 100644 persistence-modules/jooq/src/main/java/com/baeldung/jooq/model/tables/records/ArticleRecord.java create mode 100644 persistence-modules/jooq/src/main/java/com/baeldung/jooq/model/tables/records/AuthorRecord.java create mode 100644 persistence-modules/jooq/src/test/java/com/baeldung/jooq/CrudLiveTest.java diff --git a/persistence-modules/jooq/pom.xml b/persistence-modules/jooq/pom.xml new file mode 100644 index 0000000000..f0c5a27a96 --- /dev/null +++ b/persistence-modules/jooq/pom.xml @@ -0,0 +1,46 @@ + + + 4.0.0 + jooq + 0.0.1-SNAPSHOT + jooq-examples + jar + jOOQ Examples + + + com.baeldung + persistence-modules + 1.0.0-SNAPSHOT + + + + + org.jooq + jooq + 3.13.4 + + + org.jooq + jooq-meta + 3.13.4 + + + org.jooq + jooq-codegen + 3.13.4 + + + org.postgresql + postgresql + 42.2.16 + + + com.h2database + h2 + 1.4.200 + + + + diff --git a/persistence-modules/jooq/src/main/java/com/baeldung/jooq/Crud.java b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/Crud.java new file mode 100644 index 0000000000..0427b71c25 --- /dev/null +++ b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/Crud.java @@ -0,0 +1,57 @@ +package com.baeldung.jooq; + +import org.jooq.Condition; +import org.jooq.DSLContext; +import org.jooq.Field; +import org.jooq.Record; +import org.jooq.Result; +import org.jooq.SelectFieldOrAsterisk; +import org.jooq.Table; +import org.jooq.UpdatableRecord; + +import java.util.Map; + +public class Crud { + + public static > void save(UpdatableRecord record) { + record.store(); + } + + public static Result getAll(DSLContext context, Table table) { + return context.select() + .from(table) + .fetch(); + } + + public static Result getFields(DSLContext context, Table table, SelectFieldOrAsterisk... fields) { + return context.select(fields) + .from(table) + .fetch(); + } + + public static R getOne(DSLContext context, Table table, Condition condition) { + return context.fetchOne(table, condition); + } + + public static void update(DSLContext context, Table table, Map, T> values, Condition condition) { + context.update(table) + .set(values) + .where(condition) + .execute(); + } + + public static > void update(UpdatableRecord record) { + record.update(); + } + + public static void delete(DSLContext context, Table table, Condition condition) { + context.delete(table) + .where(condition) + .execute(); + } + + public static > void delete(UpdatableRecord record) { + record.delete(); + } + +} diff --git a/persistence-modules/jooq/src/main/java/com/baeldung/jooq/CrudExamples.java b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/CrudExamples.java new file mode 100644 index 0000000000..87a7b6439e --- /dev/null +++ b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/CrudExamples.java @@ -0,0 +1,117 @@ +package com.baeldung.jooq; + +import com.baeldung.jooq.model.tables.Article; +import com.baeldung.jooq.model.tables.Author; +import com.baeldung.jooq.model.tables.records.ArticleRecord; +import com.baeldung.jooq.model.tables.records.AuthorRecord; +import org.jooq.DSLContext; +import org.jooq.Field; +import org.jooq.Record; +import org.jooq.Result; +import org.jooq.SQLDialect; +import org.jooq.impl.DSL; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.util.HashMap; + +import static com.baeldung.jooq.Crud.delete; +import static com.baeldung.jooq.Crud.getAll; +import static com.baeldung.jooq.Crud.getFields; +import static com.baeldung.jooq.Crud.getOne; +import static com.baeldung.jooq.Crud.save; +import static com.baeldung.jooq.Crud.update; + +public class CrudExamples { + + public void crudExamples() throws SQLException { + String userName = "username"; + String password = "password"; + String url = "jdbc:postgresql://db_url:5432/baeldung_database"; + + Connection conn = DriverManager.getConnection(url, userName, password); + DSLContext context = DSL.using(conn, SQLDialect.POSTGRES); + + createValues(context); + readValues(context); + updateValues(context); + deleteValues(context); + } + + private void createValues(DSLContext context) { + ArticleRecord article = context.newRecord(Article.ARTICLE); + + article.setId(2); + article.setTitle("jOOQ examples"); + article.setDescription("A few examples of jOOQ CRUD operations"); + article.setAuthorId(1); + + save(article); + + AuthorRecord author = context.newRecord(Author.AUTHOR); + author.setId(1); + author.setFirstName("John"); + author.setLastName("Smith"); + author.setAge(40); + + save(author); + } + + private void readValues(DSLContext context) { + Result authors = getAll( + context, + Author.AUTHOR + ); + + authors.forEach(author -> { + Integer id = author.getValue(Author.AUTHOR.ID); + String firstName = author.getValue(Author.AUTHOR.FIRST_NAME); + String lastName = author.getValue(Author.AUTHOR.LAST_NAME); + Integer age = author.getValue(Author.AUTHOR.AGE); + System.out.printf("Author %s %s has id: %d and age: %d%n", firstName, lastName, id, age); + }); + + Result articles = getFields( + context, + Author.AUTHOR, + Article.ARTICLE.ID, Article.ARTICLE.TITLE + ); + + AuthorRecord author = getOne( + context, + Author.AUTHOR, + Author.AUTHOR.ID.eq(1) + ); + } + + private void updateValues(DSLContext context) { + HashMap, String> fieldsToUpdate = new HashMap<>(); + fieldsToUpdate.put(Author.AUTHOR.FIRST_NAME, "David"); + fieldsToUpdate.put(Author.AUTHOR.LAST_NAME, "Brown"); + update( + context, + Author.AUTHOR, + fieldsToUpdate, + Author.AUTHOR.ID.eq(1) + ); + + ArticleRecord article = context.fetchOne(Article.ARTICLE, Article.ARTICLE.ID.eq(1)); + article.setTitle("A New Article Title"); + update( + article + ); + } + + private void deleteValues(DSLContext context) { + delete( + context, + Article.ARTICLE, + Article.ARTICLE.ID.eq(1) + ); + + AuthorRecord author = context.fetchOne(Author.AUTHOR, Author.AUTHOR.ID.eq(1)); + delete(author); + } + +} diff --git a/persistence-modules/jooq/src/main/java/com/baeldung/jooq/model/DefaultCatalog.java b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/model/DefaultCatalog.java new file mode 100644 index 0000000000..b18484877a --- /dev/null +++ b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/model/DefaultCatalog.java @@ -0,0 +1,44 @@ +/* + * This file is generated by jOOQ. + */ +package com.baeldung.jooq.model; + + +import org.jooq.Schema; +import org.jooq.impl.CatalogImpl; + +import java.util.Arrays; +import java.util.List; + + +/** + * This class is generated by jOOQ. + */ +@SuppressWarnings({ "all", "unchecked", "rawtypes" }) +public class DefaultCatalog extends CatalogImpl { + + private static final long serialVersionUID = 1035293962; + + /** + * The reference instance of DEFAULT_CATALOG + */ + public static final DefaultCatalog DEFAULT_CATALOG = new DefaultCatalog(); + + /** + * The schema public. + */ + public final Public PUBLIC = Public.PUBLIC; + + /** + * No further instances allowed + */ + private DefaultCatalog() { + super(""); + } + + @Override + public final List getSchemas() { + return Arrays.asList( + Public.PUBLIC); + } +} diff --git a/persistence-modules/jooq/src/main/java/com/baeldung/jooq/model/Keys.java b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/model/Keys.java new file mode 100644 index 0000000000..461ffb58c7 --- /dev/null +++ b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/model/Keys.java @@ -0,0 +1,48 @@ +/* + * This file is generated by jOOQ. + */ +package com.baeldung.jooq.model; + + +import com.baeldung.jooq.model.tables.Article; +import com.baeldung.jooq.model.tables.Author; +import com.baeldung.jooq.model.tables.records.ArticleRecord; +import com.baeldung.jooq.model.tables.records.AuthorRecord; +import org.jooq.ForeignKey; +import org.jooq.TableField; +import org.jooq.UniqueKey; +import org.jooq.impl.Internal; + + +/** + * A class modelling foreign key relationships and constraints of tables of + * the public schema. + */ +@SuppressWarnings({"all", "unchecked", "rawtypes"}) +public class Keys { + + // ------------------------------------------------------------------------- + // UNIQUE and PRIMARY KEY definitions + // ------------------------------------------------------------------------- + + public static final UniqueKey ARTICLE_PKEY = UniqueKeys0.ARTICLE_PKEY; + public static final UniqueKey AUTHOR_PKEY = UniqueKeys0.AUTHOR_PKEY; + + // ------------------------------------------------------------------------- + // FOREIGN KEY definitions + // ------------------------------------------------------------------------- + public static final ForeignKey ARTICLE__XXX = ForeignKeys0.ARTICLE__XXX; + + // ------------------------------------------------------------------------- + // [#1459] distribute members to avoid static initialisers > 64kb + // ------------------------------------------------------------------------- + + private static class UniqueKeys0 { + public static final UniqueKey ARTICLE_PKEY = Internal.createUniqueKey(Article.ARTICLE, "article_pkey", new TableField[]{Article.ARTICLE.ID}, true); + public static final UniqueKey AUTHOR_PKEY = Internal.createUniqueKey(Author.AUTHOR, "author_pkey", new TableField[]{Author.AUTHOR.ID}, true); + } + + private static class ForeignKeys0 { + public static final ForeignKey ARTICLE__XXX = Internal.createForeignKey(Keys.AUTHOR_PKEY, Article.ARTICLE, "xxx", new TableField[]{Article.ARTICLE.AUTHOR_ID}, true); + } +} diff --git a/persistence-modules/jooq/src/main/java/com/baeldung/jooq/model/Public.java b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/model/Public.java new file mode 100644 index 0000000000..02c664522b --- /dev/null +++ b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/model/Public.java @@ -0,0 +1,59 @@ +/* + * This file is generated by jOOQ. + */ +package com.baeldung.jooq.model; + +import com.baeldung.jooq.model.tables.Article; +import com.baeldung.jooq.model.tables.Author; +import org.jooq.Catalog; +import org.jooq.Table; +import org.jooq.impl.SchemaImpl; + +import java.util.Arrays; +import java.util.List; + + +/** + * This class is generated by jOOQ. + */ +@SuppressWarnings({"all", "unchecked", "rawtypes"}) +public class Public extends SchemaImpl { + + private static final long serialVersionUID = -2049410122; + + /** + * The reference instance of public + */ + public static final Public PUBLIC = new Public(); + + /** + * The table public.article. + */ + public final Article ARTICLE = Article.ARTICLE; + + /** + * The table public.author. + */ + public final Author AUTHOR = Author.AUTHOR; + + /** + * No further instances allowed + */ + private Public() { + super("public", null); + } + + + @Override + public Catalog getCatalog() { + return DefaultCatalog.DEFAULT_CATALOG; + } + + @Override + public final List> getTables() { + return Arrays.>asList( + Article.ARTICLE, + Author.AUTHOR + ); + } +} diff --git a/persistence-modules/jooq/src/main/java/com/baeldung/jooq/model/Tables.java b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/model/Tables.java new file mode 100644 index 0000000000..eb1f14e05a --- /dev/null +++ b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/model/Tables.java @@ -0,0 +1,25 @@ +/* + * This file is generated by jOOQ. + */ +package com.baeldung.jooq.model; + +import com.baeldung.jooq.model.tables.Article; +import com.baeldung.jooq.model.tables.Author; + +/** + * Convenience access to all tables in public + */ +@SuppressWarnings({"all", "unchecked", "rawtypes"}) +public class Tables { + + /** + * The table public.article. + */ + public static final Article ARTICLE = Article.ARTICLE; + + /** + * The table public.author. + */ + public static final Author AUTHOR = Author.AUTHOR; + +} diff --git a/persistence-modules/jooq/src/main/java/com/baeldung/jooq/model/tables/Article.java b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/model/tables/Article.java new file mode 100644 index 0000000000..3159c91aa8 --- /dev/null +++ b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/model/tables/Article.java @@ -0,0 +1,159 @@ +/* + * This file is generated by jOOQ. + */ +package com.baeldung.jooq.model.tables; + + +import com.baeldung.jooq.model.Keys; +import com.baeldung.jooq.model.Public; +import com.baeldung.jooq.model.tables.records.ArticleRecord; +import org.jooq.Field; +import org.jooq.ForeignKey; +import org.jooq.Name; +import org.jooq.Record; +import org.jooq.Row4; +import org.jooq.Schema; +import org.jooq.Table; +import org.jooq.TableField; +import org.jooq.TableOptions; +import org.jooq.UniqueKey; +import org.jooq.impl.DSL; +import org.jooq.impl.TableImpl; + +import java.util.Arrays; +import java.util.List; + + +/** + * This class is generated by jOOQ. + */ +@SuppressWarnings({ "all", "unchecked", "rawtypes" }) +public class Article extends TableImpl { + + private static final long serialVersionUID = -1401275800; + + /** + * The reference instance of public.article + */ + public static final Article ARTICLE = new Article(); + + /** + * The class holding records for this type + */ + @Override + public Class getRecordType() { + return ArticleRecord.class; + } + + /** + * The column public.article.id. + */ + public final TableField ID = createField(DSL.name("id"), org.jooq.impl.SQLDataType.INTEGER.nullable(false), this, ""); + + /** + * The column public.article.title. + */ + public final TableField TITLE = createField(DSL.name("title"), org.jooq.impl.SQLDataType.VARCHAR(255).nullable(false), this, ""); + + /** + * The column public.article.description. + */ + public final TableField DESCRIPTION = createField(DSL.name("description"), org.jooq.impl.SQLDataType.VARCHAR(255), this, ""); + + /** + * The column public.article.author_id. + */ + public final TableField AUTHOR_ID = createField(DSL.name("author_id"), org.jooq.impl.SQLDataType.INTEGER, this, ""); + + /** + * Create a public.article table reference + */ + public Article() { + this(DSL.name("article"), null); + } + + /** + * Create an aliased public.article table reference + */ + public Article(String alias) { + this(DSL.name(alias), ARTICLE); + } + + /** + * Create an aliased public.article table reference + */ + public Article(Name alias) { + this(alias, ARTICLE); + } + + private Article(Name alias, Table aliased) { + this(alias, aliased, null); + } + + private Article(Name alias, Table aliased, Field[] parameters) { + super(alias, null, aliased, parameters, DSL.comment(""), TableOptions.table()); + } + + public Article(Table child, ForeignKey key) { + super(child, key, ARTICLE); + } + + @Override + public Schema getSchema() { + return Public.PUBLIC; + } + + @Override + public UniqueKey getPrimaryKey() { + return Keys.ARTICLE_PKEY; + } + + @Override + public List> getKeys() { + return Arrays.>asList(Keys.ARTICLE_PKEY); + } + + @Override + public List> getReferences() { + return Arrays.>asList(Keys.ARTICLE__XXX); + } + + public Author author() { + return new Author(this, Keys.ARTICLE__XXX); + } + + @Override + public Article as(String alias) { + return new Article(DSL.name(alias), this); + } + + @Override + public Article as(Name alias) { + return new Article(alias, this); + } + + /** + * Rename this table + */ + @Override + public Article rename(String name) { + return new Article(DSL.name(name), null); + } + + /** + * Rename this table + */ + @Override + public Article rename(Name name) { + return new Article(name, null); + } + + // ------------------------------------------------------------------------- + // Row4 type methods + // ------------------------------------------------------------------------- + + @Override + public Row4 fieldsRow() { + return (Row4) super.fieldsRow(); + } +} diff --git a/persistence-modules/jooq/src/main/java/com/baeldung/jooq/model/tables/Author.java b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/model/tables/Author.java new file mode 100644 index 0000000000..9da9415109 --- /dev/null +++ b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/model/tables/Author.java @@ -0,0 +1,149 @@ +/* + * This file is generated by jOOQ. + */ +package com.baeldung.jooq.model.tables; + +import com.baeldung.jooq.model.Keys; +import com.baeldung.jooq.model.Public; +import com.baeldung.jooq.model.tables.records.AuthorRecord; +import org.jooq.Field; +import org.jooq.ForeignKey; +import org.jooq.Name; +import org.jooq.Record; +import org.jooq.Row4; +import org.jooq.Schema; +import org.jooq.Table; +import org.jooq.TableField; +import org.jooq.TableOptions; +import org.jooq.UniqueKey; +import org.jooq.impl.DSL; +import org.jooq.impl.TableImpl; + +import java.util.Arrays; +import java.util.List; + + +/** + * This class is generated by jOOQ. + */ +@SuppressWarnings({ "all", "unchecked", "rawtypes" }) +public class Author extends TableImpl { + + private static final long serialVersionUID = -798376522; + + /** + * The reference instance of public.author + */ + public static final Author AUTHOR = new Author(); + + /** + * The class holding records for this type + */ + @Override + public Class getRecordType() { + return AuthorRecord.class; + } + + /** + * The column public.author.id. + */ + public final TableField ID = createField(DSL.name("id"), org.jooq.impl.SQLDataType.INTEGER.nullable(false), AUTHOR, ""); + + /** + * The column public.author.first_name. + */ + public final TableField FIRST_NAME = createField(DSL.name("first_name"), org.jooq.impl.SQLDataType.VARCHAR(255), this, ""); + + /** + * The column public.author.last_name. + */ + public final TableField LAST_NAME = createField(DSL.name("last_name"), org.jooq.impl.SQLDataType.VARCHAR(255), this, ""); + + /** + * The column public.author.age. + */ + public final TableField AGE = createField(DSL.name("age"), org.jooq.impl.SQLDataType.INTEGER, this, ""); + + /** + * Create a public.author table reference + */ + public Author() { + this(DSL.name("author"), null); + } + + /** + * Create an aliased public.author table reference + */ + public Author(String alias) { + this(DSL.name(alias), AUTHOR); + } + + /** + * Create an aliased public.author table reference + */ + public Author(Name alias) { + this(alias, AUTHOR); + } + + private Author(Name alias, Table aliased) { + this(alias, aliased, null); + } + + private Author(Name alias, Table aliased, Field[] parameters) { + super(alias, null, aliased, parameters, DSL.comment(""), TableOptions.table()); + } + + public Author(Table child, ForeignKey key) { + super(child, key, AUTHOR); + } + + @Override + public Schema getSchema() { + return Public.PUBLIC; + } + + @Override + public UniqueKey getPrimaryKey() { + return Keys.AUTHOR_PKEY; + } + + @Override + public List> getKeys() { + return Arrays.>asList(Keys.AUTHOR_PKEY); + } + + @Override + public Author as(String alias) { + return new Author(DSL.name(alias), this); + } + + @Override + public Author as(Name alias) { + return new Author(alias, this); + } + + /** + * Rename this table + */ + @Override + public Author rename(String name) { + return new Author(DSL.name(name), null); + } + + /** + * Rename this table + */ + @Override + public Author rename(Name name) { + return new Author(name, null); + } + + // ------------------------------------------------------------------------- + // Row4 type methods + // ------------------------------------------------------------------------- + + @Override + public Row4 fieldsRow() { + return (Row4) super.fieldsRow(); + } +} diff --git a/persistence-modules/jooq/src/main/java/com/baeldung/jooq/model/tables/records/ArticleRecord.java b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/model/tables/records/ArticleRecord.java new file mode 100644 index 0000000000..cee17fe716 --- /dev/null +++ b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/model/tables/records/ArticleRecord.java @@ -0,0 +1,218 @@ +/* + * This file is generated by jOOQ. + */ +package com.baeldung.jooq.model.tables.records; + + +import com.baeldung.jooq.model.tables.Article; + +import org.jooq.Field; +import org.jooq.Record1; +import org.jooq.Record4; +import org.jooq.Row4; +import org.jooq.impl.UpdatableRecordImpl; + + +/** + * This class is generated by jOOQ. + */ +@SuppressWarnings({ "all", "unchecked", "rawtypes" }) +public class ArticleRecord extends UpdatableRecordImpl implements Record4 { + + private static final long serialVersionUID = 1297442421; + + /** + * Setter for public.article.id. + */ + public void setId(Integer value) { + set(0, value); + } + + /** + * Getter for public.article.id. + */ + public Integer getId() { + return (Integer) get(0); + } + + /** + * Setter for public.article.title. + */ + public void setTitle(String value) { + set(1, value); + } + + /** + * Getter for public.article.title. + */ + public String getTitle() { + return (String) get(1); + } + + /** + * Setter for public.article.description. + */ + public void setDescription(String value) { + set(2, value); + } + + /** + * Getter for public.article.description. + */ + public String getDescription() { + return (String) get(2); + } + + /** + * Setter for public.article.author_id. + */ + public void setAuthorId(Integer value) { + set(3, value); + } + + /** + * Getter for public.article.author_id. + */ + public Integer getAuthorId() { + return (Integer) get(3); + } + + // ------------------------------------------------------------------------- + // Primary key information + // ------------------------------------------------------------------------- + + @Override + public Record1 key() { + return (Record1) super.key(); + } + + // ------------------------------------------------------------------------- + // Record4 type implementation + // ------------------------------------------------------------------------- + + @Override + public Row4 fieldsRow() { + return (Row4) super.fieldsRow(); + } + + @Override + public Row4 valuesRow() { + return (Row4) super.valuesRow(); + } + + @Override + public Field field1() { + return Article.ARTICLE.ID; + } + + @Override + public Field field2() { + return Article.ARTICLE.TITLE; + } + + @Override + public Field field3() { + return Article.ARTICLE.DESCRIPTION; + } + + @Override + public Field field4() { + return Article.ARTICLE.AUTHOR_ID; + } + + @Override + public Integer component1() { + return getId(); + } + + @Override + public String component2() { + return getTitle(); + } + + @Override + public String component3() { + return getDescription(); + } + + @Override + public Integer component4() { + return getAuthorId(); + } + + @Override + public Integer value1() { + return getId(); + } + + @Override + public String value2() { + return getTitle(); + } + + @Override + public String value3() { + return getDescription(); + } + + @Override + public Integer value4() { + return getAuthorId(); + } + + @Override + public ArticleRecord value1(Integer value) { + setId(value); + return this; + } + + @Override + public ArticleRecord value2(String value) { + setTitle(value); + return this; + } + + @Override + public ArticleRecord value3(String value) { + setDescription(value); + return this; + } + + @Override + public ArticleRecord value4(Integer value) { + setAuthorId(value); + return this; + } + + @Override + public ArticleRecord values(Integer value1, String value2, String value3, Integer value4) { + value1(value1); + value2(value2); + value3(value3); + value4(value4); + return this; + } + + // ------------------------------------------------------------------------- + // Constructors + // ------------------------------------------------------------------------- + + /** + * Create a detached ArticleRecord + */ + public ArticleRecord() { + super(Article.ARTICLE); + } + + /** + * Create a detached, initialised ArticleRecord + */ + public ArticleRecord(Integer id, String title, String description, Integer authorId) { + super(Article.ARTICLE); + + set(0, id); + set(1, title); + set(2, description); + set(3, authorId); + } +} diff --git a/persistence-modules/jooq/src/main/java/com/baeldung/jooq/model/tables/records/AuthorRecord.java b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/model/tables/records/AuthorRecord.java new file mode 100644 index 0000000000..365de20747 --- /dev/null +++ b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/model/tables/records/AuthorRecord.java @@ -0,0 +1,217 @@ +/* + * This file is generated by jOOQ. + */ +package com.baeldung.jooq.model.tables.records; + + +import com.baeldung.jooq.model.tables.Author; +import org.jooq.Field; +import org.jooq.Record1; +import org.jooq.Record4; +import org.jooq.Row4; +import org.jooq.impl.UpdatableRecordImpl; + + +/** + * This class is generated by jOOQ. + */ +@SuppressWarnings({ "all", "unchecked", "rawtypes" }) +public class AuthorRecord extends UpdatableRecordImpl implements Record4 { + + private static final long serialVersionUID = -2120822720; + + /** + * Setter for public.author.id. + */ + public void setId(Integer value) { + set(0, value); + } + + /** + * Getter for public.author.id. + */ + public Integer getId() { + return (Integer) get(0); + } + + /** + * Setter for public.author.first_name. + */ + public void setFirstName(String value) { + set(1, value); + } + + /** + * Getter for public.author.first_name. + */ + public String getFirstName() { + return (String) get(1); + } + + /** + * Setter for public.author.last_name. + */ + public void setLastName(String value) { + set(2, value); + } + + /** + * Getter for public.author.last_name. + */ + public String getLastName() { + return (String) get(2); + } + + /** + * Setter for public.author.age. + */ + public void setAge(Integer value) { + set(3, value); + } + + /** + * Getter for public.author.age. + */ + public Integer getAge() { + return (Integer) get(3); + } + + // ------------------------------------------------------------------------- + // Primary key information + // ------------------------------------------------------------------------- + + @Override + public Record1 key() { + return (Record1) super.key(); + } + + // ------------------------------------------------------------------------- + // Record4 type implementation + // ------------------------------------------------------------------------- + + @Override + public Row4 fieldsRow() { + return (Row4) super.fieldsRow(); + } + + @Override + public Row4 valuesRow() { + return (Row4) super.valuesRow(); + } + + @Override + public Field field1() { + return Author.AUTHOR.ID; + } + + @Override + public Field field2() { + return Author.AUTHOR.FIRST_NAME; + } + + @Override + public Field field3() { + return Author.AUTHOR.LAST_NAME; + } + + @Override + public Field field4() { + return Author.AUTHOR.AGE; + } + + @Override + public Integer component1() { + return getId(); + } + + @Override + public String component2() { + return getFirstName(); + } + + @Override + public String component3() { + return getLastName(); + } + + @Override + public Integer component4() { + return getAge(); + } + + @Override + public Integer value1() { + return getId(); + } + + @Override + public String value2() { + return getFirstName(); + } + + @Override + public String value3() { + return getLastName(); + } + + @Override + public Integer value4() { + return getAge(); + } + + @Override + public AuthorRecord value1(Integer value) { + setId(value); + return this; + } + + @Override + public AuthorRecord value2(String value) { + setFirstName(value); + return this; + } + + @Override + public AuthorRecord value3(String value) { + setLastName(value); + return this; + } + + @Override + public AuthorRecord value4(Integer value) { + setAge(value); + return this; + } + + @Override + public AuthorRecord values(Integer value1, String value2, String value3, Integer value4) { + value1(value1); + value2(value2); + value3(value3); + value4(value4); + return this; + } + + // ------------------------------------------------------------------------- + // Constructors + // ------------------------------------------------------------------------- + + /** + * Create a detached AuthorRecord + */ + public AuthorRecord() { + super(Author.AUTHOR); + } + + /** + * Create a detached, initialised AuthorRecord + */ + public AuthorRecord(Integer id, String firstName, String lastName, Integer age) { + super(Author.AUTHOR); + + set(0, id); + set(1, firstName); + set(2, lastName); + set(3, age); + } +} diff --git a/persistence-modules/jooq/src/test/java/com/baeldung/jooq/CrudLiveTest.java b/persistence-modules/jooq/src/test/java/com/baeldung/jooq/CrudLiveTest.java new file mode 100644 index 0000000000..d41344c08e --- /dev/null +++ b/persistence-modules/jooq/src/test/java/com/baeldung/jooq/CrudLiveTest.java @@ -0,0 +1,257 @@ +package com.baeldung.jooq; + +import com.baeldung.jooq.model.tables.Article; +import com.baeldung.jooq.model.tables.Author; +import com.baeldung.jooq.model.tables.records.ArticleRecord; +import org.jooq.DSLContext; +import org.jooq.Field; +import org.jooq.Record; +import org.jooq.Result; +import org.jooq.SQLDialect; +import org.jooq.impl.DSL; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.util.HashMap; + +import static com.baeldung.jooq.Crud.delete; +import static com.baeldung.jooq.Crud.getAll; +import static com.baeldung.jooq.Crud.getFields; +import static com.baeldung.jooq.Crud.getOne; +import static com.baeldung.jooq.Crud.save; +import static com.baeldung.jooq.Crud.update; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +public class CrudLiveTest { + + static DSLContext context; + + @BeforeClass + public static void setup() throws SQLException { + Connection conn = DriverManager.getConnection("jdbc:h2:mem:tes;INIT=CREATE SCHEMA IF NOT EXISTS \"public\""); + context = DSL.using(conn, SQLDialect.H2); + + context.createTable(Author.AUTHOR) + .columns( + Author.AUTHOR.ID, + Author.AUTHOR.FIRST_NAME, + Author.AUTHOR.LAST_NAME, + Author.AUTHOR.AGE + ) + .execute(); + context.createTable(Article.ARTICLE) + .columns( + Article.ARTICLE.ID, + Article.ARTICLE.TITLE, + Article.ARTICLE.DESCRIPTION, + Article.ARTICLE.AUTHOR_ID + ) + .execute(); + } + + @Before + public void cleanup() { + context.truncateTable(Article.ARTICLE) + .execute(); + context.truncateTable(Author.AUTHOR) + .execute(); + } + + @Test + public void givenArticleRecord_whenSave_thenNewRecordInDb() { + // given + ArticleRecord article = article(); + + // when + save(article); + + // then + ArticleRecord savedArticle = getOne( + context, + Article.ARTICLE, + Article.ARTICLE.ID.eq(1) + ); + assertEquals(savedArticle.getId().intValue(), 1); + assertEquals(savedArticle.getTitle(), "jOOQ examples"); + assertEquals(savedArticle.getDescription(), "A few examples of jOOQ CRUD operations"); + assertEquals(savedArticle.getAuthorId().intValue(), 1); + } + + @Test + public void givenArticleRecord_whenGetAll_thenValidOneRecord() { + // given + ArticleRecord article = article(); + save(article); + + // when + Result articles = getAll( + context, + Article.ARTICLE + ); + + // then + assertEquals(articles.size(), 1); + + Record record = articles.get(0); + ArticleRecord savedArticle = record.into(Article.ARTICLE); + + assertEquals(savedArticle.getId().intValue(), 1); + assertEquals(savedArticle.getTitle(), "jOOQ examples"); + assertEquals(savedArticle.getDescription(), "A few examples of jOOQ CRUD operations"); + assertEquals(savedArticle.getAuthorId().intValue(), 1); + } + + @Test + public void givenArticleRecord_whenGetOnlyTitles_thenValidOneValue() { + // given + ArticleRecord article = article(); + save(article); + + // when + Result articles = getFields( + context, + Article.ARTICLE, + Article.ARTICLE.TITLE + ); + + // then + assertEquals(articles.size(), 1); + + Record record = articles.get(0); + ArticleRecord savedArticle = record.into(Article.ARTICLE); + + assertNull(savedArticle.getId()); + assertEquals(savedArticle.getTitle(), "jOOQ examples"); + assertNull(savedArticle.getDescription()); + assertNull(savedArticle.getAuthorId()); + } + + @Test + public void givenArticleRecord_whenGetOne_thenValidRecord() { + // given + ArticleRecord article = article(); + save(article); + + // when + ArticleRecord savedArticle = getOne( + context, + Article.ARTICLE, + Article.ARTICLE.ID.eq(1) + ); + + // then + assertEquals(savedArticle.getId().intValue(), 1); + assertEquals(savedArticle.getTitle(), "jOOQ examples"); + assertEquals(savedArticle.getDescription(), "A few examples of jOOQ CRUD operations"); + assertEquals(savedArticle.getAuthorId().intValue(), 1); + } + + @Test + public void givenArticleRecord_whenUpdateById_thenChangedValuesDbTable() { + // given + ArticleRecord article = article(); + save(article); + + HashMap, String> updateFields = new HashMap<>(); + updateFields.put(Article.ARTICLE.TITLE, "new title"); + updateFields.put(Article.ARTICLE.DESCRIPTION, "new description"); + + // when + update( + context, + Article.ARTICLE, + updateFields, + Article.ARTICLE.ID.eq(1) + ); + + // then + ArticleRecord updatedArticle = getOne( + context, + Article.ARTICLE, + Article.ARTICLE.ID.eq(1) + ); + assertEquals(updatedArticle.getId().intValue(), 1); + assertEquals(updatedArticle.getTitle(), "new title"); + assertEquals(updatedArticle.getDescription(), "new description"); + assertEquals(updatedArticle.getAuthorId().intValue(), 1); + } + + @Test + public void givenArticleRecord_whenUpdate_thenChangedValuesDbTable() { + // given + ArticleRecord article = article(); + save(article); + + article.setTitle("new title"); + article.setDescription("new description"); + + // when + update(article); + + // then + ArticleRecord updatedArticle = getOne( + context, + Article.ARTICLE, + Article.ARTICLE.ID.eq(1) + ); + assertEquals(updatedArticle.getId().intValue(), 1); + assertEquals(updatedArticle.getTitle(), "new title"); + assertEquals(updatedArticle.getDescription(), "new description"); + assertEquals(updatedArticle.getAuthorId().intValue(), 1); + } + + @Test + public void givenArticleRecord_whenDelete_thenEmptyDbTable() { + // given + ArticleRecord article = article(); + save(article); + + // when + delete(article); + + // then + Result articles = getAll( + context, + Article.ARTICLE + ); + assertTrue(articles.isEmpty()); + } + + @Test + public void givenArticleRecord_whenDeleteById_thenEmptyDbTable() { + // given + ArticleRecord article = article(); + save(article); + + // when + delete( + context, + Article.ARTICLE, + Article.ARTICLE.ID.eq(1) + ); + + // then + Result articles = getAll( + context, + Article.ARTICLE + ); + assertTrue(articles.isEmpty()); + } + + private ArticleRecord article() { + ArticleRecord article = context.newRecord(Article.ARTICLE); + article.setId(1); + article.setTitle("jOOQ examples"); + article.setDescription("A few examples of jOOQ CRUD operations"); + article.setAuthorId(1); + + return article; + } + +} diff --git a/persistence-modules/pom.xml b/persistence-modules/pom.xml index def2deb941..590e5da76e 100644 --- a/persistence-modules/pom.xml +++ b/persistence-modules/pom.xml @@ -39,6 +39,7 @@ java-jpa-2 java-mongodb jnosql + jooq jpa-hibernate-cascade-type liquibase orientdb