In this tutorial we’ll see how to create Spring Boot + Spring Data JPA + MySQL + Spring RESTful Webservice. There is already a similar example in the post Spring Data JPA Example. By using Spring Boot you will see a significant reduction in required configuration.
If you want to see how to create Maven project, please check this post- Create Java Project Using Maven in Eclipse
Maven Dependencies
<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> <groupId>com.knpcode</groupId> <artifactId>SpringBootProject</artifactId> <version>0.0.1-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.6.RELEASE</version> </parent> <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> <!-- MySQL Driver --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
In our configuration, Spring Boot version is 2.1.6 so Spring Boot gets the dependencies which support this version.
For Spring Data JPA you need to add spring-boot-starter-data-jpa that will get Spring Data, Hibernate and other jars required for JPA.
Since we are developing a web service, we add a spring-boot-starter-web dependency, that adds the necessary dependencies required for creating a Spring web application.
spring-boot-maven-plugin is also added, this plugin provides many convenient features-
- It helps to create an executable jar (über-jar), which makes it more convenient to execute and transport your service.
- It also searches for the public static void main() method to flag the class having this method as a runnable class.
With these dependencies added Spring Boot takes care of getting the required jar dependencies, even an embedded web server (Tomcat in this case) because of the starter web dependency.
DB table Query
MySQL DB table used for this Spring Boot and Spring data JPA example can be created using the following query.
CREATE TABLE `employee` ( `id` int(11) NOT NULL AUTO_INCREMENT, `first_name` varchar(45) DEFAULT NULL, `last_name` varchar(45) DEFAULT NULL, `department` varchar(45) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
JPA Entity class
Entity class which maps to the employee table in DB.
import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name="employee") public class Employee { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; @Column(name="first_name") private String firstName; @Column(name="last_name") private String lastName; @Column(name="department") private String dept; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getDept() { return dept; } public void setDept(String dept) { this.dept = dept; } @Override public String toString() { return "Id= " + getId() + " First Name= " + getFirstName() + " Last Name= " + getLastName() + " Dept= "+ getDept(); } }
@Entity annotation specifies that this model class is an entity.
@Table annotation specifies the primary table for the entity.
@Id annotation specifies the primary key of the entity.
@GeneratedValue specifies the primary key generation strategy which is autoincrement in this case.
@Column annotation specifies the mapped table column name for the field.
Spring Data JPA Repository Class
import java.util.List; import org.springframework.data.repository.CrudRepository; import com.knpcode.springbootproject.model.Employee; public interface EmployeeRepository extends CrudRepository<Employee, Integer> { List<Employee> findByLastName(String lastName); }
EmployeeRepository interface extends CrudRepository which takes the domain class to manage (Employee in this case) as well as the id type of the domain class as type arguments.
That is all the data access code you need for your CRUD functionality, no need to write a class that implements this interface. Spring takes care of automatically implementing this repository interface.
Apart from the methods inherited from CrudRepository there is one more method findByLastName added in the Repository. Custom queries can be generated automatically or you can write the query as Named query or by using @Query annotation with in the repository.
To see an example of @Query annotation, check this post- Spring Data JPA @Query Annotation Example
To see an example of @NamedQuery annotation, check this post- Spring Data JPA @NamedQuery Annotation Example
Service class
From the service layer we’ll call the DAO layer methods. Since all we need is a repository in case of spring data so we’ll call methods of repository from the service class. Notice that repository instance has to be injected in the service class.
import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.knpcode.springbootproject.model.Employee; import com.knpcode.springbootproject.repository.EmployeeRepository; @Service public class EmployeeService { @Autowired private EmployeeRepository repository; public Employee getEmployeeById(int id) { return repository.findById(id).get(); } public List<Employee> getAllEmployees(){ return (List<Employee>) repository.findAll(); } public void deleteEmployeeById(int id){ repository.deleteById(id); } public Employee addEmployee(Employee emp) { return repository.save(emp); } public List<Employee> getEmployeeByLastName(String lastName) { return repository.findByLastName(lastName); } }
Controller class
Using a Rest controller class we’ll map the path to the methods that are to be called for the requests.
import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.DeleteMapping; 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.ResponseStatus; import org.springframework.web.bind.annotation.RestController; import com.knpcode.springbootproject.model.Employee; import com.knpcode.springbootproject.service.EmployeeService; @RestController @RequestMapping("/employee") public class EmployeeController { @Autowired EmployeeService empService; @GetMapping("/{id}") public Employee getEmployeeById(@PathVariable int id) { return empService.getEmployeeById(id); } @GetMapping public List<Employee> getAllEmployees(){ return empService.getAllEmployees(); } @DeleteMapping("/{id}") @ResponseStatus(HttpStatus.OK) public void deleteEmployeeById(@PathVariable int id){ empService.deleteEmployeeById(id); } @PostMapping @ResponseStatus(HttpStatus.CREATED) public Employee addEmployee(@RequestBody Employee emp) { return empService.addEmployee(emp); } @GetMapping("/lastname/{lastName}") public List<Employee> getEmployeeByLastName(@PathVariable String lastName) { return empService.getEmployeeByLastName(lastName); } }
DB Configuration
We have already seen how Spring Data takes the responsibility of deriving queries for the query methods so you don’t have to write boiler plate code for CRUD functionality. Now see the magic of Spring Boot and the reduction in configuration that is required.
By default Spring boot reads properties file at this location src/main/resources/application.properties
You must define the DB connection attributes and Hibernate related properties in the application.properties file.
spring.datasource.url=jdbc:mysql://localhost:3306/knpcode spring.datasource.username= spring.datasource.password= spring.jpa.properties.hibernate.sqldialect=org.hibernate.dialect.MySQLInnoDBDialect spring.jpa.properties.hibernate.showsql=true
Notice the keys used in the key/value pair stored in properties file, ensure that the same keys are used.
With this properties file and the jars in classpath for Hibernate and MySQL, Spring Boot can automatically configure Hibernate as JPA Vendor and set the DataSource using the DB connection attributes defined in application.properties file.
Create Spring Boot Application Class
Here is an application class with the main method which is the entry point for Spring Boot application.
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class JPAApp { public static void main(String[] args) { SpringApplication.run(JPAApp.class, args); } }
@SpringBootApplication is a convenience annotation that adds all of the following annotations-
- @Configuration annotation tags the class as a source of bean definitions for the application context.
- @EnableAutoConfiguration tells Spring Boot to enable auto configuration so that beans are created automatically based on classpath settings, other beans, and various property settings. For example starter spring-boot-starter-web adds Tomcat and Spring MVC so the auto-configuration assumes that you are developing a web application and sets up Spring accordingly which includes setting up a DispatcherServlet.
- @ComponentScan tells Spring to look recursively for other components, configurations and services inside this package and register them.
The main method is the application entry point which delegates to Spring Boot’s SpringApplication class by calling run. SpringApplication bootstraps this Spring Data JPA application, starting Spring, which, in turn, starts the embedded Tomcat web server.
Running the application
1- You can run it as a stand alone Java application by running the class with the main method (JPAApp.java) from Eclipse IDE itself.
Right click JPAApp.java – Run As – Java Application
If everything works fine you should see a message on console similar to following (part from messages for Initializing WebApplicationContext, Hibernate configuration)
Tomcat started on port(s): 8080 (http) with context path '' com.knpcode.springbootproject.JPAApp : Started JPAApp
2- Dependency spring-boot-starter-parent also provides a run goal that you can use to start the application. Type mvn spring-boot:run from the root project directory to start the application.
F:\knpcode\Spring WorkSpace\SpringBootProject>mvn spring-boot:run [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building SpringBootProject 0.0.1-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] [INFO] >>> spring-boot-maven-plugin:2.1.6.RELEASE:run (default-cli) > test-compile @ SpringBootProject >>> 2019-09-23 19:08:36.733 INFO 8476 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path '' 2019-09-23 19:08:36.748 INFO 8476 --- [ main] com.knpcode.springbootproject.JPAApp : Started JPAApp in 4.958 seconds (JVM running for 22.892)
3- You can also create a completely self-contained executable jar file using run mvn package from the command line.
F:\knpcode\Spring WorkSpace\SpringBootProject>mvn package [INFO] [INFO] --- maven-jar-plugin:3.1.2:jar (default-jar) @ SpringBootProject --- [INFO] Building jar: F:\knpcode\Spring WorkSpace\SpringBootProject\target\SpringBootProject-0.0.1-SNAPSHOT.jar [INFO] [INFO] --- spring-boot-maven-plugin:2.1.6.RELEASE:repackage (repackage) @ SpringBootProject --- [INFO] Replacing main artifact with repackaged archive [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS
To run application using the created jar, use the java -jar command, as follows-
java -jar target\SpringBootProject-0.0.1-SNAPSHOT.jar
Once the application is deployed on Tomcat Server, using any of the options given above, you can test the webservice using Postman client.
Adding employee
Note that the request selected is POST and the URL is http://localhost:8080/SpringJPAProject/employee
Data is sent as request body in JSON format. In the response added Employee data is sent back.
Get all employees
Get Employee by last name
You can also also send requests directly from browser as done for this request.
Delete Employee by ID
That's all for the topic Spring Boot + Spring Data JPA + MySQL + Spring RESTful. If something is missing or you have something to share about the topic please write a comment.
You may also like
- Spring Boot + Data JPA + Oracle One to Many Example
- Spring Boot + Spring Data REST Example
- Spring Data JPA Auditing Example
- Spring Boot Microservices Eureka + Ribbon
- Initializer Block in Java
- Reverse an Array In-place Java Program
- Data Compression in Hadoop Framework
- Method Overloading in Python With Examples
No comments:
Post a Comment