Here we are going to develop spring boot based REST API application. In this application we are going to use @RestController, Spring Boot JPA, MYSQL as database server.
DataBase Tables
CREATE TABLE `person` ( `pid` INT(11) NOT NULL AUTO_INCREMENT, `pname` VARCHAR(200) NOT NULL DEFAULT '0', `pgender` SMALLINT(1) NOT NULL DEFAULT '0', `pdob` DATE NOT NULL, PRIMARY KEY (`pid`) ) COLLATE='latin1_swedish_ci' ENGINE=InnoDB ; CREATE TABLE `relation_string` ( `rsid` INT(11) NOT NULL AUTO_INCREMENT, `rslabel` VARCHAR(100) NOT NULL DEFAULT '0', PRIMARY KEY (`rsid`) ) COLLATE='latin1_swedish_ci' ENGINE=InnoDB ; CREATE TABLE `realtions` ( `realtionid` INT(11) NOT NULL AUTO_INCREMENT, `rsid` INT(11) NULL DEFAULT '0', `pid` INT(11) NULL DEFAULT '0', PRIMARY KEY (`realtionid`), INDEX `FK__relation_string` (`rsid`), INDEX `FK__person` (`pid`), CONSTRAINT `FK__person` FOREIGN KEY (`pid`) REFERENCES `person` (`pid`) ON UPDATE CASCADE ON DELETE CASCADE, CONSTRAINT `FK__relation_string` FOREIGN KEY (`rsid`) REFERENCES `relation_string` (`rsid`) ON UPDATE CASCADE ON DELETE CASCADE ) COLLATE='latin1_swedish_ci' ENGINE=InnoDB ;
After creating database schema with the above details , where data base details are
Database name: jai43
Database username: jai43user
Database user password: 123456
Database connection configurations
you can choose your own database name and userdetails, then update details in application.properties file of application# Database connection details spring.datasource.url=jdbc:mysql://localhost:3306/jai43?useSSL=false&serverTimezone=UTC&useLegacyDatetimeCode=false spring.datasource.username=jai43user spring.datasource.password=123456
You have to include above database configurations in application.properties file which is located at resources folder of application
Dependencies
Then we have to add the following dependencies to pom.xml fileorg.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-data-jpa org.springframework.boot spring-boot-devtools runtime mysql mysql-connector-java runtime
you can see there we have added spring boot starters for web, JPA and devtools( for auto refresh of changes ) and mysql connector
Project directory structure
Project directory structure |
In the above you can see number of packages created for clear separation of classes which are controllers, DAO, Business classes, entities and DTO classes.
Enabling Hibernate as JPA implementation
We are using Hibernate as JPA implementation to develop this application, so that we have to add spring jpa properties hibernate dailect property in application.properties file, to enable hibernate implementation for JPA in our application we have to add the following property in application.properties file# the following property is to enable hibernate as a JPA implementation # here we have used mysql_dialect for hinernate dialect to perform SQL operations effectively on our MYSQL database spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
Project Architecture
Here we have use DAO pattern for implementing this application/example. Following image shows flow of actions in this application which include controller, service, DAO and DTO/Model.
Flow of actions |
To demonstrate a simple CRUD application we are going to work with only Person database table ( with in this tutorial) .
As our first task we need to create an Entity class for database table person. Here Entity will map with database table ( this is called as Object mapping with database table which will be happen in ORM technologies like hibernate )
Create Person Entity class
@Entity is a class level annotation to convert normal class into an entity class.
@Table is a class level annotation to specify table properties to map with class name, if table is equal to class name then @Table annotation is optional, but if table name is different than entity class name then we must specify name property of @Table annotation , in this example database table name is person and Entity class name is Person, so there is no big use with @Table annotation at this movement.
package com.jai43.jsite.entities; import java.io.Serializable; import java.sql.Date; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; import javax.validation.constraints.NotBlank; @Entity @Table(name = "person") public class Person implements Serializable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long pid; @NotBlank(message = "Person name must not be empty") private String pname; private int pgender; private Date pdob; public Long getPid() { return pid; } public void setPid(Long pid) { this.pid = pid; } public String getPname() { return pname; } public void setPname(String pname) { this.pname = pname; } public int getPgender() { return pgender; } public void setPgender(int pgender) { this.pgender = pgender; } public Date getPdob() { return pdob; } public void setPdob(Date pdob) { this.pdob = pdob; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((pdob == null) ? 0 : pdob.hashCode()); result = prime * result + pgender; result = prime * result + ((pid == null) ? 0 : pid.hashCode()); result = prime * result + ((pname == null) ? 0 : pname.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Person other = (Person) obj; if (pdob == null) { if (other.pdob != null) return false; } else if (!pdob.equals(other.pdob)) return false; if (pgender != other.pgender) return false; if (pid == null) { if (other.pid != null) return false; } else if (!pid.equals(other.pid)) return false; if (pname == null) { if (other.pname != null) return false; } else if (!pname.equals(other.pname)) return false; return true; } }
Creating Repository: Person Repository class
Here we have used JpaRepository class to create PersonRepository.java class , this has inbuilt methods to perform database operations like findByID(),save(),delete() etc...
/** * */ package com.jai43.jsite.repositories; import java.util.List; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; import com.jai43.jsite.entities.Person; /** * @author Admin * */ @Repository public interface PersonRepository extends JpaRepository<Person, Long> { }
In the line 19 we have mentioned Person and Long as a generic parameters, so that this repository can perform database operations on table person and its primary key type is long( this mapping done with Person.java entity class ).
@Repository annotation used to created repository class.
DAO classes
In this section we are going to discuss about DAO implementaion. We have created DAO interface and then we are creating DAO interface implementation class.
@Component is here used as a class level annotation , this annotation tells to the spring container that the class annotated with @Component is a bean which will be initiated during bootstrap of spring container.
package com.jai43.jsite.dao; import java.util.List; import org.springframework.stereotype.Component; @Component public interface PersonsDAO<Person> { List<Person> getAllPersons(); Person getPersonByID(long id) throws Exception; Person addNewPerson(Person p); void deletePersonByID(long id); Person updatePerson(Person person); }
The above interface ( PersonsDAO.java ) is going to be implemented in the following class
package com.jai43.jsite.dao.impl; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.jai43.jsite.dao.PersonsDAO; import com.jai43.jsite.entities.Person; import com.jai43.jsite.repositories.PersonRepository; @Component public class PersonsDAOImpl implements PersonsDAO<Person> { @Autowired PersonRepository personRepository; @Override public List<Person> getAllPersons() { // TODO Auto-generated method stub return personRepository.findAll(); } @Override public Person getPersonByID(long id) throws Exception { // TODO Auto-generated method stub return personRepository.findById(id).orElseThrow(() -> new Exception("Couldn't find a person with id: " + id)); } @Override public Person addNewPerson(Person p) { // TODO Auto-generated method stub return personRepository.save(p); } @Override public void deletePersonByID(long id) { // TODO Auto-generated method stub personRepository.deleteById(id); } @Override public Person updatePerson(Person person) { // TODO Auto-generated method stub return personRepository.save(person); } }
The above implementation class autowired a repository class.
Service Layer
In this section we are going to create service layer of our application, where business logic will be produced to REST endpoints.
@Service annotation lets the spring container to turn normal class into service class.
package com.jai43.jsite.services; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.jai43.jsite.dao.PersonsDAO; import com.jai43.jsite.dao.impl.PersonsDAOImpl; @Service public class PersonService<Person> { @Autowired PersonsDAO<Person> personsDAO; public List<Person> getAllPersons() { return personsDAO.getAllPersons(); } public Person getPersonById(long id) throws Exception { return personsDAO.getPersonByID(id); } public Person addNewPerson(Person p) { return personsDAO.addNewPerson(p); } public void deletePersonByID(long id) { personsDAO.deletePersonByID(id); } public Person updatePerson(Person person) { return personsDAO.updatePerson(person); } }
Controller for Person CRUD operations
Finally this is the time to create REST entdpoints in a rest controller. This application is an API so our controller must be annotated with @RestController.
package com.jai43.jsite.controller; import java.util.List; import javax.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.ResponseEntity; 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.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.jai43.jsite.entities.Person; import com.jai43.jsite.services.PersonService; @RestController @RequestMapping("/person") public class PersonController { @Autowired PersonService<Person> personService; @GetMapping("/all") public List<Person> getAllPersons() { return personService.getAllPersons(); } @GetMapping("/p/{pid}") Person getPErsonByID(@PathVariable(name = "pid") long id) throws Exception { return personService.getPersonById(id); } @GetMapping("/w") public String welcome() { return "Iam jai"; } @PostMapping("/addNewPerson") Person addNewPerson(@Valid @RequestBody Person p) { return personService.addNewPerson(p); } @DeleteMapping("/deletePerson/{id}") ResponseEntity<Person> deletePersonById(@PathVariable(name = "id") long pid) throws Exception { Person person = personService.getPersonById(pid); HttpHeaders headers = new HttpHeaders(); headers.add("Responded", "PersonController"); personService.deletePersonByID(pid); return ResponseEntity.ok().headers(headers).body(person); } @PutMapping("/update") Person updatePerson(@Valid @RequestBody Person p) { return personService.updatePerson(p); } }
Output screens
Following are screen shots of outputview all persons |
If we want to get gender as Male or Female as a JSON result for rest endpoints, it is not possible in this example...
You can find an article by clicking on the following link to know how to use modelmapping to customise rest endpoint results
https://code123.info/2020/04/modelmappingspringboot.html
Post a Comment
Post a Comment