SpringBoot整合MongoDB的步驟詳解
項(xiàng)目結(jié)構(gòu):
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 ###這種類似于關(guān)系型數(shù)據(jù)庫url配置 spring.data.mongodb.uri=mongodb://127.0.0.1:27017/books
3.創(chuàng)建mongodb文檔映射實(shí)體類
@Document(collection = "comment") //如果省略集合屬性,默認(rèn)為類名首字母小寫 //設(shè)置復(fù)合索引 //@CompoundIndex(def="{'userId':1},{'nickName':-1}") public class Comment implements Serializable { @Id //對(duì)應(yīng)comment中的_id private String id; @Field("content")//屬性對(duì)應(yīng)mongodb字段名,如果一致,無須該注解 private String content;//吐槽內(nèi)容 private String articleId;//文章id private Date publishTime;//發(fā)布日期 @Indexed //添加一個(gè)單字段的索引 private String userId;//發(fā)布人id private String nickName;//發(fā)布人昵稱 private Date createDateTime;//評(píng)論的日期時(shí)間 private Integer likeNum;//點(diǎn)贊數(shù) private Integer replyNum;//回復(fù)數(shù) private String state;//狀態(tài) private String parentId;//上級(jí)id // 此處忽略getter與setter方法 }
SpringBoot中MongoDB常用注解:
- @Document
標(biāo)注在實(shí)體類上,將java類聲明為mongodb的文檔,可以通過collection參數(shù)指定這個(gè)類對(duì)應(yīng)的文檔。類似于Hibernate的entity注解,表明由mongo來維護(hù)該集合(表)。
- @id
主鍵,不可重復(fù),自帶索引,可以在定義的列名上標(biāo)注,需要自己生成并維護(hù)不重復(fù)的約束。
如果自己不設(shè)置@Id主鍵,mongo會(huì)自動(dòng)生成一個(gè)唯一主鍵,插入效率遠(yuǎn)高于自己設(shè)置主鍵。
在實(shí)際業(yè)務(wù)中不建議自己設(shè)置主鍵,應(yīng)交給mongo自己生成,可以另外設(shè)置一個(gè)業(yè)務(wù)id,如int型字段,用自己設(shè)置的業(yè)務(wù)id來維護(hù)相關(guān)聯(lián)的集合(表)。
- @Indexed
聲明該字段需要加索引,加索引后以該字段為條件檢索將大大提高速度。
唯一索引的話是@Indexed(unique = true)。
也可以對(duì)數(shù)組進(jìn)行索引,如果被索引的列是數(shù)組時(shí),MongoDB會(huì)索引這個(gè)數(shù)組中的每一個(gè)元素。
也可以對(duì)整個(gè)Document進(jìn)行索引,排序是預(yù)定義的按插入BSON數(shù)據(jù)的先后升序排列。
- @CompoundIndex
復(fù)合索引,加復(fù)合索引后通過復(fù)合索引字段查詢將大大提高速度。
- @Field
實(shí)體類屬性對(duì)應(yīng)集合(表)字段名,如果一致,無須該注解
4.service業(yè)務(wù)層
CommonService,操作mongo的具體業(yè)務(wù)類
采用Repository和MongoTemplate兩種方式來實(shí)現(xiàn)的;Repository 提供最基本的數(shù)據(jù)訪問功能,其幾個(gè)子接口則擴(kuò)展了一些功能。
MongoTemplate核心操作類:Criteria和Query
- Criteria類:封裝所有的語句,以方法的形式查詢。
- Query類:將語句進(jìn)行封裝或者添加排序之類的操作。
@Service public class CommentService { @Autowired private CommentRepository commentRepository; // 注入DAO @Autowired private MongoTemplate mongoTemplate; // 注入Mongodb提供的操作模板 // 保存一個(gè) 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); } // 更新一個(gè) public void updateComment(Comment comment){ commentRepository.save(comment); } // 查詢?nèi)? public List<Comment> findCommentAll(){ // return commentRepository.findAll(); return mongoTemplate.findAll(Comment.class); } // 條件查詢 public List<Comment> findCommentByContion(Query query){ return mongoTemplate.find(query,Comment.class); } // 查詢?nèi)坎⒁詉d排序返回結(jié)果 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); } // 刪除全部數(shù)據(jù) public void deleteAll(){ commentRepository.deleteAll(); } // 批量刪除 public void deleteMulti(List<Comment> list){ commentRepository.deleteAll(list); } // 根據(jù)id更新一條文檔:點(diǎn)贊數(shù)加1 public void updateCommentLikeNumm(String id){ // 點(diǎn)贊數(shù)加一,效率低,增加id開銷 // Comment comment=commentRepository.findById(id).get(); // comment.setLikeNum(comment.getLikeNum()+1); // commentRepository.save(comment); // 拿到查詢對(duì)象 Query query=Query.query(Criteria.where("_id").is(id)); // 拿到更新對(duì)象 Update update=new Update(); // 局部更新 相當(dāng)于$set // update.set(key,value); // 遞增$inc // update.inc("likeNum",1); update.inc("likeNum"); // 指定字段自增1 mongoTemplate.updateFirst(query,update,"comment"); } // 有條件的統(tǒng)計(jì) public Long commentCount(Query query){ return mongoTemplate.count(query,Comment.class); } }
5.DAO層
dao層CommentRepository 繼承MongoRepository,MongoRepository中已經(jīng)預(yù)定義了一些增刪查的方法,根據(jù)JPA的命名規(guī)范可以定義一些查詢方法,不需要具體實(shí)現(xiàn),底層會(huì)幫你實(shí)現(xiàn)。
public interface CommentRepository extends MongoRepository<Comment,String> { //新增按父id分頁查詢 Page<Comment> findByParentId(String parentId,Pageable pageable); }
6.測(cè)試
@RunWith(SpringRunner.class) @SpringBootTest public class CommentServiceTest { @Autowired private CommentService commentService; @Test public void saveCommentTest(){ // 新增單個(gè) Comment comment=new Comment(); //comment.setId("2"); comment.setArticleId("777"); comment.setContent("添加數(shù)據(jù)測(cè)試"); 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("添加數(shù)據(jù)測(cè)試"+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() { // 查詢?nèi)? List<Comment> list=commentService.findCommentAll(); for(Comment comment:list){ System.out.println(comment); } } @Test public void findCommentListOrderTest() { // 查全部并通對(duì)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個(gè) 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個(gè) for(Comment comment1:list){ System.out.println(comment1); } } @Test public void deleteById(){ // 通過id刪除評(píng)論 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"); // 根據(jù)范圍拿到查詢對(duì)象 Query query=Query.query(Criteria.where("_id").in(list)); // 根據(jù)查詢條件拿到結(jié)果 List<Comment> list2=commentService.findCommentByContion(query); for(Comment comment1:list2){ System.out.println(comment1); } } @Test public void findCommentContionByGtLt(){ // 多條件查詢大于2小于等于6 // 拿到查詢對(duì)象 Query query=Query.query(Criteria.where("likeNum").gte(2).lte(6)); // 根據(jù)查詢條件拿到結(jié)果 List<Comment> list =commentService.findCommentByContion(query); for(Comment comment1:list){ System.out.println(comment1); } } @Test public void findCommentContionByAnd(){ // 多條件查詢and //查詢對(duì)象 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 //查詢對(duì)象 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(){ // 更新 點(diǎn)贊數(shù)加一 commentService.updateCommentLikeNumm("1"); } @Test public void commentCount(){ // 統(tǒng)計(jì)查詢 Query query=Query.query(Criteria.where("likeNum").gte(2)); // 拿到查詢器 Query query1=new Query(); Long count1=commentService.commentCount(query); // 查符合條件的文檔個(gè)數(shù) Long count2=commentService.commentCount(query1); // 查全部 System.out.println("點(diǎn)贊數(shù)大于等于2的文檔有======="+count1); System.out.println("統(tǒng)計(jì)總數(shù)======="+count2); } }
到此已經(jīng)在SpringBoot項(xiàng)目中引入了MongoDB,并通過MongoRepository和MongoTemplate兩種方式來實(shí)現(xiàn)了基本的增刪改查操。
以上就是SpringBoot整合MongoDB的步驟詳解的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot整合MongoDB的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java中LinkedHashSet的實(shí)現(xiàn)原理詳解
這篇文章主要介紹了Java中LinkedHasSet的實(shí)現(xiàn)原理詳解,LinkedHashSet?是具有可預(yù)知迭代順序的?Set?接口的哈希表和鏈接列表實(shí)現(xiàn),此實(shí)現(xiàn)與HashSet?的不同之處在于,后者維護(hù)著一個(gè)運(yùn)行于所有條目的雙重鏈接列表,需要的朋友可以參考下2023-09-09Java打印出所有的水仙花數(shù)的實(shí)現(xiàn)代碼
這篇文章主要介紹了Java打印出所有的水仙花數(shù)的實(shí)現(xiàn)代碼,需要的朋友可以參考下2017-02-02利用Java搭建個(gè)簡(jiǎn)單的Netty通信實(shí)例教程
這篇文章主要給大家介紹了關(guān)于如何利用Java搭建個(gè)簡(jiǎn)單的Netty通信,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Java具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05淺談StringBuilder類的capacity()方法和length()方法的一些小坑
這篇文章主要介紹了StringBuilder類的capacity()方法和length()方法的一些小坑,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07SpringSecurity在SpringBoot中的自動(dòng)裝配過程
這篇文章主要介紹了SpringSecurity在SpringBoot中的自動(dòng)裝配過程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07利用ThreadLocal實(shí)現(xiàn)一個(gè)上下文管理組件
本文基于ThreadLocal原理,實(shí)現(xiàn)了一個(gè)上下文狀態(tài)管理組件Scope,通過開啟一個(gè)自定義的Scope,在Scope范圍內(nèi),可以通過Scope各個(gè)方法讀寫數(shù)據(jù),感興趣的可以了解一下2022-10-10