一、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: 若新增数据的主键已经存在,则会对当前已经存在的数据进行修改操作。