1.配置文件
POM文件
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
YML文件
spring:
data:
mongodb:
uri: mongodb://localhost:27017 #连接的地址
database: curd #数据库
2.常用方法
mongoTemplate.insert(Class)
新增
mongoTemplate.remove(Query, Class)
删除
mongoTemplate.findAll(Class)
查询全部数据
mongoTemplate.findById(<id>,Class)
根据ID查询数据
mongoTemplate.find(Query, Class)
根据Query条件查询
mongoTemplate.upsert(Query, Update, Class)
修改,当查找不到对应的行时,会进行insert一条新记录,查找到时,只修改查找到的第一行
mongoTemplate.updateFirst(Query, Update, Class)
修改查找到的第一行
mongoTemplate.updateMulti(Query, Update, Class)
修改多行
mongoTemplate.aggregate(Aggregation, Class, Class)
聚合查询
Query对象
static query(CriteriaDefinition)
设置查询标准,并创建Query对象
skip(long)
设置跳过document数量,在返回结果集之前
limit(int)
限制返回document的数量
with(Sort sort)
排序
with(Pageable)
分页方式返回数据
案例
//获取第一页的10条数据,根据username,降序排序
PageRequest pageRequest = PageRequest.of(0, 10, Sort.by(Sort.Direction.DESC, "username"));
//查询age>=18的数据
Query query = Query.query(Criteria.where("age").gte(18)).with(pageRequest);
List<User> list = userDAO.list(query);
log.info("length: {} ,listTest: {}", list.size(), list); //length: 10 ,listTest:...
Criteria对象
static where(String key)
根据key进行查询,并创建Criteria对象
is(Object)
等于
ne(Object)
不等于
lt(Object)
小于
lte(Object)
小于等于
gt(Object)
大于
gte(Object)
大于等于
ne(Object)
不等于
in(Object...)
包含
in(Collection)
包含
nin(Object...)
不包含
nin(Collection)
不包含
mod(Number value, Number remainder)
取模value等于remainder的数据
all(Object...)
同时包含,与in的区别就是,in是查询某个字段的值,all是查询某个数组类型字段是否都包含
all(Collection)
同时包含
//查询address字段同时包含"深圳市","珠海市"的数据
Query query = Query.query(Criteria.where("address").all(Arrays.asList("深圳市","珠海市")));
size(int)
查询数组类型字段数量匹配的数据
//查询address数量为2的用户数据
db.user.find({'address':{$size:2}})
Query query = Query.query(Criteria.where("address").size(2));
exists(boolean)
是否存在该字段
//查询存在address字段的数据
Query query = Query.query(Criteria.where("address").exists(true));
type(int)
查询字段是对应类型的数据
Type | Number | Alias | Notes |
---|---|---|---|
Double | 1 | “double” | |
String | 2 | “string” | |
Object | 3 | “object” | |
Array | 4 | “array” | |
Binary data | 5 | “binData” | |
Undefined | 6 | “undefined” | Deprecated. |
ObjectId | 7 | “objectId” | |
Boolean | 8 | “bool” | |
Date | 9 | “date” | |
Null | 10 | “null” | |
Regular Expression | 11 | “regex” | |
DBPointer | 12 | “dbPointer” | Deprecated. |
JavaScript | 13 | “javascript” | |
Symbol | 14 | “symbol” | Deprecated. |
JavaScript (with scope) | 15 | “javascriptWithScope” | |
32-bit integer | 16 | “int” | |
Timestamp | 17 | “timestamp” | |
64-bit integer | 18 | “long” | |
Decimal128 | 19 | “decimal” | New in version 3.4. |
Min key | -1 | “minKey” | |
Max key | 127 | “maxKey” |
//查询address字段的数据类型为数组的数据
Query query = Query.query(Criteria.where("address").type(4));
type(Type... types)
查询字段是对应类型的数据
not(Object)
取反
regex(String)
正则
regex(Pattern)
正则
3.使用
model
@Document(collection = "user")
@Data
public class User implements Serializable {
private static final long serialVersionUID = 4349568198872630000L;
@Id
private String id;
private String username;
private String password;
@Field("nick_name")
private String nickName;
private Integer age;
private List<String> address;
}
dao
@Repository
public class BaseDAO<T> {
private Class<T> clazz;
@Autowired
MongoTemplate mongoTemplate;
public BaseDAO() {
clazz = getSuperClassGenericType();
}
public T insert(T t) {
T insert = mongoTemplate.insert(t);
return insert;
}
public List<T> insertAll(List<T> ts) {
List<T> collection = (List<T>) mongoTemplate.insertAll(ts);
return collection;
}
public List<T> list() {
Query query = new Query();
List<T> all = mongoTemplate.findAll(clazz);
return all;
}
public List<T> list(Query query) {
List<T> all = mongoTemplate.find(query, clazz);
return all;
}
public T getById(String id) {
T byId = mongoTemplate.findById(id, clazz);
return byId;
}
public UpdateResult upsert(Query query, UpdateDefinition updateDefinition) {
UpdateResult upsert = mongoTemplate.upsert(query, updateDefinition, clazz);
return upsert;
}
public UpdateResult updateFirst(Query query, UpdateDefinition updateDefinition) {
UpdateResult upsert = mongoTemplate.updateFirst(query, updateDefinition, clazz);
return upsert;
}
public UpdateResult updateMulti(Query query, UpdateDefinition updateDefinition) {
UpdateResult upsert = mongoTemplate.updateMulti(query, updateDefinition, clazz);
return upsert;
}
public DeleteResult remove(Query query) {
DeleteResult deleteResult = mongoTemplate.remove(query, clazz);
return deleteResult;
}
public List<T> aggregate(Aggregation aggregation) {
List<T> aggregate = aggregate(aggregation, clazz);
return aggregate;
}
public <R> List<R> aggregate(Aggregation aggregation, Class<R> outputClass) {
List<R> aggregate = aggregate(aggregation, clazz, outputClass);
return aggregate;
}
public <R> List<R> aggregate(Aggregation aggregation, Class inputClass, Class<R> outputClass) {
AggregationResults<R> aggregate = mongoTemplate.aggregate(aggregation, inputClass, outputClass);
List<R> mappedResults = aggregate.getMappedResults();
return mappedResults;
}
private Class getSuperClassGenericType() {
Type type = this.getClass().getGenericSuperclass();
if (type instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) type;
clazz = (Class<T>) parameterizedType.getActualTypeArguments()[0];
}
return clazz;
}
}
@Repository
public class UserDAO extends BaseDAO<User> {
}
测试用例
@SpringBootTest
@Slf4j
public class UserDAOTest {
@Autowired
UserDAO userDAO;
@Test
public void insertTest() {
User user = new User();
user.setAge(18);
user.setNickName("超级好看");
user.setUsername("张三");
user.setPassword("123456");
User insert = userDAO.insert(user);
log.info("insertTest: {}", insert);
}
@Test
public void insertAllTest() {
List<User> collect = IntStream.range(0, 100).mapToObj(num -> {
User user = new User();
user.setAge(18);
user.setNickName("超级好看");
user.setUsername("张三" + num);
user.setPassword("123456");
return user;
}).collect(Collectors.toList());
userDAO.insertAll(collect);
}
@Test
public void listTest() {
List<User> list = userDAO.list();
log.info("listTest: {}", list);
}
@Test
public void listTest2() {
Query query = new Query(Criteria.where("age").gte(18));
query.with(PageRequest.of(0, 10, Sort.by(Sort.Direction.DESC, "username")));
List<User> list = userDAO.list(query);
log.info("length: {} ,listTest: {}", list.size(), list);
}
@Test
public void listTest3() {
PageRequest pageRequest = PageRequest.of(0, 10, Sort.by(Sort.Direction.DESC, "username"));
Query query = Query.query(Criteria.where("age").gte(18)).with(pageRequest).limit(5);
List<User> list = userDAO.list(query);
log.info("length: {} ,listTest: {}", list.size(), list);
}
@Test
public void listTest4() {
Query query = Query.query(Criteria.where("address").size(2));
List<User> list = userDAO.list(query);
log.info("length: {} ,listTest: {}", list.size(), list);
}
@Test
public void listTest5() {
Query query = Query.query(Criteria.where("address").all(Arrays.asList("深圳市", "珠海市")));
List<User> list = userDAO.list(query);
log.info("length: {} ,listTest: {}", list.size(), list);
}
@Test
public void getByIdTest() {
User byId = userDAO.getById("5f03f180e7d7c8591deac8f9");
log.info("getByIdTest: {}", byId);
}
@Test
public void upsertTest() {
UpdateResult updateResult = userDAO.upsert(Query.query(Criteria.where("username").is("何一")), Update.update("age", 19));
log.info("upsertTest: {}", updateResult);
}
@Test
public void updateFirstTest() {
UpdateResult updateResult = userDAO.updateFirst(Query.query(Criteria.where("username").is("许二")), Update.update("age", 19));
log.info("updateFirstTest: {}", updateResult);
}
@Test
public void updateMultiTest() {
UpdateResult updateResult = userDAO.updateMulti(Query.query(Criteria.where("age").is(19)), Update.update("age", 18));
log.info("updateMultiTest: {}", updateResult);
}
@Test
public void removeTest() {
DeleteResult remove = userDAO.remove(Query.query(Criteria.where("age").is(18)));
log.info("removeTest: {}", remove);
}
@Test
public void aggregateTest() {
//获取以好看结尾的nickName,age>=16和age<=18的数据,然后以id进行分组,将username添加到username,nickName添加到nickName,同时统计条数
List<User> aggregate = userDAO.aggregate(Aggregation.newAggregation(
Aggregation.match(Criteria.where("nickName").regex("好看$")
.andOperator(Criteria.where("age").gte(16)
, Criteria.where("age").lte(18))),
Aggregation.group("id").push("username").as("username").push("nickName").as("nick_name").count().as("count")
));
log.info("aggregateTest: {}", aggregate);
}
}
4.小练习
model
@Document(collection = "favorite_unit ")
@Data
public class FavoriteUnit implements Serializable {
private static final long serialVersionUID = 1L;
@Id
private String id;
private String agentId; //代理人ID
private String unitId; //单元ID
private LocalDateTime createTime;//创建时间
}
题目:获取上个月某个代理人添加的unitId列表和对应unitId的添加次数
答案
@Test
public void aggregateTest() {
LocalDateTime localDateTime = LocalDateTime.now().minusMonths(1);
LocalDateTime firstDayOfMonth = localDateTime.with(TemporalAdjusters.firstDayOfMonth());
firstDayOfMonth = LocalDateTime.of(firstDayOfMonth.toLocalDate(), LocalTime.MIN);
LocalDateTime lastDayOfMonth = localDateTime.with(TemporalAdjusters.lastDayOfMonth());
lastDayOfMonth = LocalDateTime.of(lastDayOfMonth.toLocalDate(), LocalTime.MAX);
//统计某个agentId,上个月开始时间到结束时间的数据,然后只获取"agentId", "unitId", "createTime"字段,最后根据unitId分组,并统计条数
List<User> aggregate = userDAO.aggregate(Aggregation.newAggregation(
Aggregation.match(Criteria.where("agentId").is("5c1cacc718aad600067b7aa0")
.andOperator(Criteria.where("createTime").gte(firstDayOfMonth)
, Criteria.where("createTime").lte(lastDayOfMonth))),
Aggregation.project("agentId", "unitId", "createTime"),
Aggregation.group("unitId").count().as("count")
));
log.info("aggregateTest: {}", aggregate);
}