EzyJPA Introduction

1. Introduct to EzyJPA

EzyJPA (Easy going to JPA Interaction) is a framework support to interact to JPA, It supports:
  1. Transparently map your Java entities to database record and back
  2. Query, update, delete and aggregation by query string
  3. Annotation driven

2. Structure of EzyJPA

  1. Database Context: wraps EntityManager, DataBinding. Manages repositiors, QueryManager and DataSerializers. Provides function to get repostiories, queries and serializers
  2. Repostiories: Manages all repostiores by name and type
  3. QueryManager: Manages all queries, collects queries from annotations and deverloper set
  4. DataSerializers: Manages all data serializers and deserializers, provide a way to allow deverloper custom and set their serializers and deverlopers
  5. Repostiory: converts queries, data and calls to database

3. Install JPA

To create EzyJPA we need add dependency
<dependency>
    <groupId>com.tvd12</groupId>
    <artifactId>ezydata-jpa</artifactId>
    <version>1.1.9</version>
</dependency>
The latest version can be found in the Maven Central repository.

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