1.将MongoDB设置为复制集模式

  a.修改 mongod.cfg 文件,添加replSetName复制集名称

#replication:
replication:
replSetName: "rs0"

  b.在MongDB命令行输入初始化添加 localhost:27017 节点

rs.initiate( {_id : "rs0",members: [ { _id: 0, host: "localhost:27017" } ]})

2.添加maven依赖

    <!-- mongo -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>

  注:a.支持事务MongoDB要4.0版本以上,使用复制集,单节点不支持。

    b.Spring要 5.1.1.RELEASE 以上

    c.SpringDataMongoDB要 2.1.1.RELEASE 以上

    d.使用事务之前(@Transaction),数据库、文档、索引必须提前创建

3.书写 spring-mongo.xml 及对应 mongo.properties

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <context:property-placeholder location="classpath:mongo.properties"/> <!-- <mongo:mongo-client id="mongo-client" host="${mongo.host}" port="${mongo.port}"> -->
<mongo:mongo-client id="mongo-client" replica-set="${mongo.replSet}">
<mongo:client-options connections-per-host="${mongo.connectionsPerHost}"
threads-allowed-to-block-for-connection-multiplier="${mongo.threadsAllowedToBlockForConnectionMultiplier}"
connect-timeout="${mongo.connectTimeout}"
max-wait-time="${mongo.maxWaitTime}"
socket-keep-alive="${mongo.socketKeepAlive}"
socket-timeout="${mongo.socketTimeout}" />
</mongo:mongo-client> <mongo:repositories base-package="com.wode.dao"/> <mongo:db-factory dbname="${mongo.db}" mongo-ref="mongo-client"/> <bean id="mongoTemplate"
class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg name="mongoDbFactory" ref="mongoDbFactory"/>
</bean> <bean id="mongoTransactionManager" class="org.springframework.data.mongodb.MongoTransactionManager">
<constructor-arg name="dbFactory" ref="mongoDbFactory"/>
</bean> <tx:annotation-driven transaction-manager="mongoTransactionManager" proxy-target-class="true"/> </beans>
mongo.host=localhost
mongo.port=27017
mongo.replSet=localhost:27017
mongo.db=testmongo #################连接池配置################# #最大连接数
mongo.connectionsPerHost=8
#可被阻塞的线程数因子,默认值为5,如果connectionsPerHost配置为10,那么最多能阻塞50个线程,超过50个之后就会收到一个异常
mongo.threadsAllowedToBlockForConnectionMultiplier=4
#连接超时时间,默认值是0,就是不超时
mongo.connectTimeout=1000
#阻塞线程获取连接的最长等待时间,默认120000 ms
mongo.maxWaitTime=1500
#keep alive标志,默认false
mongo.socketKeepAlive=true
#socket超时时间,默认值是0,就是不超时
mongo.socketTimeout=1500

4.创建实体类

public class BaseBean {

    @Id
private String id; public String getId() {
return id;
} public void setId(String id) {
this.id = id;
}
}
@Document
public class Cmdty extends BaseBean { private String cmdtyCode;
private String cmdtyName;
private List<Attr> attributes;
@DBRef
private Info info; public String getCmdtyCode() {
return cmdtyCode;
} public void setCmdtyCode(String cmdtyCode) {
this.cmdtyCode = cmdtyCode;
} public String getCmdtyName() {
return cmdtyName;
} public void setCmdtyName(String cmdtyName) {
this.cmdtyName = cmdtyName;
} public List<Attr> getAttributes() {
return attributes;
} public void setAttributes(List<Attr> attributes) {
this.attributes = attributes;
} public Info getInfo() {
return info;
} public void setInfo(Info info) {
this.info = info;
} @Override
public String toString() {
return "[Cmdty]: cmdtyCode[" + cmdtyCode + "], cmdtyName[" + cmdtyName + "], attributes[" + attributes + "], info[" + info + "]";
}
}
public class Attr extends BaseBean {

    private String key;

    private String value;

    public String getKey() {
return key;
} public void setKey(String key) {
this.key = key;
} public String getValue() {
return value;
} public void setValue(String value) {
this.value = value;
} @Override
public String toString() {
return "[Attr]: key[" + key + "], value[" + value + "]";
} }
@Document
public class Info extends BaseBean { private String color; private String style; public String getColor() {
return color;
} public void setColor(String color) {
this.color = color;
} public String getStyle() {
return style;
} public void setStyle(String style) {
this.style = style;
} @Override
public String toString() {
return "[Info]: color[" + color + "], style[" + style + "]";
}
}

5.通过 MongoTemplate 的方式

  a.创建Dao

