-
Notifications
You must be signed in to change notification settings - Fork 5
MongoDb Service
For make the example a bit more complete, we go to create a service that connects with MongoDb through Spring-data and be explained with more details,we go to see the project structure:
pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.sh</groupId>
<artifactId>MongoService</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.1.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Brixton.SR5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<finalName>MongoService</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Here we include spring-boot-starter-data-mongodb and eureka,spring boot, actuator is recommended for operations like health, start and stop etc.
We go to create 2 services,one that obtain the first name from mongoDb from username and other service that returns the count of collection. For that we go to do step by step, first of all, the configuration.We want to make this application visible in our cloud, then we have to create a src/main/resources/bootstrap.properties:
spring.application.name=mongo-service
spring.cloud.config.uri=http://localhost:8888Here we give a application name and from what config server we want to get the configuration. Now we want to centralize the MongoDb connection in external properties, for that, go to the root project,and in properties folder we find the file mongo-service.properties, we have to create and commit it in the git repository creted for store properties,as same way that we did it in the other service, and the content is:
server.port=8050
mongo.db=mydb
mongo.host=localhost
mongo.port=27017
As always, the server.port, that is a spring property and automatically set the port, and later all connection properties for MongoDb,Db name,host and port. Once commited in the repository, we can start to configure Spring:
package com.sh.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import com.mongodb.MongoClient;
@Configuration
@ComponentScan("com.sh")
@EnableMongoRepositories("com.sh.repository")
@EnableAutoConfiguration
@EnableEurekaClient
@SpringBootApplication
public class Config
{
@Value("${mongo.db}")
private String db;
@Value("${mongo.host}")
private String host;
@Value("${mongo.port}")
private String port;
public @Bean
MongoDbFactory mongoDbFactory() throws Exception {
return new SimpleMongoDbFactory(new MongoClient(host, Integer.parseInt(port)), db);
}
public @Bean
MongoTemplate mongoTemplate() throws Exception {
MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory());
return mongoTemplate;
}
}Here we annotate the configuration class with @EnableEurekaClient for make it visible for Eureka. Other times the config file is empty because are basic examples, but here we have to configure 2 aspects for MongoDb:
-
@EnableMongoRepositories("com.sh.repository")Here tell that Mongo repositories can be found in this package - Configure 2 beans,
MongoDbFactoryandMongoTemplate,here setting host port and Db for make a connection.
At this point we have the application configured,but not implemented yet.
I include a Mongo dump for this example, is in src/main/resources/mydb.zip, extract in one folder and the execute
mongorestore -d mydb <directory_backup> where <directory_backup> is where we unzipped mydb.zip for import collections.
The collection is very simple,have this structure:
{
"username" : "",
"firstName" : "",
"lastName" : ""
}Here we have to build the Entity in first time:
package com.sh.entity;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
@Document(collection="users")
public class UserEntity
{
@Id
public String id;
public String username;
public String firstName;
public String lastName;
public UserEntity() {
}
public UserEntity(String userName,String firstName,String lastName)
{
this.username = userName;
this.firstName = firstName;
this.lastName = lastName;
}
@Override
public String toString() {
return String.format(
"Customer[id=%s, username='%s',firstName='%s', lastName='%s']",
id,username, firstName, lastName);
}
}Here not getters and setters, public fields and override toString() function for pretty format.
@Document(collection="users") link this object to mongoDb collection,in this case users
id field is mandatory,but is filled by mongo with a UUID, anyway we have to create it and annotate it wit @Id
Important, the name of fields are case sensitive and have to match with the fields names of the collection, if not, spring data throws an exception.
Now we have to build the MongoRepository, and interface extended to MongoRepository with 2 types, the entity and String. We have to do one repository for each collection where we want to operate.
package com.sh.repository;
import org.springframework.data.mongodb.repository.MongoRepository;
import com.sh.entity.UserEntity;
public interface UsersRepository extends MongoRepository<UserEntity, String>
{
public UserEntity findByUsername(String username);
}Only we had created one method, find a user by username.Spring data with mongo repositories are not required to implements this interface,Spring do it for you, now we will see how to use this interface.
´´´java package com.sh.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service;
import com.sh.entity.UserEntity; import com.sh.repository.UsersRepository;
@Service public class UsersService {
@Autowired
private UsersRepository repo;
public UserEntity getUser(String user)
{
return repo.findByUsername(user);
}
public List<UserEntity> getUserList()
{
return repo.findAll();
}
} ´´´
We can see 2 methods, in one we use findbyUsername method that we declared in repository, and other method that returns all results of the collection.
The controller is a usual RestController where i use the service class to call Mongo and return results.
shoecillo@2016
