SpringBoot 中使用 MongoDB 基于 MongoRepository增删改查(基础篇)

本文涉及的产品
云数据库 MongoDB,独享型 2核8GB
推荐场景:
构建全方位客户视图
简介: SpringBoot 中使用 MongoDB 基于 MongoRepository增删改查(基础篇)

一、MongoDB的配置



1.引入jar包


<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>


2.MongoDB的基础扫描包的配置


1.在配置文件里bootstrap.properties中添加驱动
spring.data.mongodb.uri = mongodb://root:root@localhost:27017/test
2.在配置文件中配置基础扫描包xml文件中或者在java.config类中配置基础扫描类


3.声明entity和repository


@Data //自动生成get、set和toString方法 lombok包里的注解
@Document(collection = "t_user") //collection与数据库中的表明相对应
public class User { //entity类
 private String id;
 private String userName;
 private int age;
 private int isDelete = 1; //假删除用的字段 0代表删除 1正常
}
public interface UserRepository extends MongoRepository<User,String> {
 User findOneByName(String userName); //用户名唯一
}


二、MongoRepository的原生方法(可直接调用)



1. count()统计总数


//实现方法的源码
public long count() {
 return this.mongoOperations.getCollection(this.entityInformation.getCollectionName()).count();
}
//返回值是long类型,功能:统计表中的数据条数
@Service
public class UserServiceImpl {
 @Autowired
 private UserRepository userRepository;
 public long getCOuntofUser(){
  return userRepository.count();
 } 
}


2. count(Example< T > example)条件统计总数


使用这个方法之前,我先解释一下Example这个类,以后经常用到这个类,由以下两部分部分组成:1.Probe: 一个domain object的具体example。2.ExampleMatcher 携带了如何匹配特定的字段的详细信息。可以在多个Examples之间复用。


「适用范围」: ① 使用一组静态或动态限制(constraints)来查询时; ②经常重构 domain objects,而不需要担心破坏现有查询; ③独立于底层的数据存储API


「缺陷」:① 不支持嵌套的/分组的 property constraints,如 firstname = ?0 or (firstname = ?1 and lastname = ?2);②仅支持字符串的 starts/contains/ends/regex 匹配和其他类型的精确匹配。


「使用规则」

// 创建domain object的实例。
 User user = new User();
 // 设置要查询的properties,可设置多个参数
 user.setUserName("Bob");
 user.setAge(18);
 //创建Example
 Example<User> example = Example.of(user);


3. count(Exampleexample):


//实现方法的源码
public <S extends T> long count(Example<S> example) {
 Assert.notNull(example, "Sample must not be null!");
    Query q = new Query((new Criteria()).alike(example));
    return this.mongoOperations.count(q, example.getProbeType(), this.entityInformation.getCollectionName());
}
//返回值是long类型,功能:有条件的统计表中的数据条数
@Service
public class UserServiceImpl {
 @Autowired
 private UserRepository userRepository;
 public long getCOuntofUser(User user){
  Example<User> example = Example.of(user);
  return userRepository.count();
 } 
}


4. delete(T t)通过对象信息删除某条数据


//实现方法的源码,底层还是通过id删除
 public void delete(T entity) {
 Assert.notNull(entity, "The given entity must not be null!");
 this.delete(this.entityInformation.getId(entity));
 }
 //返回值是void类型,功能:删除表中一条数据
 @Service
 public class UserServiceImpl {
  @Autowired
  private UserRepository userRepository;
  public void deleteOneUser(User user){
  userRepository.delete(user);
  } 
 }


5. delete(ID id)通过id删除某条数据


//实现方法的源码,底层还是通过id删除
 public void delete(ID id) {
  Assert.notNull(id, "The given id must not be null!");
    this.mongoOperations.remove(this.getIdQuery(id), this.entityInformation.getJavaType(), this.entityInformation.getCollectionName());
 }
 //返回值是void类型,功能:删除表中一条数据
 @Service
 public class UserServiceImpl {
  @Autowired
  private UserRepository userRepository;
  public void deleteOneUser(String id){
  userRepository.delete(user);
  } 
 }


