springcloud(java)+spring-data-mongo 集成 mongodb 副本集集群

本贴最后更新于 2566 天前,其中的信息可能已经时移世易

springcloud(java)+spring-data-mongo 集成 mongodb 副本集集群

环境

springcloud版本Dalston.SR1 springboot版本1.5.2.RELEASE mongodb3.4.14 3台3分片
  1. 在 pomx.ml 引入 spring-boot-starter-data-mongodb
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency>

2.在 yml 里配置

spring: data: mongodb: uri: mongodb://admin:123456@192.168.31.1:20000,192.168.31.2:20000,192.168.31.3:20000/testdb?authSource=admin&connect=replicaSet&readPreference=secondaryPreferred&safe=true&authMechanism=SCRAM-SHA-1&maxPoolSize=500&minPoolSize=10
  1. uri 参数说明
  • uri 格式
mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]
  • mongodb:// 这是固定的格式,必须要指定。
  • username:password@ 可选项,如果设置,在连接数据库服务器之后,驱动都会尝试登陆这个数据库
  • host1 必须的指定至少一个 host, host1 是这个 URI 唯一要填写的。它指定了要连接服务器的地址。如果要连接复制集,请指定多个主机地址。
  • portX 可选的指定端口,如果不填,默认为 27017
  • /database 如果指定 username:password@,连接并验证登陆指定数据库。若不指定,默认打开 test 数据库。
  • ?options 是连接选项。如果不使用/database,则前面需要加上/。所有连接选项都是键值对 name=value,键值对之间通过&或;(分号)隔开

标准的连接格式包含了多个选项(options),如下所示:

选项 描述
replicaSet=name 验证 replica set 的名称。 Impliesconnect=replicaSet.
safe=true|false true:在执行更新操作之后,驱动都会发送 getLastError 命令来确保更新成功。(还要参考 wtimeoutMS).false: 在每次更新之后,驱动不会发送 getLastError 来确保更新成功。
w=n 驱动添加 { w : n } 到 getLastError 命令. 应用于 safe=true。
wtimeoutMS=ms 驱动添加 { wtimeout : ms } 到 getlasterror 命令. 应用于 safe=true.
fsync=true|false true: 驱动添加 { fsync : true } 到 getlasterror 命令.应用于 safe=true
journal=true|false 如果设置为 true, 同步到 journal (在提交到数据库前写入到实体中). 应用于 safe=true
connectTimeoutMS=ms 可以打开连接的时间。
socketTimeoutMS=ms 发送和接受 sockets 的时间。

跟多参数参考:mongodb 官方文档

  1. 建立通用 model
    MongoOpenDoorLog.java
