Last updated on October 5th, 2024
In Spring Data JPA we use find by contains String to fetch the records from the database table using a custom query method with the Contains, Containing, IsContaining and Like keywords. The custom query method starts with the findBy keyword followed by the property name(field_name) of the JPA entity class followed by Contains, Containing, IsContaining and Like keywords then defines the String type parameter and its name. Add the property name of the JPA Entity to the method where the characters contain the records we want to find based on the provided String. Add methods in the repository interface that extends the JpaRepository interface of Spring Data JPA. In this topic, we will know how to use the JPA Repository to find records based on the string contained in the database table.
Use of Spring Data JPA Find By Contains
This Spring Data JPA find by contains is used in search functionality where we can find records from the database based on a word or partial character of a word that matched.
Methods to Spring Data JPA Find By Contains
1. Using Contains Keyword
We need to add a custom query method with a Contains keyword in the repository interface. The method starts with the findBy keyword followed by the property name(field_name) of the JPA entity class then adds the Contains keyword then adds the parameter type and name of the method[findByFieldNameContains(DataType variable_name)]. The method annotated with @Transactional annotation then will execute.
Example
public interface WebSeriesRepository extends JpaRepository<WebSeries, Long> {
@Transactional
List<WebSeries> findByNameContains(String name);
}
2. Using Containing Keyword
We need to add a custom query method starting with the findBy keyword followed by the field name then add the Containing keyword followed by parameter type and name[findByFieldNameContaining(DataType variable_name)] in the repository interface. The method annotated with @Transactional annotation then will execute.
Example
public interface WebSeriesRepository extends JpaRepository<WebSeries, Long> {
@Transactional
List<WebSeries> findByNameContaining(String name);
}
3. Using IsContaining Keyword
We need to add a custom query method starting with the findBy keyword followed by the field name then add the IsContaining keyword followed by parameter type and name[findByFieldNameIsContaining(DataType variable_name)] in the repository interface. The method annotated with @Transactional annotation then will execute.
Example
public interface WebSeriesRepository extends JpaRepository<WebSeries, Long> {
@Transactional
List<WebSeries> findByNameIsContaining(String name);
}
4. Using Like Keyword
We need to add a custom query method starting with the findBy keyword followed by the field name then add the Like keyword followed by parameter type and name[findByFieldNameLike(DataType variable_name)] in the repository interface. The method annotated with @Transactional annotation then will execute.
Example
public interface WebSeriesRepository extends JpaRepository<WebSeries, Long> {
@Transactional
List<WebSeries> findByNameLike(String name);
}
- This above method will give us records from the database table when having %prefix and postfix with value.
Handling Case-Insensitive
To handle case-insensitive in Spring Data JPA find by contains then we need to use the IgnoreCase keyword with Contains, Containing, IsContaining and Like keywords while adding a custom query method in the repository interface.
Example
public interface WebSeriesRepository extends JpaRepository<WebSeries, Long> {
@Transactional
List<WebSeries> findByNameContainsIgnoreCase(String name);
}
Step-by-Step Guide to Find By Contains
Let’s make a Spring Boot Application step-by-step guide to implement find by contains String to get records from the table in the JPA Repository. We will create an example for this we are searching the web series from a database table based on the specific word or partial characters of the word through the methods mentioned above.
These are the following steps:
- Create Spring Boot Project
- Setup in the IDE
- Configure H2 Database
- Create a JPA Entity
- Create a Repository Interface
- Create a Service Interface
- Implement the Service Interface
- Create a Controller
- Run the Spring Boot Application
1. Create Spring Boot Project
We are creating a Spring Boot Project from the web tool Spring Initializr. By Providing details for the project and select the following Maven dependencies:
- Spring Web
- Spring Data JPA
- H2 Database
- Lombok
2. Setup in the IDE
We use Eclipse IDE to set up and configure the created Spring Boot Project. You can use other IDE such as STS, IntelliJ IDEA, etc.
Project Structure of Spring Boot
This image shows the project structure of Spring Boot in Eclipse IDE.
Maven Dependency
Here is the complete maven dependencies file pom.xml for the project which will implement methods to Spring Data JPA Find By Contains.
pom.xml
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.0</version>
<relativePath/>
<!-- lookup parent from repository -->
</parent>
<groupId>com.springjava</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
3. Configure H2 Database
We are going to configure the H2 database connection in the application.properties file.
application.properties
#H2 Database Configuration
spring.datasource.url=jdbc:h2:mem:test
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto=update
spring.h2.console.enabled=true
4. Create a JPA Entity
Let’s create a JPA Entity class. For example, consider a WebSeries entity and use Lombok for generating setter and getter methods, a constructor, etc.
WebSeries.java
package com.springjava.entity;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.Data;
@Data
@Entity
public class WebSeries {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String season;
}
5. Create a Repository Interface
Create a repository interface for the WebSeries JPA Entity class that interface extends the JpaRepository interface to perform persistence operations on the web_series database table.
WebSeriesRepository.java
package com.springjava.repository;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.transaction.annotation.Transactional;
import com.springjava.entity.WebSeries;
public interface WebSeriesRepository extends JpaRepository<WebSeries, Long> {
@Transactional
List<WebSeries> findByNameContains(String name);
@Transactional
List<WebSeries> findByNameContaining(String name);
@Transactional
List<WebSeries> findByNameIsContaining(String name);
@Transactional
List<WebSeries> findByNameLike(String name);
//Case InSensitivity
@Transactional
List<WebSeries> findByNameContainsIgnoreCase(String name);
}
6. Create a Service Interface
Create a Service interface WebSeriesService with some method declaration.
WebSeriesService.java
package com.springjava.service;
import java.util.List;
import com.springjava.entity.WebSeries;
public interface WebSeriesService {
void saveAll(List<WebSeries>webSeriesList);
List<WebSeries> getByNameContains(String name);
List<WebSeries> getByNameContaining(String name);
List<WebSeries> getByNameLike(String name);
List<WebSeries> getByNameIsContaining(String name);
List<WebSeries> getByNameContainsIgnoreCase(String name);
}
7. Implement the Service Interface
Implement the WebSeriesService interface in the WebSeriesServiceImpl class. This class is annotated with @Service annotation, where we inject WebSeriesRepository to call all its methods.
WebSeriesServiceImpl.java
package com.springjava.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.springjava.entity.WebSeries;
import com.springjava.repository.WebSeriesRepository;
@Service
public class WebSeriesServiceImpl implements WebSeriesService {
@Autowired
private WebSeriesRepository webSeriesRepo;
@Override
public void saveAll(List < WebSeries > webSeriesList) {
webSeriesRepo.saveAll(webSeriesList);
}
@Override
public List < WebSeries > getByNameContains(String name) {
return webSeriesRepo.findByNameContains(name);
}
@Override
public List < WebSeries > getByNameContaining(String name) {
return webSeriesRepo.findByNameContaining(name);
}
@Override
public List < WebSeries > getByNameLike(String name) {
return webSeriesRepo.findByNameLike(name);
}
@Override
public List < WebSeries > getByNameIsContaining(String name) {
return webSeriesRepo.findByNameIsContaining(name);
}
@Override
public List < WebSeries > getByNameContainsIgnoreCase(String name) {
return webSeriesRepo.findByNameContainsIgnoreCase(name);
}
}
8. Create a Controller
Create a controller class WebSeriesController. This is annotated with @RestController to make this class a RestController.
WebSeriesController.java
package com.springjava.controller;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
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;
import com.springjava.entity.WebSeries;
import com.springjava.service.WebSeriesService;
@RestController
@RequestMapping("/api/webseries")
public class WebSeriesController {
@Autowired
private WebSeriesService webSeriesService;
@PostMapping("/save-all")
public ResponseEntity<?> save(@RequestBody List<WebSeries> webSeriesList) {
Map<String, Object> respWebSeries = new LinkedHashMap<String, Object>();
webSeriesService.saveAll(webSeriesList);
respWebSeries.put("status", 1);
respWebSeries.put("message", "Record is Saved Successfully!");
return new ResponseEntity<>(respWebSeries, HttpStatus.CREATED);
}
@GetMapping("/contains/{name}")
public ResponseEntity<?> getByNameContains(@PathVariable String name) {
Map<String, Object> respWebSeries = new LinkedHashMap<String, Object>();
List<WebSeries> webSeriesList=webSeriesService.getByNameContains(name);
if(!webSeriesList.isEmpty()) {
respWebSeries.put("status", 1);
respWebSeries.put("data", webSeriesList);
return new ResponseEntity<>(respWebSeries, HttpStatus.OK);
}else {
respWebSeries.clear();
respWebSeries.put("status", 0);
respWebSeries.put("message", "Data is not found");
return new ResponseEntity<>(respWebSeries, HttpStatus.NOT_FOUND);
}
}
@GetMapping("/containing/{name}")
public ResponseEntity<?> getByNameContaining(@PathVariable String name) {
Map<String, Object> respWebSeries = new LinkedHashMap<String, Object>();
List<WebSeries> webSeriesList=webSeriesService.getByNameContaining(name);
if(!webSeriesList.isEmpty()) {
respWebSeries.put("status", 1);
respWebSeries.put("data", webSeriesList);
return new ResponseEntity<>(respWebSeries, HttpStatus.OK);
}else {
respWebSeries.clear();
respWebSeries.put("status", 0);
respWebSeries.put("message", "Data is not found");
return new ResponseEntity<>(respWebSeries, HttpStatus.NOT_FOUND);
}
}
@GetMapping("/like/{name}")
public ResponseEntity<?> getByNameLike(@PathVariable String name) {
Map<String, Object> respWebSeries = new LinkedHashMap<String, Object>();
List<WebSeries> webSeriesList=webSeriesService.getByNameLike("%"+name+"%");
if(!webSeriesList.isEmpty()) {
respWebSeries.put("status", 1);
respWebSeries.put("data", webSeriesList);
return new ResponseEntity<>(respWebSeries, HttpStatus.OK);
}else {
respWebSeries.clear();
respWebSeries.put("status", 0);
respWebSeries.put("message", "Data is not found");
return new ResponseEntity<>(respWebSeries, HttpStatus.NOT_FOUND);
}
}
@GetMapping("/Iscontaining/{name}")
public ResponseEntity<?> getByNameIsContains(@PathVariable String name) {
Map<String, Object> respWebSeries = new LinkedHashMap<String, Object>();
List<WebSeries> webSeriesList=webSeriesService.getByNameIsContaining(name);
if(!webSeriesList.isEmpty()) {
respWebSeries.put("status", 1);
respWebSeries.put("data", webSeriesList);
return new ResponseEntity<>(respWebSeries, HttpStatus.OK);
}else {
respWebSeries.clear();
respWebSeries.put("status", 0);
respWebSeries.put("message", "Data is not found");
return new ResponseEntity<>(respWebSeries, HttpStatus.NOT_FOUND);
}
}
@GetMapping("ignoreCase/{name}")
public ResponseEntity<?> getByNameContainsIgnoreCase(@PathVariable String name) {
Map<String, Object> respWebSeries = new LinkedHashMap<String, Object>();
List<WebSeries> webSeriesList=webSeriesService.getByNameContainsIgnoreCase(name);
if(!webSeriesList.isEmpty()) {
respWebSeries.put("status", 1);
respWebSeries.put("data", webSeriesList);
return new ResponseEntity<>(respWebSeries, HttpStatus.OK);
}else {
respWebSeries.clear();
respWebSeries.put("status", 0);
respWebSeries.put("message", "Data is not found");
return new ResponseEntity<>(respWebSeries, HttpStatus.NOT_FOUND);
}
}
}
9. Run the Spring Boot Application
Right-click this Spring Boot application on the DemoApplication.java, then click Run As and select Java Application.
H2 Database Console
If we want to check the H2 database console then we need to browse this URL “http://localhost:8080/h2-console” on the browser.
JSON Array
We are creating a sample JSON Array to test the API http://localhost:8080/api/webseries/save-all.
[
{
"name": "Mirzapur",
"season": "S3"
},
{
"name": "Panchayat",
"season": "S3"
},
{
"name": "Gullak",
"season": "S4"
}
]
Test the APIs on the Postman Tool
POST: http://localhost:8080/api/webseries/save-all
GET: http://localhost:8080/api/webseries/contains/M
This API hits then Spring Data JPA (internally uses Hibernate as a JPA provider) generates SQL statement in the console below here:
Hibernate: select ws1_0.id,ws1_0.name,ws1_0.season from web_series ws1_0 where ws1_0.name like ? escape '\'
GET: http://localhost:8080/api/webseries/containing/M
This API hits then Spring Data JPA (internally uses Hibernate as a JPA provider) generates SQL statement in the console below here:
Hibernate: select ws1_0.id,ws1_0.name,ws1_0.season from web_series ws1_0 where ws1_0.name like ? escape '\'
GET: http://localhost:8080/api/webseries/Iscontaining/M
This API hits then Spring Data JPA (internally uses Hibernate as a JPA provider) generates SQL statement in the console below here:
Hibernate: select ws1_0.id,ws1_0.name,ws1_0.season from web_series ws1_0 where ws1_0.name like ? escape '\'
GET: http://localhost:8080/api/webseries/like/M
This API hits then Spring Data JPA (internally uses Hibernate as a JPA provider) generates SQL statement in the console below here:
Hibernate: select ws1_0.id,ws1_0.name,ws1_0.season from web_series ws1_0 where ws1_0.name like ? escape '\'
GET: http://localhost:8080/api/webseries/ignoreCase/m
This API hits then Spring Data JPA (internally uses Hibernate as a JPA provider) generates SQL statement in the console below here:
Hibernate: select ws1_0.id,ws1_0.name,ws1_0.season from web_series ws1_0 where upper(ws1_0.name) like upper(?) escape '\'
Conclusion
We are fetching records from the database table using Spring Data JPA find by containing a string with Spring Boot restful API web services through various custom query methods.