How to query data in Spring Data through Example?

Photo by Tima Miroshnichenko on Pexels.com

One of the frequent operations you perform on a database is retrieving data based on certain criteria.

Let’s say you have a table containing developer details , their name , experience and their primary technology skill.

And you want your app to be able to query this data.

There are many ways to do this.

You can write a Named Query in Spring Data.

You can use method names in Spring Data starting with findByFieldName

You can write native sql queries.

You can use Criteria API.

And one another way is to query by example!

Say you have a developer who has 2 years of experience in Java and you want all the developers who are like her.

Spring Data allows you to create a developer object and retrieve all the records who share similar profile like this developer!

This is achieved using the class “Example” and by using the static method “of” of the class Example.

Here is a sample piece of code:

	    DevTeam devTeam = new DevTeam();	
		devTeam.setExperience(experience);
		devTeam.setTechnology(technology);
		
		return repository.findAll(Example.of(devTeam));

Here DevTeam is an entity class representing a table in the database which contains developer details.

You create a developer with the experience and technology you pass at run time.

And then you query the repository by wrapping this object in Example.of() method.

The repository used here is JpaRepository.

Let’s check the full code below:

Here is a sample controller class:

package com.example.demo;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DevTeamController {

	@Autowired
	private DevTeamRepository repository;

	@GetMapping("/getTechMembers")
	public List<DevTeam> getTechMembers(@RequestParam(name = "technology") String technology,
			@RequestParam(name = "experience") String experience) {

		DevTeam devTeam = new DevTeam();
		devTeam.setExperience(experience);
		devTeam.setTechnology(technology);

		return repository.findAll(Example.of(devTeam));

	}
}

Here is the repository:

package com.example.demo;

import org.springframework.data.jpa.repository.JpaRepository;

public interface DevTeamRepository extends JpaRepository<DevTeam, Integer> {

}
Advertisements

Here is the entity class:

package com.example.demo;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;

@Entity
@Table(name = "DEV_TEAM")
public class DevTeam {
	
	
	@Id
	@Column(name = "id")
	private Integer id;
	
	
	@Column(name="name")
	private String name;
	
	
	@Column(name="experience")
	private String experience;
	
	@Column(name="technology")
	private String technology;

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getExperience() {
		return experience;
	}

	public void setExperience(String experience) {
		this.experience = experience;
	}

	public String getTechnology() {
		return technology;
	}

	public void setTechnology(String technology) {
		this.technology = technology;
	}

	@Override
	public String toString() {
		return "DevTeam [id=" + id + ", name=" + name + ", experience=" + experience + ", technology=" + technology
				+ "]";
	}
	
	

}

I used an in memory database to test the above example.

Here is the data I used:




INSERT INTO DEV_TEAM VALUES

(1,'JOHN','2YEARS','JAVA'),
(2,'Gaurav','5YEARS','SQL'),
(3,'Tom','3YEARS','ANGULAR'),
(4,'Raj','3YEARS','ANGULAR'),
(5,'Hasel','2YEARS','JAVA'),
(6,'Rachel','3YEARS','SQL');

Let me query developers who have 2 years of experience in Java technology as coded in the controller class.

I started the app and fired the below request in the browser:

It returned all the records who matched the developer profile we passed.

As you see the technology and experience are passed at runtime as request parameters .

And thus we can query a table using an example!

Here is the github link to the code:

https://github.com/vijaysrj/querybyexample

In addition to Example API,

You can also use various options available in ExampleMatcher while creating an ‘Example’ like ignoring some properties, matching case-insensitive, matching exact etc:

ExampleMatcher matcher = ExampleMatcher.matching().withIgnorePaths("age").withIgnoreCase("name");
Example<User> example = Example.of(user, matcher);

In this example, the matcher will ignore the ‘age’ property and match case-insensitive values for ‘name’ property while creating an example.

PS:

In production apps you can’t directly get the input from user and pass it to the repository as shown in the example ,as it could pose a security risk.

You need to validate the input just as you would do in other ways of querying the database.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s