6. delete(Iterable<? extends Apple> iterable)批量删除某条数据


//实现方法的源码,批量删除,底层还是通过id删除
public void delete(Iterable<? extends T> entities) {
 Assert.notNull(entities, "The given Iterable of entities not be null!");
 Iterator var2 = entities.iterator();
    while(var2.hasNext()) {
     T entity = var2.next();
        this.delete(entity);
    }
}
 //返回值是void类型,功能:批量删除
 @Service
 public class UserServiceImpl {
  @Autowired
  private UserRepository userRepository;
  public void deleteUsers(List<User> users){
  userRepository.delete(users);
  } 
 }


7. deleteAll() 清空表中所有的数据


//实现方法的源码
public void deleteAll() {
 this.mongoOperations.remove(new Query(), this.entityInformation.getCollectionName());
}
 //返回值是void类型,功能:情空表中所有的数据
 @Service
 public class UserServiceImpl {
  @Autowired
  private UserRepository userRepository;
  public void deleteAll(){
  userRepository.deleteAll();
  } 
 }


8. exists(ID id)  判断数据是否存在


//实现方法的源码
public boolean exists(ID id) {
 Assert.notNull(id, "The given id must not be null!");
 return this.mongoOperations.exists(this.getIdQuery(id), this.entityInformation.getJavaType(), this.entityInformation.getCollectionName());
}
 //返回值是boolean 类型,功能:判断数据是否存在
 @Service
 public class UserServiceImpl {
  @Autowired
  private UserRepository userRepository;
  public boolean isExist(String id){
  return userRepository.exists(id);
  } 
 }


9. exists(Example< T > example)  判断某特定数据是否存在


//实现方法的源码
public <S extends T> boolean exists(Example<S> example) {
 Assert.notNull(example, "Sample must not be null!");
 Query q = new Query((new Criteria()).alike(example));
 return this.mongoOperations.exists(q, example.getProbeType(),  this.entityInformation.getCollectionName());
}
 //返回值是boolean类型,功能:判断某特定数据是否存在
 @Service
 public class UserServiceImpl {
  @Autowired
  private UserRepository userRepository;
  public boolean isExist(User user){
   Example example = Example.of(user);
  return userRepository.exists(example);
  } 
 }


10. findAll()  获取表中所有的数据


//实现方法的源码
public List<T> findAll() {
 return this.findAll(new Query());
}
 //返回值是List<User>类型,功能:获取表中所有的数据
 @Service
 public class UserServiceImpl {
  @Autowired
  private UserRepository userRepository;
  public List<User> findAll(){
  return userRepository.findAll();
  } 
 }


11. findAll(Sort sort)  获取表中所有的数据,按照某特定字段排序


//实现方法的源码
public List<T> findAll(Sort sort) {
 return this.findAll((new Query()).with(sort));
}
 //返回值是List<User>类型,功能:获取表中所有的数据并排序
 @Service
 public class UserServiceImpl {
  @Autowired
  private UserRepository userRepository;
  public List<User> findAll(){
   Sort sort = new Sort(Sort.Direction.ASC,"id"); //第二个参数是变长参数,可以传多个值
  return userRepository.findAll(sort);
  } 
 }


12. findAll(Pageable pageAble)  获取表中所有的数据,分页查询


//实现方法的源码
public Page<T> findAll(Pageable pageable) {
 Long count = this.count();
 List<T> list = this.findAll((new Query()).with(pageable));
 return new PageImpl(list, pageable, count);
}
 //返回值是Page<User>类型,功能:分页查询获取表中的数据
 @Service
 public class UserServiceImpl {
  @Autowired
  private UserRepository userRepository;
  public Page<User> findAll(int page, int size){
    Pageable pageable = new PageRequest(page,size);
  return userRepository.findAll(pageable);
  } 
 }
 //值得注意的是PageRequest有几个构造器,分别为:
 /*
  *1.page指代当前页,size代表每页的条数;
  *功能:分页查询
  */
 public PageRequest(int page, int size) { 
  this(page, size, (Sort)null);
 }
 /*
  *2.page指代当前页,size代表每页的条数,sort代表排序的
  *方式(sort的实现方式上面有介绍就不在赘述
  *功能:分页查询并排序
  */
 public PageRequest(int page, int size, Sort sort) {
  super(page, size);
 this.sort = sort;
}
/*
 *3.page指代当前页,size代表每页的条数,sort代表排序的
 *方式,properties 变长参数,代表查询条件
 *功能:分页条件查询并排序
 */
 public PageRequest(int page, int size, Direction direction, String... properties) {
 this(page, size, new Sort(direction, properties));
}