import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.index.CompoundIndex; import org.springframework.data.mongodb.core.index.CompoundIndexes; import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.core.mapping.Field; import java.io.Serializable; @Document(collection="open_door_log") @CompoundIndexes({ @CompoundIndex(name = "id_1_user_id_1_open_time_1", def = "{'user_id': 1, 'open_time': 1}"), @CompoundIndex(name = "door_id_1_community_id_1_build_id_1_cell_id_1", def = "{'door_id': 1, 'community_id': 1,'build_id':1,'cell_id':1}") }) public class MongoOpenDoorLog implements Serializable{ @Id private String id; private String tid; @Field("log_time") private long logTime; @Field("door_id") private String doorId; @Field("user_id") private String userId; @Field("user_type") private String userType; @Field("device_type") private String deviceType; @Field("device_sys") private String deviceSys; @Field("open_time") private long openTime; @Field("lock_type") private int lockType; @Field("open_type") private int openType; @Field("open_info") private String openInfo; @Field("area_id") private String areaId; private String area; @Field("community_id") private String communityId; @Field("community_name") private String communityName; @Field("build_id") private String buildId; @Field("build_name") private String buildName; @Field("build_num") private String buildNum; @Field("cell_id") private String cellId; @Field("cell_name") private String cellName; @Field("cell_num") private String cellNum; private int feedback; @Field("feedback_time") private long feedbackTime; private String img; private boolean deletec; /** * 创建时间 */ @Field("create_time") private long createTime; /** * 更新时间 */ @Field("update_time") private long updateTime; public void setId(String id){ this.id = id; } public String getId(){ return this.id; } public void setLogTime(long logTime){ this.logTime = logTime; } public long getLogTime(){ return this.logTime; } public void setDoorId(String doorId){ this.doorId = doorId; } public String getDoorId(){ return this.doorId; } public void setDeviceType(String deviceType){ this.deviceType = deviceType; } public String getDeviceType(){ return this.deviceType; } public void setDeviceSys(String deviceSys){ this.deviceSys = deviceSys; } public String getDeviceSys(){ return this.deviceSys; } public void setOpenTime(long openTime){ this.openTime = openTime; } public long getOpenTime(){ return this.openTime; } public void setLockType(int lockType){ this.lockType = lockType; } public int getLockType(){ return this.lockType; } public void setOpenType(int openType){ this.openType = openType; } public int getOpenType(){ return this.openType; } public void setOpenInfo(String openInfo){ this.openInfo = openInfo; } public String getOpenInfo(){ return this.openInfo; } public void setAreaId(String areaId){ this.areaId = areaId; } public String getAreaId(){ return this.areaId; } public void setArea(String area){ this.area = area; } public String getArea(){ return this.area; } public void setCommunityId(String communityId){ this.communityId = communityId; } public String getCommunityId(){ return this.communityId; } public void setCommunityName(String communityName){ this.communityName = communityName; } public String getCommunityName(){ return this.communityName; } public void setBuildId(String buildId){ this.buildId = buildId; } public String getBuildId(){ return this.buildId; } public void setBuildName(String buildName){ this.buildName = buildName; } public String getBuildName(){ return this.buildName; } public void setBuildNum(String buildNum){ this.buildNum = buildNum; } public String getBuildNum(){ return this.buildNum; } public void setCellId(String cellId){ this.cellId = cellId; } public String getCellId(){ return this.cellId; } public void setCellName(String cellName){ this.cellName = cellName; } public String getCellName(){ return this.cellName; } public void setCellNum(String cellNum){ this.cellNum = cellNum; } public String getCellNum(){ return this.cellNum; } public void setFeedback(int feedback){ this.feedback = feedback; } public int getFeedback(){ return this.feedback; } public void setFeedbackTime(long feedbackTime){ this.feedbackTime = feedbackTime; } public long getFeedbackTime(){ return this.feedbackTime; } public void setImg(String img){ this.img = img; } public String getImg(){ return this.img; } public boolean isDeletec() { return deletec; } public void setDeletec(boolean deletec) { this.deletec = deletec; } public long getCreateTime() { return createTime; } public void setCreateTime(long createTime) { this.createTime = createTime; } public long getUpdateTime() { return updateTime; } public void setUpdateTime(long updateTime) { this.updateTime = updateTime; } public String getUserId() { return userId; } public void setUserId(String userId) { this.userId = userId; } public String getUserType() { return userType; } public void setUserType(String userType) { this.userType = userType; } public String getTid() { return tid; } public void setTid(String tid) { this.tid = tid; } }
  1. 建立通用 dao
    MongoBaseDao.java
