Introduce EzyMongo
Updated at 16998035520001. Introduce EzyMongo
EzyMongo (Easy going to Mongo Interaction) is a framework support to interact to MongoDB, It supports:- Transparently map your Java entities to MongoDB documents and back.
- Query, update, delete and aggregation by query string.
- Annotation driven.
2. Structure of EzyMongo
- Database Context: wraps MongoClient, 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 MongoDB
3. Install EzyMongo
1. To create EzyMongo we need add dependency
<dependency> <groupId>com.tvd12</groupId> <artifactId>ezydata-mongodb</artifactId> <version>1.2.8</version> </dependency>
The latest version can be found in the Maven Central repository. 2. To use EzyMongo you need config 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.1.0</version> </dependency>
Or because with some reason, you can not use ezyfox-boot-autoconfigure
you can config like this:
import com.mongodb.MongoClient; import com.tvd12.ezydata.database.EzyDatabaseContext; import com.tvd12.ezydata.mongodb.EzyMongoDatabaseContextBuilder; import com.tvd12.ezydata.mongodb.loader.EzySimpleMongoClientLoader; import com.tvd12.ezyfox.annotation.EzyProperty; 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.EzyConfigurationBefore; import com.tvd12.ezyfox.util.EzyPropertiesAware; import lombok.Setter; import java.util.Map; import java.util.Properties; @Setter @EzyConfigurationBefore public class EzyMongoConfiguration implements EzyBeanConfig, EzyPropertiesAware, EzySingletonFactoryAware { @EzyProperty("database.mongo.database") private String databaseName; private Properties properties; private EzySingletonFactory singletonFactory; @Override public void config() { EzyDatabaseContext databaseContext = newMongodbDatabaseContext(); Map repos = databaseContext.getRepositoriesByName(); for (String repoName : repos.keySet()) { singletonFactory.addSingleton(repoName, repos.get(repoName)); } } private EzyDatabaseContext newMongodbDatabaseContext() { EzyMongoDatabaseContextBuilder builder = new EzyMongoDatabaseContextBuilder() .properties(properties) .scan("your_package_to_scan") .mongoClient(newMongoClient()) .databaseName(databaseName); return builder.build(); } protected MongoClient newMongoClient() { return EzySimpleMongoClientLoader.load(properties); } }
3. You can add to your configuration file like this:
# for application.yaml database: mongo: uri: mongodb://ezydata_mongo:ezydata_mongo@localhost:27017/ezydata-mongo database: ezydata-mongo collection: naming: case: UNDERSCORE ignored_suffix: Entity
# for application.properties database.mongo.uri=mongodb://ezydata_mongo:ezydata_mongo@localhost:27017/ezydata-mongo database.mongo.database=ezydata-mongo database.mongo.collection.naming.case=UNDERSCORE database.mongo.collection.naming.ignored_suffix=Entity
4. Example
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 MongoDB, we need create 3 entities:
import com.tvd12.ezydata.database.annotation.EzyCollection; import com.tvd12.ezyfox.annotation.EzyId; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @Getter @Setter @EzyCollection @AllArgsConstructor @NoArgsConstructor public class Category { @EzyId private long id; private String name; } @Getter @Setter @EzyCollection @AllArgsConstructor @NoArgsConstructor public class Author { @EzyId private long id; private String name; } @Getter @Setter @EzyCollection @AllArgsConstructor @NoArgsConstructor public class Book { @EzyId private Long id; private Long categoryId; private Long authorId; private String name; private BigDecimal price; private LocalDate releaseDate; private LocalDateTime releaseTime; }
4.2 Create repositories
We need create 3 repositories for 3 entities:
import com.tvd12.ezydata.example.mongo.entity.Category; import com.tvd12.ezydata.mongodb.EzyMongoRepository; import com.tvd12.ezyfox.database.annotation.EzyRepository; @EzyRepository public interface CategoryRepository extends EzyMongoRepository { Category findByName(String name); }
import com.tvd12.ezydata.example.mongo.entity.Author; import com.tvd12.ezydata.mongodb.EzyMongoRepository; import com.tvd12.ezyfox.database.annotation.EzyRepository; @EzyRepository public interface AuthorRepository extends EzyMongoRepository { }
import java.util.List; import com.tvd12.ezydata.database.annotation.EzyQuery; import com.tvd12.ezydata.example.mongo.entity.Book; import com.tvd12.ezydata.example.mongo.result.SumBookPriceResult; import com.tvd12.ezydata.mongodb.EzyMongoRepository; import com.tvd12.ezyfox.database.annotation.EzyRepository; import com.tvd12.ezyfox.util.Next; @EzyRepository public interface BookRepository extends EzyMongoRepository { Book findByNameAndAuthorId(String name, Long authorId); @EzyQuery("{$orderby:{name:1}}") List findBooks(Next next); @EzyQuery("{$query:{name:{$lt:?0}}, $orderby:{name:1}}") List findByNameLt(String name, Next next); @EzyQuery("{$query:{name:{$gt:?0}}, $orderby:{name:1}}") List findByNameGt(String name, Next next); @EzyQuery("[{ $group: { _id : 'sum', sum : { $sum: {$toDecimal: '$price'}} } }]") SumBookPriceResult sumPrice(); }
4.3 Save entities
Save a category, see more details
Category category = new Category( maxIdRepository.incrementAndGet("category"), request.getCategoryName() ); categoryRepository.save(category);
Save an author, see more details:
Author author = new Author( maxIdRepository.incrementAndGet("author"), request.getAuthorName() ); authorRepository.save(author); return author;
Save a book, see more details:
val bookId = maxIdRepository.incrementAndGet("book");
val book = requestToEntityConverter.toBookEntity(request, bookId);
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 BookController to get more details
@EzyQuery("[{ $group: { _id : 'sum', sum : { $sum: {$toDecimal: '$price'}} } }]") SumBookPriceResult sumPrice();
bookRepository.sumPrice().getSum()
4.5 Update data
You can update data with a function has update
prefix like this:
@EzyQuery("{$query: {_id : 4}, $update: {$set: {category: ?0}}}") void updateCategory(String category);
And you can delete data with a function has delete
prefix like this:
@EzyQuery("{_id : {$gt: ?0}}") void deleteByIdGt(int id);
Full source code available on Github.
5. Conclusion
With EzyMongo you will work with MongoDB lot easier and more native. With query string, you will don't need care about bson, criteria and you will reduce a lot of your source code.
Next
You can take a look EzyMongo configuration.