mongoDB和java整合
我们使用 springboot 搭建项目,环境准备如下:
- springboot 2.3.0.RELEASE
- jdk 1.8
- idea
整合步骤如下:
1,项目的pom文件中,需要引入 mongodb 相关:
<!-- mongodb 相关 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
2,配置项中添加对应的配置
# mongodb 的地址
spring.data.mongodb.host=192.168.75.135
# 端口
spring.data.mongodb.port=27017
# 要连接的database
spring.data.mongodb.database=liuqiuyiTest
也可以使用 uri 的配置方法,例如:
spring.data.mongodb.uri=mongodb://192.168.75.135:27017/liuqiuyiTest
如果mongoDB使用了副本集,这里的uri写法为:
# slaveOk=true 表示开启从节点读权限;connect=replicaSet 自动选择好读写机器; myrs 为副本集的名称
spring.data.mongodb.uri=mongodb://192.168.75.135:27017,192.168.75.135:27018,192.168.75.135:27019/liuqiuyiTest?connect=replicaSet&slaveOk=true&replicaSet=myrs
3,编写对应的实体类,添加对应的注解
创建一个文章类
@Data
@Document(collection = "comment")
public class CommentDocument implements Serializable {
private static final long serialVersionUID = -4141268149154432823L;
@Id
private Long id;
/**
* 内容
*/
private String content;
/**
* 用户id
*/
private User userInfo;
/**
* 点赞数
*/
private Integer likeNum;
}
创建一个用户类:
@Data
@Document(collection = "user")
public class User implements Serializable {
private static final long serialVersionUID = 7995473171705971357L;
@Id
private Long id;
/**
* 用户id
*/
private String userId;
/**
* 用户名称
*/
private String name;
}
常用的注解有:
| 注解名称 | 含义 |
|---|---|
| @Document(collection= "document") | 申明这个类是mongodb的文档类,collection 指定对应的集合名称。注意 collection 不要写错 |
| @Id | 用于标记id字段 |
| @Field("content") | 如果 java 实体类的字段名和 mongoDb 中的名称不一样,可以使用 @Field("content") 指定 mongoDb 中的名称 |
| @Indexed | 表示对 userId 字段添加 单字段索引,direction 参数可以指定排序方向,升或降序,unique 可以指定是否为唯一索引。索引既可以通过mongoDb的命令添加,也可以在实体类中通过注解指定 |
| @Transient | 被该注解标注的,将不会被录入到数据库中。只作为普通的javaBean属性 |
如果要对多个字段添加复合索引,需要在类上添加 @CompoundIndex 注解,例如
@Document(collection = "comment")
# 这里表示对 likeNum 字段和 replyNum 字段建立复合索引,1表示正序排序,-1 表示倒序排序
@CompoundIndex(def = "{'likeNum':1,'replyNum':-1}")
public class Comment implements Serializable {
private static final long serialVersionUID = -4141268149154432823L;
}
如果有多个复合索引,可以使用 @CompoundIndexes 注解
@CompoundIndexes({
@CompoundIndex(name = "idx_likeNum_re", def = "{'likeNum':1,'replyNum':-1}")
})
4,编写一个DAO接口
编写一个DAO接口,继承 MongoRepository 类,指定 mongoDB 的文档类和 id 类型
public interface CommentRepository extends MongoRepository<Comment, Long> {
}
5,编写测试类
直接注入 CommentRepository 接口
@Autowired
CommentRepository commentRepository;
5.1 insert 方法测试
@Test
public void insertComment() {
User user = new User();
user.setId(1L);
user.setName("liuqiuyi");
Comment comment = new Comment();
comment.setContent("测试内容");
comment.setId(1L);
comment.setLikeNum(0);
comment.setUserInfo(user);
commentRepository.insert(comment);
}
查看执行结果
5.2 save 方法测试
@Test
public void saveComment() {
User user = new User();
user.setId(1L);
user.setName("liuqiuyi");
Comment comment = new Comment();
comment.setContent("更新测试内容");
comment.setId(1L);
comment.setLikeNum(0);
comment.setUserInfo(user);
commentRepository.save(comment);
}
查看执行结果
save 方法和 insert 的区别:insert 方法插入时,如果主键存在报错。save 方法插入时,主键存在就更新,不存在则插入。
5.3 根据主键删除
@Test
public void updateComment() {
commentRepository.deleteById(1L);
}
5.4 查询所有
@Test
public void findAllComment() {
System.out.println(commentRepository.findAll());
}
5.5 根据 id 查询
@Test
public void findCommentById() {
System.out.println(commentRepository.findById(2L));
}
5.6 分页查询
分页查询需要借助 PageRequest 类,例如
@Test
public void pageQueryComment() {
int page = 1;
int size = 2;
Page<Comment> commentPage = commentRepository.findByLikeNum(0, PageRequest.of(page - 1, size));
// 查询的数据集合
System.out.println(commentPage.getContent());
// 总页数
System.out.println(commentPage.getTotalPages());
// 总条数
System.out.println(commentPage.getTotalElements());
}
**注意:**这里的 page 一定要 -1 ,因为 mongodb 的第一页是从0开始的
5.7 使用 MongoTemplate 完成复杂的操作
在进行一些复杂的操作是,我们可以借助 MongoTemplate 类完成,例如:
- 对某个值进行 ++ 操作,类似于带条件更新
@Test
public void testIncr() {
// 这个是要更新的条件,类似于 where 后面的
Query query = Query.query(Criteria.where("id").is(2L));
// 要更新的值
Update update = new Update();
update.inc("likeNum", -1);
mongoTemplate.updateMulti(query, update, Comment.class);
}
- 按条件查询,并且排序、分页
@Test
public void testLimit() {
Query query = Query.query(Criteria.where("userInfo.name").is("liuqiuyi"));
query.limit(2);
query.with(Sort.by(Sort.Order.asc("likeNum"), Sort.Order.desc("id")));
List<Comment> commentList = mongoTemplate.find(query, Comment.class);
System.out.println(commentList);
}