Saturday, 3 August 2019

Spring boot: Configuring Data Source


This is continuous to my previous application. You can download previous working application from this link.

I am going to use H2 embeddable data base to store the data. If you want to learn more about H2 database, I would recommend you to go through my below post.

Note:
Clear the VM argument ‘-Dspring.profiles.active=prod’ that we added in previous step.

Step 1: Add dependencies for spring data jpa and H2 database.
 <dependencies>
 
  <dependency>
   <groupId>junit</groupId>
   <artifactId>junit</artifactId>
   <version>3.8.1</version>
   <scope>test</scope>
  </dependency>

  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
  </dependency>

  <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-jpa -->
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-jpa</artifactId>
  </dependency>

  <!-- https://mvnrepository.com/artifact/com.h2database/h2 -->
  <dependency>
   <groupId>com.h2database</groupId>
   <artifactId>h2</artifactId>
  </dependency>

 </dependencies>

Step 2: Update application.properties with following content.

application.properties
# Setting log level to DEBUG
logging.level.org.springframework.web=DEBUG

# Application launch at this port
server.port=8080

## H2 specific properties
spring.h2.console.enabled=true
spring.h2.console.path=/h2

spring.datasource.url=jdbc:h2:file:~/db/myDatabase.db;DB_CLOSE_ON_EXIT=FALSE;DB_CLOSE_DELAY=-1;

spring.datasource.username=krishna
spring.datasource.password=password123

spring.datasource.driverClassName=org.h2.Driver

## JPA specific properties
spring.jpa.hibernate.ddl-auto=update

spring.jpa.database-platform=org.hibernate.dialect.H2Dialect

spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true

## Database connection pooling properties
# Number of ms to wait before throwing an exception if no connection is available.
spring.datasource.max-wait=10000

# Maximum number of active connections that can be allocated from this pool at the same time.
spring.datasource.tomcat.max-active=10
spring.datasource.tomcat.max-idle=5
spring.datasource.tomcat.min-idle=3

H2 console is only intended for use during development, so you should take care to ensure that spring.h2.console.enabled is not set to true in production.

By default, the console is available at /h2-console. You can customize the console’s path by using the spring.h2.console.path property.

Step 3: Run App.java application.


Since we configured H2 database console path to /h2, ppen the url ‘http://localhost:8080/h2/’ in browser to see H2 console.

Spring boot configures H2 database with default values.

Update JDBC URL User Name and Password values from application.properties.


Click on Connect button.

Go to you home directory, you can see that there is a folder named ‘db’ is created.

$tree db
db
└── myDatabase.db.mv.db

0 directories, 1 file

Step 4: Adding JPA specific configurations on Employee model class.

Employee.java
package com.sample.app.model;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Employee {
 @Id
 @GeneratedValue(strategy = GenerationType.AUTO)
 private int id;
 private String firstName;
 private String lastName;

 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;
 }

}

Step 5: Define EmployeeRepository interface like below.

EmployeeRepository.java
package com.sample.app.repository;

import org.springframework.data.repository.CrudRepository;

import com.sample.app.model.Employee;  

public interface EmployeeRepository extends CrudRepository<Employee, Integer> {

 
}

Since Employee table has an integer as primary key, we should extend CrudRepository<Employee, Integer> interface.

Step 6: Define EmployeeService class like below.

EmployeeService.java
package com.sample.app.service;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.sample.app.model.Employee;
import com.sample.app.repository.EmployeeRepository;

@Service
public class EmployeeService {

 @Autowired
 private EmployeeRepository employeeRepository;

 public List<Employee> getAllEmployees() {
  List<Employee> emps = new ArrayList<>();
  employeeRepository.findAll().forEach(emps::add);
  return emps;
 }

 public Optional<Employee> getEmployee(int id) {
  return employeeRepository.findById(id);
 }

 public Employee createEmployee(Employee emp) {
  return employeeRepository.save(emp);
 }