import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Update; import java.util.List; public interface MongoBaseDao<T> { //保存一个对象到mongodb public T save(T bean); // 根据id删除对象 public void deleteById(T t); // 根据对象的属性删除 public void deleteByCondition(T t); // 通过条件查询更新数据 public void update(Query query, Update update); // 根据id进行更新 public void updateById(String id, T t); // 通过条件查询实体(集合) public List<T> find(Query query); public List<T> findByCondition(T t); // 通过一定的条件查询一个实体 public T findOne(Query query); // 通过ID获取记录 public T get(String id); // 通过ID获取记录,并且指定了集合名(表的意思) public T get(String id, String collectionName); public MongoTemplate getMongoTemplate(); }
  1. 建立通用 daosuport
    MongoDaoSupport.java
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Update; import java.io.Serializable; import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; import java.util.List; public abstract class MongoDaoSupport<T extends Serializable> implements MongoBaseDao<T> { @Autowired @Qualifier("mongoTemplate") protected MongoTemplate mongoTemplate; //保存一个对象到mongodb public T save(T bean) { mongoTemplate.save(bean); return bean; } // 根据id删除对象 public void deleteById(T t) { mongoTemplate.remove(t); } // 根据对象的属性删除 public void deleteByCondition(T t) { Query query = buildBaseQuery(t); mongoTemplate.remove(query, getEntityClass()); } // 通过条件查询更新数据 public void update(Query query, Update update) { mongoTemplate.updateMulti(query, update, this.getEntityClass()); } // 根据id进行更新 public void updateById(String id, T t) { Query query = new Query(); query.addCriteria(Criteria.where("id").is(id)); Update update = buildBaseUpdate(t); update(query, update); } // 通过条件查询实体(集合) public List<T> find(Query query) { return mongoTemplate.find(query, this.getEntityClass()); } public List<T> findByCondition(T t) { Query query = buildBaseQuery(t); return mongoTemplate.find(query, getEntityClass()); } // 通过一定的条件查询一个实体 public T findOne(Query query) { return mongoTemplate.findOne(query, this.getEntityClass()); } // 通过ID获取记录 public T get(String id) { return mongoTemplate.findById(id, this.getEntityClass()); } // 通过ID获取记录,并且指定了集合名(表的意思) public T get(String id, String collectionName) { return mongoTemplate.findById(id, this.getEntityClass(), collectionName); } // 根据vo构建查询条件Query private Query buildBaseQuery(T t) { Query query = new Query(); Field[] fields = t.getClass().getDeclaredFields(); for (Field field : fields) { field.setAccessible(true); try { Object value = field.get(t); if (value != null) { org.springframework.data.mongodb.core.mapping.Field queryField = field.getAnnotation(org.springframework.data.mongodb.core.mapping.Field.class); if (queryField != null) { query.addCriteria(Criteria.where(queryField.value()).is(value)); }else{ query.addCriteria(Criteria.where(field.getName()).is(value)); } } } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } return query; } private Update buildBaseUpdate(T t) { Update update = new Update(); Field[] fields = t.getClass().getDeclaredFields(); for (Field field : fields) { field.setAccessible(true); try { Object value = field.get(t); if (value != null) { update.set(field.getName(), value); } } catch (Exception e) { e.printStackTrace(); } } return update; } // 获取需要操作的实体类class @SuppressWarnings("unchecked") protected Class<T> getEntityClass() { return ((Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]); } public MongoTemplate getMongoTemplate() { return mongoTemplate; } }

8.建立 service 接口
MongoOpenDoorLogService.java

public interface MongoOpenDoorLogService extends MongoBaseDao<MongoOpenDoorLog> { }
  1. 建立 service 实现类
    MongoOpenDoorLogServiceImpl.java
import org.springframework.stereotype.Service; @Service("mongoOpenDoorLogServiceImpl") public class MongoOpenDoorLogServiceImpl extends MongoDaoSupport<MongoOpenDoorLog> implements MongoOpenDoorLogService{ }
  1. 暴露接口
    RequestObject.java
import com.zzwtec.common.validation.constraint.ZNotBlank; import com.zzwtec.common.validation.constraint.ZNotNullWithStr; import javax.validation.Valid; public class RequestObject<T> { @ZNotBlank private String requestId; @Valid @ZNotNullWithStr private T data; public RequestObject() { this.requestId = RequestIdContext.get(); } public RequestObject(T data) { this(); this.data = data; } public RequestObject(String requestId, T data) { this.requestId = requestId; this.data = data; } public String getRequestId() { return requestId; } public RequestObject<T> setRequestId(String requestId) { this.requestId = requestId; return this; } public T getData() { return data; } public RequestObject<T> setData(T data) { this.data = data; return this; } public static <T> RequestObject<T> build(T data) { return new RequestObject<T>(data); } public static <T> RequestObject<T> build(T data,String requestId) { return new RequestObject<T>(requestId,data); } public static <T> RequestObject<T> build(String requestId,T data) { return new RequestObject<T>(requestId,data); } @Override public String toString() { return "RequestObject [requestId=" + requestId + ", data=" + data + "]"; } }

ResultObject.java

public class ResultObject<T> { public static final String SUCCESS_CODE = "0"; public static final String SUCCESS_MSG = "success"; public static final String ERROR_CODE = "1"; public static final String ERROR_MSG = "error"; private String requestId; /** * 返回码 */ private String code; /** * 返回描述 */ private String msg; /** * 请求数据 */ private T data; public ResultObject() { } public ResultObject(String requestId) { this.requestId = requestId; } @SuppressWarnings("rawtypes") public ResultObject(RequestObject request) { this(request.getRequestId()); } @SuppressWarnings("rawtypes") public ResultObject(RequestObject request, String code, String msg) { this(request); this.code = code; this.msg = msg; } @SuppressWarnings("rawtypes") public ResultObject(RequestObject request, String code, String msg, T data) { this(request, code, msg); this.data = data; } public String getRequestId() { return requestId; } public ResultObject<T> setRequestId(String requestId) { this.requestId = requestId; return this; } public String getCode() { return code; } public ResultObject<T> setCode(String code) { this.code = code; return this; } public String getMsg() { return msg; } public ResultObject<T> setMsg(String msg) { this.msg = msg; return this; } public T getData() { return data; } public ResultObject<T> setData(T data) { this.data = data; return this; } public boolean isSuccess() { return SUCCESS_CODE.equals(code); } @Override public String toString() { return "ResultObject [requestId=" + requestId + ", code=" + code + ", msg=" + msg + ", data=" + data + "]"; } }

OpenDoorLogService.java

import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiOperation; import org.springframework.cloud.netflix.feign.FeignClient; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @FeignClient(name = "a", fallback = OpenDoorLogServiceFallback.class) @RequestMapping("odls") @Api(value="OpenDoorLogService", description="mongodb开门日志操作外部服务接口", consumes = "application/json", produces = "application/json", protocols = "http") public interface OpenDoorLogService { /** * 添加单条开门日志 * @param request * @return */ @ApiOperation(value="add", notes="添加单条开门日志") @ApiImplicitParam(name = "request", required = true, dataType = "RequestObject<MongoOpenDoorLog>", paramType = "body") @RequestMapping(value = "add", method = RequestMethod.POST) public ResultObject<Void> saveOpenDoorLog(@GroupsValid({Add.class}) @RequestBody RequestObject<MongoOpenDoorLog> request); }

OpenDoorLogServiceController.java

import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; @RestController public class OpenDoorLogServiceController implements OpenDoorLogService { @Autowired private MongoOpenDoorLogService mongoOpenDoorLogService; @Override public ResultObject<Void> saveOpenDoorLog(@GroupsValid({Add.class}) @RequestBody RequestObject<MongoOpenDoorLog> request){ MongoOpenDoorLog t = request.getData(); mongoOpenDoorLogService.save(t); return ResultBuilder.success(request); } }
  1. 其它辅助类
    GroupsValid.java
import java.lang.annotation.*; @Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface GroupsValid { Class<?>[] value() default {}; }
Add.java public interface Add { } Delete.java public interface Delete { } Query.java public interface Query { } Update.java public interface Update { }
  • 集群
    29 引用 • 65 回帖 • 1 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • Hadoop

    Hadoop 是由 Apache 基金会所开发的一个分布式系统基础架构。用户可以在不了解分布式底层细节的情况下,开发分布式程序。充分利用集群的威力进行高速运算和存储。

    93 引用 • 122 回帖 • 624 关注
  • 程序员

    程序员是从事程序开发、程序维护的专业人员。

    594 引用 • 3541 回帖 • 1 关注
  • 强迫症

    强迫症(OCD)属于焦虑障碍的一种类型,是一组以强迫思维和强迫行为为主要临床表现的神经精神疾病,其特点为有意识的强迫和反强迫并存,一些毫无意义、甚至违背自己意愿的想法或冲动反反复复侵入患者的日常生活。

    15 引用 • 161 回帖 • 1 关注
  • NGINX

    NGINX 是一个高性能的 HTTP 和反向代理服务器,也是一个 IMAP/POP3/SMTP 代理服务器。 NGINX 是由 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru 站点开发的,第一个公开版本 0.1.0 发布于 2004 年 10 月 4 日。

    316 引用 • 547 回帖 • 1 关注
  • 架构

    我们平时所说的“架构”主要是指软件架构,这是有关软件整体结构与组件的抽象描述,用于指导软件系统各个方面的设计。另外还有“业务架构”、“网络架构”、“硬件架构”等细分领域。

    142 引用 • 442 回帖
  • API

    应用程序编程接口(Application Programming Interface)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节。

    79 引用 • 431 回帖
  • LeetCode

    LeetCode(力扣)是一个全球极客挚爱的高质量技术成长平台,想要学习和提升专业能力从这里开始,充足技术干货等你来啃,轻松拿下 Dream Offer!

    209 引用 • 72 回帖
  • ReactiveX

    ReactiveX 是一个专注于异步编程与控制可观察数据(或者事件)流的 API。它组合了观察者模式,迭代器模式和函数式编程的优秀思想。

    1 引用 • 2 回帖 • 191 关注
  • 周末

    星期六到星期天晚,实行五天工作制后,指每周的最后两天。再过几年可能就是三天了。

    14 引用 • 297 回帖 • 1 关注
  • 分享

    有什么新发现就分享给大家吧!

    249 引用 • 1799 回帖
  • Flutter

    Flutter 是谷歌的移动 UI 框架,可以快速在 iOS 和 Android 上构建高质量的原生用户界面。 Flutter 可以与现有的代码一起工作,它正在被越来越多的开发者和组织使用,并且 Flutter 是完全免费、开源的。

    39 引用 • 92 回帖 • 14 关注
  • SQLite

    SQLite 是一个进程内的库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。SQLite 是全世界使用最为广泛的数据库引擎。

    4 引用 • 7 回帖
  • SendCloud

    SendCloud 由搜狐武汉研发中心孵化的项目,是致力于为开发者提供高质量的触发邮件服务的云端邮件发送平台,为开发者提供便利的 API 接口来调用服务,让邮件准确迅速到达用户收件箱并获得强大的追踪数据。

    2 引用 • 8 回帖 • 515 关注
  • Ruby

    Ruby 是一种开源的面向对象程序设计的服务器端脚本语言,在 20 世纪 90 年代中期由日本的松本行弘(まつもとゆきひろ/Yukihiro Matsumoto)设计并开发。在 Ruby 社区,松本也被称为马茨(Matz)。

    7 引用 • 31 回帖 • 277 关注
  • CongSec

    本标签主要用于分享网络空间安全专业的学习笔记

    1 引用 • 1 回帖 • 41 关注
  • 阿里云

    阿里云是阿里巴巴集团旗下公司,是全球领先的云计算及人工智能科技公司。提供云服务器、云数据库、云安全等云计算服务,以及大数据、人工智能服务、精准定制基于场景的行业解决方案。

    85 引用 • 324 回帖
  • 链书

    链书(Chainbook)是 B3log 开源社区提供的区块链纸质书交易平台,通过 B3T 实现共享激励与价值链。可将你的闲置书籍上架到链书,我们共同构建这个全新的交易平台,让闲置书籍继续发挥它的价值。

    链书社

    链书目前已经下线,也许以后还有计划重制上线。

    14 引用 • 257 回帖
  • 微信

    腾讯公司 2011 年 1 月 21 日推出的一款手机通讯软件。用户可以通过摇一摇、搜索号码、扫描二维码等添加好友和关注公众平台,同时可以将自己看到的精彩内容分享到微信朋友圈。

    135 引用 • 798 回帖 • 1 关注
  • CodeMirror
    2 引用 • 17 回帖 • 184 关注
  • 资讯

    资讯是用户因为及时地获得它并利用它而能够在相对短的时间内给自己带来价值的信息,资讯有时效性和地域性。

    57 引用 • 85 回帖
  • JetBrains

    JetBrains 是一家捷克的软件开发公司,该公司位于捷克的布拉格,并在俄国的圣彼得堡及美国麻州波士顿都设有办公室,该公司最为人所熟知的产品是 Java 编程语言开发撰写时所用的集成开发环境:IntelliJ IDEA

    18 引用 • 54 回帖 • 3 关注
  • App

    App(应用程序,Application 的缩写)一般指手机软件。

    91 引用 • 384 回帖
  • 爬虫

    网络爬虫(Spider、Crawler),是一种按照一定的规则,自动地抓取万维网信息的程序。

    106 引用 • 275 回帖 • 1 关注
  • BookxNote

    BookxNote 是一款全新的电子书学习工具,助力您的学习与思考,让您的大脑更高效的记忆。

    笔记整理交给我,一心只读圣贤书。

    1 引用 • 1 回帖 • 2 关注
  • Typecho

    Typecho 是一款博客程序,它在 GPLv2 许可证下发行,基于 PHP 构建,可以运行在各种平台上,支持多种数据库(MySQL、PostgreSQL、SQLite)。

    12 引用 • 67 回帖 • 445 关注
  • TGIF

    Thank God It's Friday! 感谢老天,总算到星期五啦!

    293 引用 • 4496 回帖 • 664 关注
  • uTools

    uTools 是一个极简、插件化、跨平台的现代桌面软件。通过自由选配丰富的插件,打造你得心应手的工具集合。

    8 引用 • 37 回帖