13. findAll(Example< T > example)  条件查询


//实现方法的源码
 public <S extends T> List<S> findAll(Example<S> example) {
  return this.findAll(example, (Sort)null);
 }
 //返回值是List<User>类型,功能:条件获取表中所有的数据
 @Service
 public class UserServiceImpl {
  @Autowired
  private UserRepository userRepository;
  public List<User> findAll(user){
   Example example = Example.of(user);
  return userRepository.findAll(example);
  } 
 }


14. findAll(Iterableids)  条件查询


//实现方法的源码
public Iterable<T> findAll(Iterable<ID> ids) {
 Set<ID> parameters = new HashSet<ID>(tryDetermineRealSizeOrReturn(ids, 10));
 for (ID id : ids) {
  parameters.add(id);
 }
 return findAll(new Query(new Criteria(entityInformation.getIdAttribute()).in(parameters)));
}
 //返回值是List<User>类型,功能:获取所有List中所有数据
 @Service
 public class UserServiceImpl {
  @Autowired
  private UserRepository userRepository;
  public List<User> findAll(List<String> ids){ //这里参数只限于id的集合
  return userRepository.findAll(ids);
  } 
 }


15. findAll(Example< T > example,Pageable pageable)  条件分页查询


//实现方法的源码
public <S extends T> Page<S> findAll(final Example<S> example, Pageable pageable) {
 Assert.notNull(example, "Sample must not be null!");
 final Query q = new Query(new Criteria().alike(example)).with(pageable);
 List<S> list = mongoOperations.find(q, example.getProbeType(), entityInformation.getCollectionName());
 return PageableExecutionUtils.getPage(list, pageable, new TotalSupplier() {
  @Override
  public long get() {
   return mongoOperations.count(q, example.getProbeType(), entityInformation.getCollectionName());
  }
 });
}
 //返回值是Page<User>类型,功能:获取表中所有的数据,分页
 @Service
 public class UserServiceImpl {
  @Autowired
  private UserRepository userRepository;
  public Page<User> findAll(int page,int size,User user){ 
   Example example = Example.of(user);
   Pageable pageable = new PageRequest(page,size);
  return userRepository.findAll(example ,pageable );
  } 
 }


16. findAll(Example< T > example,Sort sort)  条件查询排序


//实现方法的源码
public <S extends T> List<S> findAll(Example<S> example, Sort sort) {
 Assert.notNull(example, "Sample must not be null!");
 Query q = new Query(new Criteria().alike(example));
 if (sort != null) {
  q.with(sort);
 }
 return mongoOperations.find(q, example.getProbeType(), entityInformation.getCollectionName());
}
 //返回值是List<User>类型,功能:条件获取表中所有的数据
 @Service
 public class UserServiceImpl {
  @Autowired
  private UserRepository userRepository;
  public List<User> findAll(User user){
   Example<User> example = Example.of(user);
   Sort sort = new Sort(Sort.Direction.ASC,"userName");
  return userRepository.findAll(ids);
  } 
 }


17. findOne(String id)  通过id查询一条数据


//实现方法的源码
public T findOne(ID id) {
 Assert.notNull(id, "The given id must not be null!");
 return mongoOperations.findById(id, entityInformation.getJavaType(), entityInformation.getCollectionName());
}
 //返回值是User 类型,功能:获取表中一条数据
 @Service
 public class UserServiceImpl {
  @Autowired
  private UserRepository userRepository;
  public User findOne(String id){
  return userRepository.findOne(id);
  } 
 }


18. findOne(Example example)  通过id查询一条数据


