EzyJPA Introduction
1. Introduce EzyJPA
2. Structure of EzyJPA

- Database Context: wraps EntityManager, DataBinding. Manages repositiors, QueryManager and DataSerializers. Provides function to get repostiories, queries and serializers
- Repostiories: Manages all repostiores by name and type
- QueryManager: Manages all queries, collects queries from annotations and deverloper set
- DataSerializers: Manages all data serializers and deserializers, provide a way to allow deverloper custom and set their serializers and deverlopers
- Repostiory: converts queries, data and calls to database
3. Install JPA
1. To use EzyJPA you need add dependency
<dependency>
<groupId>com.tvd12</groupId>
<artifactId>ezydata-jpa</artifactId>
<version>1.2.7</version>
</dependency>
The latest version can be found in the Maven Central repository.
2. To use EzyJPA you need configure to create repositories
You can use ezyfox-boot-autoconfigure by add to your pom.xml:
<dependency>
<groupId>com.tvd12</groupId>
<artifactId>ezyfox-boot-autoconfigure</artifactId>
<version>1.0.9</version>
</dependency>
Or because with some reason, you can not use
ezyfox-boot-autoconfigure
you can config like this: import com.tvd12.ezydata.database.EzyDatabaseContext;
import com.tvd12.ezydata.jpa.EzyJpaDatabaseContextBuilder;
import com.tvd12.ezydata.jpa.loader.EzyJpaDataSourceLoader;
import com.tvd12.ezydata.jpa.loader.EzyJpaEntityManagerFactoryLoader;
import com.tvd12.ezyfox.bean.EzyBeanConfig;
import com.tvd12.ezyfox.bean.EzyPackagesToScanAware;
import com.tvd12.ezyfox.bean.EzySingletonFactory;
import com.tvd12.ezyfox.bean.EzySingletonFactoryAware;
import com.tvd12.ezyfox.bean.annotation.EzyAutoBind;
import com.tvd12.ezyfox.bean.annotation.EzyConfigurationBefore;
import com.tvd12.ezyfox.util.EzyPropertiesAware;
import lombok.Setter;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import java.util.Properties;
import java.util.Set;
import static com.tvd12.ezyfox.boot.util.EzyDatabaseContexts.addRepositoriesFromDatabaseContextToSingletonFactory;
@Setter
@EzyConfigurationBefore
public class EzyJpaConfiguration implements
EzyBeanConfig,
EzyPropertiesAware,
EzySingletonFactoryAware {
private Properties properties;
@EzyAutoBind
private EzySingletonFactory singletonFactory;
@Override
public void config() {
addRepositoriesFromDatabaseContextToSingletonFactory(
databaseContext(),
singletonFactory
);
}
private EzyDatabaseContext databaseContext() {
return new EzyJpaDatabaseContextBuilder()
.properties(properties)
.entityManagerFactory(entityManagerFactory())
.scan("your_package_to_scan")
.build();
}
private EntityManagerFactory entityManagerFactory() {
return new EzyJpaEntityManagerFactoryLoader()
.entityPackages(packagesToScan)
.dataSource(dataSource())
.properties(properties)
.load("Default");
}
private DataSource dataSource() {
return new EzyJpaDataSourceLoader()
.properties(properties, "datasource")
.load();
}
}
3. You can add to your configuration file like this:
# for application.yaml
datasource:
jdbcUrl: jdbc:mysql://root:12345678@localhost:3306/test
driverClassName: com.mysql.cj.jdbc.Driver
# for application.properties
datasource.jdbcUrl=jdbc:mysql://root:12345678@localhost:3306/test
datasource.driverClassName=com.mysql.cj.jdbc.Driver
4. Example
For full example you can look at ezyfox-examples Github repo
Let’s say we need create an http server application to manage a book store (Category, Author and Book), we need 6 apis
- api/v1/author/add: Add an author
- api/v1/category/add: Add a category
- api/v1/book/add: Add a book
- api/v1/books/{bookId}: Get a book by id
- api/v1/books: Get a list of books
- apiv1/books/expected-revenue:
4.1 Create entities class
To store Category, Author and Book to MySQL, we need create 3 entities
@Data
@Entity
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(of = "id", callSuper = false)
public class Author extends CommonEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String name;
}
@Data
@Entity
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(of = "id", callSuper = false)
public class Book extends CommonEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private Long categoryId;
private Long authorId;
private String name;
private BigDecimal price;
private LocalDate releaseDate;
private LocalDateTime releaseTime;
}
@Data
@Entity
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(of = "id", callSuper = false)
public class Category extends CommonEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String name;
}
4.2 Create repositories
We need create 3 repositories for 3 entities
import com.tvd12.ezydata.database.EzyDatabaseRepository;
import com.tvd12.ezydata.example.jpa.entity.Author;
import com.tvd12.ezyfox.database.annotation.EzyRepository;
@EzyRepository
public interface AuthorRepository extends EzyDatabaseRepository<Long, Author> {
}
import java.util.List;
import com.tvd12.ezydata.database.EzyDatabaseRepository;
import com.tvd12.ezydata.example.jpa.entity.Book;
import com.tvd12.ezydata.example.jpa.result.SumBookPriceResult;
import com.tvd12.ezyfox.database.annotation.EzyQuery;
import com.tvd12.ezyfox.database.annotation.EzyRepository;
import com.tvd12.ezyfox.util.Next;
@EzyRepository
public interface BookRepository extends EzyDatabaseRepository<Long, Book> {
Book findByNameAndAuthorId(String name, Long authorId);
@EzyQuery("select e from Book e")
List<Book> findBooks(Next next);
@EzyQuery("select e from Book e where e.name < ?0 order by e.name")
List<Book> findByNameLt(String name, Next next);
@EzyQuery("select e from Book e where e.name > ?0 order by e.name")
List<Book> findByNameGt(String name, Next next);
@EzyQuery(value = "select sum(e.price) as sum from Book e", nativeQuery = true)
SumBookPriceResult sumPrice();
}
import com.tvd12.ezydata.database.EzyDatabaseRepository;
import com.tvd12.ezydata.example.jpa.entity.Category;
import com.tvd12.ezyfox.database.annotation.EzyRepository;
@EzyRepository
public interface CategoryRepository extends EzyDatabaseRepository<Long, Category> {
Category findByName(String name);
}
4.3 Save entities
Save a category, see more details
final Category entity = dataToEntityConverter.toEntity(data);
categoryRepository.save(entity);
Save an author, see more details
final Author entity = dataToEntityConverter.toEntity(data);
authorRepository.save(entity);
Save a book, see more details
final Book book = dataToEntityConverter.toEntity(data);
bookRepository.save(book);
4.4 Query data
Find a category by id, see more details
Category category = categoryRepository.findById(request.getCategoryId());
Find an author by id, see more details
Author author = authorRepository.findById(request.getAuthorId());
Find a book by name and author id, see more details
Book existedBook = bookRepository.findByNameAndAuthorId(
request.getBookName(),
request.getAuthorId()
);
Get sum of all book prices, see BookRepository and BookService to get more details
@EzyQuery(value = "select sum(e.price) as sum from Book e", nativeQuery = true)
SumBookPriceResult sumPrice();
bookRepository.sumPrice().getSum()
Full source code available on Github
5. Conclusion
With EzyJPA you will work with database lot easier. With query string, you will don't need care about data and query result mapping, you will reduce a lot of your source code, save your time to focus to your business
Next
You can take a look the list of default functions