springboot2.0.4
MongoDB4.0.1数据库
实现了MongoDB的事务
1.导入MongoDB的依赖
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-mongodbartifactId>
dependency>
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 [email protected]
* @date 2018/8/12
*/
@Data
public class Employee {
@Id
private ObjectId id;
private String name;
private Integer age;
}
4.编写dao层的方法
package com.zkane.repository;
import com.zkane.domain.Employee;
import org.springframework.data.mongodb.repository.MongoRepository;
import java.util.List;
/**
* @author [email protected]
* @date 2018/8/12
*/
public interface EmpRepository extends MongoRepository<Employee, Long> {
Employee findByName(String name);
List findByAgeGreaterThan(int age);
}
jpa支持很多方法命名规则来自动生成查询语句
Keyword | Sample | Logical result |
---|---|---|
After | findByBirthdateAfter(Date date) | {“birthdate” : {“$gt” : date}} |
GreaterThan | findByAgeGreaterThan(int age) | {“age” : {“$gt” : age}} |
GreaterThanEqual | findByAgeGreaterThanEqual(int age) | {“age” : {“$gte” : age}} |
Before | findByBirthdateBefore(Date date) | {“birthdate” : {“$lt” : date}} |
LessThan | findByAgeLessThan(int age) | {“age” : {“$lt” : age}} |
LessThanEqual | findByAgeLessThanEqual(int age) | {“age” : {“$lte” : age}} |
Between | findByAgeBetween(int from, int to) | {“age” : {“$gt” : from, “$lt” : to}} |
In | findByAgeIn(Collection ages) | {“age” : {“$in” : [ages…]}} |
NotIn | findByAgeNotIn(Collection ages) | {“age” : {“$nin” : [ages…]}} |
IsNotNull, NotNull | findByFirstnameNotNull() | {“firstname” : {“$ne” : null}} |
IsNull, Null | findByFirstnameNull() | {“firstname” : null} |
Like, StartingWith, EndingWith | findByFirstnameLike(String name) | {“firstname” : name} (name as regex) |
NotLike, IsNotLike | findByFirstnameNotLike(String name) | {“firstname” : { “$not” : name }} (name as regex) |
Containing on String | findByFirstnameContaining(String name) | {“firstname” : name} (name as regex) |
NotContaining on String | findByFirstnameNotContaining(String name) | {“firstname” : { “$not” : name}} (name as regex) |
Containing on Collection | findByAddressesContaining(Address address) | {“addresses” : { “$in” : address}} |
NotContaining on Collection | findByAddressesNotContaining(Address address) | {“addresses” : { “$not” : { “$in” : address}}} |
Regex | findByFirstnameRegex(String firstname) | {“firstname” : {“$regex” : firstname }} |
(No keyword) | findByFirstname(String name) | {“firstname” : name} |
Not | findByFirstnameNot(String name) | {“firstname” : {“$ne” : name}} |
Near | findByLocationNear(Point point) | {“location” : {“$near” : [x,y]}} |
Near | findByLocationNear(Point point, Distance max) | {“location” : {“$near” : [x,y], “$maxDistance” : max}} |
Near | findByLocationNear(Point point, Distance min, Distance max) | {“location” : {“$near” : [x,y], “$minDistance” : min, “$maxDistance” : max}} |
Within | findByLocationWithin(Circle circle) | {“location” : {“$geoWithin” : {“$center” : [ [x, y], distance]}}} |
Within | findByLocationWithin(Box box) | {“location” : {“$geoWithin” : {“$box” : [ [x1, y1], x2, y2]}}} |
IsTrue, True | findByActiveIsTrue() | {“active” : true} |
IsFalse, False | findByActiveIsFalse() | {“active” : false} |
Exists | findByLocationExists(boolean exists) | {“location” : {“$exists” : exists }} |
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);
}
}
1.目前事务回滚只能在复制集上操作,单独的mongodb server不能操作事务
D:\Program Files\MongoDB\Server\4.0\bin> .\mongod.exe -dbpath ..\data\db --replSet rs0
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.代码实现
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: [email protected]
* @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;
}
}
}
}
}
源码地址:码云