//实现方法的源码
public <S extends T> S findOne(Example<S> example) {
 Assert.notNull(example, "Sample must not be null!");
 Query q = new Query(new Criteria().alike(example));
 return mongoOperations.findOne(q, example.getProbeType(), entityInformation.getCollectionName());
}
 //返回值是User 类型,功能:获取表中一条数据
 @Service
 public class UserServiceImpl {
  @Autowired
  private UserRepository userRepository;
  public User findOne(String userName){
   User user = new User();
   user.setUserName(userName);
   Example<User> example = Example.of(user);
  return userRepository.findOne(example);
  } 
 }


19. insert(T t)  插入一条数据


//实现方法的源码
public <S extends T> S insert(S entity) {
 Assert.notNull(entity, "Entity must not be null!");
 mongoOperations.insert(entity, entityInformation.getCollectionName());
 return entity;
}
 //返回值是User 类型,功能:往表中加入一条数据
 @Service
 public class UserServiceImpl {
  @Autowired
  private UserRepository userRepository;
  public User insert(User user){
  return userRepository.insert(user);
  } 
 }


20. insert(Iterable< T > iterable)  插入多条数据


//实现方法的源码
public <S extends T> List<S> insert(Iterable<S> entities) {
 Assert.notNull(entities, "The given Iterable of entities not be null!");
 List<S> list = convertIterableToList(entities);
 if (list.isEmpty()) {
  return list;
 }
 mongoOperations.insertAll(list);
 return list;
}
 //返回值是User 类型,功能:往表中加入多条数据
 @Service
 public class UserServiceImpl {
  @Autowired
  private UserRepository userRepository;
  public User insert(List<User> users){
  return userRepository.insert(users);
  } 
 }


21. save(T t)  保存一条数据


//实现方法的源码
public <S extends T> S save(S entity) {
 Assert.notNull(entity, "Entity must not be null!");
 if (entityInformation.isNew(entity)) {
  mongoOperations.insert(entity, entityInformation.getCollectionName());
 } else {
  mongoOperations.save(entity, entityInformation.getCollectionName());
  }
 return entity;
}
 //返回值是User 类型,功能:往表中加入一条数据
 @Service
 public class UserServiceImpl {
  @Autowired
  private UserRepository userRepository;
  public User insert(User user){
  return userRepository.save(user);
  } 
 }


22. save(Iterable< T > iterable)  加入多条数据


//实现方法的源码
public <S extends T> List<S> save(Iterable<S> entities) {
 Assert.notNull(entities, "The given Iterable of entities not be null!");
 List<S> result = convertIterableToList(entities);
 boolean allNew = true;
 for (S entity : entities) {
  if (allNew && !entityInformation.isNew(entity)) {
   allNew = false;
  }
 }
 if (allNew) {
  mongoOperations.insertAll(result);
 } else {
  for (S entity : result) {
   save(entity);
  }
 }
 return result;
}
 //返回值是List<User> 类型,功能:往表中加入多条数据
 @Service
 public class UserServiceImpl {
  @Autowired
  private UserRepository userRepository;
  public User insert(List<User> users){
  return userRepository.save(users);
  } 
 }


三、总结:



「原生方法中的save()和insert()都是往表中添加一条数据,那他们有什么区别呢?」


官方文档描述:

1.Updates an existing document or inserts a new document, depending on its document parameter

2.If the document does not contain an _id field, then the save() method calls the insert() method. During the operation, the mongo shell will create an ObjectId and assign it to the _id field.


意义:save()方法更新一个已存在的文件或者插入一条数据,取决于一个文件中的一个字段。如果一个文件中不包含一个id,然后save()方法直接调用insert()方法和生成一个id;如果包含id就直接更新。


//不带_id参数
 db.products.save( { userName: "Lushirui", age: 20 } )
 //结果
 { "_id" : ObjectId("50691737d386d8fadbd6b01d"), "userName " : "userName ", "age" : 20}
 //带_id参数,但是找不到一个已经存在的文档
 db.products.save( { _id: 100, userName: "Lujianlong", age: 20 } )
 //结果
 { "_id" : 100, userName : "Lujianlong", "age" : 20 }


