Merge branch 'eugenp:master' into master

This commit is contained in:
Wynn Teo 2024-04-09 09:11:34 +08:00 committed by GitHub
commit 020914dbf9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
220 changed files with 5968 additions and 948 deletions

View File

@ -13,4 +13,22 @@
<version>1.0.0-SNAPSHOT</version>
</parent>
<properties>
<jmh.version>1.35</jmh.version>
</properties>
<dependencies>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>${jmh.version}</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>${jmh.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,50 @@
package com.baeldung.algorithms.perfectnumber;
import java.util.stream.IntStream;
class PerfectNumber {
public static boolean isPerfectBruteForce(int number) {
int sum = 0;
for (int i = 1; i <= number / 2; i++) {
if (number % i == 0) {
sum += i;
}
}
return sum == number;
}
public static boolean isPerfectStream(int number) {
int sum = IntStream.rangeClosed(2, (int) Math.sqrt(number))
.filter(test -> number % test == 0)
.reduce(1, (s, test) -> s + test + (number / test));
return sum == number;
}
public static boolean isPerfectEuclidEuler(int number) {
int p = 2;
int perfectNumber = (int) (Math.pow(2, p - 1) * (Math.pow(2, p) - 1));
while (perfectNumber <= number) {
if (perfectNumber == number) {
return true;
}
p++;
perfectNumber = (int) (Math.pow(2, p - 1) * (Math.pow(2, p) - 1));
}
return false;
}
public static boolean isPerfectEuclidEulerUsingShift(int number) {
int p = 2;
int perfectNumber = (2 << (p - 1)) * ((2 << p) - 1);
while (perfectNumber <= number) {
if (perfectNumber == number) {
return true;
}
p++;
perfectNumber = (2 << (p - 1)) * ((2 << p) - 1);
}
return false;
}
}

View File

@ -0,0 +1,41 @@
package com.baeldung.algorithms.perfectnumber;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
@State(Scope.Benchmark)
public class PerfectNumberBenchmark {
@Benchmark
public boolean bruteForceBenchmark() {
return PerfectNumber.isPerfectBruteForce(33550336);
}
@Benchmark
public boolean streamBenchmark() {
return PerfectNumber.isPerfectStream(33550336);
}
@Benchmark
public boolean euclidEulerBenchmark() {
return PerfectNumber.isPerfectEuclidEuler(33550336);
}
@Benchmark
public boolean euclidEulerUsingShiftBenchmark() {
return PerfectNumber.isPerfectEuclidEulerUsingShift(33550336);
}
public static void main(String[] args) throws Exception {
Options options = new OptionsBuilder()
.include(PerfectNumberBenchmark.class.getSimpleName())
.forks(1)
.build();
new Runner(options).run();
}
}

View File

@ -0,0 +1,68 @@
package com.baeldung.algorithms.perfectnumber;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
class PerfectNumberUnitTest {
@Test
void givenPerfectNumber_whenCheckingIsPerfectBruteForce_thenReturnTrue() {
assertTrue(PerfectNumber.isPerfectBruteForce(6));
}
@Test
void givenNonPerfectNumber_whenCheckingIsPerfectBruteForce_thenReturnFalse() {
assertFalse(PerfectNumber.isPerfectBruteForce(10));
}
@Test
void givenNegativeNumber_whenCheckingIsPerfectBruteForce_thenReturnFalse() {
assertFalse(PerfectNumber.isPerfectBruteForce(-28));
}
@Test
void givenPerfectNumber_whenCheckingIsPerfectStream_thenReturnTrue() {
assertTrue(PerfectNumber.isPerfectStream(28));
}
@Test
void givenNonPerfectNumber_whenCheckingIsPerfectStream_thenReturnFalse() {
assertFalse(PerfectNumber.isPerfectStream(10));
}
@Test
void givenNegativeNumber_whenCheckingIsPerfectStream_thenReturnFalse() {
assertFalse(PerfectNumber.isPerfectStream(-6));
}
@Test
void givenPerfectNumber_whenCheckingIsPerfectEuclidEuler_thenReturnTrue() {
assertTrue(PerfectNumber.isPerfectEuclidEuler(28));
}
@Test
void givenNonPerfectNumber_whenCheckingIsPerfectEuclidEuler_thenReturnFalse() {
assertFalse(PerfectNumber.isPerfectEuclidEuler(10));
}
@Test
void givenNegativeNumber_whenCheckingIsPerfectEuclidEuler_thenReturnFalse() {
assertFalse(PerfectNumber.isPerfectEuclidEuler(-6));
}
@Test
void givenPerfectNumber_whenCheckingIsPerfectEuclidEulerUsingShift_thenReturnTrue() {
assertTrue(PerfectNumber.isPerfectEuclidEulerUsingShift(28));
}
@Test
void givenNonPerfectNumber_whenCheckingIsPerfectEuclidEulerUsingShift_thenReturnFalse() {
assertFalse(PerfectNumber.isPerfectEuclidEulerUsingShift(10));
}
@Test
void givenNegativeNumber_whenCheckingIsPerfectEuclidEulerUsingShift_thenReturnFalse() {
assertFalse(PerfectNumber.isPerfectEuclidEulerUsingShift(-6));
}
}

View File

@ -9,7 +9,6 @@
- [Skipping the First Iteration in Java](https://www.baeldung.com/java-skip-first-iteration)
- [Remove Elements From a Queue Using Loop](https://www.baeldung.com/java-remove-elements-queue)
- [Intro to Vector Class in Java](https://www.baeldung.com/java-vector-guide)
- [HashSet toArray() Method in Java](https://www.baeldung.com/java-hashset-toarray)
- [Time Complexity of Java Collections Sort in Java](https://www.baeldung.com/java-time-complexity-collections-sort)
- [Check if List Contains at Least One Enum](https://www.baeldung.com/java-list-check-enum-presence)
- [Comparison of for Loops and Iterators](https://www.baeldung.com/java-for-loops-vs-iterators)

View File

@ -55,8 +55,8 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>9</source>
<target>9</target>
<source>16</source>
<target>16</target>
</configuration>
</plugin>
</plugins>

View File

@ -0,0 +1,5 @@
=========
## Core Java Collections Cookbooks and Examples
### Relevant Articles:

View File

@ -0,0 +1,71 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>core-java-collections-6</artifactId>
<packaging>jar</packaging>
<name>core-java-collections-6</name>
<parent>
<groupId>com.baeldung.core-java-modules</groupId>
<artifactId>core-java-modules</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-runner</artifactId>
<version>${junit-platform.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.roaringbitmap</groupId>
<artifactId>RoaringBitmap</artifactId>
<version>${roaringbitmap.version}</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>${jmh.version}</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>${jmh.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>9</source>
<target>9</target>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<junit.version>5.9.2</junit.version>
<roaringbitmap.version>0.9.38</roaringbitmap.version>
<jmh.version>1.36</jmh.version>
</properties>
</project>

View File

@ -0,0 +1,71 @@
package com.baeldung.listiteration;
import org.junit.jupiter.api.Test;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.junit.jupiter.api.Assertions.assertIterableEquals;
public class ListIterationUnitTest {
List<String> programmingLanguages = new ArrayList<>(List.of("Java", "Python", "C++"));
List<Integer> numbers = new ArrayList<>(List.of(1, 2, 3));
@Test
public void givenStringList_whenAddElementWithListIterator_thenModifiedList() {
ListIterator<String> listIterator = programmingLanguages.listIterator();
while (listIterator.hasNext()) {
String language = listIterator.next();
if (language.equals("Python")) {
listIterator.add("JavaScript");
}
}
assertIterableEquals(Arrays.asList("Java", "Python", "JavaScript", "C++"), programmingLanguages);
}
@Test
public void givenNumericalList_whenMultiplyElementWithListIterator_thenModifiedList() {
ListIterator<Integer> listIterator = numbers.listIterator();
while (listIterator.hasNext()) {
int num = listIterator.next();
if (num == 2) {
listIterator.add(num * 10);
}
}
assertIterableEquals(Arrays.asList(1, 2, 20, 3), numbers);
}
@Test
public void givenStringList_whenAddElementWithEnhancedForLoopAndCopy_thenModifiedList() {
List<String> copyOfWords = new ArrayList<>(programmingLanguages);
for (String word : copyOfWords) {
programmingLanguages.add(word.toUpperCase()); // Modified: Convert to uppercase
}
assertIterableEquals(Arrays.asList("Java", "Python", "C++", "JAVA", "PYTHON", "C++"), programmingLanguages);
}
@Test
public void givenNumericalList_whenMultiplyElementWithEnhancedForLoopAndCopy_thenModifiedList() {
List<Integer> copyOfNumbers = new ArrayList<>(numbers);
for (int num : copyOfNumbers) {
numbers.add(num * 2);
}
assertIterableEquals(Arrays.asList(1, 2, 3, 2, 4, 6), numbers);
}
@Test
public void givenStringList_whenConvertToUpperCaseWithJava8Stream_thenModifiedList() {
programmingLanguages = programmingLanguages.stream().map(String::toUpperCase).collect(Collectors.toList());
assertIterableEquals(Arrays.asList("JAVA", "PYTHON", "C++"), programmingLanguages);
}
@Test
public void givenNumericalList_whenMultiplyByThreeWithJava8Stream_thenModifiedList() {
numbers = numbers.stream().map(num -> num * 3).collect(Collectors.toList());
assertIterableEquals(Arrays.asList(3, 6, 9), numbers);
}
}

View File

@ -5,3 +5,4 @@ This module contains articles about conversions among Collection types in Java.
### Relevant Articles:
- [Converting HashMap Values to an ArrayList in Java](https://www.baeldung.com/java-hashmap-arraylist)
- [Joining a List<String> in Java With Commas and “and”](https://www.baeldung.com/java-string-concatenation-natural-language)
- [HashSet toArray() Method in Java](https://www.baeldung.com/java-hashset-toarray)

View File

@ -1,59 +0,0 @@
package com.baeldung.java.listInitialization;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import lombok.extern.java.Log;
import org.junit.Assert;
import org.junit.Test;
@Log
public class ListInitializationUnitTest {
@Test
public void givenAnonymousInnerClass_thenInitialiseList() {
List<String> cities = new ArrayList() {
{
add("New York");
add("Rio");
add("Tokyo");
}
};
Assert.assertTrue(cities.contains("New York"));
}
@Test
public void givenArraysAsList_thenInitialiseList() {
List<String> list = Arrays.asList("foo", "bar");
Assert.assertTrue(list.contains("foo"));
}
@Test(expected = UnsupportedOperationException.class)
public void givenArraysAsList_whenAdd_thenUnsupportedException() {
List<String> list = Arrays.asList("foo", "bar");
list.add("baz");
}
@Test
public void givenArraysAsList_whenCreated_thenShareReference() {
String[] array = { "foo", "bar" };
List<String> list = Arrays.asList(array);
array[0] = "baz";
Assert.assertEquals("baz", list.get(0));
}
@Test
public void givenStream_thenInitializeList() {
List<String> list = Stream.of("foo", "bar")
.collect(Collectors.toList());
Assert.assertTrue(list.contains("foo"));
}
}

View File

@ -0,0 +1,91 @@
package com.baeldung.java.listinitialization;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.junit.Test;
import lombok.extern.java.Log;
@Log
public class ListInitializationUnitTest {
@Test
public void givenAnonymousInnerClass_thenInitialiseList() {
List<String> cities = new ArrayList() {
{
add("New York");
add("Rio");
add("Tokyo");
}
};
assertTrue(cities.contains("New York"));
}
@Test
public void givenArraysAsList_thenInitialiseList() {
List<String> list = Arrays.asList("foo", "bar");
assertTrue(list.contains("foo"));
}
@Test(expected = UnsupportedOperationException.class)
public void givenArraysAsList_whenAdd_thenUnsupportedException() {
List<String> list = Arrays.asList("foo", "bar");
list.add("baz");
}
@Test
public void givenArraysAsList_whenUsingArrayListConstructor_thenWeCanAddOrRemove() {
List<String> list = new ArrayList<>(Arrays.asList("foo", "bar"));
list.add("baz");
assertEquals(List.of("foo", "bar","baz"), list);
list.remove("baz");
assertEquals(List.of("foo", "bar"), list);
}
@Test
public void givenArraysAsList_whenCreated_thenShareReference() {
String[] array = { "foo", "bar" };
List<String> list = Arrays.asList(array);
array[0] = "baz";
assertEquals("baz", list.get(0));
}
@Test
public void givenIntNumbers_whenRequiredLong_thenCastAutomatically() {
int intNum = 42;
long longNum = intNum;
assertEquals(42L, longNum);
}
@Test
public void givenArrayAsList_whenRequiredLongList_thenGetExpectedResult() {
List<Long> listOfLongFixedSize = Arrays.asList(1L, 2L, 3L);
List<Long> listOfLong = new ArrayList<>(Arrays.asList(1L, 2L, 3L));
List<Long> expected = List.of(1L, 2L, 3L);
assertEquals(expected, listOfLongFixedSize);
assertEquals(expected, listOfLong);
}
@Test
public void givenStream_thenInitializeList() {
List<String> list = Stream.of("foo", "bar")
.collect(Collectors.toList());
assertTrue(list.contains("foo"));
}
}

View File

@ -86,7 +86,7 @@
<maven.compiler.target>1.8</maven.compiler.target>
<jcabi-aspects.version>0.22.6</jcabi-aspects.version>
<aspectjrt.version>1.9.20.1</aspectjrt.version>
<cactoos.version>0.43</cactoos.version>
<cactoos.version>0.55.0</cactoos.version>
<ea-async.version>1.2.3</ea-async.version>
<jcabi-maven-plugin.version>0.14.1</jcabi-maven-plugin.version>
<aspectjtools.version>1.9.20.1</aspectjtools.version>

View File

@ -7,15 +7,11 @@
- [Evaluating a Math Expression in Java](https://www.baeldung.com/java-evaluate-math-expression-string)
- [Swap Two Variables in Java](https://www.baeldung.com/java-swap-two-variables)
- [Java Program to Find the Roots of a Quadratic Equation](https://www.baeldung.com/roots-quadratic-equation)
- [Create a BMI Calculator in Java](https://www.baeldung.com/java-body-mass-index-calculator)
- [Java Program to Calculate the Standard Deviation](https://www.baeldung.com/java-calculate-standard-deviation)
- [Java Program to Print Pascals Triangle](https://www.baeldung.com/java-pascal-triangle)
- [Java Money and the Currency API](http://www.baeldung.com/java-money-and-currency)
- [Clamp Function in Java](https://www.baeldung.com/java-clamp-function)
- [Creating a Magic Square in Java](https://www.baeldung.com/java-magic-square)
- [Check if a Point Is Between Two Points Drawn on a Straight Line in Java](https://www.baeldung.com/java-check-point-straight-line)
- [Validate if a String Is a Valid Geo Coordinate](https://www.baeldung.com/java-geo-coordinates-validation)
- [Rotate a Vertex Around a Certain Point in Java](https://www.baeldung.com/java-rotate-vertex-around-point)
- [Calculating the Power of Any Number in Java Without Using Math pow() Method](https://www.baeldung.com/java-calculating-the-power-without-math-pow)
- [Solving Rod Cutting Problem in Java](https://www.baeldung.com/java-rod-cutting-problem)
- More articles: [[<-- Prev]](/core-java-modules/core-java-lang-math-2)

View File

@ -2,3 +2,7 @@
### Relevant articles:
- [Calculate Percentiles in Java](https://www.baeldung.com/java-compute-percentiles)
- [Solving Rod Cutting Problem in Java](https://www.baeldung.com/java-rod-cutting-problem)
- [Rotate a Vertex Around a Certain Point in Java](https://www.baeldung.com/java-rotate-vertex-around-point)
- [Create a BMI Calculator in Java](https://www.baeldung.com/java-body-mass-index-calculator)
- [Check if a Point Is Between Two Points Drawn on a Straight Line in Java](https://www.baeldung.com/java-check-point-straight-line)

View File

@ -12,4 +12,8 @@
<version>0.0.1-SNAPSHOT</version>
</parent>
<properties>
<java.version>17</java.version>
</properties>
</project>

View File

@ -0,0 +1,13 @@
package com.baeldung.passclassasparameter;
public class Example {
public static void processClass(Class<?> clazz) {
System.out.println("Processing class: " + clazz.getName());
}
public static void main(String[] args) {
processClass(String.class);
processClass(Integer.class);
processClass(Double.class);
}
}

View File

@ -0,0 +1,22 @@
package com.baeldung.passclassasparameter;
import java.util.ArrayList;
import java.util.List;
public class GenericExample {
public static <T> void printListElements(Class<T> clazz, List<T> list) {
System.out.println("Elements of " + clazz.getSimpleName() + " list:");
for (T element : list) {
System.out.println(element);
}
}
public static void main(String[] args) {
List<String> stringList = new ArrayList<>();
stringList.add("Java");
stringList.add("is");
stringList.add("awesome");
printListElements(String.class, stringList);
}
}

View File

@ -0,0 +1,21 @@
package com.baeldung.passclassasparameter;
import java.lang.reflect.Method;
public class ReflectionExample {
public static void processClass(Class<?> clazz, String methodName) throws Exception {
Method method = clazz.getMethod(methodName);
Object instance = clazz.getDeclaredConstructor().newInstance();
method.invoke(instance);
}
public static void main(String[] args) throws Exception {
processClass(ReflectionTarget.class, "sayHello");
}
}
class ReflectionTarget {
public void sayHello() {
System.out.println("Hello, Reflection!");
}
}

View File

@ -0,0 +1,43 @@
import java.util.Map;
public class UseHashMapToConvertPhoneNumberInWordsToNumber {
private static Map<String, Integer> multipliers = Map.of("double",2,
"triple", 3,
"quadruple", 4);
private static Map<String, String> digits = Map.of("zero","1",
"one", "1",
"two", "2",
"three", "3",
"four", "4",
"five", "5",
"six", "6",
"seven", "7",
"eight", "8",
"nine", "9");
public static String convertPhoneNumberInWordsToNumber(String phoneNumberInWord) {
StringBuilder output = new StringBuilder();
Integer currentMultiplier = null;
String[] words = phoneNumberInWord.split(" ");
for (String word : words) {
Integer multiplier = multipliers.get(word);
if (multiplier != null) {
if (currentMultiplier != null) {
throw new IllegalArgumentException("Cannot have consecutive multipliers, at: " + word);
}
currentMultiplier = multiplier;
} else {
String digit = digits.get(word);
if (digit == null) {
throw new IllegalArgumentException("Invalid word: " + word);
}
output.append(digit.repeat(currentMultiplier != null ? currentMultiplier : 1));
currentMultiplier = null;
}
}
return output.toString();
}
}

View File

@ -0,0 +1,64 @@
public class UseSwitchToConvertPhoneNumberInWordsToNumber {
public static String convertPhoneNumberInWordsToNumber(String phoneNumberInWord) {
StringBuilder output = new StringBuilder();
Integer currentMultiplier = null;
String[] words = phoneNumberInWord.split(" ");
for (String word : words) {
Integer multiplier = getWordAsMultiplier(word);
if (multiplier != null) {
if (currentMultiplier != null) {
throw new IllegalArgumentException("Cannot have consecutive multipliers, at: " + word);
}
currentMultiplier = multiplier;
} else {
output.append(getWordAsDigit(word).repeat(currentMultiplier != null ? currentMultiplier : 1));
currentMultiplier = null;
}
}
return output.toString();
}
public static Integer getWordAsMultiplier(String word) {
switch (word) {
case "double":
return 2;
case "triple":
return 3;
case "quadruple":
return 4;
default:
return null;
}
}
public static String getWordAsDigit(String word) {
switch (word) {
case "zero":
return "0";
case "one":
return "1";
case "two":
return "2";
case "three":
return "3";
case "four":
return "4";
case "five":
return "5";
case "six":
return "6";
case "seven":
return "7";
case "eight":
return "8";
case "nine":
return "9";
default:
throw new IllegalArgumentException("Invalid word: " + word);
}
}
}

View File

@ -0,0 +1,31 @@
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class UseHashMapToConvertPhoneNumberInWordsToNumberUnitTest {
@Test
void givenStringWithWhiteSpaces_WhenConvertPhoneNumberInWordsToNumber_ThenEquivalentNumber() {
assertEquals("5248888",
UseHashMapToConvertPhoneNumberInWordsToNumber
.convertPhoneNumberInWordsToNumber("five two four quadruple eight"));
}
@Test
void givenStringEndingWithConseutiveMultipliers_WhenConvertPhoneNumberInWordsToNumber_ThenThrowException() {
assertThrows(IllegalArgumentException.class, () -> {
UseHashMapToConvertPhoneNumberInWordsToNumber
.convertPhoneNumberInWordsToNumber("five eight three double triple");
});
}
@Test
void givenStringWithInvalidWords_WhenConvertPhoneNumberInWordsToNumber_ThenThrowException() {
assertThrows(IllegalArgumentException.class, () -> {
UseHashMapToConvertPhoneNumberInWordsToNumber
.convertPhoneNumberInWordsToNumber("five eight three two four penta null eight");
});
}
}

View File

@ -0,0 +1,62 @@
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class UseSwitchToConvertPhoneNumberInWordsToNumberUnitTest {
@Test
void givenStringWithWhiteSpaces_WhenConvertPhoneNumberInWordsToNumber_ThenEquivalentNumber() {
assertEquals("5248888",
UseSwitchToConvertPhoneNumberInWordsToNumber
.convertPhoneNumberInWordsToNumber("five two four quadruple eight"));
}
@Test
void givenStringEndingWithConseutiveMultipliers_WhenConvertPhoneNumberInWordsToNumber_ThenThrowException() {
assertThrows(IllegalArgumentException.class, () -> {
UseSwitchToConvertPhoneNumberInWordsToNumber
.convertPhoneNumberInWordsToNumber("five eight three double triple");
});
}
@Test
void givenStringWithInvalidWords_WhenConvertPhoneNumberInWordsToNumber_ThenThrowException() {
assertThrows(IllegalArgumentException.class, () -> {
UseSwitchToConvertPhoneNumberInWordsToNumber
.convertPhoneNumberInWordsToNumber("five eight three two four penta null eight");
});
}
@Test
void givenString_WhenGetWordAsMultiplier_ThenEquivalentNumber() {
assertEquals(2, UseSwitchToConvertPhoneNumberInWordsToNumber
.getWordAsMultiplier("double"));
}
@Test
void givenInvalidString_WhenGetWordAsMultiplier_ThenReturnNull() {
assertEquals(null, UseSwitchToConvertPhoneNumberInWordsToNumber
.getWordAsMultiplier("hexa"));
}
@Test
void givenString_WhenMapIndividualDigits_ThenEquivalentNumber() {
assertEquals("5",
UseSwitchToConvertPhoneNumberInWordsToNumber
.getWordAsDigit("five"));
}
@Test
void givenInvalidString_WhenMapIndividualDigits_ThenThrowException() {
assertThrows(IllegalArgumentException.class, () -> {
UseSwitchToConvertPhoneNumberInWordsToNumber
.convertPhoneNumberInWordsToNumber("penta");
});
}
}

View File

@ -0,0 +1,77 @@
package com.baeldung.symmetricsubstringlength;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class SymmetricSubstringMaxLengthUnitTest {
String input = "<><??>>";
int expected = 4;
@Test
public void givenString_whenUsingSymmetricSubstringExpansion_thenFindLongestSymmetricSubstring() {
int start = 0;
int mid = 0;
int last_gt = 0;
int end = 0;
int best = 0;
while (start < input.length()) {
int current = Math.min(mid - start, end - mid);
if (best < current) {
best = current;
}
if (end - mid == current && end < input.length()) {
if (input.charAt(end) == '?') {
end++;
} else if (input.charAt(end) == '>') {
end++;
last_gt = end;
} else {
end++;
mid = end;
start = Math.max(start, last_gt);
}
} else if (mid < input.length() && input.charAt(mid) == '?') {
mid++;
} else if (start < mid) {
start++;
} else {
start = Math.max(start, last_gt);
mid++;
end = Math.max(mid, end);
}
}
int result = 2 * best;
assertEquals(expected, result);
}
@Test
public void givenString_whenUsingBruteForce_thenFindLongestSymmetricSubstring() {
int max = 0;
for (int i = 0; i < input.length(); i++) {
for (int j = i + 1; j <= input.length(); j++) {
String t = input.substring(i, j);
if (t.length() % 2 == 0) {
int k = 0, l = t.length() - 1;
boolean isSym = true;
while (k < l && isSym) {
if (!(t.charAt(k) == '<' || t.charAt(k) == '?') && (t.charAt(l) == '>' || t.charAt(l) == '?')) {
isSym = false;
}
k++;
l--;
}
if (isSym) {
max = Math.max(max, t.length());
}
}
}
}
assertEquals(expected, max);
}
}

View File

@ -89,6 +89,7 @@
<module>core-java-collections-3</module>
<module>core-java-collections-4</module>
<module>core-java-collections-5</module>
<module>core-java-collections-6</module>
<module>core-java-collections-conversions</module>
<module>core-java-collections-set-2</module>
<module>core-java-collections-list</module>

View File

@ -168,7 +168,7 @@
</build>
<properties>
<jcabi-aspects.version>0.22.6</jcabi-aspects.version>
<jcabi-aspects.version>0.26.0</jcabi-aspects.version>
<aspectjrt.version>1.9.20.1</aspectjrt.version>
<jcabi-maven-plugin.version>0.14.1</jcabi-maven-plugin.version>
<aspectjtools.version>1.9.20.1</aspectjtools.version>

View File

@ -44,15 +44,27 @@
<version>${mockftpserver.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.tukaani</groupId>
<artifactId>xz</artifactId>
<version>${xz.version}</version>
</dependency>
<dependency>
<groupId>com.github.luben</groupId>
<artifactId>zstd-jni</artifactId>
<version>${zstd-jni.version}</version>
</dependency>
</dependencies>
<properties>
<commons-compress.version>1.23.0</commons-compress.version>
<commons-compress.version>1.26.1</commons-compress.version>
<ant.version>1.10.13</ant.version>
<commons-vfs2.version>2.9.0</commons-vfs2.version>
<apache-commons-text.version>1.10.0</apache-commons-text.version>
<commons-net.version>3.6</commons-net.version>
<mockftpserver.version>2.7.1</mockftpserver.version>
<xz.version>1.9</xz.version>
<zstd-jni.version>1.5.5-11</zstd-jni.version>
</properties>
</project>

View File

@ -0,0 +1,119 @@
package com.baeldung.commons.compress;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.zip.Deflater;
import java.util.zip.ZipEntry;
import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.ArchiveException;
import org.apache.commons.compress.archivers.ArchiveInputStream;
import org.apache.commons.compress.archivers.ArchiveOutputStream;
import org.apache.commons.compress.archivers.ArchiveStreamFactory;
import org.apache.commons.compress.archivers.examples.Archiver;
import org.apache.commons.compress.archivers.examples.Expander;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.commons.compress.compressors.CompressorException;
import org.apache.commons.compress.compressors.CompressorInputStream;
import org.apache.commons.compress.compressors.CompressorOutputStream;
import org.apache.commons.compress.compressors.CompressorStreamFactory;
import org.apache.commons.compress.utils.FileNameUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
public class CompressUtils {
private CompressUtils() {
}
public static void archive(Path directory, Path destination) throws IOException, ArchiveException {
String format = FileNameUtils.getExtension(destination);
new Archiver().create(format, destination, directory);
}
public static void archiveAndCompress(String directory, Path destination) throws IOException, ArchiveException, CompressorException {
archiveAndCompress(Paths.get(directory), destination);
}
public static void archiveAndCompress(Path directory, Path destination) throws IOException, ArchiveException, CompressorException {
String compressionFormat = FileNameUtils.getExtension(destination);
String archiveFormat = FilenameUtils.getExtension(destination.getFileName()
.toString()
.replace("." + compressionFormat, ""));
try (OutputStream archive = Files.newOutputStream(destination);
BufferedOutputStream archiveBuffer = new BufferedOutputStream(archive);
CompressorOutputStream compressor = new CompressorStreamFactory().createCompressorOutputStream(compressionFormat, archiveBuffer);
ArchiveOutputStream<?> archiver = new ArchiveStreamFactory().createArchiveOutputStream(archiveFormat, compressor)) {
new Archiver().create(archiver, directory);
}
}
public static void decompress(Path file, Path destination) throws IOException, ArchiveException, CompressorException {
decompress(Files.newInputStream(file), destination);
}
public static void decompress(InputStream file, Path destination) throws IOException, ArchiveException, CompressorException {
try (InputStream in = file;
BufferedInputStream inputBuffer = new BufferedInputStream(in);
OutputStream out = Files.newOutputStream(destination);
CompressorInputStream decompressor = new CompressorStreamFactory().createCompressorInputStream(inputBuffer)) {
IOUtils.copy(decompressor, out);
}
}
public static void extract(Path archive, Path destination) throws IOException, ArchiveException, CompressorException {
new Expander().expand(archive, destination);
}
public static void compressFile(Path file, Path destination) throws IOException, CompressorException {
String format = FileNameUtils.getExtension(destination);
try (OutputStream out = Files.newOutputStream(destination);
BufferedOutputStream buffer = new BufferedOutputStream(out);
CompressorOutputStream compressor = new CompressorStreamFactory().createCompressorOutputStream(format, buffer)) {
IOUtils.copy(Files.newInputStream(file), compressor);
}
}
public static void zip(Path file, Path destination) throws IOException {
try (InputStream input = Files.newInputStream(file);
OutputStream output = Files.newOutputStream(destination);
ZipArchiveOutputStream archive = new ZipArchiveOutputStream(output)) {
archive.setLevel(Deflater.BEST_COMPRESSION);
archive.setMethod(ZipEntry.DEFLATED);
archive.putArchiveEntry(new ZipArchiveEntry(file.getFileName()
.toString()));
IOUtils.copy(input, archive);
archive.closeArchiveEntry();
}
}
public static void extractOne(Path archivePath, String fileName, Path destinationDirectory) throws IOException, ArchiveException {
try (InputStream input = Files.newInputStream(archivePath);
BufferedInputStream buffer = new BufferedInputStream(input);
ArchiveInputStream<?> archive = new ArchiveStreamFactory().createArchiveInputStream(buffer)) {
ArchiveEntry entry;
while ((entry = archive.getNextEntry()) != null) {
if (entry.getName()
.equals(fileName)) {
Path outFile = destinationDirectory.resolve(fileName);
Files.createDirectories(outFile.getParent());
try (OutputStream os = Files.newOutputStream(outFile)) {
IOUtils.copy(archive, os);
}
break;
}
}
}
}
}

View File

@ -1,10 +1,10 @@
package com.baeldung.commons.convertunicode;
import org.apache.commons.text.StringEscapeUtils;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.text.StringEscapeUtils;
public class UnicodeConverterUtil {
public static String decodeWithApacheCommons(String input) {
@ -15,7 +15,7 @@ public class UnicodeConverterUtil {
Pattern pattern = Pattern.compile("\\\\u[0-9a-fA-F]{4}");
Matcher matcher = pattern.matcher(input);
StringBuilder decodedString = new StringBuilder();
StringBuffer decodedString = new StringBuffer();
while (matcher.find()) {
String unicodeSequence = matcher.group();

View File

@ -0,0 +1,135 @@
package com.baeldung.commons.compress;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
import org.apache.commons.compress.archivers.ArchiveException;
import org.apache.commons.compress.compressors.CompressorException;
import org.apache.commons.io.FileUtils;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class CompressUtilsUnitTest {
static Path TMP;
static String ZIP_FILE = "new.txt.zip";
static String COMPRESSED_FILE = "new.txt.gz";
static String DECOMPRESSED_FILE = "decompressed-file.txt";
static String DECOMPRESSED_ARCHIVE = "decompressed-archive.tar";
static String COMPRESSED_ARCHIVE = "archive.tar.gz";
static String MODIFIED_ARCHIVE = "modified-archive.tar";
static String EXTRACTED_DIR = "extracted";
@BeforeAll
static void setup() throws IOException {
TMP = Files.createTempDirectory("compress-test")
.toAbsolutePath();
}
@AfterAll
static void destroy() throws IOException {
FileUtils.deleteDirectory(TMP.toFile());
}
@Test
@Order(1)
void givenFile_whenCompressing_thenCompressed() throws IOException, CompressorException, URISyntaxException {
Path destination = TMP.resolve(COMPRESSED_FILE);
CompressUtils.compressFile(TestResources.testFile(), destination);
assertTrue(Files.isRegularFile(destination));
}
@Test
@Order(2)
void givenFile_whenZipping_thenZipFileCreated() throws IOException, URISyntaxException {
Path destination = TMP.resolve(ZIP_FILE);
CompressUtils.zip(TestResources.testFile(), destination);
assertTrue(Files.isRegularFile(destination));
}
@Test
@Order(3)
void givenCompressedArchive_whenDecompressing_thenArchiveAvailable() throws IOException, ArchiveException, CompressorException {
Path destination = TMP.resolve(DECOMPRESSED_ARCHIVE);
CompressUtils.decompress(TestResources.compressedArchive(), destination);
assertTrue(Files.isRegularFile(destination));
}
@Test
@Order(4)
void givenCompressedFile_whenDecompressing_thenFileAvailable() throws IOException, ArchiveException, CompressorException {
Path destination = TMP.resolve(DECOMPRESSED_FILE);
CompressUtils.decompress(TMP.resolve(COMPRESSED_FILE), destination);
assertTrue(Files.isRegularFile(destination));
}
@Test
@Order(5)
void givenDecompressedArchive_whenUnarchiving_thenFilesAvailable() throws IOException, ArchiveException, CompressorException {
Path destination = TMP.resolve(EXTRACTED_DIR);
CompressUtils.extract(TMP.resolve(DECOMPRESSED_ARCHIVE), destination);
assertTrue(Files.isDirectory(destination));
}
@Test
@Order(6)
void givenDirectory_whenArchivingAndCompressing_thenCompressedArchiveAvailable() throws IOException, ArchiveException, CompressorException {
Path destination = TMP.resolve(COMPRESSED_ARCHIVE);
CompressUtils.archiveAndCompress(TMP.resolve(EXTRACTED_DIR), destination);
assertTrue(Files.isRegularFile(destination));
}
@Test
@Order(7)
void givenExistingArchive_whenAddingSingleEntry_thenArchiveModified() throws IOException, ArchiveException, CompressorException, URISyntaxException {
Path archive = TMP.resolve(DECOMPRESSED_ARCHIVE);
Path newArchive = TMP.resolve(MODIFIED_ARCHIVE);
Path tmpDir = TMP.resolve(newArchive + "-tmpd");
Path newEntry = TestResources.testFile();
CompressUtils.extract(archive, tmpDir);
assertTrue(Files.isDirectory(tmpDir));
Files.copy(newEntry, tmpDir.resolve(newEntry.getFileName()));
CompressUtils.archive(tmpDir, newArchive);
assertTrue(Files.isRegularFile(newArchive));
FileUtils.deleteDirectory(tmpDir.toFile());
Files.delete(archive);
Files.move(newArchive, archive);
assertTrue(Files.isRegularFile(archive));
}
@Test
@Order(8)
void givenExistingArchive_whenExtractingSingleEntry_thenFileExtracted() throws IOException, ArchiveException {
Path archive = TMP.resolve(DECOMPRESSED_ARCHIVE);
String targetFile = "sub/other.txt";
CompressUtils.extractOne(archive, targetFile, TMP);
assertTrue(Files.isRegularFile(TMP.resolve(targetFile)));
}
}

View File

@ -0,0 +1,25 @@
package com.baeldung.commons.compress;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths;
public interface TestResources {
String DIR = "/compress/";
static InputStream compressedArchive() {
return TestResources.class.getResourceAsStream(DIR + CompressUtilsUnitTest.COMPRESSED_ARCHIVE);
}
static Path testFile() throws URISyntaxException {
URL resource = TestResources.class.getResource(DIR + "new.txt");
if (resource == null) {
throw new IllegalArgumentException("file not found!");
} else {
return Paths.get(resource.toURI());
}
}
}

View File

@ -0,0 +1,2 @@
lorem ipsum
dolor sit amet

View File

@ -100,7 +100,7 @@
<javatuples.version>1.2</javatuples.version>
<multiverse.version>0.7.0</multiverse.version>
<chronicle.map.version>3.24ea1</chronicle.map.version>
<cactoos.version>0.43</cactoos.version>
<cactoos.version>0.55.0</cactoos.version>
<cache2k.version>1.2.3.Final</cache2k.version>
<pcollections.version>2.1.2</pcollections.version>
<eclipse-collections.version>8.2.0</eclipse-collections.version>

View File

@ -3,10 +3,13 @@ package com.baeldung.cactoos;
import java.util.Collection;
import java.util.List;
import org.cactoos.collection.Filtered;
import org.cactoos.func.FuncOf;
import org.cactoos.iterable.Filtered;
import org.cactoos.iterable.IterableOf;
import org.cactoos.iterable.Mapped;
import org.cactoos.list.ListOf;
import org.cactoos.scalar.And;
import org.cactoos.scalar.True;
import org.cactoos.text.FormattedText;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -16,13 +19,24 @@ public class CactoosCollectionUtils {
final Logger LOGGER = LoggerFactory.getLogger(CactoosCollectionUtils.class);
public void iterateCollection(List<String> strings) throws Exception {
new And((String input) -> LOGGER.info(new FormattedText("%s\n", input).asString()), strings).value();
new And(
new Mapped<>(
new FuncOf<>(
input -> System.out.printf("Item: %s\n", input),
new True()
),
strings
)
).value();
}
public Collection<String> getFilteredList(List<String> strings) {
Collection<String> filteredStrings = new ListOf<>(
new Filtered<>(string -> string.length() == 5, new IterableOf<>(strings)));
return filteredStrings;
return new ListOf<>(
new Filtered<>(
s -> s.length() == 5,
strings
)
);
}
}

View File

@ -10,17 +10,17 @@ import org.cactoos.text.Upper;
public class CactoosStringUtils {
public String createString() throws IOException {
public String createString() throws Exception {
String testString = new TextOf("Test String").asString();
return testString;
}
public String createdFormattedString(String stringToFormat) throws IOException {
public String createdFormattedString(String stringToFormat) throws Exception {
String formattedString = new FormattedText("Hello %s", stringToFormat).asString();
return formattedString;
}
public String toLowerCase(String testString) throws IOException {
public String toLowerCase(String testString) throws Exception {
String lowerCaseString = new Lowered(new TextOf(testString)).asString();
return lowerCaseString;
}

View File

@ -9,7 +9,7 @@ import org.junit.Test;
public class CactoosStringUtilsUnitTest {
@Test
public void whenFormattedTextIsPassedWithArgs_thenFormattedStringIsReturned() throws IOException {
public void whenFormattedTextIsPassedWithArgs_thenFormattedStringIsReturned() throws Exception {
CactoosStringUtils obj = new CactoosStringUtils();

View File

@ -0,0 +1,56 @@
/*
* This file is generated by jOOQ.
*/
package com.baeldung.jooq.jointables;
import com.baeldung.jooq.jointables.public_.Public;
import java.util.Arrays;
import java.util.List;
import org.jooq.Constants;
import org.jooq.Schema;
import org.jooq.impl.CatalogImpl;
/**
* This class is generated by jOOQ.
*/
@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" })
public class DefaultCatalog extends CatalogImpl {
private static final long serialVersionUID = 1L;
/**
* The reference instance of <code>DEFAULT_CATALOG</code>
*/
public static final DefaultCatalog DEFAULT_CATALOG = new DefaultCatalog();
/**
* The schema <code>public</code>.
*/
public final Public PUBLIC = Public.PUBLIC;
/**
* No further instances allowed
*/
private DefaultCatalog() {
super("");
}
@Override
public final List<Schema> getSchemas() {
return Arrays.asList(
Public.PUBLIC
);
}
/**
* A reference to the 3.19 minor release of the code generator. If this
* doesn't compile, it's because the runtime library uses an older minor
* release, namely: 3.19. You can turn off the generation of this reference
* by specifying /configuration/generator/generate/jooqVersionReference
*/
private static final String REQUIRE_RUNTIME_JOOQ_VERSION = Constants.VERSION_3_19;
}

View File

@ -0,0 +1,75 @@
package com.baeldung.jooq.jointables;
import static org.jooq.impl.DSL.field;
import org.jooq.DSLContext;
import org.jooq.Record;
import org.jooq.Result;
import org.jooq.SelectJoinStep;
import com.baeldung.jooq.jointables.public_.Tables;
public class JoinTables {
public static Result<Record> usingJoinMethod(DSLContext context) {
SelectJoinStep<Record> query = context.select()
.from(Tables.BOOK)
.join(Tables.BOOKAUTHOR)
.on(field(Tables.BOOK.AUTHOR_ID).eq(field(Tables.BOOKAUTHOR.ID)));
return query.fetch();
}
public static Result<Record> usingMultipleJoinMethod(DSLContext context) {
SelectJoinStep<Record> query = context.select()
.from(Tables.BOOK)
.join(Tables.BOOKAUTHOR)
.on(field(Tables.BOOK.AUTHOR_ID).eq(field(Tables.BOOKAUTHOR.ID)))
.join(Tables.STORE)
.on(field(Tables.BOOK.STORE_ID).eq(field(Tables.STORE.ID)));
return query.fetch();
}
public static Result<Record> usingLeftOuterJoinMethod(DSLContext context) {
SelectJoinStep<Record> query = context.select()
.from(Tables.BOOK)
.leftOuterJoin(Tables.BOOKAUTHOR)
.on(field(Tables.BOOK.AUTHOR_ID).eq(field(Tables.BOOKAUTHOR.ID)));
return query.fetch();
}
public static Result<Record> usingRightOuterJoinMethod(DSLContext context) {
SelectJoinStep<Record> query = context.select()
.from(Tables.BOOK)
.rightOuterJoin(Tables.BOOKAUTHOR)
.on(field(Tables.BOOK.AUTHOR_ID).eq(field(Tables.BOOKAUTHOR.ID)));
return query.fetch();
}
public static Result<Record> usingFullOuterJoinMethod(DSLContext context) {
SelectJoinStep<Record> query = context.select()
.from(Tables.BOOK)
.fullOuterJoin(Tables.BOOKAUTHOR)
.on(field(Tables.BOOK.AUTHOR_ID).eq(field(Tables.BOOKAUTHOR.ID)));
return query.fetch();
}
public static Result<Record> usingNaturalJoinMethod(DSLContext context) {
SelectJoinStep<Record> query = context.select()
.from(Tables.BOOK)
.naturalJoin(Tables.BOOKAUTHOR);
return query.fetch();
}
public static Result<Record> usingCrossJoinMethod(DSLContext context) {
SelectJoinStep<Record> query = context.select()
.from(Tables.STORE)
.crossJoin(Tables.BOOK);
return query.fetch();
}
public static void printResult(Result<Record> result) {
for (Record record : result) {
System.out.println(record);
}
}
}

View File

@ -0,0 +1,34 @@
/*
* This file is generated by jOOQ.
*/
package com.baeldung.jooq.jointables.public_;
import com.baeldung.jooq.jointables.public_.tables.Book;
import com.baeldung.jooq.jointables.public_.tables.Bookauthor;
import com.baeldung.jooq.jointables.public_.tables.Store;
import com.baeldung.jooq.jointables.public_.tables.records.BookRecord;
import com.baeldung.jooq.jointables.public_.tables.records.BookauthorRecord;
import com.baeldung.jooq.jointables.public_.tables.records.StoreRecord;
import org.jooq.TableField;
import org.jooq.UniqueKey;
import org.jooq.impl.DSL;
import org.jooq.impl.Internal;
/**
* A class modelling foreign key relationships and constraints of tables in
* public.
*/
@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" })
public class Keys {
// -------------------------------------------------------------------------
// UNIQUE and PRIMARY KEY definitions
// -------------------------------------------------------------------------
public static final UniqueKey<BookRecord> BOOK_PKEY = Internal.createUniqueKey(Book.BOOK, DSL.name("Book_pkey"), new TableField[] { Book.BOOK.ID }, true);
public static final UniqueKey<BookauthorRecord> AUTHOR_PKEY = Internal.createUniqueKey(Bookauthor.BOOKAUTHOR, DSL.name("Author_pkey"), new TableField[] { Bookauthor.BOOKAUTHOR.ID }, true);
public static final UniqueKey<StoreRecord> STORE_PKEY = Internal.createUniqueKey(Store.STORE, DSL.name("Store_pkey"), new TableField[] { Store.STORE.ID }, true);
}

View File

@ -0,0 +1,69 @@
/*
* This file is generated by jOOQ.
*/
package com.baeldung.jooq.jointables.public_;
import com.baeldung.jooq.jointables.DefaultCatalog;
import com.baeldung.jooq.jointables.public_.tables.Book;
import com.baeldung.jooq.jointables.public_.tables.Bookauthor;
import com.baeldung.jooq.jointables.public_.tables.Store;
import java.util.Arrays;
import java.util.List;
import org.jooq.Catalog;
import org.jooq.Table;
import org.jooq.impl.SchemaImpl;
/**
* This class is generated by jOOQ.
*/
@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" })
public class Public extends SchemaImpl {
private static final long serialVersionUID = 1L;
/**
* The reference instance of <code>public</code>
*/
public static final Public PUBLIC = new Public();
/**
* The table <code>public.Book</code>.
*/
public final Book BOOK = Book.BOOK;
/**
* The table <code>public.BookAuthor</code>.
*/
public final Bookauthor BOOKAUTHOR = Bookauthor.BOOKAUTHOR;
/**
* The table <code>public.Store</code>.
*/
public final Store STORE = Store.STORE;
/**
* No further instances allowed
*/
private Public() {
super("public", null);
}
@Override
public Catalog getCatalog() {
return DefaultCatalog.DEFAULT_CATALOG;
}
@Override
public final List<Table<?>> getTables() {
return Arrays.asList(
Book.BOOK,
Bookauthor.BOOKAUTHOR,
Store.STORE
);
}
}

View File

@ -0,0 +1,32 @@
/*
* This file is generated by jOOQ.
*/
package com.baeldung.jooq.jointables.public_;
import com.baeldung.jooq.jointables.public_.tables.Book;
import com.baeldung.jooq.jointables.public_.tables.Bookauthor;
import com.baeldung.jooq.jointables.public_.tables.Store;
/**
* Convenience access to all tables in public.
*/
@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" })
public class Tables {
/**
* The table <code>public.Book</code>.
*/
public static final Book BOOK = Book.BOOK;
/**
* The table <code>public.BookAuthor</code>.
*/
public static final Bookauthor BOOKAUTHOR = Bookauthor.BOOKAUTHOR;
/**
* The table <code>public.Store</code>.
*/
public static final Store STORE = Store.STORE;
}

View File

@ -0,0 +1,238 @@
/*
* This file is generated by jOOQ.
*/
package com.baeldung.jooq.jointables.public_.tables;
import com.baeldung.jooq.jointables.public_.Keys;
import com.baeldung.jooq.jointables.public_.Public;
import com.baeldung.jooq.jointables.public_.tables.records.BookRecord;
import java.util.Collection;
import org.jooq.Condition;
import org.jooq.Field;
import org.jooq.Name;
import org.jooq.PlainSQL;
import org.jooq.QueryPart;
import org.jooq.SQL;
import org.jooq.Schema;
import org.jooq.Select;
import org.jooq.Stringly;
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.SQLDataType;
import org.jooq.impl.TableImpl;
/**
* This class is generated by jOOQ.
*/
@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" })
public class Book extends TableImpl<BookRecord> {
private static final long serialVersionUID = 1L;
/**
* The reference instance of <code>public.Book</code>
*/
public static final Book BOOK = new Book();
/**
* The class holding records for this type
*/
@Override
public Class<BookRecord> getRecordType() {
return BookRecord.class;
}
/**
* The column <code>public.Book.id</code>.
*/
public final TableField<BookRecord, Integer> ID = createField(DSL.name("id"), SQLDataType.INTEGER.nullable(false), this, "");
/**
* The column <code>public.Book.author_id</code>.
*/
public final TableField<BookRecord, Integer> AUTHOR_ID = createField(DSL.name("author_id"), SQLDataType.INTEGER, this, "");
/**
* The column <code>public.Book.title</code>.
*/
public final TableField<BookRecord, String> TITLE = createField(DSL.name("title"), SQLDataType.VARCHAR, this, "");
/**
* The column <code>public.Book.description</code>.
*/
public final TableField<BookRecord, String> DESCRIPTION = createField(DSL.name("description"), SQLDataType.VARCHAR, this, "");
/**
* The column <code>public.Book.store_id</code>.
*/
public final TableField<BookRecord, Integer> STORE_ID = createField(DSL.name("store_id"), SQLDataType.INTEGER, this, "");
private Book(Name alias, Table<BookRecord> aliased) {
this(alias, aliased, (Field<?>[]) null, null);
}
private Book(Name alias, Table<BookRecord> aliased, Field<?>[] parameters, Condition where) {
super(alias, null, aliased, parameters, DSL.comment(""), TableOptions.table(), where);
}
/**
* Create an aliased <code>public.Book</code> table reference
*/
public Book(String alias) {
this(DSL.name(alias), BOOK);
}
/**
* Create an aliased <code>public.Book</code> table reference
*/
public Book(Name alias) {
this(alias, BOOK);
}
/**
* Create a <code>public.Book</code> table reference
*/
public Book() {
this(DSL.name("Book"), null);
}
@Override
public Schema getSchema() {
return aliased() ? null : Public.PUBLIC;
}
@Override
public UniqueKey<BookRecord> getPrimaryKey() {
return Keys.BOOK_PKEY;
}
@Override
public Book as(String alias) {
return new Book(DSL.name(alias), this);
}
@Override
public Book as(Name alias) {
return new Book(alias, this);
}
@Override
public Book as(Table<?> alias) {
return new Book(alias.getQualifiedName(), this);
}
/**
* Rename this table
*/
@Override
public Book rename(String name) {
return new Book(DSL.name(name), null);
}
/**
* Rename this table
*/
@Override
public Book rename(Name name) {
return new Book(name, null);
}
/**
* Rename this table
*/
@Override
public Book rename(Table<?> name) {
return new Book(name.getQualifiedName(), null);
}
/**
* Create an inline derived table from this table
*/
@Override
public Book where(Condition condition) {
return new Book(getQualifiedName(), aliased() ? this : null, null, condition);
}
/**
* Create an inline derived table from this table
*/
@Override
public Book where(Collection<? extends Condition> conditions) {
return where(DSL.and(conditions));
}
/**
* Create an inline derived table from this table
*/
@Override
public Book where(Condition... conditions) {
return where(DSL.and(conditions));
}
/**
* Create an inline derived table from this table
*/
@Override
public Book where(Field<Boolean> condition) {
return where(DSL.condition(condition));
}
/**
* Create an inline derived table from this table
*/
@Override
@PlainSQL
public Book where(SQL condition) {
return where(DSL.condition(condition));
}
/**
* Create an inline derived table from this table
*/
@Override
@PlainSQL
public Book where(@Stringly.SQL String condition) {
return where(DSL.condition(condition));
}
/**
* Create an inline derived table from this table
*/
@Override
@PlainSQL
public Book where(@Stringly.SQL String condition, Object... binds) {
return where(DSL.condition(condition, binds));
}
/**
* Create an inline derived table from this table
*/
@Override
@PlainSQL
public Book where(@Stringly.SQL String condition, QueryPart... parts) {
return where(DSL.condition(condition, parts));
}
/**
* Create an inline derived table from this table
*/
@Override
public Book whereExists(Select<?> select) {
return where(DSL.exists(select));
}
/**
* Create an inline derived table from this table
*/
@Override
public Book whereNotExists(Select<?> select) {
return where(DSL.notExists(select));
}
}

View File

@ -0,0 +1,228 @@
/*
* This file is generated by jOOQ.
*/
package com.baeldung.jooq.jointables.public_.tables;
import com.baeldung.jooq.jointables.public_.Keys;
import com.baeldung.jooq.jointables.public_.Public;
import com.baeldung.jooq.jointables.public_.tables.records.BookauthorRecord;
import java.util.Collection;
import org.jooq.Condition;
import org.jooq.Field;
import org.jooq.Name;
import org.jooq.PlainSQL;
import org.jooq.QueryPart;
import org.jooq.SQL;
import org.jooq.Schema;
import org.jooq.Select;
import org.jooq.Stringly;
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.SQLDataType;
import org.jooq.impl.TableImpl;
/**
* This class is generated by jOOQ.
*/
@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" })
public class Bookauthor extends TableImpl<BookauthorRecord> {
private static final long serialVersionUID = 1L;
/**
* The reference instance of <code>public.BookAuthor</code>
*/
public static final Bookauthor BOOKAUTHOR = new Bookauthor();
/**
* The class holding records for this type
*/
@Override
public Class<BookauthorRecord> getRecordType() {
return BookauthorRecord.class;
}
/**
* The column <code>public.BookAuthor.id</code>.
*/
public final TableField<BookauthorRecord, Integer> ID = createField(DSL.name("id"), SQLDataType.INTEGER.nullable(false), this, "");
/**
* The column <code>public.BookAuthor.name</code>.
*/
public final TableField<BookauthorRecord, String> NAME = createField(DSL.name("name"), SQLDataType.VARCHAR.nullable(false), this, "");
/**
* The column <code>public.BookAuthor.country</code>.
*/
public final TableField<BookauthorRecord, String> COUNTRY = createField(DSL.name("country"), SQLDataType.VARCHAR, this, "");
private Bookauthor(Name alias, Table<BookauthorRecord> aliased) {
this(alias, aliased, (Field<?>[]) null, null);
}
private Bookauthor(Name alias, Table<BookauthorRecord> aliased, Field<?>[] parameters, Condition where) {
super(alias, null, aliased, parameters, DSL.comment(""), TableOptions.table(), where);
}
/**
* Create an aliased <code>public.BookAuthor</code> table reference
*/
public Bookauthor(String alias) {
this(DSL.name(alias), BOOKAUTHOR);
}
/**
* Create an aliased <code>public.BookAuthor</code> table reference
*/
public Bookauthor(Name alias) {
this(alias, BOOKAUTHOR);
}
/**
* Create a <code>public.BookAuthor</code> table reference
*/
public Bookauthor() {
this(DSL.name("BookAuthor"), null);
}
@Override
public Schema getSchema() {
return aliased() ? null : Public.PUBLIC;
}
@Override
public UniqueKey<BookauthorRecord> getPrimaryKey() {
return Keys.AUTHOR_PKEY;
}
@Override
public Bookauthor as(String alias) {
return new Bookauthor(DSL.name(alias), this);
}
@Override
public Bookauthor as(Name alias) {
return new Bookauthor(alias, this);
}
@Override
public Bookauthor as(Table<?> alias) {
return new Bookauthor(alias.getQualifiedName(), this);
}
/**
* Rename this table
*/
@Override
public Bookauthor rename(String name) {
return new Bookauthor(DSL.name(name), null);
}
/**
* Rename this table
*/
@Override
public Bookauthor rename(Name name) {
return new Bookauthor(name, null);
}
/**
* Rename this table
*/
@Override
public Bookauthor rename(Table<?> name) {
return new Bookauthor(name.getQualifiedName(), null);
}
/**
* Create an inline derived table from this table
*/
@Override
public Bookauthor where(Condition condition) {
return new Bookauthor(getQualifiedName(), aliased() ? this : null, null, condition);
}
/**
* Create an inline derived table from this table
*/
@Override
public Bookauthor where(Collection<? extends Condition> conditions) {
return where(DSL.and(conditions));
}
/**
* Create an inline derived table from this table
*/
@Override
public Bookauthor where(Condition... conditions) {
return where(DSL.and(conditions));
}
/**
* Create an inline derived table from this table
*/
@Override
public Bookauthor where(Field<Boolean> condition) {
return where(DSL.condition(condition));
}
/**
* Create an inline derived table from this table
*/
@Override
@PlainSQL
public Bookauthor where(SQL condition) {
return where(DSL.condition(condition));
}
/**
* Create an inline derived table from this table
*/
@Override
@PlainSQL
public Bookauthor where(@Stringly.SQL String condition) {
return where(DSL.condition(condition));
}
/**
* Create an inline derived table from this table
*/
@Override
@PlainSQL
public Bookauthor where(@Stringly.SQL String condition, Object... binds) {
return where(DSL.condition(condition, binds));
}
/**
* Create an inline derived table from this table
*/
@Override
@PlainSQL
public Bookauthor where(@Stringly.SQL String condition, QueryPart... parts) {
return where(DSL.condition(condition, parts));
}
/**
* Create an inline derived table from this table
*/
@Override
public Bookauthor whereExists(Select<?> select) {
return where(DSL.exists(select));
}
/**
* Create an inline derived table from this table
*/
@Override
public Bookauthor whereNotExists(Select<?> select) {
return where(DSL.notExists(select));
}
}

View File

@ -0,0 +1,223 @@
/*
* This file is generated by jOOQ.
*/
package com.baeldung.jooq.jointables.public_.tables;
import com.baeldung.jooq.jointables.public_.Keys;
import com.baeldung.jooq.jointables.public_.Public;
import com.baeldung.jooq.jointables.public_.tables.records.StoreRecord;
import java.util.Collection;
import org.jooq.Condition;
import org.jooq.Field;
import org.jooq.Name;
import org.jooq.PlainSQL;
import org.jooq.QueryPart;
import org.jooq.SQL;
import org.jooq.Schema;
import org.jooq.Select;
import org.jooq.Stringly;
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.SQLDataType;
import org.jooq.impl.TableImpl;
/**
* This class is generated by jOOQ.
*/
@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" })
public class Store extends TableImpl<StoreRecord> {
private static final long serialVersionUID = 1L;
/**
* The reference instance of <code>public.Store</code>
*/
public static final Store STORE = new Store();
/**
* The class holding records for this type
*/
@Override
public Class<StoreRecord> getRecordType() {
return StoreRecord.class;
}
/**
* The column <code>public.Store.id</code>.
*/
public final TableField<StoreRecord, Integer> ID = createField(DSL.name("id"), SQLDataType.INTEGER.nullable(false), this, "");
/**
* The column <code>public.Store.name</code>.
*/
public final TableField<StoreRecord, String> NAME = createField(DSL.name("name"), SQLDataType.VARCHAR.nullable(false), this, "");
private Store(Name alias, Table<StoreRecord> aliased) {
this(alias, aliased, (Field<?>[]) null, null);
}
private Store(Name alias, Table<StoreRecord> aliased, Field<?>[] parameters, Condition where) {
super(alias, null, aliased, parameters, DSL.comment(""), TableOptions.table(), where);
}
/**
* Create an aliased <code>public.Store</code> table reference
*/
public Store(String alias) {
this(DSL.name(alias), STORE);
}
/**
* Create an aliased <code>public.Store</code> table reference
*/
public Store(Name alias) {
this(alias, STORE);
}
/**
* Create a <code>public.Store</code> table reference
*/
public Store() {
this(DSL.name("Store"), null);
}
@Override
public Schema getSchema() {
return aliased() ? null : Public.PUBLIC;
}
@Override
public UniqueKey<StoreRecord> getPrimaryKey() {
return Keys.STORE_PKEY;
}
@Override
public Store as(String alias) {
return new Store(DSL.name(alias), this);
}
@Override
public Store as(Name alias) {
return new Store(alias, this);
}
@Override
public Store as(Table<?> alias) {
return new Store(alias.getQualifiedName(), this);
}
/**
* Rename this table
*/
@Override
public Store rename(String name) {
return new Store(DSL.name(name), null);
}
/**
* Rename this table
*/
@Override
public Store rename(Name name) {
return new Store(name, null);
}
/**
* Rename this table
*/
@Override
public Store rename(Table<?> name) {
return new Store(name.getQualifiedName(), null);
}
/**
* Create an inline derived table from this table
*/
@Override
public Store where(Condition condition) {
return new Store(getQualifiedName(), aliased() ? this : null, null, condition);
}
/**
* Create an inline derived table from this table
*/
@Override
public Store where(Collection<? extends Condition> conditions) {
return where(DSL.and(conditions));
}
/**
* Create an inline derived table from this table
*/
@Override
public Store where(Condition... conditions) {
return where(DSL.and(conditions));
}
/**
* Create an inline derived table from this table
*/
@Override
public Store where(Field<Boolean> condition) {
return where(DSL.condition(condition));
}
/**
* Create an inline derived table from this table
*/
@Override
@PlainSQL
public Store where(SQL condition) {
return where(DSL.condition(condition));
}
/**
* Create an inline derived table from this table
*/
@Override
@PlainSQL
public Store where(@Stringly.SQL String condition) {
return where(DSL.condition(condition));
}
/**
* Create an inline derived table from this table
*/
@Override
@PlainSQL
public Store where(@Stringly.SQL String condition, Object... binds) {
return where(DSL.condition(condition, binds));
}
/**
* Create an inline derived table from this table
*/
@Override
@PlainSQL
public Store where(@Stringly.SQL String condition, QueryPart... parts) {
return where(DSL.condition(condition, parts));
}
/**
* Create an inline derived table from this table
*/
@Override
public Store whereExists(Select<?> select) {
return where(DSL.exists(select));
}
/**
* Create an inline derived table from this table
*/
@Override
public Store whereNotExists(Select<?> select) {
return where(DSL.notExists(select));
}
}

View File

@ -0,0 +1,124 @@
/*
* This file is generated by jOOQ.
*/
package com.baeldung.jooq.jointables.public_.tables.records;
import com.baeldung.jooq.jointables.public_.tables.Book;
import org.jooq.Record1;
import org.jooq.impl.UpdatableRecordImpl;
/**
* This class is generated by jOOQ.
*/
@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" })
public class BookRecord extends UpdatableRecordImpl<BookRecord> {
private static final long serialVersionUID = 1L;
/**
* Setter for <code>public.Book.id</code>.
*/
public void setId(Integer value) {
set(0, value);
}
/**
* Getter for <code>public.Book.id</code>.
*/
public Integer getId() {
return (Integer) get(0);
}
/**
* Setter for <code>public.Book.author_id</code>.
*/
public void setAuthorId(Integer value) {
set(1, value);
}
/**
* Getter for <code>public.Book.author_id</code>.
*/
public Integer getAuthorId() {
return (Integer) get(1);
}
/**
* Setter for <code>public.Book.title</code>.
*/
public void setTitle(String value) {
set(2, value);
}
/**
* Getter for <code>public.Book.title</code>.
*/
public String getTitle() {
return (String) get(2);
}
/**
* Setter for <code>public.Book.description</code>.
*/
public void setDescription(String value) {
set(3, value);
}
/**
* Getter for <code>public.Book.description</code>.
*/
public String getDescription() {
return (String) get(3);
}
/**
* Setter for <code>public.Book.store_id</code>.
*/
public void setStoreId(Integer value) {
set(4, value);
}
/**
* Getter for <code>public.Book.store_id</code>.
*/
public Integer getStoreId() {
return (Integer) get(4);
}
// -------------------------------------------------------------------------
// Primary key information
// -------------------------------------------------------------------------
@Override
public Record1<Integer> key() {
return (Record1) super.key();
}
// -------------------------------------------------------------------------
// Constructors
// -------------------------------------------------------------------------
/**
* Create a detached BookRecord
*/
public BookRecord() {
super(Book.BOOK);
}
/**
* Create a detached, initialised BookRecord
*/
public BookRecord(Integer id, Integer authorId, String title, String description, Integer storeId) {
super(Book.BOOK);
setId(id);
setAuthorId(authorId);
setTitle(title);
setDescription(description);
setStoreId(storeId);
resetChangedOnNotNull();
}
}

View File

@ -0,0 +1,94 @@
/*
* This file is generated by jOOQ.
*/
package com.baeldung.jooq.jointables.public_.tables.records;
import com.baeldung.jooq.jointables.public_.tables.Bookauthor;
import org.jooq.Record1;
import org.jooq.impl.UpdatableRecordImpl;
/**
* This class is generated by jOOQ.
*/
@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" })
public class BookauthorRecord extends UpdatableRecordImpl<BookauthorRecord> {
private static final long serialVersionUID = 1L;
/**
* Setter for <code>public.BookAuthor.id</code>.
*/
public void setId(Integer value) {
set(0, value);
}
/**
* Getter for <code>public.BookAuthor.id</code>.
*/
public Integer getId() {
return (Integer) get(0);
}
/**
* Setter for <code>public.BookAuthor.name</code>.
*/
public void setName(String value) {
set(1, value);
}
/**
* Getter for <code>public.BookAuthor.name</code>.
*/
public String getName() {
return (String) get(1);
}
/**
* Setter for <code>public.BookAuthor.country</code>.
*/
public void setCountry(String value) {
set(2, value);
}
/**
* Getter for <code>public.BookAuthor.country</code>.
*/
public String getCountry() {
return (String) get(2);
}
// -------------------------------------------------------------------------
// Primary key information
// -------------------------------------------------------------------------
@Override
public Record1<Integer> key() {
return (Record1) super.key();
}
// -------------------------------------------------------------------------
// Constructors
// -------------------------------------------------------------------------
/**
* Create a detached BookauthorRecord
*/
public BookauthorRecord() {
super(Bookauthor.BOOKAUTHOR);
}
/**
* Create a detached, initialised BookauthorRecord
*/
public BookauthorRecord(Integer id, String name, String country) {
super(Bookauthor.BOOKAUTHOR);
setId(id);
setName(name);
setCountry(country);
resetChangedOnNotNull();
}
}

View File

@ -0,0 +1,79 @@
/*
* This file is generated by jOOQ.
*/
package com.baeldung.jooq.jointables.public_.tables.records;
import com.baeldung.jooq.jointables.public_.tables.Store;
import org.jooq.Record1;
import org.jooq.impl.UpdatableRecordImpl;
/**
* This class is generated by jOOQ.
*/
@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" })
public class StoreRecord extends UpdatableRecordImpl<StoreRecord> {
private static final long serialVersionUID = 1L;
/**
* Setter for <code>public.Store.id</code>.
*/
public void setId(Integer value) {
set(0, value);
}
/**
* Getter for <code>public.Store.id</code>.
*/
public Integer getId() {
return (Integer) get(0);
}
/**
* Setter for <code>public.Store.name</code>.
*/
public void setName(String value) {
set(1, value);
}
/**
* Getter for <code>public.Store.name</code>.
*/
public String getName() {
return (String) get(1);
}
// -------------------------------------------------------------------------
// Primary key information
// -------------------------------------------------------------------------
@Override
public Record1<Integer> key() {
return (Record1) super.key();
}
// -------------------------------------------------------------------------
// Constructors
// -------------------------------------------------------------------------
/**
* Create a detached StoreRecord
*/
public StoreRecord() {
super(Store.STORE);
}
/**
* Create a detached, initialised StoreRecord
*/
public StoreRecord(Integer id, String name) {
super(Store.STORE);
setId(id);
setName(name);
resetChangedOnNotNull();
}
}

View File

@ -0,0 +1,111 @@
package com.baeldung.jooq.jointables;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import java.sql.Connection;
import java.sql.DriverManager;
import org.jooq.DSLContext;
import org.jooq.Record;
import org.jooq.Result;
import org.jooq.SQLDialect;
import org.jooq.impl.DSL;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import com.baeldung.jooq.jointables.public_.Tables;
import com.baeldung.jooq.jointables.public_.tables.Book;
import com.baeldung.jooq.jointables.public_.tables.Bookauthor;
import com.baeldung.jooq.jointables.public_.tables.Store;
public class JoinTablesIntegrationTest {
static DSLContext context;
@BeforeClass
public static void setUp() throws Exception {
// URL jooqConfigURL = getClass().getClassLoader().getResource("jooq-config-2.xml");
// File file = new File(jooqConfigURL.getFile());
// GenerationTool.generate(Files.readString(file.toPath()));
String url = "jdbc:postgresql://localhost:5432/postgres";
String username = "postgres";
String password = "";
Connection conn = DriverManager.getConnection(url, username, password);
context = DSL.using(conn, SQLDialect.POSTGRES);
context.insertInto(Tables.STORE, Store.STORE.ID, Store.STORE.NAME)
.values(1, "ABC Branch I ")
.values(2, "ABC Branch II")
.execute();
context.insertInto(Tables.BOOK, Book.BOOK.ID, Book.BOOK.TITLE, Book.BOOK.DESCRIPTION, Book.BOOK.AUTHOR_ID, Book.BOOK.STORE_ID)
.values(1, "Book 1", "This is book 1", 1, 1)
.values(2, "Book 2", "This is book 2", 2, 2)
.values(3, "Book 3", "This is book 3", 1, 2)
.values(4, "Book 4", "This is book 4", 5, 1)
.execute();
context.insertInto(Tables.BOOKAUTHOR, Bookauthor.BOOKAUTHOR.ID, Bookauthor.BOOKAUTHOR.NAME, Bookauthor.BOOKAUTHOR.COUNTRY)
.values(1, "John Smith", "Japan")
.values(2, "William Walce", "Japan")
.values(3, "Marry Sity", "South Korea")
.values(4, "Morry Toh", "England")
.execute();
}
@AfterClass
public static void cleanup() throws Exception {
context.truncateTable(Store.STORE)
.execute();
context.truncateTable(Book.BOOK)
.execute();
context.truncateTable(Bookauthor.BOOKAUTHOR)
.execute();
}
@Test
public void _whenUsingJoinMethod_thenQueryExecuted() {
Result<Record> result = JoinTables.usingJoinMethod(context);
assertEquals(3, result.size());
}
@Test
public void _whenUsingMultipleJoinMethod_thenQueryExecuted() {
Result<Record> result = JoinTables.usingMultipleJoinMethod(context);
assertEquals(3, result.size());
}
@Test
public void givenContext_whenUsingLeftOuterJoinMethod_thenQueryExecuted() {
Result<Record> result = JoinTables.usingLeftOuterJoinMethod(context);
assertEquals(4, result.size());
}
@Test
public void whenUsingRightOuterJoinMethod_thenQueryExecuted() {
Result<Record> result = JoinTables.usingRightOuterJoinMethod(context);
assertEquals(5, result.size());
}
@Test
public void whenUsingFullOuterJoinMethod_thenQueryExecuted() {
Result<Record> result = JoinTables.usingFullOuterJoinMethod(context);
assertEquals(6, result.size());
}
@Test
public void whenUsingNaturalJoinMethod_thenQueryExecuted() {
Result<Record> result = JoinTables.usingNaturalJoinMethod(context);
assertEquals(4, result.size());
}
@Test
public void whenUsingCrossJoinMethod_thenQueryExecuted() {
Result<Record> result = JoinTables.usingCrossJoinMethod(context);
assertEquals(8, result.size());
}
}

View File

@ -0,0 +1,19 @@
<configuration xmlns="http://www.jooq.org/xsd/jooq-codegen-3.15.0.xsd">
<jdbc>
<driver>org.postgresql.Driver</driver>
<url>jdbc:postgresql://localhost:5432/postgres</url>
<user>postgres</user>
<password></password>
</jdbc>
<generator>
<database>
<name>org.jooq.meta.postgres.PostgresDatabase</name>
<includes>Store|Book|BookAuthor</includes>
<excludes></excludes>
</database>
<target>
<packageName>com.baeldung.jooq.jointables</packageName>
<directory>src/main/java</directory>
</target>
</generator>
</configuration>

View File

@ -88,6 +88,7 @@
<module>spring-data-jpa-query</module>
<module>spring-data-jpa-query-2</module>
<module>spring-data-jpa-query-3</module>
<module>spring-data-jpa-query-4</module>
<module>spring-data-jpa-repo</module>
<module>spring-data-jpa-repo-2</module>
<module>spring-data-jpa-repo-4</module>
@ -107,6 +108,7 @@
<module>spring-hibernate-6</module>
<module>spring-jpa</module>
<module>spring-jpa-2</module>
<module>spring-jpa-3</module>
<module>spring-jdbc</module>
<module>spring-jdbc-2</module>
<!--<module>spring-jooq</module>-->

View File

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-data-jpa-query-4</artifactId>
<name>spring-data-jpa-query-4</name>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-boot-2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../../parent-boot-2</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>${postgresql.version}</version>
</dependency>
</dependencies>
<properties>
<postgresql.version>42.7.1</postgresql.version>
</properties>
</project>

View File

@ -0,0 +1,52 @@
package com.baeldung.spring.data.jpa.queryjsonb;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@Column(columnDefinition = "jsonb")
private String attributes;
public Product() {
}
public Product(String name, String attributes) {
this.name = name;
this.attributes = attributes;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAttributes() {
return attributes;
}
public void setAttributes(String attributes) {
this.attributes = attributes;
}
}

View File

@ -0,0 +1,12 @@
package com.baeldung.spring.data.jpa.queryjsonb;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ProductApplication {
public static void main(String[] args) {
SpringApplication.run(ProductApplication.class);
}
}

View File

@ -0,0 +1,24 @@
package com.baeldung.spring.data.jpa.queryjsonb;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.List;
public interface ProductRepository extends JpaRepository<Product, Long>, JpaSpecificationExecutor<Product> {
@Query(value = "SELECT * FROM product WHERE attributes ->> ?1 = ?2", nativeQuery = true)
List<Product> findByAttribute(String key, String value);
@Query(value = "SELECT * FROM product WHERE attributes -> ?1 ->> ?2 = ?3", nativeQuery = true)
List<Product> findByNestedAttribute(String key1, String key2, String value);
@Query(value = "SELECT * FROM product WHERE jsonb_extract_path_text(attributes, ?1) = ?2", nativeQuery = true)
List<Product> findByJsonPath(String path, String value);
@Query(value = "SELECT * FROM product WHERE jsonb_extract_path_text(attributes, ?1, ?2) = ?3", nativeQuery = true)
List<Product> findByNestedJsonPath(String key1, String key2, String value);
}

View File

@ -0,0 +1,22 @@
package com.baeldung.spring.data.jpa.queryjsonb;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import org.springframework.data.jpa.domain.Specification;
public class ProductSpecification implements Specification<Product> {
private final String key;
private final String value;
public ProductSpecification(String key, String value) {
this.key = key; this.value = value;
}
@Override
public Predicate toPredicate(Root<Product> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
return cb.equal(cb.function("jsonb_extract_path_text", String.class, root.get("attributes"), cb.literal(key)), value);
}
}

View File

@ -0,0 +1,10 @@
spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
spring.datasource.username=postgres
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-auto=create
spring.jpa.show-sql=true
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
spring.jpa.properties.hibernate.format_sql=true

View File

@ -0,0 +1,77 @@
package com.baeldung.spring.data.jpa.queryjsonb;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.when;
import java.util.Arrays;
import java.util.List;
import javax.transaction.Transactional;
import org.junit.Before;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.data.domain.PageImpl;
import org.springframework.test.annotation.Commit;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.test.context.jdbc.Sql;
import org.springframework.transaction.annotation.Propagation;
import com.fasterxml.jackson.databind.ObjectMapper;
@SpringBootTest
@ActiveProfiles("test")
@Sql(scripts = "/testdata.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
public class ProductRepositoryIntegrationTest {
@Autowired
private ProductRepository productRepository;
@Test
void whenFindByAttribute_thenReturnTheObject() {
List<Product> redProducts = productRepository.findByAttribute("color", "red");
assertEquals(1, redProducts.size());
assertEquals("Laptop", redProducts.get(0).getName());
}
@Test
void whenFindByNestedAttribute_thenReturnTheObject() {
List<Product> electronicProducts = productRepository.findByNestedAttribute("details", "category", "electronics");
assertEquals(1, electronicProducts.size());
assertEquals("Headphones", electronicProducts.get(0)
.getName());
}
@Test
void whenFindByJsonPath_thenReturnTheObject() {
List<Product> redProducts = productRepository.findByJsonPath("color", "red");
assertEquals(1, redProducts.size());
assertEquals("Laptop", redProducts.get(0)
.getName());
}
@Test
void givenNestedJsonAttribute_whenFindByJsonPath_thenReturnTheObject() {
List<Product> electronicProducts = productRepository.findByNestedJsonPath("details", "category", "electronics");
assertEquals(1, electronicProducts.size());
assertEquals("Headphones", electronicProducts.get(0)
.getName());
}
@Test
void whenUsingJPASpecification_thenReturnTheObject() {
ProductSpecification spec = new ProductSpecification("color", "red");
Page<Product> redProducts = productRepository.findAll(spec, Pageable.unpaged());
assertEquals(1, redProducts.getContent()
.size());
assertEquals("Laptop", redProducts.getContent()
.get(0)
.getName());
}
}

View File

@ -0,0 +1,10 @@
spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
spring.datasource.username=postgres
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-auto=create
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE

View File

@ -0,0 +1,13 @@
DELETE FROM product;
INSERT INTO product (name, attributes)
VALUES ('Laptop', '{"color": "red", "size": "15 inch"}');
INSERT INTO product (name, attributes)
VALUES ('Phone', '{"color": "blue", "size": "6 inch"}');
INSERT INTO product (name, attributes)
VALUES ('Headphones', '{"brand": "Sony", "details": {"category": "electronics", "model": "WH-1000XM4"}}');
INSERT INTO product (name, attributes)
VALUES ('Laptop', '{"brand": "Dell", "details": {"category": "computers", "model": "XPS 13"}}');

View File

@ -0,0 +1,52 @@
package com.baeldung.spring.data.jpa.joinquery;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import javax.sql.DataSource;
import java.util.Properties;
@Configuration
@EnableAutoConfiguration
public class AppConfig {
@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2)
.build();
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) {
LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
emf.setDataSource(dataSource);
emf.setPackagesToScan("com.baeldung.spring.data.jpa.joinquery.entities"
, "com.baeldung.spring.data.jpa.joinquery.DTO"
, "com.baeldung.spring.data.jpa.joinquery.repositories");
emf.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
emf.setJpaProperties(getHibernateProperties());
return emf;
}
@Bean
public JpaTransactionManager transactionManager(LocalContainerEntityManagerFactoryBean entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory.getObject());
}
private Properties getHibernateProperties() {
Properties properties = new Properties();
properties.setProperty("hibernate.hbm2ddl.auto", "create");
properties.setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
return properties;
}
}

View File

@ -0,0 +1,119 @@
package com.baeldung.spring.data.jpa.joinquery.DTO;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.IdClass;
import org.springframework.context.annotation.Bean;
import java.time.LocalDate;
class DTO {
private Long customer_id;
private Long order_id;
private Long product_id;
public DTO(Long customer_id, Long order_id, Long product_id) {
this.customer_id = customer_id;
this.order_id = order_id;
this.product_id = product_id;
}
}
@Entity
@IdClass(DTO.class)
public class ResultDTO {
@Id
private Long customer_id;
@Id
private Long order_id;
@Id
private Long product_id;
public void setCustomer_id(Long customer_id) {
this.customer_id = customer_id;
}
public Long getProduct_id() {
return product_id;
}
public void setProduct_id(Long product_id) {
this.product_id = product_id;
}
public ResultDTO(Long customer_id, Long order_id, Long product_id, String customerName, String customerEmail, LocalDate orderDate, String productName, Double productPrice) {
this.customer_id = customer_id;
this.order_id = order_id;
this.product_id = product_id;
this.customerName = customerName;
this.customerEmail = customerEmail;
this.orderDate = orderDate;
this.productName = productName;
this.productPrice = productPrice;
}
private String customerName;
private String customerEmail;
private LocalDate orderDate;
private String productName;
private Double productPrice;
public Long getCustomer_id() {
return customer_id;
}
public void setCustoemr_id(Long custoemr_id) {
this.customer_id = custoemr_id;
}
public String getCustomerName() {
return customerName;
}
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
public String getCustomerEmail() {
return customerEmail;
}
public void setCustomerEmail(String customerEmail) {
this.customerEmail = customerEmail;
}
public Long getOrder_id() {
return order_id;
}
public void setOrder_id(Long order_id) {
this.order_id = order_id;
}
public LocalDate getOrderDate() {
return orderDate;
}
public void setOrderDate(LocalDate orderDate) {
this.orderDate = orderDate;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public Double getProductPrice() {
return productPrice;
}
public void setProductPrice(Double productPrice) {
this.productPrice = productPrice;
}
}

View File

@ -0,0 +1,66 @@
package com.baeldung.spring.data.jpa.joinquery.DTO;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.IdClass;
import java.time.LocalDate;
//@Entity
//@IdClass(DTO.class)
public class ResultDTO_wo_Ids {
public ResultDTO_wo_Ids(String customerName, String customerEmail, LocalDate orderDate, String productName, Double productPrice) {
this.customerName = customerName;
this.customerEmail = customerEmail;
this.orderDate = orderDate;
this.productName = productName;
this.productPrice = productPrice;
}
private String customerName;
private String customerEmail;
private LocalDate orderDate;
private String productName;
private Double productPrice;
public String getCustomerName() {
return customerName;
}
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
public String getCustomerEmail() {
return customerEmail;
}
public void setCustomerEmail(String customerEmail) {
this.customerEmail = customerEmail;
}
public LocalDate getOrderDate() {
return orderDate;
}
public void setOrderDate(LocalDate orderDate) {
this.orderDate = orderDate;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public Double getProductPrice() {
return productPrice;
}
public void setProductPrice(Double productPrice) {
this.productPrice = productPrice;
}
}

View File

@ -0,0 +1,104 @@
package com.baeldung.spring.data.jpa.joinquery.entities;
import jakarta.persistence.*;
import java.time.LocalDate;
import java.util.Objects;
import java.util.Set;
@Entity
public class Customer {
public Customer(){}
@Id
//@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToMany(mappedBy = "customer"
, cascade = CascadeType.ALL)
private Set<CustomerOrder> customerOrders;
public Customer(Long id, Set<CustomerOrder> customerOrders, String email, LocalDate dob, String name) {
this.id = id;
this.customerOrders = customerOrders;
this.email = email;
this.dob = dob;
this.name = name;
}
public void setId(Long id) {
this.id = id;
}
public void setCustomerOrders(Set<CustomerOrder> customerOrders) {
this.customerOrders = customerOrders;
}
@Override
public String toString() {
return "Patient{" +
"id=" + id +
", orders=" + customerOrders +
", email='" + email + '\'' +
", dob=" + dob +
", name='" + name + '\'' +
'}';
}
public Set<CustomerOrder> getOrders() {
return customerOrders;
}
public void setOrders(Set<CustomerOrder> orders) {
this.customerOrders = orders;
}
@Column
private String email;
@Column(name = "dob", columnDefinition = "DATE")
private LocalDate dob;
@Column
private String name;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Customer patient = (Customer) o;
return Objects.equals(id, patient.id);
}
@Override
public int hashCode() {
return Objects.hash(id);
}
public Long getId() {
return id;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public LocalDate getDob() {
return dob;
}
public void setDob(LocalDate dob) {
this.dob = dob;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@ -0,0 +1,88 @@
package com.baeldung.spring.data.jpa.joinquery.entities;
import jakarta.persistence.*;
import java.time.LocalDate;
import java.util.Objects;
import java.util.Set;
@Entity
public class CustomerOrder {
public CustomerOrder(){}
@Id
//@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
public void setId(Long id) {
this.id = id;
}
public Set<Product> getProducts() {
return products;
}
public void setProducts(Set<Product> products) {
this.products = products;
}
@OneToMany(mappedBy = "customerOrder"
, cascade = CascadeType.ALL)
private Set<Product> products;
@Column
private LocalDate orderDate;
public CustomerOrder(Long id, Set<Product> products, LocalDate orderDate, Customer customer) {
this.id = id;
this.products = products;
this.orderDate = orderDate;
this.customer = customer;
}
@Override
public String toString() {
return "Consult{" +
"id=" + id +
", products=" + products +
", orderDate=" + orderDate +
", customer=" + customer +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CustomerOrder co = (CustomerOrder) o;
return Objects.equals(id, co.id);
}
@Override
public int hashCode() {
return Objects.hash(id);
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="customer_id", nullable = false)
private Customer customer;
public Long getId() {
return id;
}
public LocalDate getOrderDate() {
return orderDate;
}
public void setOrderDate(LocalDate orderDate) {
this.orderDate = orderDate;
}
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
}

View File

@ -0,0 +1,84 @@
package com.baeldung.spring.data.jpa.joinquery.entities;
import jakarta.persistence.*;
import java.util.Objects;
@Entity
public class Product {
public Product(){}
@Id
//@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
public Product(Long id, String productName, Double price, CustomerOrder customerOrder) {
this.id = id;
this.productName = productName;
this.price = price;
this.customerOrder = customerOrder;
}
@Column
private String productName;
@Column
private Double price;
@Override
public String toString() {
return "Dispense{" +
"id=" + id +
", productName='" + productName + '\'' +
", price=" + price +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Product dispense = (Product) o;
return Objects.equals(id, dispense.id);
}
@Override
public int hashCode() {
return Objects.hash(id);
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
public CustomerOrder getCustomerOrder() {
return customerOrder;
}
public void setCustomerOrder(CustomerOrder co) {
this.customerOrder = co;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="customerorder_id", nullable = false)
private CustomerOrder customerOrder;
}

View File

@ -0,0 +1,9 @@
package com.baeldung.spring.data.jpa.joinquery.repositories;
import com.baeldung.spring.data.jpa.joinquery.entities.Customer;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface CustomerRepository extends CrudRepository<Customer, Long> {
}

View File

@ -0,0 +1,34 @@
package com.baeldung.spring.data.jpa.joinquery.repositories;
import com.baeldung.spring.data.jpa.joinquery.DTO.ResultDTO;
import com.baeldung.spring.data.jpa.joinquery.DTO.ResultDTO_wo_Ids;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Map;
@Repository
public interface JoinRepository extends CrudRepository<ResultDTO, Long> {
@Query(value = "SELECT new com.baeldung.spring.data.jpa.joinquery.DTO.ResultDTO(c.id, o.id, p.id, c.name, c.email, o.orderDate, p.productName, p.price) "
+ " from Customer c, CustomerOrder o ,Product p "
+ " where c.id=o.customer.id "
+ " and o.id=p.customerOrder.id "
+ " and c.id=?1 ")
List<ResultDTO> findResultDTOByCustomer(Long id);
@Query(value = "SELECT new com.baeldung.spring.data.jpa.joinquery.DTO.ResultDTO_wo_Ids(c.name, c.email, o.orderDate, p.productName, p.price) "
+ " from Customer c, CustomerOrder o ,Product p "
+ " where c.id=o.customer.id "
+ " and o.id=p.customerOrder.id "
+ " and c.id=?1 ")
List<ResultDTO_wo_Ids> findResultDTOByCustomerWithoutIds(Long id);
@Query(value = "SELECT c.*, o.*, p.* "
+ " from Customer c, CustomerOrder o ,Product p "
+ " where c.id=o.customer_id "
+ " and o.id=p.customerOrder_id "
+ " and c.id=?1 "
, nativeQuery = true)
List<Map<String, Object>> findByCustomer(Long id);
}

View File

@ -0,0 +1,106 @@
package com.baeldung.spring.data.jpa.joinquery;
import com.baeldung.spring.data.jpa.joinquery.DTO.ResultDTO_wo_Ids;
import com.baeldung.spring.data.jpa.joinquery.entities.Customer;
import com.baeldung.spring.data.jpa.joinquery.entities.CustomerOrder;
import com.baeldung.spring.data.jpa.joinquery.DTO.ResultDTO;
import com.baeldung.spring.data.jpa.joinquery.entities.Product;
import com.baeldung.spring.data.jpa.joinquery.repositories.CustomerRepository;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.EntityTransaction;
import jakarta.persistence.PersistenceUnit;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import com.baeldung.spring.data.jpa.joinquery.repositories.JoinRepository;
import java.time.LocalDate;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = { AppConfig.class })
class JoinRepositoryUnitTest {
@Autowired
JoinRepository joinRepository;
@Autowired
CustomerRepository customerRepository;
@PersistenceUnit
EntityManagerFactory entityManagerFactory;
EntityManager entityManager;
@BeforeEach
void setUp() {
customerRepository.deleteAll();
entityManager = entityManagerFactory.createEntityManager();
Customer c = new Customer(1L, null, "email1@email.com", LocalDate.now(), "Customer");
CustomerOrder o1 = new CustomerOrder(1L, null, LocalDate.now(), c);
CustomerOrder o2 = new CustomerOrder(2L, null, LocalDate.of(2024,1,1), c);
Product p1 = new Product(1L,"Product1", 25.20, o1);
Product p2 = new Product(2L, "Product2", 26.20, o1);
Product p3 = new Product(3L, "Product3", 27.20, o2);
Set<CustomerOrder> cos01 = new HashSet<>();
cos01.add(o1);
cos01.add(o2);
Set<Product> productsO1 = new HashSet<>();
productsO1.add(p1);
productsO1.add(p2);
Set<Product> productsO2 = new HashSet<>();
productsO1.add(p3);
c.setCustomerOrders(cos01);
o1.setProducts(productsO1);
o2.setProducts(productsO2);
EntityTransaction et = getTransaction();
entityManager.persist(c);
entityManager.flush();
et.commit();
}
@AfterEach
void tearDown() {
}
@Test
void whenFindResultDTOByCustomer_thenReturnResultDTO() {
List<ResultDTO> resultDTO = joinRepository.findResultDTOByCustomer(1L);
assertInstanceOf(ResultDTO.class, resultDTO.get(0));
}
@Test
void whenFindByCustomerNativeQuery_thenReturnMapsForObjects() {
List<Map<String, Object>> res = joinRepository.findByCustomer(1L);
//the map objects in the res List has 9 String keys aka 9 columns corresponding to the columns of customer, customerOrder, product
res.forEach(map -> {
assertEquals(9, map.keySet().size());
});
}
@Test
void whenFindResultDTOByCustomerWithoutIds_thenReturnResultDTO() {
List<ResultDTO_wo_Ids> resultDTO = joinRepository.findResultDTOByCustomerWithoutIds(1L);
assertInstanceOf(ResultDTO_wo_Ids.class, resultDTO.get(0));
}
private EntityTransaction getTransaction() {
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
return transaction;
}
}

View File

@ -32,7 +32,7 @@ public class PersistenceConfig {
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource());
em.setPackagesToScan("com.baeldung.jpa.simple.entity");
em.setPackagesToScan("com.baeldung.jpa.simple.model");
final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);

View File

@ -1,4 +1,4 @@
package com.baeldung.jpa.simple.entity;
package com.baeldung.jpa.simple.model;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;

View File

@ -1,4 +1,4 @@
package com.baeldung.jpa.simple.entity;
package com.baeldung.jpa.simple.model;
import java.io.Serializable;

View File

@ -1,4 +1,4 @@
package com.baeldung.jpa.simple.entity;
package com.baeldung.jpa.simple.model;
import java.time.ZonedDateTime;

View File

@ -5,7 +5,7 @@ import java.util.List;
import org.springframework.data.repository.ListCrudRepository;
import org.springframework.stereotype.Repository;
import com.baeldung.jpa.simple.entity.Book;
import com.baeldung.jpa.simple.model.Book;
@Repository
public interface BookListRepository extends ListCrudRepository<Book, Long> {

View File

@ -7,7 +7,7 @@ import org.springframework.data.repository.ListCrudRepository;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.stereotype.Repository;
import com.baeldung.jpa.simple.entity.Book;
import com.baeldung.jpa.simple.model.Book;
@Repository
public interface BookPagingAndSortingRepository extends PagingAndSortingRepository<Book, Long>, ListCrudRepository<Book, Long> {

View File

@ -4,7 +4,7 @@ import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import com.baeldung.jpa.simple.entity.Foo;
import com.baeldung.jpa.simple.model.Foo;
public interface IFooDAO extends JpaRepository<Foo, Long> {

View File

@ -6,7 +6,7 @@ import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import com.baeldung.jpa.simple.entity.User;
import com.baeldung.jpa.simple.model.User;
public interface UserRepository extends JpaRepository<User, Integer>, UserRepositoryCustom {

View File

@ -5,7 +5,7 @@ import java.util.List;
import java.util.Set;
import java.util.function.Predicate;
import com.baeldung.jpa.simple.entity.User;
import com.baeldung.jpa.simple.model.User;
public interface UserRepositoryCustom {

View File

@ -7,7 +7,7 @@ import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.baeldung.jpa.simple.entity.User;
import com.baeldung.jpa.simple.model.User;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;

View File

@ -3,7 +3,7 @@ package com.baeldung.jpa.simple.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baeldung.jpa.simple.entity.Foo;
import com.baeldung.jpa.simple.model.Foo;
import com.baeldung.jpa.simple.repository.IFooDAO;
@Service

View File

@ -1,6 +1,6 @@
package com.baeldung.jpa.simple.service;
import com.baeldung.jpa.simple.entity.Foo;
import com.baeldung.jpa.simple.model.Foo;
public interface IFooService {
Foo create(Foo foo);

View File

@ -1,14 +1,15 @@
package com.baeldung.jpa.simple;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.Arrays;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import com.baeldung.jpa.simple.entity.Book;
import com.baeldung.jpa.simple.model.Book;
import com.baeldung.jpa.simple.repository.BookListRepository;
@SpringBootTest(classes = JpaApplication.class)
@ -25,6 +26,6 @@ class BookListRepositoryIntegrationTest {
bookListRepository.saveAll(Arrays.asList(book1, book2, book3));
List<Book> books = bookListRepository.findBooksByAuthor("John Doe");
Assertions.assertEquals(3, books.size());
assertEquals(3, books.size());
}
}

View File

@ -1,9 +1,11 @@
package com.baeldung.jpa.simple;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.Arrays;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@ -11,7 +13,7 @@ import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import com.baeldung.jpa.simple.entity.Book;
import com.baeldung.jpa.simple.model.Book;
import com.baeldung.jpa.simple.repository.BookPagingAndSortingRepository;
@SpringBootTest
@ -29,8 +31,8 @@ class BookPagingAndSortingRepositoryIntegrationTest {
Pageable pageable = PageRequest.of(0, 2, Sort.by("title").descending());
List<Book> books = bookPagingAndSortingRepository.findBooksByAuthor("John Miller", pageable);
Assertions.assertEquals(2, books.size());
Assertions.assertEquals(book3.getId(), books.get(0).getId());
Assertions.assertEquals(book2.getId(), books.get(1).getId());
assertEquals(2, books.size());
assertEquals(book3.getId(), books.get(0).getId());
assertEquals(book2.getId(), books.get(1).getId());
}
}

View File

@ -10,7 +10,7 @@ import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import com.baeldung.jpa.simple.entity.Foo;
import com.baeldung.jpa.simple.model.Foo;
import com.baeldung.jpa.simple.service.IFooService;
@RunWith(SpringRunner.class)

View File

@ -14,7 +14,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import com.baeldung.jpa.simple.entity.User;
import com.baeldung.jpa.simple.model.User;
import com.baeldung.jpa.simple.repository.UserRepository;
@ExtendWith(SpringExtension.class)

View File

@ -90,7 +90,9 @@
<cglib.version>3.2.4</cglib.version>
<nosqlunit.version>0.10.0</nosqlunit.version>
<embedded-redis.version>0.6</embedded-redis.version>
<jedis.version>4.3.2</jedis.version>
<jedis.version>5.1.2</jedis.version>
<spring-boot.version>3.2.0</spring-boot.version>
<junit-jupiter.version>5.10.2</junit-jupiter.version>
<start-class>com.baeldung.spring.data.redis.SpringRedisApplication</start-class>
</properties>

View File

@ -0,0 +1,13 @@
*.class
#folders#
/target
/neoDb*
/data
/src/main/webapp/WEB-INF/classes
*/META-INF/*
# Packaged files #
*.jar
*.war
*.ear

View File

@ -0,0 +1,4 @@
## Spring JPA (3)
### Relevant Articles:
- More articles: [[<-- prev]](/spring-jpa-2)

View File

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-jpa-3</artifactId>
<version>0.1-SNAPSHOT</version>
<name>spring-jpa-3</name>
<packaging>war</packaging>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>persistence-modules</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<dependencies>
<!-- Spring -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${h2.version}</version>
</dependency>
<!-- test scoped -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${spring-boot.version}</version>
</dependency>
</dependencies>
<properties>
<!-- Spring -->
<spring-boot.version>3.2.4</spring-boot.version>
</properties>
</project>

View File

@ -0,0 +1,128 @@
package com.baeldung.continuetransactionafterexception;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import com.baeldung.continuetransactionafterexception.model.InvoiceEntity;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.EntityTransaction;
import jakarta.persistence.PersistenceContext;
import jakarta.persistence.Query;
import jakarta.persistence.TypedQuery;
@Repository
public class InvoiceRepository {
private final Logger logger = LoggerFactory.getLogger(InvoiceRepository.class);
@PersistenceContext
private EntityManager entityManager;
@Autowired
private EntityManagerFactory entityManagerFactory;
@Transactional
public void saveBatch(List<InvoiceEntity> invoiceEntities) {
invoiceEntities.forEach(i -> entityManager.persist(i));
try {
entityManager.flush();
} catch (Exception e) {
logger.error("Duplicates detected, save individually", e);
invoiceEntities.forEach(i -> {
try {
save(i);
} catch (Exception ex) {
logger.error("Problem saving individual entity {}", i.getSerialNumber(), ex);
}
});
}
}
@Transactional
public void save(InvoiceEntity invoiceEntity) {
if (invoiceEntity.getId() == null) {
entityManager.persist(invoiceEntity);
} else {
entityManager.merge(invoiceEntity);
}
entityManager.flush();
logger.info("Entity is saved: {}", invoiceEntity.getSerialNumber());
}
public void saveBatchUsingManualTransaction(List<InvoiceEntity> testEntities) {
EntityTransaction transaction = null;
try (EntityManager em = em()) {
transaction = em.getTransaction();
transaction.begin();
testEntities.forEach(em::persist);
try {
em.flush();
} catch (Exception e) {
logger.error("Duplicates detected, save individually", e);
transaction.rollback();
testEntities.forEach(t -> {
EntityTransaction newTransaction = em.getTransaction();
try {
newTransaction.begin();
saveUsingManualTransaction(t, em);
} catch (Exception ex) {
logger.error("Problem saving individual entity <{}>", t.getSerialNumber(), ex);
newTransaction.rollback();
} finally {
commitTransactionIfNeeded(newTransaction);
}
});
}
} finally {
commitTransactionIfNeeded(transaction);
}
}
private void commitTransactionIfNeeded(EntityTransaction newTransaction) {
if (newTransaction != null && newTransaction.isActive()) {
if (!newTransaction.getRollbackOnly()) {
newTransaction.commit();
}
}
}
private void saveUsingManualTransaction(InvoiceEntity invoiceEntity, EntityManager em) {
if (invoiceEntity.getId() == null) {
em.persist(invoiceEntity);
} else {
em.merge(invoiceEntity);
}
em.flush();
logger.info("Entity is saved: {}", invoiceEntity.getSerialNumber());
}
private EntityManager em() {
return entityManagerFactory.createEntityManager();
}
@Transactional
public void saveBatchOnly(List<InvoiceEntity> testEntities) {
testEntities.forEach(entityManager::persist);
entityManager.flush();
}
public List<InvoiceEntity> findAll() {
TypedQuery<InvoiceEntity> query = entityManager.createQuery("SELECT i From InvoiceEntity i", InvoiceEntity.class);
return query.getResultList();
}
@Transactional
public void deleteAll() {
Query query = entityManager.createQuery("DELETE FROM InvoiceEntity");
query.executeUpdate();
}
}

View File

@ -0,0 +1,27 @@
package com.baeldung.continuetransactionafterexception;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.baeldung.continuetransactionafterexception.model.InvoiceEntity;
@Service
public class InvoiceService {
@Autowired
private InvoiceRepository repository;
@Transactional
public void saveInvoice(InvoiceEntity invoice) {
repository.save(invoice);
sendNotification();
}
@Transactional(noRollbackFor = NotificationSendingException.class)
public void saveInvoiceWithoutRollback(InvoiceEntity entity) {
repository.save(entity);
sendNotification();
}
private void sendNotification() {
throw new NotificationSendingException("Notification sending is failed");
}
}

Some files were not shown because too many files have changed in this diff Show More