# springboot2-mongodb-demo **Repository Path**: knowz/springboot2-mongodb-demo ## Basic Information - **Project Name**: springboot2-mongodb-demo - **Description**: springboot2整合MongoDB4.0与事务实现 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 7 - **Forks**: 8 - **Created**: 2018-08-12 - **Last Updated**: 2020-12-18 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # springboot2-mongodb-demo #### 项目介绍 - springboot2.0.4 - MongoDB4.0.1数据库 - 实现了MongoDB的事务 #### 使用说明 1. 导入MongoDB的依赖 ``` org.springframework.boot spring-boot-starter-data-mongodb ``` 2. 配置MongoDB的连接 ``` spring.data.mongodb.uri=mongodb://username:password@localhost:27017/test ``` 3. 编写pojo类 当id设置为 **ObjectId** 类型和添加 **@Id** 注解时时,MongoDB数据库会自动生成主键,我们在保存对象时就不用设置id的值 ``` package com.zkane.domain; import lombok.Data; import org.bson.types.ObjectId; import org.springframework.data.annotation.Id; /** * @author 594781919@qq.com * @date 2018/8/12 */ @Data public class Employee { @Id private ObjectId id; private String name; private Integer age; } ``` 4. 编写dao层的方法 jpa支持很多方法命名规则来自动生成查询语句 ``` package com.zkane.repository; import com.zkane.domain.Employee; import org.springframework.data.mongodb.repository.MongoRepository; import java.util.List; /** * @author 594781919@qq.com * @date 2018/8/12 */ public interface EmpRepository extends MongoRepository { Employee findByName(String name); List findByAgeGreaterThan(int age); } ``` ![输入图片说明](https://images.gitee.com/uploads/images/2018/0812/171714_58b4bc1f_1305332.png "屏幕截图.png") ![输入图片说明](https://images.gitee.com/uploads/images/2018/0812/171740_762836a1_1305332.png "屏幕截图.png") 5. 测试 ``` package com.zkane; import com.zkane.domain.Employee; import com.zkane.repository.EmpRepository; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.domain.Example; import org.springframework.data.domain.ExampleMatcher; 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.test.context.junit4.SpringRunner; import java.util.List; @RunWith(SpringRunner.class) @SpringBootTest public class Springboot2MongodbDemoApplicationTests { @Autowired private EmpRepository empRepository; @Autowired private MongoTemplate mongoTemplate; @Test public void test1() { Employee employee = new Employee(); employee.setName("王五"); employee.setAge(29); empRepository.save(employee); System.out.println(employee); } @Test public void test2() { Employee employee = empRepository.findByName("张三"); System.out.println(employee); } @Test public void test3() { // 通过MongoTemplate来查询数据 Query query = new Query(Criteria.where("age").in(20, 23)); List employees = mongoTemplate.find(query, Employee.class); System.out.println(employees); } @Test public void test4() { // 查询年龄大于25的数据 List employeeList = empRepository.findByAgeGreaterThan(25); System.out.println(employeeList); } } ``` #### MongoDB的事务 1. 目前事务回滚只能在复制集上操作,单独的mongodb server不能操作事务 - 开启服务器27017 ``` D:\Program Files\MongoDB\Server\4.0\bin> .\mongod.exe -dbpath ..\data\db --replSet rs0 ``` - 开启服务器27018 ``` D:\Program Files\MongoDB\Server\4.0\bin> .\mongod.exe -dbpath ..\data\db27018 --port 27018 --replSet rs0 ``` - 设置集群 ``` D:\Program Files\MongoDB\Server\4.0\bin> .\mongo.exe --port 27017 > rs.initiate() rs0:SECONDARY> rs.add('localhost:27018') ``` 2.代码实现 - 修改导入的依赖 ``` org.springframework.boot spring-boot-starter-data-mongodb org.mongodb mongodb-driver org.mongodb mongo-java-driver 3.8.0 com.alibaba fastjson 1.2.47 ``` - 测试代码 ``` package com.zkane.service; import com.alibaba.fastjson.JSONObject; import com.mongodb.MongoClient; import com.mongodb.MongoException; import com.mongodb.client.ClientSession; import com.mongodb.client.MongoCollection; import com.zkane.domain.Address; import com.zkane.domain.Employee; import com.zkane.repository.EmpRepository; import org.bson.Document; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; /** * @author: 594781919@qq.com * @date: 2018/8/13 */ @Service public class EmployeeService { @Autowired private EmpRepository empRepository; @Autowired private MongoClient client; /** * 测验MongoDB的事务回滚 */ public void save() { try (ClientSession clientSession = client.startSession()) { clientSession.startTransaction(); Employee employee = new Employee(); employee.setName("王五"); employee.setAge(31); Address address = new Address(); address.setCity("北京"); address.setStreet("长安路"); employee.setAddress(address); MongoCollection employeeCollection = client.getDatabase("test").getCollection("employee"); employeeCollection.insertOne(clientSession, Document.parse(JSONObject.toJSONString(employee))); //int i = 1 / 0; employee = new Employee(); employee.setName("赵六"); employee.setAge(25); address = new Address(); address.setCity("北京"); address.setStreet("太升路"); employee.setAddress(address); employeeCollection.insertOne(clientSession, Document.parse(JSONObject.toJSONString(employee))); commitWithRetry(clientSession); } } /** * 提交失败时,进行重新提交 * @param clientSession */ void commitWithRetry(ClientSession clientSession) { while (true) { try { clientSession.commitTransaction(); System.out.println("Transaction committed"); break; } catch (MongoException e) { // can retry commit if (e.hasErrorLabel(MongoException.UNKNOWN_TRANSACTION_COMMIT_RESULT_LABEL)) { System.out.println("UnknownTransactionCommitResult, retrying commit operation ..."); continue; } else { System.out.println("Exception during commit ..."); throw e; } } } } } ```