1.insert: 若新增数据的主键已经存在,则会抛 org.springframework.dao.Duplicate KeyException 异常提示主键重复,不保存当前数据。


2.save: 若新增数据的主键已经存在,则会对当前已经存在的数据进行修改操作。


相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。 &nbsp; 相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
目录
相关文章
|
1月前
|
NoSQL Java MongoDB
Springboot WebFlux项目结合mongodb进行crud
这篇文章介绍了如何使用Spring Boot WebFlux框架结合MongoDB进行基本的CRUD(创建、读取、更新、删除)操作,包括项目设置、实体类和Repository的创建、控制器的实现以及配置文件的编写。
40 0
Springboot WebFlux项目结合mongodb进行crud
|
3月前
|
NoSQL Java MongoDB
SpringBoot中MongoDB的那些高级用法
本文探讨了在Spring Boot项目中使用MongoDB的多种方式及其高级用法。MongoDB作为一种NoSQL数据库,在某些场景下相较于SQL数据库有着独特的优势。文中详细介绍了在Spring Boot中使用MongoDB的三种主要方式:直接使用官方SDK、使用Spring JPA以及使用MongoTemplate,并对比分析了它们之间的差异。此外,文章深入讲解了Spring Data MongoDB提供的各种注解(如@Id, @Document, @Field等)以简化操作流程,并探讨了MongoTemplate监听器的应用,如设置主键值、记录日志等。
159 2
|
1月前
|
SQL NoSQL Java
springboot操作nosql的mongodb,或者是如何在mongodb官网创建服务器并进行操作
本文介绍了如何在Spring Boot中操作NoSQL数据库MongoDB,包括在MongoDB官网创建服务器、配置Spring Boot项目、创建实体类、仓库类、服务类和控制器类,以及如何进行测试。
17 1
springboot操作nosql的mongodb,或者是如何在mongodb官网创建服务器并进行操作
|
2月前
|
SQL JSON Java
springboot 如何编写增删改查后端接口,小白极速入门,附完整代码
本文为Spring Boot增删改查接口的小白入门教程,介绍了项目的构建、配置YML文件、代码编写(包括实体类、Mapper接口、Mapper.xml、Service和Controller)以及使用Postman进行接口测试的方法。同时提供了SQL代码和完整代码的下载链接。
springboot 如何编写增删改查后端接口,小白极速入门,附完整代码
|
25天前
|
前端开发 Java 数据库
springBoot:template engine&自定义一个mvc&后端给前端传数据&增删改查 (三)
本文介绍了如何自定义一个 MVC 框架,包括后端向前端传递数据、前后端代理配置、实现增删改查功能以及分页查询。详细展示了代码示例,从配置文件到控制器、服务层和数据访问层的实现,帮助开发者快速理解和应用。
|
3月前
|
NoSQL Java MongoDB
SpringBoot中MongoDB的那些骚操作用法
MongoDB作为一种NoSQL数据库,在不需要传统SQL数据库的表格结构的情况下,提供了灵活的数据存储方案。在Spring Boot中可以通过官方SDK、Spring JPA或MongoTemplate等方式集成MongoDB。文章重点介绍了Spring Data MongoDB提供的注解功能,例如`@Id`、`@Document`和`@Field`等,这些注解简化了Java对象到MongoDB文档的映射。此外,文中还讨论了MongoTemplate监听器的使用,包括设置主键值和日志记录等高级特性。
205 0
SpringBoot中MongoDB的那些骚操作用法
|
4月前
|
SQL NoSQL API
MongoDB 增删改查 常用sql总结
MongoDB 增删改查 常用sql总结
146 1
|
3月前
|
druid Java 数据库连接
SpringBoot项目整合MybatisPlus持久层框架+Druid数据库连接池,以及实现增删改查功能
SpringBoot项目整合MybatisPlus和Druid数据库连接池,实现基本的增删改查功能。
309 0
|
3月前
|
NoSQL Java MongoDB
MongoDB 读写分离——SpringBoot读写分离
MongoDB 读写分离——SpringBoot读写分离
117 0
|
4月前
|
NoSQL Java MongoDB
Spring Boot与MongoDB的集成应用
Spring Boot与MongoDB的集成应用