您的位置:首页 > 数据库 > Mongodb

Spring与MongoDB集成使用

2017-09-14 00:04 253 查看

Spring与MongoDB结合

前言

POM依赖

applicationContext文件

使用代码

前言

公司让将一些离线数据,如交易订单、记账信息等数据存入MongoDB这样的,最像关系型的非关系型数据库中,于是我便开始研究怎样通过Spring方便地使用MongoDB,这里记录一下使用和配置的过程。

MongoDB这种可以在集合中任意增加字段的存储方式,非常适合公司多变的业务,并且其可配置为分布式的存储方式,非常适合横向扩展。MongoDB集合中的每条记录可设置索引,并且也支持聚合等运算,因此,在业务计算不是特别复杂,没有多表关联查询的场景,并且存储数据量非常庞大的场景下,可以考虑使用MongoDB作为数据存储的方式。

本文的配置及代码编写参考了Spring的官方文档 [ Spring Data MongoDB ]

POM依赖

这里说明一下,以下的配置JDK版本必须要升级至8,Spring版本需要是4。

往pom.xml文件中添加如下两个依赖。

<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>2.0.0.M1</version>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>3.3.0</version>
</dependency>


为什么依赖这两个版本呢,因为公司的仓库里只有这个版本,如果往里加的话还要申请,太麻烦了。

就先这么用着。

编写applicationContext.xml文件

这里我是通过applicationContext.xml文件来配置Spring的MongoDbTemplate的。具体的配置内容如下:

<bean id="mongoCredential" class="com.mongodb.MongoCredential"
factory-method="createCredential">
<constructor-arg value="${cashbase_balance_mongodb_username}"/>
<constructor-arg value="admin"/>
<constructor-arg value="${cashbase_balance_mongodb_password}"/>
</bean>
<bean id="userCredential"
class="org.springframework.data.authentication.UserCredentials">
<constructor-arg>
<null/>
</constructor-arg>
<constructor-arg>
<null/>
</constructor-arg>
</bean>

<bean id="mongoClientOptions" class="com.***.MongoClientUtils"
factory-method="getMongoClientOptions"/>

<bean id="mongoClient" class="com.mongodb.MongoClient">
<constructor-arg
value="${cashbase_balance_mongodb_host}:${cashbase_balance_mongodb_port}"/>
<constructor-arg>
<list>
<ref bean="mongoCredential"/>
</list>
</constructor-arg>
<constructor-arg ref="mongoClientOptions"/>

</bean>

<bean id="mongoFactory" class="org.springframework.data.mongodb.core.SimpleMongoDbFactory">
<constructor-arg ref="mongoClient"/>
<constructor-arg value="${mongo_database}"/>
<constructor-arg ref="userCredential"/>
</bean>

<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg ref="mongoFactory"/>
</bean>


从以上的配置中,可以看出,我的配置还是相当麻烦的。为什么会配得这么麻烦,因为按照官方文档给出的配置方法,可以使用mongo标签进行配置,但是我添加了相应的xmlns和xsi后,还是会提示我找不到标签之类等错误。并且标签的配置方法会造成初始化MongoDBFactory等初始化的错误,从错误信息来看是mongodb的版本和spring版本之间不兼容导致的。因此,干脆用最原始的方法来生成bean。

mongoTemplate

mongoTemplate是我们用于增删改查等操作的对象,在之后的代码示例中会再解释。初始化它需要使用mongoDbFactory。

mongoDbFactory

mongoDbFactory是一个提供数据库连接的工厂对象,这个接口目前只有一个实现类。它需要一个mongoClient对象,待连接的数据库名称(String对象)以及一个用户认证对象userCredential。这里比较特殊的一点是这个userCredential的用户名和密码必须为空字符串,而真正的安全性信息,需要填写在mongoCredential对象中。

mongoClient

这个对象需传入你的mongoDB连接地址,以及端口号,然后再传入mongoCredential这个bean,从配置文件中,可以看出,这个bean的构造方法必须传两个null,代表账号和密码。在Factory的源码中,如果你的mongoCredential对象中,账号和密码包含有非null的值,是会抛异常的。在我用的spring-data-mongodb版本中,账密的设置已经迁移到mongoCredential中了。这个对象还需提供一个ClientOption,这里可以设置你的定制化配置。我写的这个Option如下,只设置了一个超时时间:

import com.mongodb.MongoClientOptions;

public class MongoClientUtils {
public static MongoClientOptions getMongoClientOptions() {
MongoClientOptions.Builder builder = new MongoClientOptions.Builder();
builder.socketTimeout(10 * 1000);
return builder.build();
}
}


mongoCredential

mongoCredential对象可以设置客户端与MongoDB的安全通信方式,这里我使用的是默认的通信方式。此对象的构造方法需要传递连接到MongoDB的账户和密码,以及提供首选的库名,我这里写的是admin。

使用代码

上一节就是整个初始化的过程,下面说一下MongoTemplate的用法。

在我们的业务代码中,主要使用mongoTemplate进行常见的增删改查操作,代码如下。

import static org.springframework.data.mongodb.core.query.Criteria.where;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
* mongoDb,从mongo中读写数据
* Created by on 17-9-14
*/
@Component
public class MerchantMongoDAO {

@Autowired
private MongoTemplate mongoTemplate;

private final Logger logger = LoggerFactory.getLogger(getClass());

/**
* Insert if not Exists otherwise update
*
* @param merchantReportInfo merchantReportInfo
*/
public void save(MerchantReportInfo merchantReportInfo) {
if (Objects.isNull(merchantReportInfo)) {
logger.info("insert object MerchantReportInfo is null");
return;
}
merchantReportInfo.setId(merchantReportInfo.getReportIndex());
String collectionName = "t_bal_merchant_monthly_summary";
if (!mongoTemplate.collectionExists(collectionName)) {
mongoTemplate.createCollection(collectionName);
}
logger.info("存入mongoDb,merchantReportInfo={}", merchantReportInfo);
mongoTemplate.save(merchantReportInfo, collectionName);
}

/**
* 通过mode和accountNo查询
*
* @param mode            模式
* @param accountingMonth 商户帐号
* @return List<MerchantReportInfo>
*/
public List<MerchantReportInfo> query(int mode, int accountingMonth) {
String collectionName = "t_bal_merchant_monthly_summary";
Query query = new Query(where("month").is(accountingMonth).and("reportMode").is(mode));
query.with(new Sort(new Sort.Order(Sort.Direction.ASC, "merchantId")));
return mongoTemplate.find(query, MerchantReportInfo.class, collectionName);
}
}


以上两段代码提供了插入和查询这两个操作。这个插入操作呢,就是无记录插入,有记录则更新。默认情况下mongoTemplate会以对象中的id字段作为主键。查询有Query、Where、Sort等方法,和SQL非常相近,比较好用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  spring mongodb 存储