常用查询
类似mysql 的like
// 原生查询
{name:/名字/}
// java 驱动查询
document.put("page_html", Pattern.compile("名字"));
// 分页
Pageable pageable = new PageRequest(pageNum,pageSize);
//创建排序规则
Sort sort = new Sort(Sort.Direction.DESC, "cTime");
// 带入
Query query = new Query();
query.with(pageable);
query.with(sort);
// 精确查询
//如果name精确查询
if(!StringUtils.isEmpty(name)){
query.addCriteria(
Criteria.where("name").is(name)
);
}
// 模糊查询
//如果name使用模糊查询则 创建正则
Pattern pattern= Pattern.compile("^.*"+name+".*$", Pattern.CASE_INSENSITIVE);
if(!StringUtils.isEmpty(name)){
query.addCriteria(
new Criteria().and("name").regex(pattern)
);
}
// 时间段范围查询
if(!StringUtils.isEmpty(stime)){
query.addCriteria(
new Criteria().andOperator(
Criteria.where("cTime").gte(stime),
Criteria.where("cTime").lte(etime)
)
);
}
// 查询总行数
Long count = mongoTemplate.count(query,GoodsModel.class);
// 返回指定字段
Query query=new Query();
query.addfields().include("你要返回的字段1");
query.addfields().include("你要返回的字段2");
query.addfields().exclude("你不返回的字段");
query.addCriteria(Criteria.where("XM").ne(null));//你要添加的查询
return mongoTemplate.find(query,你要返回的类型.class);
关联查询
@DBRef
// 关联查询
long startSkip = 0;
Criteria criteria = new Criteria();
Pattern pattern = Pattern.compile("^.*" + "免费余额" + ".*$", Pattern.CASE_INSENSITIVE);
criteria.and("name").regex(pattern);
Aggregation aggregation = Aggregation.newAggregation(
Aggregation.lookup("activity_info", "ak", "_id", "ActivityInfo"),
Aggregation.match(criteria),
Aggregation.skip(startSkip),
Aggregation.limit(10));
List<AccountBalanceTypeVo> list = mongoTemplate.aggregate(aggregation, "account_balance_type", AccountBalanceTypeVo.class).getMappedResults();
System.out.println(list);
原生查询
//假如说我们关联查询时候就要加条建
db.student22.aggregate([
{$lookup:{
from:"parent22", //关联从表的表名
let: {
nm: "$name", // 定义要筛选的字段
},
pipeline: [{
$match: {
$expr: {
$eq: ["张1","$name"] // 筛选从表name等于张1的信息
}
},
}
//下面还可以继续指定其他管道阶段符合
],
as:"pr" //给结果起个别名
}
}
])
常用注解
@Id
/*主键,不可重复,自带索引*/
@Document
/*标注在实体类上,类似于hibernate的entity注解,标明由mongo来维护该表
org.springframework.data.mongodb.core.mapping.Document.class
把一个java类声明为mongodb的文档,可以通过collection参数指定这个类对应的文档。*/
@Document(collection=“mongodb 对应 collection 名”)
// 若未加 @Document ,该 bean save 到 mongo 的 user collection
// 若添加 @Document ,则 save 到 reUser collection
@Document(collection=“reUser”)
public class User{
}
@Indexed
/*声明该字段需要加索引,加索引后以该字段为条件检索将大大提高速度。
唯一索引的话是@Indexed(unique = true)。
也可以对数组进行索引,如果被索引的列是数组时,MongoDB会索引这个数组中的每一个元素。
也可以对整个Document进行索引,排序是预定义的按插入BSON数据的先后升序排列。*/
@CompoundIndex
/*复合索引,加复合索引后通过复合索引字段查询将大大提高速度。*/
@Document
@CompoundIndexes({
@CompoundIndex(name = “age_idx”, def = “{‘lastName’: 1, ‘age’: -1}”)
})
/*写法如上,lastName和age将作为复合索引,数字参数指定索引的方向,1为正序,-1为倒序。方向对单键索引和随机存不要紧,
但如果你要执行分组和排序操作的时候,它就非常重要了。*/
public class Person {
}
@Field
/*代表一个字段,可以不加,不加的话默认以参数名为列名。
给映射存储到 mongodb 的字段取别名
在 java bean 中字段名为 firstName,存储到 mongo 中 key 为 fName
*/
@Field(“fName”)
private String firstName;
@Transient
// 被该注解标注的,将不会被录入到数据库中。只作为普通的javaBean属性。
@DBRef
// 关联另一个document对象。类似于mysql的表关联,但并不一样,mongo不会做级联的操作。
@JsonFormat
// 后端格式化日期后返回给前端
@JsonFormat(pattern = “yyyy-MM-dd”, timezone = “GMT+8”)
private Date birthday;//生日
@JsonFormat(pattern = “yyyy-MM-dd HH:mm:ss”, timezone = “GMT+8”)
private Date createTime;//创建时间
@JsonFormat(pattern = DateUtils.LONG_TIME_FORMAT, timezone = “GMT+8”)
private Date modifyTime;//修改时间
开启事务
package com.example.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.MongoTransactionManager;
@Configuration
public class TransactionConfig {
@Bean
MongoTransactionManager transactionManager(MongoDbFactory factory){
return new MongoTransactionManager(factory);
}
}
使用事务
@Transactional(rollbackFor = Exception.class,value = "transactionManager")
public void saveTest(Mongo test) {
mongoTemplate.save(test);
int i = 1/0;
}
在启动类上加上事务注解@EnableTransactionManagement
。
开启事务常见问题
- 1.MongoDB的版本必须是4.0
- 2.MongoDB事务功能必须是在多副本集的情况下才能使用,否则报错"Sessions are not supported by the MongoDB cluster to which this client is connected",4.2版本会支持分片事务。
- 3.事务控制只能用在已存在的集合中,也就是集合需要手工添加不会由jpa创建会报错"Cannot create namespace glcloud.test_user in multi-document transaction."
- 4.多数据源时需要指定事务 @Transactional(value = "transactionManager") 如果只有1个数据源不需要指定value
- 5.事务注解到类上时,该类的所有 public 方法将都具有该类型的事务属性,但一般都是注解到方法上便于实现更精确的事务控制
- 6.事务传递性,事务子方法上不必添加事务注解,如果子方法也提供api调用可用注解propagation = Propagation.REQUIRED也就是继承调用它的事务,如果没有事务则新起一个事务
- 7.启动类上的@EnableTransactionManagement注解,并不是像网上所说必需添加的注解,因为spring boot 默认开始了这个注解的。
- 8.有人说:注解必须是@Transactional(rollbackFor = { Exception.class }) 测试并不需要rollbackFor = { Exception.class },因为本例中自定义异常类继承自RuntimeException spring boot事物默认在遇到RuntimeException不论rollbackFor的异常是啥,都会进行事务的回滚,加上rollbackFor=Exception.class,可以让事物在遇到非运行时异常时也回滚
具体rollbackFor用法可参考:
Spring中的@Transactional(rollbackFor = Exception.class)属性详解一次Spring Transactional嵌套事务使用不同的rollbackFor的分析
作者:DevMuYuer