@Repository
public class TestDao { @Resource
protected MongoTemplate mongoTemplate;
private Class<Cmdty> clazz; @PostConstruct
private void construct(){
clazz = Cmdty.class;
} //添加
public Cmdty insert(Cmdty t) {
return mongoTemplate.insert(t);
} //保存
public Cmdty save(Cmdty t) {
return mongoTemplate.save(t);
} //保存商品信息
public Info saveInfo(Info t) {
return mongoTemplate.save(t);
} //修改
public int update(Map<String, Object> filter, Map<String, Object> updater) {
UpdateResult result = mongoTemplate.updateMulti(this.getQuery(filter), this.getUpdater(updater), this.clazz);
return (int) result.getModifiedCount();
} //删除
public long delete(Map<String, Object> filter) {
DeleteResult result = mongoTemplate.remove(this.getQuery(filter), this.clazz);
return result.getDeletedCount();
} //存在
public boolean exist(Map<String, Object> filter) {
return mongoTemplate.exists(this.getQuery(filter), this.clazz);
} //个数
public long count(Map<String, Object> filter) {
return mongoTemplate.count(this.getQuery(filter), this.clazz);
} //查询一个
public Cmdty getObject(Map<String, Object> filter) {
return mongoTemplate.findOne(this.getQuery(filter), this.clazz);
} //查询多个
public List<Cmdty> getList(Map<String, Object> filter) {
return mongoTemplate.find(this.getQuery(filter), this.clazz);
} protected Query getQuery(Map<String, Object> filter){
Query query = new Query();
for(Map.Entry<String, Object> entry : filter.entrySet()){
String key = entry.getKey();
Object value = entry.getValue();
switch (key){
case "id":
query = query.addCriteria(Criteria.where("_id").is(value));
break;
case "cmdtyName":
query = query.addCriteria(Criteria.where("cmdtyName").is(value));
break;
case "cmdtyNameLike":
Pattern pattern = Pattern.compile("^.*"+value+".*$", Pattern.CASE_INSENSITIVE);
query = query.addCriteria(Criteria.where("cmdtyName").regex(pattern));
break;
case "cmdtyCode":
query = query.addCriteria(Criteria.where("cmdtyCode").is(value));
break;
default:
break;
}
}
return query;
} protected Update getUpdater(Map<String, Object> updater) {
Update update = new Update();
for(Map.Entry<String, Object> entry : updater.entrySet()){
update.set(entry.getKey(), entry.getValue());
}
return update;
} }

  b.创建Service

@Service
public class TestService { @Resource
private TestDao dao; @Transactional
public boolean saveCmdty(Cmdty cmdty, Info info){
dao.saveInfo(info);
// int a = 1/0; //回滚测试代码
dao.save(cmdty);
return true;
} }

  c.测试代码

    public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
TestService service = (TestService) applicationContext.getBean("testService"); //商品信息
Info info = new Info();
info.setColor("silver");
info.setStyle("111");
//商品
Cmdty cmdty = new Cmdty();
cmdty.setCmdtyCode("Ag111");
cmdty.setCmdtyName("银111");
//商品属性
List<Attr> attributes = new ArrayList<>();
Attr attribute = new Attr();
attribute.setKey("品质");
attribute.setValue("特优");
attributes.add(attribute); cmdty.setInfo(info);
cmdty.setAttributes(attributes); service.saveCmdty(cmdty, info); }

  d.其他

    ①.排序:

        Sort.Direction direction = isAsc ? Sort.Direction.ASC : Sort.Direction.DESC;
query.with(new Sort(direction, sort));

    ②.分页:

        int skip = (pageIndex - 1) * pageSize;
query.skip(skip).limit(pageSize);

      或者

        Pageable pageable = new PageRequest(pageIndex, pageSize);
query.with(pageable);

    ③.返回指定字段:

        Document document = new Document();
for(String field : fields){
document.put(field, isReturn);
}
Query query = new BasicQuery(new Document(), document);

6.使用 MongoRepository 的方式

  a.书写Dao接口,继承 MongoRepository

@Repository
public interface TestRepositoryDao extends MongoRepository<Cmdty, String> { @Query(value="{'info.$id': ?0 }")
public Cmdty findByInfoId(ObjectId id); public Cmdty findByCmdtyCode(String cmdtyCode); }

    注:这种方式也支持 JPA 命名规则

  b.书写Service

@Service
public class TestRepositoryService { @Resource
private TestRepositoryDao dao; public Cmdty findByInfoId(String infoId){
return dao.findByInfoId(new ObjectId(infoId));
} public Cmdty findByCmdtyCode(String cmdtyCode){
return dao.findByCmdtyCode(cmdtyCode);
}
}

  e.测试

    public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
TestRepositoryService service = (TestRepositoryService) applicationContext.getBean("testRepositoryService"); // Cmdty cmdty = service.findByInfoId("5cc15f32a0e5eaeb0413dfde");
Cmdty cmdty = service.findByCmdtyCode("Ag111");
System.out.println(cmdty);
}

