pom.xml依赖
在spring构造页面时添加Spring Data MongoDB选项
或者手动添加依赖库
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
配置
修改 src/main/resources/application.properties
文件。
操作Spring Data CRUD
对数据库的操作一定要放在 @Service
类中,而不是放在 @Controller
类中;且 @Controller
类可以调用 @Service
类的方法,反之则不行。这是 SpringMVC
的经典架构设计理念。
@Service
类主要用于不易变的核心业务逻辑。@Controller
类与前端页面紧密配合,调用@Service
服务读写数据,从而响应前端请求,
增加数据
新增数据就是向数据库中插入一条数据,所谓数据就是实例对象。
import org.springframework.data.mongodb.core.MongoTemplate;@Autowiredprivate MongoTemplate mongoTemplate;public void test() {Song song = new Song();song.setSubjectId("s001");song.setLyrics("...");song.setName("成都");mongoTemplate.insert(song);}
查询数据
mongoTemplate.findById(songId, Song.class)
findById()
方法第 1 个参数就是主键 id,第 2 个参数是具体的类,写法是 类名.class
修改数据
修改条件和修改字段
// 修改 id=1 的数据
Query query = new Query(Criteria.where("id").is("1"));// 把歌名修改为 “new name”
Update updateData = new Update();
updateData.set("name", "new name");// 执行修改,修改返回结果的是一个对象
UpdateResult result = mongoTemplate.updateFirst(query, updateData, Song.class);
// 修改的记录数大于 0 ,表示修改成功
System.out.println("修改的数据记录数量:" + result.getModifiedCount());
约定:主键不能修改;且其它字段值为 null 表示不修改,值为长度为 0 的字符串 "" 表示清空此字段。
删除数据
调用 mongoTemplate.remove()
方法即可删除数据,参数是对象,表示需要删除哪些数据。
Song song = new Song();
song.setId(songId);// 执行删除
DeleteResult result = mongoTemplate.remove(song);
// 删除的记录数大于 0 ,表示删除成功
System.out.println("删除的数据记录数量:" + result.getDeletedCount());
条件查询
List<Song> songs = mongoTemplate.find(query, Song.class);
第一个参数是查询对象 Query
实例;第二个参数就表示查询什么样的对象,写法是 类名.class
。
用构建好的 Criteria
条件对象的实例,来构建 Query
实例:
Query query = new Query(criteria);
构建 Criteria
条件对象,一般有两种情况:
-
单一条件,用:
Criteria criteria1 = Criteria.where("条件字段名").is("条件值")
即可返回一个条件对象的实例。 -
组合条件,根据或(or)、且(and)的关系进行组合,多个子条件对象组合成一个总条件对象:
-
或(or)关系:
Criteria criteria = new Criteria(); criteria.orOperator(criteria1, criteria2);
-
且(and)关系:
Criteria criteria = new Criteria(); criteria.andOperator(criteria1, criteria2);
-
orOperator()
和andOperator()
的参数,都可以输入多个子条件,也可以输入子条件数组 -
import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Criteria;public List<Song> list(Song songParam) {// 总条件Criteria criteria = new Criteria();// 可能有多个子条件List<Criteria> subCris = new ArrayList();if (StringUtils.hasText(songParam.getName())) {subCris.add(Criteria.where("name").is(songParam.getName()));}if (StringUtils.hasText(songParam.getLyrics())) {subCris.add(Criteria.where("lyrics").is(songParam.getLyrics()));}if (StringUtils.hasText(songParam.getSubjectId())) {subCris.add(Criteria.where("subjectId").is(songParam.getSubjectId()));}// 必须至少有一个查询条件if (subCris.isEmpty()) {LOG.error("input song query param is not correct.");return null;}// 三个子条件以 and 关键词连接成总条件对象,相当于 name='' and lyrics='' and subjectId=''criteria.andOperator(subCris.toArray(new Criteria[]{}));// 条件对象构建查询对象Query query = new Query(criteria);// 仅演示:由于很多同学都在运行演示程序,所以需要限定输出,以免查询数据量太大query.limit(10);List<Song> songs = mongoTemplate.find(query, Song.class);return songs;
-
SPring Data 分页
分页是查询中最常用的功能,同时也为了防止一次查询的数据量太大而影响性能。
查询支持分页也比较简单,只需要调用 PageRequest.of()
方法构建一个分页对象,然后注入到查询对象即可。
ageRequest.of()
方法第一个参数是页码,注意从 0
开始计数,第一页的值是 0
;第二个参数是每页的数量。
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;Pageable pageable = PageRequest.of(0 , 20);
query.with(pageable);
对于分页来说,除了要查询结果以外,还需要查询总数
- 调用
count(query, XXX.class)
方法查询总数。第一个参数是查询条件,第二个参数表示查询什么样的对象; - 根据结果、分页条件、总数三个数据,构建分页器对象。
import org.springframework.data.domain.Page;
import org.springframework.data.repository.support.PageableExecutionUtils;// 总数
long count = mongoTemplate.count(query, Song.class);
// 构建分页器
Page<Song> pageResult = PageableExecutionUtils.getPage(songs, pageable, new LongSupplier() {@Overridepublic long getAsLong() {return count;}
});
PageableExecutionUtils.getPage()
方法第一个参数是查询结果;第二个参数是分页条件对象;第三个参数稍微复杂一点,实现一个 LongSupplier
接口的匿名类,在匿名类的 getAsLong()
方法中返回结果总数。方法返回值是一个 Page
分页器对象,