Sunday, July 1, 2018

Multiple Database Configuration Spring Boot


Salam,

Untuk kesempatan kali ini saya akan sharing bagaimana cara menggunakan lebih dari satu database di spring boot.
oke langsung saja klo begitu .

Pertama kita bisa create new project spring boot di https://start.spring.io/




Selanjutnya konfigurasi database, kita akan menggunakan 2 database sebagai contoh.
Disini saya menggunakan 2 database mysql di file application.properties dan hibernate.properties

  • application.properties
spring.user.datasource.url=jdbc:mysql://localhost:3306/user
spring.user.datasource.username=root
spring.user.datasource.password=root
spring.user.datasource.driver-class-name=com.mysql.jdbc.Driver

spring.booking.datasource.url=jdbc:mysql://localhost:3306/booking
spring.booking.datasource.username=root
spring.booking.datasource.password=root
spring.booking.datasource.driver-class-name=com.mysql.jdbc.Driver

  • hibernate.properties

hibernate.show_sql=true
hibernate.format_sql=true
Kemudian kita buat model class untuk masing - masing database
  • Tabel user_details
package com.devglan.model;

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 = "user_details")
public class UserDetails {

 @Id
 @Column
 @GeneratedValue(strategy = GenerationType.IDENTITY)
 private Long id;

 @Column(name = "first_name")
 private String firstName;
 
 @Column(name = "last_name")
 private String lastName;
 
 @Column
 private String email;
 @Column
 private String password;

 public Long getId() {
  return id;
 }

 public void setId(Long 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 getEmail() {
  return email;
 }

 public void setEmail(String email) {
  this.email = email;
 }

 public String getPassword() {
  return password;
 }
 public void setPassword(String password) {
  this.password = password;
 }
 
}
  • Tabel Booking
package com.devglan.model;

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 = "booking")
public class Booking {
 
 @Id
 @Column
 @GeneratedValue(strategy = GenerationType.IDENTITY)
 private Long id;
 
 private Long createdBy;
 private String pickupAddress;
 private String dropAddress;
 private String bookingAmount;
 
 public Long getId() {
  return id;
 }
 public void setId(Long id) {
  this.id = id;
 }
 public Long getCreatedBy() {
  return createdBy;
 }
 public void setCreatedBy(Long createdBy) {
  this.createdBy = createdBy;
 }
 public String getPickupAddress() {
  return pickupAddress;
 }
 public void setPickupAddress(String pickupAddress) {
  this.pickupAddress = pickupAddress;
 }
 public String getDropAddress() {
  return dropAddress;
 }
 public void setDropAddress(String dropAddress) {
  this.dropAddress = dropAddress;
 }
 public String getBookingAmount() {
  return bookingAmount;
 }
 public void setBookingAmount(String bookingAmount) {
  this.bookingAmount = bookingAmount;
 }

}
Lalu kita buat konfigurasi class untuk masing - masing tabel dari 2 database yang berbeda
  • Database User
package com.devglan.config;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.stream.Collectors;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import com.devglan.model.UserDetails;

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
  entityManagerFactoryRef = "userEntityManager", 
  transactionManagerRef = "userTransactionManager", 
  basePackages = "com.devglan.user.dao"
)
public class UserDBConfig {

 @Bean
 @ConfigurationProperties(prefix = "spring.user.datasource")
 public DataSource postgresqlDataSource() {
  return DataSourceBuilder
     .create()
     .build();
 }

 @Bean(name = "userEntityManager")
 public LocalContainerEntityManagerFactoryBean postgresqlEntityManagerFactory(EntityManagerFactoryBuilder builder) {
  return builder
     .dataSource(postgresqlDataSource())
     .properties(hibernateProperties())
     .packages(UserDetails.class)
     .persistenceUnit("userPU")
     .build();
 }

 @Bean(name = "userTransactionManager")
 public PlatformTransactionManager postgresqlTransactionManager(@Qualifier("userEntityManager") EntityManagerFactory entityManagerFactory) {
  return new JpaTransactionManager(entityManagerFactory);
 }