MongoDB与Spring整合(支持事务)——SpringDataMongoDB的更多相关文章

  1. MongoDB 学习(三)MongoDB 和 Spring 整合(Maven)

    一.MongoDB 和 Spring 整合(Maven) 1.相关 jar 包准备 2.用 Maven 创建项目,pom.xml 文件 <project xmlns="http://m ...

  2. Spring整合JMS——事务管理

    Spring提供了一个JmsTransactionManager用于对JMS ConnectionFactory做事务管理.这将允许JMS应用利用Spring的事务管理特性.JmsTransactio ...

  3. 像我这样优雅地进行Spring整合MongoDB

    本文重点是要将mongodb与spring整合到项目中去,在实践中发现问题,追踪问题,然后解决问题. 一.准备 Maven.Spring(spring-data-mongodb) spring Dat ...

  4. 使用Spring管理数据库事务

    在整个JavaWeb项目开发中,事务是用来开发可靠性网络应用程序的最关键部分.当应用程序与后端资源进行交互时,就会用到事务,这里的后端资源包括数据库.MQ.ERP等.而数据库事务是最常见的类型,而我们 ...

  5. MongoDB与SpringBoot整合(支持事务)

    1.创建SpringBoot工程,选择 Web.MonogDB 依赖,pom如下: <parent> <groupId>org.springframework.boot< ...

  6. spring整合mongodb

    使用spring整合mongodb maven 依赖 <dependency> <groupId>org.mongodb</groupId> <artifac ...

  7. Spring整合MongoDB(转)

    1.认识Spring Data MongoDB 之前还的确不知道Spring连集成Nosql的东西都实现了,还以为自己又要手动封装一个操作MongoDB的API呢,结果就发现了Spring Data ...

  8. Spring整合JMS(四)——事务管理

    原文链接:http://haohaoxuexi.iteye.com/blog/1983532 Spring提供了一个JmsTransactionManager用于对JMS ConnectionFact ...

  9. MongoDB系列:四、spring整合mongodb,带用户验证

    在前面的两篇博客 MongoDB常用操作练习.springboot整合mongoDB的简单demo中,我们基本上熟悉了mongodb,也把它与spring boot进行了整合并且简单使用.在本篇博客中 ...

随机推荐

  1. kubernetes 核心技术概念(二)之 volume namespace annoation

    volume k8s通过数据卷来提供pod数据的持久化,k8s的数据卷是对docker数据卷的扩展,k8s的数据卷是pod级别的,用来实现pod中容器的文件共享 volume是pod中能被多个容器访问 ...

  2. 08--STL关联容器(set/multiset)

    一:set/multiset的简介 set是一个集合容器,其中所包含的元素是唯一的,集合中的元素按一定的顺序排列.元素插入过程是按排序规则插入,所以不能指定插入位置. set采用红黑树变体的数据结构实 ...

  3. javascript 获取字符递增

    比如A->B,AA->AB,Z->AA 参考https://blog.csdn.net/xiaotao2004/article/details/75096607 C#版本,改写为ja ...

  4. 【LOJ 6041】「雅礼集训 2017 Day7」事情的相似度

    Description 人的一生不仅要靠自我奋斗,还要考虑到历史的行程. 历史的行程可以抽象成一个 01 串,作为一个年纪比较大的人,你希望从历史的行程中获得一些姿势. 你发现在历史的不同时刻,不断的 ...

  5. 2018-2019 20165237网络对抗 Exp5 MSF基础应用

    2018-2019 20165237网络对抗 Exp5 MSF基础应用 实验目标 本实践目标是掌握metasploit的基本应用方式,重点常用的三种攻击方式的思路.具体需要完成: 一个主动攻击实践,如 ...

  6. centos7 搭建jenkins服务器

    具体可参考:https://blog.csdn.net/it_lihongmin/article/details/80814384 注意: 1. 修改主目录:默认是/var/lib/jenkins,  ...

  7. c++ Qt向PHP接口POST文件流

    Qt调用PHP写的接口,向其传递图片文件,并保存在服务器. 二进制文件无法直接传递,Qt采用Base64进行编码发送,PHP解码保存为文件. 注意:PHP收到数据之后会将POST过来的数据中的加号(+ ...

  8. NB-IoT有三种部署方式及特点【转】

    转自:http://blog.sina.com.cn/s/blog_13ddf053f0102wcbz.html NB-IoT有三种运营模式,一种是独立的在运营商的网络外面重做:第二种是在LTE的保护 ...

  9. nginx的location配置详解

    语法规则: location [=|~|~*|^~] /uri/ { … } =开头表示精确匹配 ^~开头表示uri以某个常规字符串开头,理解为匹配url路径即可.nginx不对url做编码,因此请求 ...

  10. scrapy发送邮件

    scrapy发送邮件 应用场景:在爬虫关闭或者爬虫空闲时可以通过发送邮件的提醒. 通过twisted的非阻塞IO实现,可以直接写在spider中,也可以写在中间件或者扩展中,看你具体的需求. 在网上找 ...