Pasang Iklan Atas 1

Down Menu

Drop Down MenusCSS Drop Down MenuPure CSS Dropdown Menu

Thursday, January 31, 2019

Using multiple datasources with Spring Boot and Spring Data JpaRepository


Spring Boot with Spring Data makes it easy to access a database through so called Repositories. But what if you want to access multiple databases maybe even with different Database Management Systems?
Luckily Spring provides a way of doing this.
I provided an example project with two PostgreSQL datasources on GitHub: https://github.com/jahe/spring-boot-multiple-datasources

1. Add an additional datasource configuration to your application.properties

# Oracle DB - "foo"
spring.datasource.url=jdbc:oracle:thin:@//db-server-foo:1521/FOO
spring.datasource.username=fooadmin
spring.datasource.password=foo123
spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
# PostgreSQL DB - "bar"
bar.datasource.url=jdbc:postgresql://db-server-bar:5432/bar
bar.datasource.username=baradmin
bar.datasource.password=bar123
bar.datasource.driver-class-name=org.postgresql.Driver

2. Set the SQL Dialect to “default” in your application.properties to let Spring autodetect the different SQL Dialects of each datasource

spring.jpa.database=default

3. Create a Java Package for each datasource with two nested Packages “domain” and “repo”

src/main/java
- com.foobar
  - foo
    - domain
    - repo
  - bar
    - domain
    - repo

4. Create a Configuration Class for the Oracle database “foo” named “FooDbConfig.java”

package com.foobar;
 
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
  entityManagerFactoryRef = "entityManagerFactory",
  basePackages = { "com.foobar.foo.repo" }
)
public class FooDbConfig {
  
  @Primary
  @Bean(name = "dataSource")
  @ConfigurationProperties(prefix = "spring.datasource")
  public DataSource dataSource() {
    return DataSourceBuilder.create().build();
  }
  
  @Primary
  @Bean(name = "entityManagerFactory")
  public LocalContainerEntityManagerFactoryBean 
  entityManagerFactory(
    EntityManagerFactoryBuilder builder,
    @Qualifier("dataSource") DataSource dataSource
  ) {
    return builder
      .dataSource(dataSource)
      .packages("com.foobar.foo.domain")
      .persistenceUnit("foo")
      .build();
  }
    
  @Primary
  @Bean(name = "transactionManager")
  public PlatformTransactionManager transactionManager(
    @Qualifier("entityManagerFactory") EntityManagerFactory 
    entityManagerFactory
  ) {
    return new JpaTransactionManager(entityManagerFactory);
  }
}

5. Create a Configuration Class for the PostgreSQL database “bar” named “BarDbConfig.java”

package com.foobar;

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
  entityManagerFactoryRef = "barEntityManagerFactory",
  transactionManagerRef = "barTransactionManager",
  basePackages = { "com.foobar.bar.repo" }
)
public class BarDbConfig {
 
  @Bean(name = "barDataSource")
  @ConfigurationProperties(prefix = "bar.datasource")
  public DataSource dataSource() {
    return DataSourceBuilder.create().build();
  }
  
  @Bean(name = "barEntityManagerFactory")
  public LocalContainerEntityManagerFactoryBean 
  barEntityManagerFactory(
    EntityManagerFactoryBuilder builder,
    @Qualifier("barDataSource") DataSource dataSource
  ) {
    return
      builder
        .dataSource(dataSource)
        .packages("com.foobar.bar.domain")
        .persistenceUnit("bar")
        .build();
  }
  @Bean(name = "barTransactionManager")
  public PlatformTransactionManager barTransactionManager(
    @Qualifier("barEntityManagerFactory") EntityManagerFactory
    barEntityManagerFactory
  ) {
    return new JpaTransactionManager(barEntityManagerFactory);
  }
}

6. Create an Entity “Foo.java” for the Oracle database “foo”

package com.foobar.foo.domain;
 
@Entity
@Table(name = "FOO")
public class Foo {
  
  @Id
  @GeneratedValue
  @Column(name = "ID")
  private Long id;
  
  @Column(name = "FOO")
  private String foo;
  
  Foo(String foo) {
    this.foo = foo;
  }
  
  Foo() {
    // Default constructor needed by JPA
  }
}

7. Create a Repository “FooRepository.java” for the Oracle database “foo”

package com.foobar.foo.repo;
 
@Repository
public interface FooRepository extends JpaRepository<Foo, Long> {
  
  Foo findById(Long id); 
  
}