 private Map<String, Object> hibernateProperties() {

  Resource resource = new ClassPathResource("hibernate.properties");
  
  try {
   Properties properties = PropertiesLoaderUtils.loadProperties(resource);
   
   return properties.entrySet().stream()
           .collect(Collectors.toMap(
              e -> e.getKey().toString(),
              e -> e.getValue())
             );
  } catch (IOException e) {
   return new HashMap<String, Object>();
  }
 }
}
  • Database Booking
package com.devglan.config;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.stream.Collectors;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import com.devglan.model.Booking;

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
  entityManagerFactoryRef = "bookingEntityManager", 
  transactionManagerRef = "bookingTransactionManager", 
  basePackages = "com.devglan.booking.dao"
)
public class BookingDBConfig {

 @Primary
 @Bean
 @ConfigurationProperties(prefix = "spring.booking.datasource")
 public DataSource mysqlDataSource() {
  return DataSourceBuilder
     .create()
     .build();
 }

 @Primary
 @Bean(name = "bookingEntityManager")
 public LocalContainerEntityManagerFactoryBean mysqlEntityManagerFactory(EntityManagerFactoryBuilder builder) {
  return builder
     .dataSource(mysqlDataSource())
     .properties(hibernateProperties())
     .packages(Booking.class)
     .persistenceUnit("bookingPU")
     .build();
 }

 @Primary
 @Bean(name = "bookingTransactionManager")
 public PlatformTransactionManager mysqlTransactionManager(@Qualifier("bookingEntityManager") EntityManagerFactory entityManagerFactory) {
  return new JpaTransactionManager(entityManagerFactory);
 }

 private Map<String, Object> hibernateProperties() {

  Resource resource = new ClassPathResource("hibernate.properties");
  
  try {
   Properties properties = PropertiesLoaderUtils.loadProperties(resource);
   
   return properties.entrySet().stream()
           .collect(Collectors.toMap(
              e -> e.getKey().toString(),
              e -> e.getValue())
             );
  } catch (IOException e) {
   return new HashMap<String, Object>();
  }
 }
}
Kemudian kita buat file dao dari masing- masing model
  • Dao Tabel UserDetails
package com.devglan.user.dao;

import org.springframework.data.repository.CrudRepository;

import com.devglan.model.UserDetails;

public interface UserDao extends CrudRepository<UserDetails, Long> {
 
 UserDetails findByEmail(String email);
 
}
  • Dao Tabel Booking
package com.devglan.booking.dao;

import java.util.List;

import org.springframework.data.repository.CrudRepository;

import com.devglan.model.Booking;

public interface BookingDao extends CrudRepository<Booking, Long> {
 
 List<Booking> findByCreatedBy(Long userId);

}
Selanjutnya kita buat class service
package com.devglan.service.impl;

import java.util.List;

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

import com.devglan.booking.dao.BookingDao;
import com.devglan.model.Booking;
import com.devglan.model.UserDetails;
import com.devglan.service.BookingService;
import com.devglan.user.dao.UserDao;

@Service
public class BookingServiceImpl implements BookingService {
 
 @Autowired
 private UserDao userDao;
 
 @Autowired
 private BookingDao bookingDao;

 public List<Booking> findUserBookings(String emailId) {
  UserDetails userdetails = userDao.findByEmail(emailId);
  List<Booking> bookings = bookingDao.findByCreatedBy(userdetails.getId());
  return bookings;
 }
}
package com.devglan.service;

import java.util.List;

import com.devglan.model.Booking;

public interface BookingService {

 List<Booking> findUserBookings(String emailId);
}
Lalu kita buat controller
package com.devglan.controller;

import java.util.List;

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

import com.devglan.model.Booking;
import com.devglan.service.BookingService;

@Controller
@RequestMapping("/booking")
public class BookingController {
 
 @Autowired
 private BookingService bookingService;

 @RequestMapping(value = "/{email:.+}", method = RequestMethod.GET)
 public ResponseEntity<List<Booking>> findUserBookings(@PathVariable(name = "email", value = "email") String email) {

  List<Booking> bookings = bookingService.findUserBookings(email);
  return new ResponseEntity<List<Booking>>(bookings, HttpStatus.OK);
 }

}
Kemudian kita coba jalankan aplikasi yang telah kita buat dan coba kita test di url  -localhost:8080/booking/abc@test.com dan lihat hasilnya

Referensi
- https://www.devglan.com/spring-boot/spring-boot-multiple-database-configuration

No comments:

Post a Comment