一、引入依赖
<!--MongoDB-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
二、修改application.yml
server:
port: 80
spring:
data:
mongodb:
port: 27017 #端口号
host: localhost #地址
database: test #数据库
三、新建实体类
1、新建评论类
package com.hq.mongodb.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.util.Date;
import java.util.List;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class Comment {
/**
* id
*/
private Integer id;
/**
* 评论内容
*/
private String content;
/**
* 评论等级
*/
private String grage;
/**
* 用户id
*/
private String userId;
/**
* 创建时间
*/
private Date createTime;
/**
* 回复
*/
private List<Reply> replyList;
}
2、新建回复类
package com.hq.mongodb.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class Reply {
@Id
private String id;
/**
* 回复id
*/
private String replyId;
/**
* 评论id
*/
private String commentId;
/**
* 回复内容
*/
private String content;
/**
* 用户id
*/
private Integer userId;
/**
* 创建时间
*/
private String createTime;
}
四、注入MongoDBTemplet
@Autowired
private MongoTemplate mongoTemplate;
五、添加文档
1、集合名为类名
/**
* 测试添加评论
*/
@Test
public void testSave() {
mongoTemplate.save(new Comment()
.setContent("测试内容")
.setUserId(1)
.setGrage(1)
.setCreateTime(new Date()));
}
2、自定义集合名
/**
* 测试添加评论
*/
@Test
public void testSave() {
mongoTemplate.save(new Comment()
.setContent("测试内容")
.setUserId(1)
.setGrage(1)
.setCreateTime(new Date()),"集合名");
}
六、删除文档
1、根据id删除,集合名为类名
/**
* 测试删除评论
*/
@Test
public void testRemove() {
Comment comment = new Comment();
comment.setId("621f78b913664d2f38447f28");
DeleteResult result = mongoTemplate.remove(comment);
System.out.println("删除数量:" + result.getDeletedCount());
}
2、根据id删除,自定义集合名
方法如下:
public DeleteResult remove(Object object, String collectionName);
参数说明:object为传入的对象,collectionName为集合名;
例:
Comment comment = new Comment();
comment.setId("621f7aab9f11ca72786cd94a");
DeleteResult result = mongoTemplate.remove(comment,"comment");
3、根据自定义条件删除,自定义集合名
方法如下:
public DeleteResult remove(Query query, String collectionName) {
参数说明:query为传入的条件构造器,具体用法请看这,collectionName为集合名;
例:
Query query = new Query(Criteria.where("content").is("测试内容"));
DeleteResult result = mongoTemplate.remove(query,"comment");
System.out.println("删除数量:" + result.getDeletedCount());
4、根据自定义条件和传入类.Class文件删除
方法如下:
public DeleteResult remove(Query query, Class<?> entityClass);
参数说明:query为传入的条件构造器,entityClass为类名.class
例:
Query query = new Query(Criteria.where("content").is("测试内容"));
DeleteResult result = mongoTemplate.remove(query,Comment.class);
System.out.println("删除数量:" + result.getDeletedCount());
七、修改文档
1、根据条件修改查询出来的第一条数据
方法如下
UpdateResult updateFirst(Query query, UpdateDefinition update, String collectionName:集合名);
参数说明:query:根据什么条件进行修改
update:需要修改的键
collectionName:集合名
例
Query query = new Query(Criteria.where("content").is("测试内容"));
Update update = Update.update("grade", "5");
UpdateResult result=mongoTemplate.updateFirst(query,update,"comment");
System.out.println("修改数量:" + result.getModifiedCount());
2、根据条件修改数据
方法如下
public UpdateResult updateMulti(Query query, UpdateDefinition update, String collectionName)
参数说明:query:根据什么条件进行修改
update:需要修改的键
collectionName:集合名
例
Query query = new Query(Criteria.where("content").is("测试内容"));
Update update = Update.update("grade", "1");
UpdateResult result=mongoTemplate.updateMulti(query,update,"comment");
System.out.println("修改数量:" + result.getModifiedCount());
八、基本查询
1、查询所有数据
1)、根据传入的类.class查询所有数据
方法如下
public <T> List<T> findAll(Class<T> entityClass);
参数说明:entityClass:传入的类名.class
例
List<Comment> list=mongoTemplate.findAll(Comment.class);
2、只查询指定键
方法如下
public Field include(String field);
public Field include(String... fields)
参数说明:field:键名,可以是多个参数
例
Query query = new Query();
query.fields().include("content","grade");
List<Comment> list=mongoTemplate.find(query, Comment.class);
注:id是默认返回的,如果不想返回就
Query query = new Query();
query.fields().include("content").exclude("_id");
List<Comment> list=mongoTemplate.find(query, Comment.class);
3、不查询指定键
方法如下
public Field exclude(String field)
public Field exclude(String... fields)
参数说明:field:键名,可以是多个参数
例
Query query = new Query();
query.fields().exclude("content","grade");
List<Comment> list=mongoTemplate.find(query, Comment.class);
注:除_id外不能同时有包含和排除键
4、等值匹配
Query query = new Query(Criteria.where("_id").is(1));
Comment comment=mongoTemplate.findOne(query, Comment.class);
注:findOne是只查询一条数据,查询多条改成find
5、比较条件
Query query = new Query(Criteria.where("_id").gt(1));
Comment comment=mongoTemplate.findOne(query, Comment.class);
注:gt:>、gte:>=、lt:<、lte:<=、ne:!=
6、判断不为空
Query query=new Query();
Criteria criteria = new Criteria();
criteria.andOperator(Criteria.where("content").ne(null),Criteria.where("content").ne("");
query.addCriteria(criteria);
List<Comment> list=mongoTemplate.find(query,Comment.class);
7、and条件
方法如下
public Criteria and(String key)
key:键名
例:查询content为aa并且userId为1的数据
Query query=new Query(Criteria.where("content").is("aa").and("memberId").is(1));
List<Comment> list=mongoTemplate.find(query,Comment.class);
8、or条件
9、in和not in
1、参数为可变参数
方法如下
//in
public Criteria in(Object... values);
//not in
public Criteria nin(Object... values);
例
//in
Query query = new Query(Criteria.where("userId").in(1,2));
//not in
Query query = new Query(Criteria.where("userId").in(1,2));
List<Comment> comment=mongoTemplate.find(query, Comment.class);
2)参数为集合
方法如下
//in
public Criteria in(Collection<?> values);
//not in
public Criteria nin(Collection<?> values);
例
List<Integer> list=new ArrayList<>();
list.add(1);
list.add(2);
//in
Query query = new Query(Criteria.where("userId").in(list));
//not in
Query query = new Query(Criteria.where("userId").nin(list));
List<Comment> comment=mongoTemplate.find(query, Comment.class);
10、like、左like、右like
1)、类型为String
方法如下
public Criteria regex(String regex);
like:以^.*开头,以.*$结尾或者直接写值
左like:以^.*开头或以^开头
右like:以.*$结尾或以$结尾
例
//查询content包含测试的数据(like)
Query query = new Query(Criteria.where("content").regex("测试"));
//查询content以测试开头的数据(左like)
Query query = new Query(Criteria.where("content").regex("^测试"));
//查询content以测试结尾的数据(右like)
Query query = new Query(Criteria.where("content").regex("测试$"));
List<Comment> comment=mongoTemplate.find(query, Comment.class);
11、count
方法如下,选第一种即可
//query:条件过滤器,entityClass:集合名为类.class
public long count(Query query, Class<?> entityClass);
//query:条件过滤器,collectionName:集合名
public long count(Query query, String collectionName)
//query:条件过滤器,entityClass:类名.class,collectionName:集合名
public long count(Query query, @Nullable Class<?> entityClass, String collectionName:集合名);
例:查询用户id为1的有多少记录
Query query = new Query(Criteria.where("userId").regex(1));
long count=mongoTemplate.count(query, Comment.class);
12、升序和降序
方法如下
//升序:优先级从左往右降序
query.with(Sort.by(Sort.Direction.ASC,"grade","userId"));
//降序:优先级从左往右降序
query.with(Sort.by(Sort.Direction.DESC,"grade","userId"));
//先升序,相同的值再降序
query.with(Sort.by(Sort.Direction.ASC,"grade").and(Sort.by(Sort.Direction.DESC,"userId")));
例:根据grade升序,遇到相同的值按照userId升序
Query query=new Query();
query.with(Sort.by(Sort.Direction.ASC,"grade","userId");
List<Comment> count=mongoTemplate.find(query, Comment.class);
13、跳过N条数据
方法如下
public Query skip(long skip)
注:skip为0则是从第一条记录开始查询
例
Query query=new Query();
query.skip(1);
List<Comment> count=mongoTemplate.find(query, Comment.class);
14、查询N条数据
方法如下
public Query limit(int skip)
例
Query query=new Query();
query.limit(1);
List<Comment> count=mongoTemplate.find(query, Comment.class);
15、分页
例
Query query=new Query();
query.skip(1).limit(1);
List<Comment> count=mongoTemplate.find(query, Comment.class);
九、子集合操作
1、添加
Comment comment = mongoTemplate.findById("621f89cb80c07d03b92835ce", Comment.class);
List<Reply> list = new ArrayList<>();
if (comment.getReplyList() != null) {
list = comment.getReplyList();
}
Reply reply = new Reply();
reply.setContent("回复内容");
reply.setId(System.currentTimeMillis()+"");
list.add(reply);
comment.setReplyList(list);
mongoTemplate.save(comment, "comment");
2、删除
Update update = new Update();
//需要删除的数据
update.pull("replyList",new BasicDBObject("_id","1647572876015"));
//先根据条件查询到父集合对应的数据,再根据对应集合属性的键进行查找
Query query = new Query(Criteria.where("_id").is("621f89cb80c07d03b92835ce").and("replyList.id").is("1647572876015"));
//执行
UpdateResult result = mongoTemplate.updateMulti(query, update, Comment.class, "comment");
3、修改
Update update = new Update();
//需要修改的值(键名必须是子集合的key.$.需要修改的key)
update.set("replyList.$.content", "ss");
//先查询出对应的父集合,然后根据对应子集合条件查询
Query query = new Query(Criteria.where("userId").is(1).and("replyList").elemMatch(Criteria.where("id").is("1647572876015")));
UpdateResult result = mongoTemplate.updateMulti(query, update, Comment.class, "comment");
System.out.println(result.getModifiedCount());
4、查询
Aggregation aggregation=Aggregation.newAggregation(
//先查询父集合
Aggregation.match(Criteria.where("_id").is("621f89cb80c07d03b92835ce")),
//拆分子集合字段
Aggregation.unwind("replyList"),
//再根据子集合条件进行查询
Aggregation.match(Criteria.
where("replyList.content").is("回复内容"))
);
//执行查询,泛型只能是JSONObject
AggregationResults<JSONObject> reminds = mongoTemplate
.aggregate(aggregation, "comment", JSONObject.class);
List<JSONObject> mappedResults = reminds.getMappedResults();
List<Reply> list=new ArrayList<>();
if(mappedResults!=null&&mappedResults.size()!=0){
//依次添加
for (JSONObject mappedResult : mappedResults) {
list.add(JSONObject.parseObject(mappedResult.getJSONObject("replyList").toJSONString(),Reply.class));
}
}
九、聚合管道查询
1、条件过滤
方法如下
public static MatchOperation match(Criteria criteria);
criteria:跟基本查询一样,构造一个条件过滤器
例
Aggregation aggregation = Aggregation.newAggregation(
Aggregation.match(criteria)
);
AggregationResults<Comment> giveRewardList=mongoTemplate.aggregate(aggregation,"comment",Comment.class);
List<Comment> list=giveRewardList.getMappedResults();
2、只查询指定键
方法如下
//参数为可变参数
Aggregation.project(String... fields);
//参数为类名.class:查询该类的所有key
Aggregation.project(Class<?> type);
例
Aggregation aggregation = Aggregation.newAggregation(
Aggregation.project("content")
);
AggregationResults<Comment> giveRewardList=mongoTemplate.aggregate(aggregation,"comment",Comment.class);
List<Comment> list=giveRewardList.getMappedResults();
注:_id是默认查询出来的,如果不想查询出来可以
Aggregation.project("content").andExclude("_id")
3、不查询指定key
方法如下
Aggregation.project().andExclude(String... fieldNames)
例
Aggregation aggregation = Aggregation.newAggregation(
Aggregation.project().andExclude("content")
);
AggregationResults<Comment> giveRewardList=mongoTemplate.aggregate(aggregation,"comment",Comment.class);
List<Comment> list=giveRewardList.getMappedResults();
注:project()是必须要写的,而且不能带任何参数
4、排序
方法如下
Aggregation.sort();
参数请参考基本查询的排序
例
Aggregation aggregation = Aggregation.newAggregation(
Aggregation.sort(Sort.by(Sort.Direction.ASC,"grade","userId"))
);
AggregationResults<Comment> giveRewardList=mongoTemplate.aggregate(aggregation,"comment",Comment.class);
List<Comment> list=giveRewardList.getMappedResults();
5、分页
方法如下
//跳过第N条记录
Aggregation.skip(long elementsToSkip);
//只查询N条记录
Aggregation.limit(long maxElements);
例:查询第1-5条数据
Aggregation aggregation = Aggregation.newAggregation(
Aggregation.skip(0),
Aggregation.limit(5)
);
AggregationResults<Comment> giveRewardList=mongoTemplate.aggregate(aggregation,"comment",Comment.class);
List<Comment> list=giveRewardList.getMappedResults();
6、分组
方法如下
Aggregation.group(String... fields)
例
Aggregation aggregation = Aggregation.newAggregation(
Aggregation.group("userId")
);
AggregationResults<Comment> giveRewardList=mongoTemplate.aggregate(aggregation,"comment",Comment.class);
List<Comment> list=giveRewardList.getMappedResults();
7、求和
十、MongoRepository操作
1、CrudRepository里面的方法
功能 | 方法 |
---|---|
添加一条数据 | |
添加多条数据 | |
根据id删除 | void deleteById(ID id); |
删除所有数据 | void deleteAll(); |
根据id批量删除 | void deleteAllById(Iterable<? extends ID> ids); |
根据id修改 | |
批量修改 | |
查询所有数据 | Iterable findAll(); |
根据id查询 | Optional findById(ID id); |
查询总记录数 | long count(); |
是否存在该数据 | boolean existsById(ID id); |
注:save方法如果存在对应的id则是修改否则是添加。
2、MongoRepository里面的方法
1)、批量添加或批量修改
方法如下
<S extends T> List<S> saveAll(Iterable<S> entities)
参数:实体类集合
返回值:添加或修改完成的实体类集合
例
Comment comment=new Comment();
comment.setContent("测试内容");
List<Comment> commentList=new ArrayList<>();
commentList.add(comment);
List<Comment> list=commentRepository.saveAll(commentList);
填写id: 存在:修改
不存在:添加时指定id
不填写id:添加,id自动生成
2)、查询所有
方法如下
List<T> findAll();
返回值:实体类集合
例
List<Comment> list=commentRepository.findAll();
3)、查询所有并排序
方法如下
List<T> findAll(Sort sort);
参数:排序构造器
返回值:实体类集合
例
List<Comment> list=commentRepository.findAll(Sort.by(Sort.Direction.ASC,"userId"))
4)、添加
方法如下
<S extends T> S insert(S entity);
参数:实体类
返回值:添加完成的实体类,会包含自动生成的id
例
Comment comment=new Comment();
comment.setContent("测试内容");
Comment result=commentRepository.insert(comment);
5)、批量添加
方法如下
<S extends T> List<S> insert(Iterable<S> entities);
参数:实体类集合
返回值:添加完成的实体类集合,会包含自动生成的id
例
Comment comment=new Comment();
comment.setContent("测试内容1");
List<Comment> commentList=new ArrayList<>();
commentList.add(comment);
List<Comment> list=commentRepository.insert(commentList);
6)、条件查询(只能=查询)
方法如下
<S extends T> List<S> findAll(Example<S> example);
参数:实体类构造器
返回值:实体类集合
例
Comment comment=new Comment();
comment.setContent("内容");
Example example=Example.of(comment);
List<Comment> list=commentRepository.findAll(example);
注:写两个条件就是and
7)、条件查询并排序(只能=查询)
方法如下
<S extends T> List<S> findAll(Example<S> example, Sort sort);
参数:example:实体类构造器
sort:排序构造器
返回值:实体类集合
例:根据content为内容并且userId为1查询并按照userId升序
Comment comment=new Comment();
comment.setContent("内容");
comment.setUserId(1);
Example example=Example.of(comment);
List<Comment> list=commentRepository.findAll(example,Sort.by(Sort.Direction.ASC,"userId"));
3、其他方法
1)、分页
方法如下
Page<T> findAll(Pageable pageable);
参数:分页构造器
返回值:实体类分页结果,使用方式参考
例:查询第一页,每页查询五条数据
Pageable pageable= PageRequest.of(0,5);
Page<Comment> list=commentRepository.findAll(pageable);
注:page是从0开始的
2)、根据条件查询一条数据
方法如下
<S extends T> Optional<S> findOne(Example<S> var1);
参数:实体类构造器
返回值:实体类的Optional,需要通过get()获取实体类对象
例
Comment comment=new Comment();
comment.setContent("1");
Example example=Example.of(comment);
Optional<Comment> result=commentRepository.findOne(example);
3)、条件查询并分页
方法如下
<S extends T> Page<S> findAll(Example<S> example, Pageable pageable);
参数:example:实体类构造器
pageable:分页构造器
返回值:实体类分页结果
例
Comment comment=new Comment();
comment.setContent("测");
Pageable pageable= PageRequest.of(0,5);
Example example=Example.of(comment);
Page<Comment> list=commentRepository.findAll(example,pageable);
4)、条件查询总记录数
方法如下
<S extends T> long count(Example<S> example);
参数:example:实体类构造器
返回值:总记录数
例
Comment comment=new Comment();
comment.setContent("测");
Example example=Example.of(comment);
long count=commentRepository.count(example);
5)、条件查询是否存在
方法如下
<S extends T> boolean exists(Example<S> example);
参数:example:实体类构造器
返回值:是否存在
例
Comment comment=new Comment();
comment.setContent("测");
Example example=Example.of(comment);
long count=commentRepository.exists(example);
二、jpa语法
一、基本语法
功能 | 前缀 |
---|---|
查询 | findBy |
总记录数 | countBy |
删除 | deleteBy |
功能 | 关键字 | 例 | 数据库 |
---|---|---|---|
= | 无 | findById | where id=? |
!= | Not | findByIdNot | where id!=? |
< | LessThan | findByIdLessThan | where id<? |
> | GreaterThan | findByIdGreaterThan | where id>? |
<= | LessThanEqual | findByAgeLessThanEqual | where age<=? |
>= | GreaterThanEqual | findByAgeGreaterThanEqual | where age>=? |
and | And | findByAgeAndSex | where age=? and sex=? |
or | Or | findByAgeOrSex | where age=? or sex=? |
in | In | findByAgeIn | where age in(?,?,?) |
not in | NotIn | findByAgeNotIn | where age not in(?,?,?) |
like | Containing | findByContentContaining | where content like ‘%?%’ |
left like | StartingWith | findByContentStartingWith | where content like ‘?%’ |
right like | EndWith | findByContentEndWith | where content like ‘%?’ |
between | Between | findByCreateTimeEndWith | where create_time between ? and ? |
is null | IsNull | findByAgeIsNull | where age is null |
is not null | IsNotNull | findByAgeIsNotNull | where age is not null |
not like | NotLike | findByContentNotLike | where age is not like ‘%?%’ |