項目結構:
1.pom引入mongodb依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
2 配置application.properties
#spring.data.mongodb.host=127.0.0.1
#spring.data.mongodb.port=27017
#spring.data.mongodb.database=books
###這種類似於關系型數據庫url配置
spring.data.mongodb.uri=mongodb://127.0.0.1:27017/books
3.創建mongodb文檔映射實體類
@Document(collection = "comment") //如果省略集合屬性,默認為類名首字母小寫
//設置復合索引
//@CompoundIndex(def="{'userId':1},{'nickName':-1}")
public class Comment implements Serializable {
@Id //對應comment中的_id
private String id;
@Field("content")//屬性對應mongodb字段名,如果一致,無須該注解
private String content;//吐槽內容
private String articleId;//文章id
private Date publishTime;//發布日期
@Indexed //添加一個單字段的索引
private String userId;//發布人id
private String nickName;//發布人昵稱
private Date createDateTime;//評論的日期時間
private Integer likeNum;//點贊數
private Integer replyNum;//回復數
private String state;//狀態
private String parentId;//上級id
// 此處忽略getter與setter方法
}
SpringBoot中MongoDB常用注解:
-
@Document
標注在實體類上,將java類聲明為mongodb的文檔,可以通過collection
參數指定這個類對應的文檔。類似於Hibernate的entity注解,表明由mongo來維護該集合(表)。 -
@id
主鍵,不可重復,自帶索引,可以在定義的列名上標注,需要自己生成並維護不重復的約束。
如果自己不設置@Id主鍵,mongo會自動生成一個唯一主鍵,插入效率
遠高於自己設置主鍵。
在實際業務中不建議自己設置主鍵,應交給mongo自己生成,可以另外設置一個業務id,如int型字段,用自己設置的業務id來維護相關聯的集合(表)。 -
@Indexed
聲明該字段需要加索引,加索引后以該字段為條件檢索將大大提高速度。
唯一索引的話是@Indexed(unique = true)。
也可以對數組進行索引,如果被索引的列是數組時,MongoDB會索引這個數組中的每一個元素。
也可以對整個Document進行索引,排序是預定義的按插入BSON數據的先后升序排列。 -
@CompoundIndex
復合索引,加復合索引后通過復合索引字段查詢將大大提高速度。 -
@Field
實體類屬性對應集合(表)字段名,如果一致,無須該注解
4.service業務層
CommonService,操作mongo的具體業務類
采用Repository
和MongoTemplate
兩種方式來實現的;Repository 提供最基本的數據訪問功能,其幾個子接口則擴展了一些功能。
MongoTemplate核心操作類:Criteria和Query
- Criteria類:封裝所有的語句,以方法的形式查詢。
- Query類:將語句進行封裝或者添加排序之類的操作。
@Service
public class CommentService {
@Autowired
private CommentRepository commentRepository; // 注入DAO
@Autowired
private MongoTemplate mongoTemplate; // 注入Mongodb提供的操作模板
// 保存一個
public void saveComment(Comment comment){
commentRepository.save(comment);
// mongoTemplate.save(comment);
// mongoTemplate.insert(comment);
}
// 批量保存
public void mutilSaveComment(List<Comment> list){
commentRepository.saveAll(list);
// mongoTemplate.insertAll(list);
}
// 更新一個
public void updateComment(Comment comment){
commentRepository.save(comment);
}
// 查詢全部
public List<Comment> findCommentAll(){
// return commentRepository.findAll();
return mongoTemplate.findAll(Comment.class);
}
// 條件查詢
public List<Comment> findCommentByContion(Query query){
return mongoTemplate.find(query,Comment.class);
}
// 查詢全部並以id排序返回結果
public List<Comment> findCommentAllOrder(){
// return commentRepository.findAll(Sort.by(Sort.Order.desc("_id")));
Query query=new Query();
query.with(Sort.by(Sort.Direction.DESC,"id"));
return mongoTemplate.find(query,Comment.class);
}
// 通過id查詢
public Comment findCommentById(String id){
//return commentRepository.findById(id).get();
return mongoTemplate.findById(id,Comment.class);
}
/**
* @param parentId
* @param page
* @param size
* @return
*/
public Page<Comment> findByparentIdPage1(String parentId, int page,int size){
return commentRepository.findByParentId(parentId, PageRequest.of(page-1,size));
}
// 方式二
public List<Comment> findByparentIdPage2(String parentId, int page,int size){
Query query=Query.query(Criteria.where("parentId").is(parentId));
query.with(PageRequest.of(page-1,size));
return mongoTemplate.find(query,Comment.class);
}
// 通過id刪除
public void deleteById(String id){
// commentRepository.deleteById(id);
Comment comment=new Comment();
comment.setId(id);
mongoTemplate.remove(comment);
}
// 刪除全部數據
public void deleteAll(){
commentRepository.deleteAll();
}
// 批量刪除
public void deleteMulti(List<Comment> list){
commentRepository.deleteAll(list);
}
// 根據id更新一條文檔:點贊數加1
public void updateCommentLikeNumm(String id){
// 點贊數加一,效率低,增加id開銷
// Comment comment=commentRepository.findById(id).get();
// comment.setLikeNum(comment.getLikeNum()+1);
// commentRepository.save(comment);
// 拿到查詢對象
Query query=Query.query(Criteria.where("_id").is(id));
// 拿到更新對象
Update update=new Update();
// 局部更新 相當於$set
// update.set(key,value);
// 遞增$inc
// update.inc("likeNum",1);
update.inc("likeNum"); // 指定字段自增1
mongoTemplate.updateFirst(query,update,"comment");
}
// 有條件的統計
public Long commentCount(Query query){
return mongoTemplate.count(query,Comment.class);
}
}
5.DAO層
dao層CommentRepository 繼承MongoRepository,MongoRepository中已經預定義了一些增刪查的方法,根據JPA的命名規范
可以定義一些查詢方法,不需要具體實現,底層會幫你實現。
public interface CommentRepository extends MongoRepository<Comment,String> {
//新增按父id分頁查詢
Page<Comment> findByParentId(String parentId,Pageable pageable);
}
6.測試
@RunWith(SpringRunner.class)
@SpringBootTest
public class CommentServiceTest {
@Autowired
private CommentService commentService;
@Test
public void saveCommentTest(){ // 新增單個
Comment comment=new Comment();
//comment.setId("2");
comment.setArticleId("777");
comment.setContent("添加數據測試");
comment.setPublishTime(new Date());
comment.setUserId("1001");
comment.setNickName("張三");
comment.setCreateDateTime(new Date());
comment.setLikeNum(1);
comment.setReplyNum(0);
comment.setState("1");
comment.setParentId("0");
commentService.saveComment(comment);
}
@Test
public void mutilSaveComment(){ // 批量新增
List<Comment> list=new ArrayList<>();
Comment comment;
for(int i=1;i<=10;i++){
comment=new Comment();
comment.setId(""+i);
comment.setArticleId(""+i);
comment.setContent("添加數據測試"+i);
comment.setPublishTime(new Date());
comment.setUserId("1001");
comment.setNickName("張三");
comment.setCreateDateTime(new Date());
comment.setLikeNum(0);
comment.setReplyNum(0);
comment.setState("1");
comment.setParentId("0");
list.add(comment);
}
commentService.mutilSaveComment(list);
}
@Test
public void findCommentListTest() { // 查詢全部
List<Comment> list=commentService.findCommentAll();
for(Comment comment:list){
System.out.println(comment);
}
}
@Test
public void findCommentListOrderTest() { // 查全部並通對id排序
List<Comment> list=commentService.findCommentAllOrder();
for(Comment comment:list){
System.out.println(comment);
}
}
@Test
public void findCommentById() { // 通過id刪除
Comment comment=commentService.findCommentById("1");
System.out.println(comment);
}
@Test
public void findByParentId(){ // 通過父id分頁查詢1
Page<Comment> page=commentService.findByparentIdPage1("0",1,10); // 第1頁,每頁10個
System.out.println(page.getTotalElements());
System.out.println(page.getContent());
}
@Test
public void findByparentIdPage2(){ // 通過父id分頁查詢2
List<Comment> list=commentService.findByparentIdPage2("0",1,10); // 第1頁,每頁10個
for(Comment comment1:list){
System.out.println(comment1);
}
}
@Test
public void deleteById(){ // 通過id刪除評論
commentService.deleteById("1");
}
@Test
public void deleteAll(){ // 刪除全部
commentService.deleteAll();
}
@Test
public void deleteMulti(){ // 批量刪除
List<Comment> list=new ArrayList<>();
Comment comment;
for(int i=1;i<=10;i++) {
comment = new Comment();
comment.setId("" + i);
list.add(comment);
}
commentService.deleteMulti(list);
}
@Test
public void findCommentByContion(){ // 多條件查詢in
// 拿到查詢范圍
List<String> list=new ArrayList<>();
list.add("1");
list.add("2");
list.add("3");
// 根據范圍拿到查詢對象
Query query=Query.query(Criteria.where("_id").in(list));
// 根據查詢條件拿到結果
List<Comment> list2=commentService.findCommentByContion(query);
for(Comment comment1:list2){
System.out.println(comment1);
}
}
@Test
public void findCommentContionByGtLt(){ // 多條件查詢大於2小於等於6
// 拿到查詢對象
Query query=Query.query(Criteria.where("likeNum").gte(2).lte(6));
// 根據查詢條件拿到結果
List<Comment> list =commentService.findCommentByContion(query);
for(Comment comment1:list){
System.out.println(comment1);
}
}
@Test
public void findCommentContionByAnd(){ // 多條件查詢and
//查詢對象
Query query=Query.query(new Criteria().andOperator(Criteria.where("likeNum").gte(2)
,Criteria.where("state").is("1")));
List<Comment> list =commentService.findCommentByContion(query);
for(Comment comment1:list){
System.out.println(comment1);
}
}
@Test
public void findCommentContionByOr(){ // 多條件查詢or
//查詢對象
Query query=Query.query(new Criteria().orOperator(Criteria.where("likeNum").gte(2)
,Criteria.where("state").is("0")));
List<Comment> list =commentService.findCommentByContion(query);
for(Comment comment1:list){
System.out.println(comment1);
}
}
@Test
public void updateCommentLikeNumm(){ // 更新 點贊數加一
commentService.updateCommentLikeNumm("1");
}
@Test
public void commentCount(){ // 統計查詢
Query query=Query.query(Criteria.where("likeNum").gte(2)); // 拿到查詢器
Query query1=new Query();
Long count1=commentService.commentCount(query); // 查符合條件的文檔個數
Long count2=commentService.commentCount(query1); // 查全部
System.out.println("點贊數大於等於2的文檔有======="+count1);
System.out.println("統計總數======="+count2);
}
}
到此已經在SpringBoot項目中引入了MongoDB,並通過MongoRepository和MongoTemplate兩種方式來實現了基本的增刪改查操。