### Example API Call for Searching Posts Source: https://github.com/simplecore-inc/searchable-jpa/blob/master/README.md This bash snippet provides an example of how to make an API call to search for posts. It demonstrates how to specify search criteria (e.g., title contains 'Spring'), sorting preferences (createdAt in descending order), and pagination parameters (page 0, size 10). ```bash # Search posts containing "Spring" in title GET /api/posts/search?title.contains=Spring&sort=createdAt,desc&page=0&size=10 ``` -------------------------------- ### Example URL Parameters for Search Source: https://context7.com/simplecore-inc/searchable-jpa/llms.txt These bash commands illustrate various ways to construct URL query parameters for searching products. They demonstrate filtering by status, price ranges, names, categories, and handling null values, along with sorting options. ```bash # Search for active products with price between 100 and 500 GET /api/products/search?status.equals=ACTIVE&price.between=100,500&sort=price.asc,createdAt.desc&page=0&size=20 # Search for products containing "laptop" in name GET /api/products/search?name.contains=laptop&sort=name.asc # Search with multiple conditions GET /api/products/search?status.in=ACTIVE,FEATURED&price.greaterThan=50&categoryName.equals=Electronics # Null checks GET /api/products/search?categoryName.isNotNull=true ``` -------------------------------- ### Implement Searchable JPA Service and Controller Source: https://context7.com/simplecore-inc/searchable-jpa/llms.txt Illustrates the implementation of a base service and a REST controller using Searchable JPA. The example shows extending DefaultSearchableService and using SearchableParamsParser to handle search parameters from requests for findAllWithSearch and countWithSearch operations. ```java @Entity @Table(name = "products") public class Product { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private BigDecimal price; @Enumerated(EnumType.STRING) private ProductStatus status; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "category_id") private Category category; private LocalDateTime createdAt; } @Repository public interface ProductRepository extends JpaRepository, JpaSpecificationExecutor { } @Service public class ProductService extends DefaultSearchableService { public ProductService(ProductRepository repository, EntityManager entityManager) { super(repository, entityManager); } } @RestController @RequestMapping("/api/products") public class ProductController { private final ProductService productService; public ProductController(ProductService productService) { this.productService = productService; } @GetMapping("/search") public Page search(@RequestParam Map params) { SearchCondition condition = new SearchableParamsParser<>(ProductSearchDTO.class).convert(params); return productService.findAllWithSearch(condition); } @GetMapping("/count") public long count(@RequestParam Map params) { SearchCondition condition = new SearchableParamsParser<>(ProductSearchDTO.class).convert(params); return productService.countWithSearch(condition); } } ``` -------------------------------- ### GET /api/products/search/summary - Projection Support Source: https://context7.com/simplecore-inc/searchable-jpa/llms.txt Enables fetching search results as type-safe interface-based projections, optimizing data transfer by selecting only necessary fields. ```APIDOC ## GET /api/products/search/summary ### Description Retrieves a paginated list of products using query parameters, returning results as a specific projection (e.g., `ProductSummary`). This optimizes data transfer by returning only the fields defined in the projection interface. ### Method GET ### Endpoint `/api/products/search/summary` ### Parameters #### Query Parameters - **param_name** (string) - Required - Key-value pairs representing search conditions and sorting. Examples: - `status.equals=ACTIVE` - `price.between=100,500` - `sort=price.asc,createdAt.desc` - `page=0` - `size=20` ### Request Example ``` GET /api/products/search/summary?status.equals=ACTIVE&price.between=100,500&sort=price.asc&page=0&size=20 ``` ### Response #### Success Response (200) - **content** (array) - Array of objects adhering to the `ProductSummary` interface (or the specified projection). - **pageable** (object) - Pagination information. - **totalPages** (integer) - Total number of pages. - **totalElements** (integer) - Total number of elements. #### Response Example ```json { "content": [ { "id": 1, "name": "Example Product", "price": 150.00, "status": "ACTIVE" } ], "pageable": { "pageNumber": 0, "pageSize": 20, "sort": [ { "field": "price", "direction": "ASC" } ] }, "totalPages": 1, "totalElements": 1 } ``` ### Projection Interface Example ```java public interface ProductSummary { Long getId(); String getName(); BigDecimal getPrice(); String getStatus(); } ``` ``` -------------------------------- ### Execute Batch Operations via HTTP Requests Source: https://context7.com/simplecore-inc/searchable-jpa/llms.txt Illustrates how to perform batch update and delete operations using HTTP requests. It shows example `PUT` and `DELETE` requests with query parameters for filtering and a JSON body for update data. ```bash # Update all products with status DRAFT to ACTIVE PUT /api/products/bulk-update?status.equals=DRAFT Content-Type: application/json { "status": "ACTIVE", "updatedAt": "2026-01-07T12:00:00" } # Delete all products with price less than 10 DELETE /api/products/bulk-delete?price.lessThan=10 ``` -------------------------------- ### Create Controller for Search API (Java) Source: https://github.com/simplecore-inc/searchable-jpa/blob/master/README.md This Java code defines a REST controller with a GET endpoint for searching posts. It uses `@SearchableParams` to bind request parameters to a `SearchCondition` object, which is then passed to the `postService` for execution. ```java @RestController public class PostController { @GetMapping("/api/posts/search") public Page searchPosts( @RequestParam @SearchableParams(PostSearchDTO.class) Map params ) { SearchCondition condition = new SearchableParamsParser<>(PostSearchDTO.class).convert(params); return postService.findAllWithSearch(condition); } } ``` -------------------------------- ### Example JSON for POST-Based Search Source: https://context7.com/simplecore-inc/searchable-jpa/llms.txt This JSON payload demonstrates a complex search condition for products using nested AND/OR operators, value ranges, and sorting. It's designed to be sent in the request body of a POST request to a search endpoint. ```json { "conditions": [ { "operator": "and", "field": "status", "searchOperator": "equals", "value": "ACTIVE" }, { "operator": "and", "field": "price", "searchOperator": "between", "value": 100, "value2": 500 }, { "operator": "or", "conditions": [ { "field": "name", "searchOperator": "contains", "value": "laptop" }, { "field": "categoryName", "searchOperator": "equals", "value": "Electronics" } ] } ], "sort": { "orders": [ { "field": "createdAt", "direction": "desc" }, { "field": "name", "direction": "asc" } ] }, "page": 0, "size": 20 } ``` -------------------------------- ### GET /api/products/search - URL Parameter Search Source: https://context7.com/simplecore-inc/searchable-jpa/llms.txt Allows searching for products using HTTP query parameters. The `SearchableParamsParser` converts these parameters into a `SearchCondition` object for flexible filtering and sorting. ```APIDOC ## GET /api/products/search ### Description Searches for products using query parameters. Supports filtering, sorting, pagination, and null checks. ### Method GET ### Endpoint `/api/products/search` ### Parameters #### Query Parameters - **param_name** (string) - Required - Key-value pairs representing search conditions and sorting. Examples: - `status.equals=ACTIVE` - `price.between=100,500` - `sort=price.asc,createdAt.desc` - `page=0` - `size=20` - `name.contains=laptop` - `categoryName.isNotNull=true` ### Request Example ``` GET /api/products/search?status.equals=ACTIVE&price.between=100,500&sort=price.asc,createdAt.desc&page=0&size=20 ``` ### Response #### Success Response (200) - **content** (array) - Array of product objects matching the search criteria. - **pageable** (object) - Pagination information. - **totalPages** (integer) - Total number of pages. - **totalElements** (integer) - Total number of elements. #### Response Example ```json { "content": [ { "id": 1, "name": "Example Product", "price": 150.00, "status": "ACTIVE" } ], "pageable": { "pageNumber": 0, "pageSize": 20, "sort": [ { "field": "price", "direction": "ASC" } ] }, "totalPages": 1, "totalElements": 1 } ``` ``` -------------------------------- ### SearchOperator Enum in Java Source: https://context7.com/simplecore-inc/searchable-jpa/llms.txt This Java code snippet defines an enum `SearchOperator` that lists 18 different operators for filtering data. It includes comparison, pattern matching, null checks, collection, and range operations. The example `UserSearchDTO` shows how to use these operators with DTO annotations. ```java // Comparison operators SearchOperator.EQUALS SearchOperator.NOT_EQUALS SearchOperator.GREATER_THAN SearchOperator.GREATER_THAN_OR_EQUAL_TO SearchOperator.LESS_THAN SearchOperator.LESS_THAN_OR_EQUAL_TO // String pattern matching SearchOperator.CONTAINS SearchOperator.NOT_CONTAINS SearchOperator.STARTS_WITH SearchOperator.NOT_STARTS_WITH SearchOperator.ENDS_WITH SearchOperator.NOT_ENDS_WITH // Null checks SearchOperator.IS_NULL SearchOperator.IS_NOT_NULL // Collection operations SearchOperator.IN SearchOperator.NOT_IN // Range operations SearchOperator.BETWEEN SearchOperator.NOT_BETWEEN // Usage in DTO annotations public class UserSearchDTO { @SearchableField(operators = {EQUALS, CONTAINS, STARTS_WITH}) private String username; @SearchableField(operators = {GREATER_THAN, LESS_THAN, BETWEEN}) private Integer age; @SearchableField(operators = {IN, NOT_IN}) private UserRole role; @SearchableField(operators = {IS_NULL, IS_NOT_NULL}) private LocalDateTime deletedAt; } ``` -------------------------------- ### Implement Version Selector for Documentation Source: https://github.com/simplecore-inc/searchable-jpa/blob/master/docs/index.html This JavaScript code dynamically creates and manages a version selector dropdown for the documentation. It fetches available versions from 'versions.json', determines the current version from the URL, and allows users to switch between versions. Dependencies: Browser's Fetch API, 'versions.json' file. ```javascript function getCurrentVersion() { var path = window.location.pathname; var match = path.match(/^\/([^\/]+)\/\//); return match ? match[1] : null; } function initVersionSelector() { var currentVersion = getCurrentVersion(); if (!currentVersion) return; fetch('../versions.json') .then(function(response) { if (!response.ok) throw new Error('versions.json not found'); return response.json(); }) .then(function(versions) { createVersionSelector(versions, currentVersion); }) .catch(function(err) { console.log('Version selector not available:', err.message); }); } function createVersionSelector(versions, currentVersion) { var sidebar = document.querySelector('.sidebar'); if (!sidebar) { setTimeout(function() { createVersionSelector(versions, currentVersion); }, 100); return; } if (document.querySelector('.version-selector')) return; var container = document.createElement('div'); container.className = 'version-selector'; var label = document.createElement('label'); label.textContent = 'Version'; var select = document.createElement('select'); select.id = 'version-select'; if (versions.snapshot) { var opt = document.createElement('option'); opt.value = versions.snapshot; opt.textContent = versions.snapshot + ' (SNAPSHOT)'; opt.className = 'version-snapshot'; if (versions.snapshot === currentVersion) opt.selected = true; select.appendChild(opt); } if (versions.releases && versions.releases.length > 0) { versions.releases.forEach(function(version) { var opt = document.createElement('option'); opt.value = version; opt.textContent = version; if (version === currentVersion) opt.selected = true; select.appendChild(opt); }); } select.addEventListener('change', function() { var newVersion = this.value; var currentPath = window.location.hash || '#/'; window.location.href = '../' + newVersion + '/' + currentPath; }); container.appendChild(label); container.appendChild(select); var appName = sidebar.querySelector('.app-name'); if (appName) { appName.parentNode.insertBefore(container, appName.nextSibling); } else { sidebar.insertBefore(container, sidebar.firstChild); } } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initVersionSelector); } else { setTimeout(initVersionSelector, 500); } ``` -------------------------------- ### Add Searchable JPA Dependency (Gradle) Source: https://github.com/simplecore-inc/searchable-jpa/blob/master/README.md This snippet shows how to add the Searchable JPA starter dependency to your Gradle project. It specifies the library artifact and the version to be used. Ensure compatibility with your Spring Boot version. ```gradle implementation 'dev.simplecore.searchable:spring-boot-starter-searchable-jpa:1.0.0-SNAPSHOT' ``` -------------------------------- ### Configure Searchable JPA Properties (YAML) Source: https://github.com/simplecore-inc/searchable-jpa/blob/master/README.md This snippet demonstrates optional configuration for Searchable JPA using application.yml. It covers enabling OpenAPI documentation generation, setting the maximum page size, and defining the default page size. These settings allow customization of library behavior. ```yaml searchable: swagger: enabled: true # Enable automatic OpenAPI documentation generation (default: true) max-page-size: 1000 # Maximum page size (default: 1000) default-page-size: 20 # Default page size (default: 20) ``` -------------------------------- ### Implement Searchable Service (Java) Source: https://github.com/simplecore-inc/searchable-jpa/blob/master/README.md This Java code shows how to implement a service class that extends `DefaultSearchableService`. It injects the repository and `EntityManager` to leverage Searchable JPA's functionality for data access and searching. ```java @Service public class PostService extends DefaultSearchableService { public PostService(PostRepository repository, EntityManager entityManager) { super(repository, entityManager); } } ``` -------------------------------- ### Configure OpenAPI GroupedOpenApi Bean in Java Source: https://context7.com/simplecore-inc/searchable-jpa/llms.txt Provides a Java configuration class to set up `GroupedOpenApi` for integrating Searchable JPA with OpenAPI. It defines a bean that groups product-related API endpoints and applies customizers for search conditions. ```java @Configuration public class SearchableConfig { @Bean public GroupedOpenApi productApi( @Qualifier("searchConditionCustomizer") OperationCustomizer searchConditionCustomizer) { return GroupedOpenApi.builder() .group("product-api") .displayName("Product API") .pathsToMatch("/api/products/**") .addOperationCustomizer(searchConditionCustomizer) .build(); } } ``` -------------------------------- ### Build Search Conditions with Fluent Builder Source: https://context7.com/simplecore-inc/searchable-jpa/llms.txt Demonstrates the programmatic construction of complex search conditions using the SearchConditionBuilder's fluent API. This includes combining multiple criteria with logical operators, specifying sorting, pagination, and fetching specific fields. ```java SearchCondition condition = SearchConditionBuilder.create(ProductSearchDTO.class) .where(w -> w .equals("status", ProductStatus.ACTIVE) .greaterThanOrEqualTo("price", new BigDecimal("10.00"))) .and(a -> a .contains("name", "laptop") .orContains("name", "computer')) .or(o -> o .in("categoryName", Arrays.asList("Electronics", "Computers'))) .sort(s -> s .desc("createdAt") .asc("name')) .page(0) .size(20) .fetchFields("category") .build(); Page results = productService.findAllWithSearch(condition); SearchCondition betweenCondition = SearchConditionBuilder.create(ProductSearchDTO.class) .where(w -> w.between("price", new BigDecimal("100"), new BigDecimal("500'))) .build(); SearchCondition nullCheckCondition = SearchConditionBuilder.create(ProductSearchDTO.class) .where(w -> w.isNotNull("categoryName")) .build(); ``` -------------------------------- ### Product Search API Source: https://context7.com/simplecore-inc/searchable-jpa/llms.txt Retrieves a paginated list of products based on search criteria. The `@SearchableParams` annotation facilitates automatic OpenAPI documentation generation for search parameters. ```APIDOC ## GET /api/products/search ### Description Searches for products based on provided query parameters and returns a paginated result. ### Method GET ### Endpoint /api/products/search ### Parameters #### Query Parameters - **params** (Map) - Required - Dynamic search parameters that adhere to the `ProductSearchDTO` schema. These are automatically documented by `@SearchableParams`. ### Response #### Success Response (200) - **content** (List) - A list of products matching the search criteria. - **pageable** (Pageable) - Information about the pagination. - **totalElements** (Long) - The total number of elements matching the criteria. - **totalPages** (Integer) - The total number of pages. - **last** (Boolean) - Whether this is the last page. - **first** (Boolean) - Whether this is the first page. - **size** (Integer) - The number of elements per page. - **number** (Integer) - The current page number. - **sort** (Sort) - Sorting information. - **numberOfElements** (Integer) - The number of elements in the current page. - **empty** (Boolean) - Whether the page is empty. ``` -------------------------------- ### Integrate OpenAPI with @SearchableParams in Java Source: https://context7.com/simplecore-inc/searchable-jpa/llms.txt Demonstrates using the `@SearchableParams` annotation in a Spring Boot controller to automatically generate OpenAPI/Swagger documentation for search parameters. This annotation integrates with `SearchableParamsParser` for dynamic query building. ```java @RestController @RequestMapping("/api/products") public class ProductController { private final ProductService productService; @GetMapping("/search") public Page searchProducts( @RequestParam @SearchableParams(ProductSearchDTO.class) Map params) { SearchCondition condition = new SearchableParamsParser<>(ProductSearchDTO.class).convert(params); return productService.findAllWithSearch(condition); } } ``` -------------------------------- ### Product Search and Count API Source: https://context7.com/simplecore-inc/searchable-jpa/llms.txt Endpoints for searching products with dynamic criteria and retrieving the total count of products matching the criteria. ```APIDOC ## GET /api/products/search ### Description Retrieves a paginated list of products based on the provided search parameters. ### Method GET ### Endpoint /api/products/search ### Query Parameters - **params** (Map) - Required - A map of search parameters used to filter and sort products. These are parsed into a `SearchCondition` object. ### Request Example (No request body for GET requests, parameters are in query string) ### Response #### Success Response (200) - **Page** (Object) - A page object containing a list of `Product` entities and pagination information. #### Response Example ```json { "content": [ { "id": 1, "name": "Laptop", "price": 1200.00, "status": "AVAILABLE", "category": { "id": 101, "name": "Electronics" }, "createdAt": "2023-10-27T10:00:00Z" } ], "pageable": { "sort": { "sorted": true, "unsorted": false, "empty": false }, "offset": 0, "pageNumber": 0, "pageSize": 20, "paged": true, "unpaged": false }, "totalPages": 5, "totalElements": 95, "last": false, "size": 20, "number": 0, "sort": { "sorted": true, "unsorted": false, "empty": false }, "numberOfElements": 1, "first": true, "empty": false } ``` --- ## GET /api/products/count ### Description Retrieves the total count of products that match the provided search parameters. ### Method GET ### Endpoint /api/products/count ### Query Parameters - **params** (Map) - Required - A map of search parameters used to filter products. These are parsed into a `SearchCondition` object. ### Request Example (No request body for GET requests, parameters are in query string) ### Response #### Success Response (200) - **long** (Number) - The total count of products matching the search criteria. #### Response Example ```json 50 ``` ``` -------------------------------- ### Bulk Product Delete API Source: https://context7.com/simplecore-inc/searchable-jpa/llms.txt Enables bulk deletion of products based on specified search conditions. It uses query parameters to define the criteria for deletion. ```APIDOC ## DELETE /api/products/bulk-delete ### Description Deletes multiple products matching the provided search criteria. ### Method DELETE ### Endpoint /api/products/bulk-delete ### Parameters #### Query Parameters - **params** (Map) - Required - Parameters used to build the search condition (e.g., `price.lessThan=10`). ### Request Example ```bash # Delete all products with price less than 10 DELETE /api/products/bulk-delete?price.lessThan=10 ``` ### Response #### Success Response (200) - **deletedCount** (Long) - The number of products that were deleted. ``` -------------------------------- ### Type-Safe Projection of Search Results in Java Source: https://context7.com/simplecore-inc/searchable-jpa/llms.txt This Java code demonstrates how to achieve type-safe projection of search results using interfaces. The `ProductSummary` interface defines the structure of the projected data. The `ProductService` and `ProductController` show how to integrate this with the search functionality to return optimized data subsets. ```java public interface ProductSummary { Long getId(); String getName(); BigDecimal getPrice(); String getStatus(); } @Service public class ProductService extends DefaultSearchableService { public ProductService(ProductRepository repository, EntityManager entityManager) { super(repository, entityManager); } } @RestController @RequestMapping("/api/products") public class ProductController { private final ProductService productService; @GetMapping("/search/summary") public Page searchProductSummary(@RequestParam Map params) { SearchCondition condition = new SearchableParamsParser<>(ProductSearchDTO.class).convert(params); return productService.findAllWithSearch(condition, ProductSummary.class); } } ``` -------------------------------- ### Bulk Product Update API Source: https://context7.com/simplecore-inc/searchable-jpa/llms.txt Allows for bulk updating of products based on specified search conditions. It takes query parameters to define the search criteria and a request body containing the update data. ```APIDOC ## PUT /api/products/bulk-update ### Description Updates multiple products matching the provided search criteria. ### Method PUT ### Endpoint /api/products/bulk-update ### Parameters #### Query Parameters - **params** (Map) - Required - Parameters used to build the search condition (e.g., `status.equals=DRAFT`). #### Request Body - **updateData** (ProductUpdateDTO) - Required - The data to update the products with. - **status** (ProductStatus) - Optional - The new status for the products. - **price** (BigDecimal) - Optional - The new price for the products. - **updatedAt** (LocalDateTime) - Optional - The timestamp for the update. ### Request Example ```bash # Update all products with status DRAFT to ACTIVE PUT /api/products/bulk-update?status.equals=DRAFT Content-Type: application/json { "status": "ACTIVE", "updatedAt": "2026-01-07T12:00:00" } ``` ### Response #### Success Response (200) - **updatedCount** (Long) - The number of products that were updated. ``` -------------------------------- ### Perform Batch Updates and Deletes using Search in Java Source: https://context7.com/simplecore-inc/searchable-jpa/llms.txt Provides Java code for performing bulk update and delete operations on entities based on search conditions. It includes a DTO for update data and controller methods to handle these operations, leveraging automatic entity management. ```java public class ProductUpdateDTO { private ProductStatus status; private BigDecimal price; private LocalDateTime updatedAt; } @RestController @RequestMapping("/api/products") public class ProductController { private final ProductService productService; @PutMapping("/bulk-update") public ResponseEntity bulkUpdate( @RequestParam Map params, @RequestBody ProductUpdateDTO updateData) { SearchCondition condition = new SearchableParamsParser<>(ProductSearchDTO.class).convert(params); long updatedCount = productService.updateWithSearch(condition, updateData); return ResponseEntity.ok(updatedCount); } @DeleteMapping("/bulk-delete") public ResponseEntity bulkDelete(@RequestParam Map params) { SearchCondition condition = new SearchableParamsParser<>(ProductSearchDTO.class).convert(params); long deletedCount = productService.deleteWithSearch(condition); return ResponseEntity.ok(deletedCount); } } ``` -------------------------------- ### Spring Boot Dependency Version Migration Source: https://github.com/simplecore-inc/searchable-jpa/blob/master/README.md This code snippet illustrates the dependency update required when migrating from Spring Boot 2.x to 3.x for Searchable JPA. It shows the Gradle implementation line for the older 0.1.x version and the newer 1.0.0+ version. ```gradle // 0.1.x version (Spring Boot 2.x) implementation 'dev.simplecore.searchable:spring-boot-starter-searchable-jpa:0.1.x' // 1.0.0+ version (Spring Boot 3.x) implementation 'dev.simplecore.searchable:spring-boot-starter-searchable-jpa:1.0.0+' ``` -------------------------------- ### Add 'Edit on GitHub' Link to Docsify Pages Source: https://github.com/simplecore-inc/searchable-jpa/blob/master/docs/index.html This JavaScript snippet modifies the Docsify markdown renderer to automatically append an 'Edit on GitHub' link to the bottom of markdown pages. It constructs the link based on the file's path in the repository. Dependencies: Docsify.js, GitHub repository. ```javascript function(hook, vm) { var editTexts = { ko: 'GitHub에서 편집', en: 'Edit on GitHub' }; hook.beforeEach(function(html) { if (/githubusercontent\.com/.test(vm.route.file)) { return html; } var lang = (vm.route.path && vm.route.path.startsWith('/en/')) ? 'en' : 'ko'; var editText = editTexts[lang] || editTexts.ko; var url = 'https://github.com/simplecore-inc/searchable-jpa/blob/master/' + vm.route.file; var editHtml = '\n\n---\n\n' + '
' + ' ' + editText + ' ' + '
'; return html + editHtml; }); } ``` -------------------------------- ### Convert URL Parameters to SearchCondition in Java Source: https://context7.com/simplecore-inc/searchable-jpa/llms.txt This Java code demonstrates how to use SearchableParamsParser to convert HTTP query parameters into a SearchCondition object for GET-based search endpoints. It requires the SearchableParamsParser class and a DTO for defining search fields. The output is a Page of Product objects. ```java import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import java.util.Map; @RestController @RequestMapping("/api/products") public class ProductController { private final ProductService productService; @GetMapping("/search") public Page searchProducts(@RequestParam Map params) { SearchCondition condition = new SearchableParamsParser<>(ProductSearchDTO.class).convert(params); return productService.findAllWithSearch(condition); } } ``` -------------------------------- ### Render Mermaid Diagrams in Docsify Source: https://github.com/simplecore-inc/searchable-jpa/blob/master/docs/index.html This code configures Docsify's markdown renderer to specifically handle 'mermaid' code blocks. It wraps them in a div with the class 'mermaid', allowing the Mermaid.js library to render them as diagrams. Dependencies: Docsify.js, Mermaid.js. ```javascript window.$docsify.markdown = { renderer: { code: function(code, lang) { if (lang === 'mermaid') { return '
' + code + '
'; } return this.origin.code.apply(this, arguments); } } }; ``` -------------------------------- ### Extend SearchCondition with Additional Filters (Java) Source: https://context7.com/simplecore-inc/searchable-jpa/llms.txt Demonstrates how to create a new SearchCondition by extending an existing one using `SearchConditionBuilder.from()`. This method preserves the original condition and allows for adding new filters using `and()` or `or()`, ensuring immutability. It's useful for applying tenant-specific filters or layering additional search criteria. ```java SearchCondition baseCondition = SearchConditionBuilder.create(ProductSearchDTO.class) .where(w -> w.equals("status", ProductStatus.ACTIVE)) .sort(s -> s.desc("createdAt")) .size(20) .build(); SearchCondition extendedCondition = SearchConditionBuilder .from(baseCondition, ProductSearchDTO.class) .and(a -> a.greaterThan("price", new BigDecimal("50"))) .build(); @Service public class TenantAwareProductService extends DefaultSearchableService { public TenantAwareProductService(ProductRepository repository, EntityManager entityManager) { super(repository, entityManager); } public Page findForTenant(SearchCondition userCondition, Long tenantId) { SearchCondition tenantCondition = SearchConditionBuilder .from(userCondition, ProductSearchDTO.class) .and(a -> a.equals("tenantId", tenantId)) .build(); return findAllWithSearch(tenantCondition); } } ``` -------------------------------- ### Control Eager Loading with Fetch Fields in Java Source: https://context7.com/simplecore-inc/searchable-jpa/llms.txt Demonstrates how to explicitly control eager loading of lazy associations to prevent N+1 query problems using `fetchFields`. This method allows specifying which related entities or their sub-fields should be fetched along with the main entity. ```java SearchCondition condition = SearchConditionBuilder.create(ProductSearchDTO.class) .where(w -> w.equals("status", ProductStatus.ACTIVE)) .fetchFields("category", "category.parent", "reviews") .build(); Page results = productService.findAllWithSearch(condition); Set fetchPaths = new HashSet<>(Arrays.asList("category", "reviews.author")); SearchCondition conditionWithSet = SearchConditionBuilder.create(ProductSearchDTO.class) .where(w -> w.greaterThan("price", new BigDecimal("100"))) .fetchFields(fetchPaths) .build(); ``` -------------------------------- ### POST-Based Search with JSON Request Body in Java Source: https://context7.com/simplecore-inc/searchable-jpa/llms.txt This Java code defines a REST controller endpoint for searching products using a JSON request body. It accepts a SearchCondition object directly, allowing for complex nested queries and sorting. This is suitable for POST requests where query parameters might become too long or complex. ```java import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/api/products") public class ProductController { private final ProductService productService; @PostMapping("/search") public Page searchProducts(@RequestBody SearchCondition condition) { return productService.findAllWithSearch(condition); } } ``` -------------------------------- ### POST /api/products/search - JSON-Based Search Source: https://context7.com/simplecore-inc/searchable-jpa/llms.txt Enables complex search queries using a JSON request body. This method supports nested conditions and multiple operators for advanced filtering. ```APIDOC ## POST /api/products/search ### Description Performs searches using a structured JSON request body. Allows for complex queries with nested conditions and various operators. ### Method POST ### Endpoint `/api/products/search` ### Parameters #### Request Body - **conditions** (array) - An array of search conditions. Each condition can have an `operator` (AND/OR), `field`, `searchOperator`, and `value`. Nested conditions are supported. - **sort** (object) - Optional. Defines the sorting order for the results. - **orders** (array) - Array of sort orders, each with a `field` and `direction` (ASC/DESC). - **page** (integer) - Optional. The page number to retrieve (0-indexed). - **size** (integer) - Optional. The number of items per page. ### Request Example ```json { "conditions": [ { "operator": "and", "field": "status", "searchOperator": "equals", "value": "ACTIVE" }, { "operator": "and", "field": "price", "searchOperator": "between", "value": 100, "value2": 500 }, { "operator": "or", "conditions": [ { "field": "name", "searchOperator": "contains", "value": "laptop" }, { "field": "categoryName", "searchOperator": "equals", "value": "Electronics" } ] } ], "sort": { "orders": [ { "field": "createdAt", "direction": "desc" }, { "field": "name", "direction": "asc" } ] }, "page": 0, "size": 20 } ``` ### Response #### Success Response (200) - **content** (array) - Array of product objects matching the search criteria. - **pageable** (object) - Pagination information. - **totalPages** (integer) - Total number of pages. - **totalElements** (integer) - Total number of elements. #### Response Example ```json { "content": [ { "id": 1, "name": "Example Product", "price": 150.00, "status": "ACTIVE" } ], "pageable": { "pageNumber": 0, "pageSize": 20, "sort": [ { "field": "createdAt", "direction": "DESC" } ] }, "totalPages": 1, "totalElements": 1 } ``` ``` -------------------------------- ### Annotate DTO Fields for Searchable JPA Source: https://context7.com/simplecore-inc/searchable-jpa/llms.txt Demonstrates how to use the @SearchableField annotation on DTO fields to define their searchability, sortability, allowed operators, and entity field mappings. This annotation is crucial for configuring the library's behavior for specific fields. ```java public class ProductSearchDTO { @SearchableField(operators = {EQUALS}, sortable = true) private Long id; @SearchableField(operators = {EQUALS, CONTAINS, STARTS_WITH}, sortable = true) private String name; @SearchableField(operators = {GREATER_THAN, LESS_THAN, BETWEEN}, sortable = true) private BigDecimal price; @SearchableField(operators = {EQUALS, IN, NOT_IN}) private ProductStatus status; @SearchableField(entityField = "category.name", operators = {EQUALS, CONTAINS}) private String categoryName; @SearchableField(operators = {GREATER_THAN, LESS_THAN}, sortable = true) private LocalDateTime createdAt; } ``` -------------------------------- ### Define Search DTO with Annotations (Java) Source: https://github.com/simplecore-inc/searchable-jpa/blob/master/README.md This Java code defines a Data Transfer Object (DTO) for search criteria, using `@SearchableField` annotations. These annotations specify which fields are searchable and sortable, and define the allowed search operators (e.g., EQUALS, CONTAINS, GREATER_THAN). ```java public class PostSearchDTO { @SearchableField(operators = {EQUALS, CONTAINS}, sortable = true) private String title; @SearchableField(operators = {EQUALS}, sortable = true) private PostStatus status; @SearchableField(operators = {GREATER_THAN, LESS_THAN}, sortable = true) private LocalDateTime createdAt; } ``` -------------------------------- ### SearchOperator Enum Source: https://context7.com/simplecore-inc/searchable-jpa/llms.txt Defines a comprehensive set of 18 search operators for data filtering, including comparison, pattern matching, null checks, and range operations. ```APIDOC ## Search Operators ### Description Provides a wide range of operators for building search conditions. ### Operators **Comparison Operators:** - `EQUALS` - `NOT_EQUALS` - `GREATER_THAN` - `GREATER_THAN_OR_EQUAL_TO` - `LESS_THAN` - `LESS_THAN_OR_EQUAL_TO` **String Pattern Matching:** - `CONTAINS` - `NOT_CONTAINS` - `STARTS_WITH` - `NOT_STARTS_WITH` - `ENDS_WITH` - `NOT_ENDS_WITH` **Null Checks:** - `IS_NULL` - `IS_NOT_NULL` **Collection Operations:** - `IN` - `NOT_IN` **Range Operations:** - `BETWEEN` - `NOT_BETWEEN` ### Usage Example (DTO Annotation) ```java public class UserSearchDTO { @SearchableField(operators = {SearchOperator.EQUALS, SearchOperator.CONTAINS, SearchOperator.STARTS_WITH}) private String username; @SearchableField(operators = {SearchOperator.GREATER_THAN, SearchOperator.LESS_THAN, SearchOperator.BETWEEN}) private Integer age; @SearchableField(operators = {SearchOperator.IN, SearchOperator.NOT_IN}) private UserRole role; @SearchableField(operators = {SearchOperator.IS_NULL, SearchOperator.IS_NOT_NULL}) private LocalDateTime deletedAt; } ``` ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.