EzyJPA: Connect Multi Datasources
Nowaday, we usually work with microservice system, so, we will have a requirement to fetch data from many datasources. With EzyJPA this task is so simple.
1. Configuration
Let's say we need connect to 2 datasource named
author
and book
for book management system. For first step, we need add to the configuration file like this: # for application.yaml
author:
datasource:
jdbcUrl: jdbc:mysql://root:12345678@localhost:3306/author
driverClassName: com.mysql.cj.jdbc.Driver
book:
datasource:
jdbcUrl: jdbc:mysql://root:12345678@localhost:3306/book
driverClassName: com.mysql.cj.jdbc.Driver
# for application.properties
author.datasource.jdbcUrl=jdbc:mysql://root:12345678@localhost:3306/author
author.datasource.driverClassName=com.mysql.cj.jdbc.Driver
book.datasource.jdbcUrl=jdbc:mysql://root:12345678@localhost:3306/book
book.datasource.driverClassName=com.mysql.cj.jdbc.Driver
Next step, if you're using in your project's dependencies, you need exclude
EzyJpaConfiguration
from bean management like this: import com.tvd12.ezyfox.bean.annotation.EzyExclusiveClassesConfiguration;
import com.tvd12.ezyfox.boot.jpa.EzyJpaConfiguration;
@EzyExclusiveClassesConfiguration(
EzyJpaConfiguration.class
)
public class ExampleJpaMultiDatasourceApplication {
public static void main(String[] args) throws Exception {
EzyHttpApplicationBootstrap.start(ExampleJpaMultiDatasourceApplication.class);
}
}
Now, you can create 2 configration classes like this:
import static com.tvd12.properties.file.util.PropertiesUtil.getPropertiesByPrefix;
import static java.util.Collections.singleton;
import java.util.Properties;
import java.util.Set;
import com.tvd12.ezyfox.bean.annotation.EzyConfigurationBefore;
import com.tvd12.ezyfox.boot.jpa.EzyJpaConfiguration;
@EzyConfigurationBefore
public class AuthorJpaConfiguration extends EzyJpaConfiguration {
@Override
public void setPackagesToScan(Set<String> packagesToScan) {
super.setPackagesToScan(
singleton("com.tvd12.ezydata.example.jpa.author")
);
}
@Override
public void setProperties(Properties properties) {
final Properties clone = new Properties(properties);
clone.putAll(getPropertiesByPrefix(properties, "author"));
super.setProperties(clone);
}
}
import static com.tvd12.properties.file.util.PropertiesUtil.getPropertiesByPrefix;
import static java.util.Collections.singleton;
import java.util.Properties;
import java.util.Set;
import com.tvd12.ezyfox.bean.annotation.EzyConfigurationBefore;
import com.tvd12.ezyfox.boot.jpa.EzyJpaConfiguration;
@EzyConfigurationBefore
public class BookJpaConfiguration extends EzyJpaConfiguration {
@Override
public void setPackagesToScan(Set<String> packagesToScan) {
super.setPackagesToScan(
singleton("com.tvd12.ezydata.example.jpa.book")
);
}
@Override
public void setProperties(Properties properties) {
final Properties clone = new Properties(properties);
clone.putAll(getPropertiesByPrefix(properties, "book"));
super.setProperties(clone);
}
}
For entity classes and repository interfaces, you will need to organize them into the respective packages like this:
root-package/ +--config/ | +--AuthorJpaConfiguration.java | +--BookJpaConfiguration.java +--author/ | +--repository/ | | +--AuthorRepository.java | +--entity/ | +--Author.java +--book/ | +--repository/ | | +--BookRepository.java | | +--CategoryRepository.java | +--result/ | | +--SumBookPriceResult.java | +--entity/ | +--Category.java | +--Book.java
2. Usage
After the configuration, you can use the repositories normally like single data source like this:
@EzySingleton
@AllArgsConstructor
public class BookService {
private final AuthorRepository authorRepository;
private final BookRepository bookRepository;
public BookData addBook(AddBookData data) {
Book existedBook = bookRepository.findByNameAndAuthorId(
data.getBookName(),
data.getAuthorId()
);
if (existedBook != null) {
throw new DuplicatedBookException(
"author: " + data.getAuthorId() +
" has already registered book: " + data.getBookName()
);
}
final Author author = authorRepository.findById(data.getAuthorId());
if (author == null) {
throw new InvalidAuthorIdException(
"author: " + data.getAuthorId() + " not found"
);
}
// other codes
}
}