* BAEL-7490 read write file in separate thread

* Change the to try resources

* Update the code to sync with article

* Jsonb query

* Added new module to parent pom
This commit is contained in:
Wynn Teo 2024-04-05 10:01:52 +08:00 committed by GitHub
parent 7cb3519bd2
commit bb544b9168
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 266 additions and 0 deletions

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>

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"}}');