 public Employee deleteEmployee(int id) {
  Optional<Employee> emp = employeeRepository.findById(id);
  
  if(!emp.isPresent()) {
   return null;
  }
  
  Employee returnedEmp = emp.get();
  employeeRepository.deleteById(id);
  return returnedEmp;
 }

 public Employee updateEmployee(Employee emp) {
  Optional<Employee> persistedEmp = employeeRepository.findById(emp.getId());

  if (!persistedEmp.isPresent()) {
   return null;
  }

  Employee employeeFromDB = persistedEmp.get();
  employeeFromDB.setFirstName(emp.getFirstName());
  employeeFromDB.setLastName(emp.getLastName());

  return employeeRepository.save(employeeFromDB);

 }
}

Step 7: Update EmployeeController class like below.

EmployeeController.java
package com.sample.app.controller;

import java.util.List;
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.sample.app.model.Employee;
import com.sample.app.service.EmployeeService;

@RestController
@RequestMapping("api/v1/")
public class EmployeeController {

 @Autowired
 private EmployeeService empService;

 @RequestMapping(value = "employees", method = RequestMethod.GET)
 public ResponseEntity<List<Employee>> all() {
  return ResponseEntity.ok(empService.getAllEmployees());
 }

 @RequestMapping(value = "employees", method = RequestMethod.POST)
 public ResponseEntity<Employee> create(@RequestBody Employee emp) {
  return new ResponseEntity<>(empService.createEmployee(emp), HttpStatus.CREATED);

 }

 @RequestMapping(value = "employees/{id}", method = RequestMethod.GET)
 public ResponseEntity<Employee> byId(@PathVariable int id) {
  Optional<Employee> emp = empService.getEmployee(id);

  if (!emp.isPresent()) {
   return new ResponseEntity<>(HttpStatus.NOT_FOUND);
  }

  return ResponseEntity.ok(emp.get());

 }

 @RequestMapping(value = "employees/{id}", method = RequestMethod.DELETE)
 public ResponseEntity<Employee> deleteById(@PathVariable int id) {

  Employee emp = empService.deleteEmployee(id);

  if (emp == null) {
   return new ResponseEntity<>(HttpStatus.NOT_FOUND);
  }

  return ResponseEntity.ok(emp);
 }

 @RequestMapping(value = "employees/{id}", method = RequestMethod.PUT)
 public ResponseEntity<Employee> updateById(@PathVariable int id, @RequestBody Employee emp) {

  emp.setId(id);
  Employee updatedEmployee = empService.updateEmployee(emp);

  if (updatedEmployee == null) {
   return new ResponseEntity<>(HttpStatus.NOT_FOUND);
  }

  return ResponseEntity.ok(updatedEmployee);
 }

}


App.java
package com.sample.app;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class App {
 public static void main(String[] args) {
  SpringApplication.run(App.class, args);
 }
}

Run App.java.


Open the url ‘http://localhost:8080/h2’.


Enter password as ‘password123’ and click on Connect button.

As you see left side of the window, EMPLOYEE table is created.

Let’s insert new employee by hitting below request.

Method: POST
Payload:
{
    "firstName" : "Joel",
    "lastName" : "Chelli"
}

Once you hit the request, you will receive below response.

{
    "id": 1,
    "firstName": "Joel",
    "lastName": "Chelli"
}

Hit below request to retrieve all the employees from database.

API: http://localhost:8080/api/v1/employees
Method: GET

Once you hit above request, you will receive below response.
[
    {
        "id": 1,
        "firstName": "Joel",
        "lastName": "Chelli"
    }
]

That’s it….you are done. In my next post, I am going to explain how to test the spring boot application.

You can download complete working application from below github link.

Total project structure looks like below.


Note
a.   As part of spring-boot auto configuration, it uses tomcat-jdbc as default connection pooling strategy.
b.   Spring boot also support other connection pooling libraries like Hikari CP, Commons DBCP, Commons DBCP2.



Previous                                                    Next                                                    Home

No comments:

Post a Comment