8. Create an Entity “Bar.java” for the PostgreSQL database “bar”

package com.foobar.bar.domain;
 
@Entity
@Table(name = "BAR")
public class Bar {
  
  @Id
  @GeneratedValue
  @Column(name = "ID")
  private Long id;
  
  @Column(name = "BAR")
  private String bar;
  
  Bar(String bar) {
    this.bar = bar;
  }
  
  Bar() {
    // Default constructor needed by JPA
  }
}

9. Create a Repository “BarRepository.java” for the PostgreSQL database “bar”

package com.foobar.bar.repo;
 
@Repository
public interface BarRepository extends JpaRepository<Bar, Long> {
  
  Bar findById(Long id); 
  
}

10. Create the Spring Boot Main Class “Application.java”

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

11. Use the Repositories in a REST Controller (or somewhere else)

package com.foobar;
 
@RestController
public class FooBarController {
  
  private final FooRepository fooRepo;
  private final BarRepository barRepo;
  
  @Autowired
  FooBarController(FooRepository fooRepo, BarRepository barRepo) {
    this.fooRepo = fooRepo;
    this.barRepo = barRepo;
  }
  
  @RequestMapping("/foobar/{id}")
  public String fooBar(@PathVariable("id") Long id) {
    Foo foo = fooRepo.findById(id);
    Bar bar = barRepo.findById(id);
    
    return foo.getFoo() + " " + bar.getBar(); 
  }
}

Done. 👍

Follow me on Twitter if you like: @joeclever
Example project with two PostgreSQL datasources: https://github.com/jahe/spring-boot-multiple-datasources

Friday, January 25, 2019

OEM - Object Exchange Model (Pengertian, makna, manfaat, karakteristik)

Hasil gambar untuk object exchange model
Gambar 1.0 Object Exchange Model Example from de.Wikipedia.org
Object Exchange Model (OEM) adalah yaitu sebuah model untuk bertukar data semi-terstruktur antara berorientasi objek database. berfungsi sebagai model data dasar dalam berbagai proyek kelompok Stanford University Database, termasuk Tsimmis, pengetahuan, dan C3.
Variasi sedikit OEM telah berkembang di berbagai proyek Stanford. Di Lore, label sebenarnya berada di "tautan" induk-anak alih-alih objek. Misalnya, jika objek OEM memiliki banyak orangtua, objek orangtua yang berbeda dapat menggunakan label yang berbeda untuk mengidentifikasi objek itu.
OEM - Object Exchange Model adalah salah satu cara untuk menggambarkan data semi tersetruktur di dalam object oriented database dan ditampilkan menggunakan beberapa tipe graph berlabel.
OEM menggunakan konsep child & parent serta tree dalam desain graphnya. selain itu OEM mengidentifikasi satu sama lain menggunakan labels yang mana adalah mandatory.
Objek OEM berisi pengidentifikasi objek, label tekstual deskriptif, tipe dan nilai. Dalam kebanyakan kasu pengidentifikasi objek hanya digunakan dalam implementasi sistem dan tetap tersembunyi dari pengguna akhir. Nilai dapat berupa atom atau kompleks. Nilai - nilai OEM atomik dapat berupa bilangan bulat, real, string, gambar, klip video, klip suara, kueri, program, atau nilai data lainnya yang harus dianggap tidak dapat dibagi oleh database. Tipe selalu dikaitkan dengan nilai atom, tetapi tipe yang berbeda tidak spesifik untuk OEM. Nilai OEM yang kompleks, di sisi lain, adalah kumpulan 0 atau lebih objek OEM. Objek OEM kompleks dapat dianggap sebagai induk dari sejumlah objek anak OEM. Perhatikan bahwa satu objek OEM mungkin memiliki beberapa objek induk. Dengan definisi rekursif yang sederhana ini, kita dapat membangun jaringan OEM yang kompleks untuk memodelkan hubungan antar data.
Model data semi terstruktur object exchange model (OEM) mempunyai karakteristik sebagai berikut :
* memiliki object identifier
* obyek berbentuk triple (label, tipe, nilai)
* obyek yang kompleks di dekomposis secara hirarki ke dalam obyek yang lebih kecil
* selain itu, object disebut sebagai complex object
* complex object bisa  menjadi parent atau child dari object lainnya
* label menyatakan apa yang direpresentasikan objectnya. Name adalah label khusus yang bisa berfungsi sebagai alias dari sebuah object
* sebuah object OEM dapat bersifat quadruple (lable, oid, type, value)