详解MongoDB和Spring整合的实例代码

时间:2022-05-12 22:29:49

MongoDB现在用的非常非常多,如何和Spring整合也是经常碰到的问题。

Spring提供了MongoTemplate这样一个模板类的实现方法,简化了具体操作。

下面讲一下具体实现:

添加依赖

?
1
2
3
4
5
<dependency>
   <groupId>org.springframework.data</groupId>
   <artifactId>spring-data-mongodb</artifactId>
   <version>1.10.3.RELEASE</version>
</dependency>

其余Spring相关的忽略

Spring的配置applicationContext-mongo.xml

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:util="http://www.springframework.org/schema/util"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mongo="http://www.springframework.org/schema/data/mongo"
    xsi:schemaLocation="
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
  http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
  http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo.xsd">
  <context:property-placeholder
      ignore-unresolvable="true" location="classpath:/mongodb.properties"/>
 
  <mongo:mongo-client id="mongoClient" host="${mongo.host}" port="${mongo.port}">
    <!-- credentials="${mongo.user}:${mongo.pwd}@${mongo.defaultDbName}"-->
  </mongo:mongo-client>
 
  <mongo:db-factory id="mongoDbFactory"
           dbname="${mongo.database}"
           mongo-ref="mongoClient"/>
  <!-- 默认Mongodb类型映射 -->
  <bean id="defaultMongoTypeMapper" class="org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper">
    <constructor-arg name="typeKey">
      <!-- 这里设置为空,可以把 spring data mongodb 多余保存的_class字段去掉 -->
      <null/>
    </constructor-arg>
  </bean>
 
  <mongo:repositories base-package="com.critc.mongo"/>
  <!-- 自动扫描以下包的有Doucment注解的类 -->
  <mongo:mapping-converter id="mappingConverter" base-package="com.critc.mongo.model"
               type-mapper-ref="defaultMongoTypeMapper">
  </mongo:mapping-converter>
 
  <!-- Mongodb的模板 -->
  <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
    <constructor-arg name="mongoDbFactory" ref="mongoDbFactory"/>
    <constructor-arg name="mongoConverter" ref="mappingConverter"/>
  </bean>
</beans>

mongo:mongo-client是定义MongoDB的客户端连接,需要host和port参数,如果需要账号密码的话,需要增加credentials配置

mongo:db-factory配置连接工厂,指定具体的连接数据库,本例默认为test

defaultMongoTypeMapper默认Mongodb类型映射

mongo:mapping-converterMongoDB的实体映射

mongoTemplate这是最主要的,定义模板类,依赖连接工厂和实体映射

这里举一个article的增删改查的例子。

相关实体Article.java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Document(collection = "article_info")
public class Article {
  @Id
  private String id;//id
  @Field("title")
  private String title;//标题
  @Field("url")
  private String url;//链接
  @Field("author")
  private String author;//作者
  @Field("tags")
  private List<String> tags;//tag 标签
  @Field("visit_count")
  private Long visitCount;//访问次数
  @Field("add_time")
  private Date addTime;//添加时间
// get set方法省略

@Document(collection = "article_info")这个注解和Hibernate的注解Entiry非常相似,就是定义一个文档,对象MongoDB存储的Collection的名称是article_info

@Id指该字段是主键,不能缺少

@Field("add_time")指该字段映射MongoDB的实际字段,如果一致可以省略

ArticleRepository实际访问接口

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@Repository("ArticleRepository")
public interface ArticleRepository extends PagingAndSortingRepository<Article, String> {
 
  //分页查询
  public Page<Article> findAll(Pageable pageable);
 
 
  //根据author查询
  public List<Article> findByAuthor(String author);
 
  //根据作者和标题查询
  public List<Article> findByAuthorAndTitle(String author, String title);
 
  //忽略参数大小写
  public List<Article> findByAuthorIgnoreCase(String author);
 
  //忽略所有参数大小写
  public List<Article> findByAuthorAndTitleAllIgnoreCase(String author, String title);
 
  //排序
  public List<Article> findByAuthorOrderByVisitCountDesc(String author);
  public List<Article> findByAuthorOrderByVisitCountAsc(String author);
 
  //自带排序条件
  public List<Article> findByAuthor(String author, Sort sort);
 
}

Spring的data repository封装了一套增删改查的方法,就和JPA实现的一样,ArticleRepository继承PagingAndSortingRepository,就集成了常用的增删改查方法,比如save、findOne、exists、findAll、delete等等,可以采用默认实现方式来完成常用的增删改查操作。

测试上述各个方法ArticleRepositoryTest.java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath*:applicationContext-mongo.xml"})
public class ArticleRepositoryTest {
 
  @Autowired
  private ArticleRepository articleRepository;
 
  /**
   * 新增记录
   */
  @Test
  public void add() {
    //增加一条记录
    Article article = new Article();
    article.setId("1");
    article.setTitle("MongoTemplate的基本使用");
    article.setAuthor("kcy");
    article.setUrl("http://jianshu.com/");
    article.setTags(Arrays.asList("java", "mongodb", "spring"));
    article.setVisitCount(0L);
    article.setAddTime(new Date());
    articleRepository.save(article);
 
    //批量添加
    List<Article> articles = new ArrayList<>(10);
    for (int i = 0; i < 10; i++) {
      Article article2 = new Article();
      article2.setId(String.valueOf(i + 1));
      article2.setTitle("MongoTemplate的基本使用");
      article2.setAuthor("kcy");
      article2.setUrl("http://jianshu.com" + i);
      article2.setTags(Arrays.asList("java", "mongodb", "spring"));
      article2.setVisitCount(0L);
      article2.setAddTime(new Date());
      articles.add(article2);
    }
    articleRepository.save(articles);
  }
 
  /**
   * 修改记录,修改id为1的访问次数+1
   */
  @Test
  public void update() {
    Article article = articleRepository.findOne("1");
    article.setVisitCount(article.getVisitCount() + 1);
    articleRepository.save(article);
  }
 
  /**
   * 批量修改,查看author为kcy的统一修改为kcy2
   */
  @Test
  public void batchUpdate() {
    List<Article> articles = articleRepository.findByAuthor("kcy");
    articles.forEach(article -> {
      article.setAuthor("kcy2");
    });
    articleRepository.save(articles);
  }
 
  /**
   * 删除记录,删除id为10的
   */
  @Test
  public void delete() {
    Article article = articleRepository.findOne("10");
    articleRepository.delete(article);
  }
 
  @Test
  public void batchDelete() {
    List<Article> articles = articleRepository.findByAuthor("kcy2");
    articleRepository.delete(articles);
  }
 
  /**
   * 查询所有
   *
   * @author 孔垂云
   */
  @Test
  public void findAll() {
    Iterable<Article> articles = articleRepository.findAll();
    articles.forEach(article -> {
      System.out.println(article.toString());
    });
  }
 
  /**
   * 根据author查询
   *
   * @author 孔垂云
   */
  @Test
  public void findByAuthor() {
    List<Article> articles = articleRepository.findByAuthor("kcy");
    articles.forEach(article -> {
      System.out.println(article.toString());
    });
  }
 
  /**
   * 按照author和title查询
   *
   * @author 孔垂云
   */
  @Test
  public void findByAuthorAndTitle() {
    List<Article> articles = articleRepository.findByAuthorAndTitle("kcy", "MongoTemplate的基本使用");
    articles.forEach(article -> {
      System.out.println(article.toString());
    });
  }
 
  /**
   * 根据作者查询,忽略大小写
   *
   * @author 孔垂云
   */
  @Test
  public void findByAuthorIgnoreCase() {
    List<Article> articles = articleRepository.findByAuthorIgnoreCase("JASON");
    articles.forEach(article -> {
      System.out.println(article.getId());
    });
  }
 
  /**
   * 忽略所有参数的大小写
   *
   * @author 孔垂云
   */
  @Test
  public void findByAuthorAndTitleAllIgnoreCase() {
    List<Article> articles = articleRepository.findByAuthorAndTitleAllIgnoreCase("KCY", "MONGOTEMPLATE的基本使用");
    articles.forEach(article -> {
      System.out.println(article.toString());
    });
  }
 
  /**
   * 根据author查询,并且以访问次数降序排序显示
   *
   * @author 孔垂云
   */
  @Test
  public void findByAuthorOrderByVisitCountDesc() {
    List<Article> articles = articleRepository.findByAuthorOrderByVisitCountDesc("kcy");
    articles.forEach(article -> {
      System.out.println(article.toString());
    });
  }
 
 
  /**
   * 根据作者查询,并且以访问次数升序排序显示
   *
   * @author 孔垂云
   */
  @Test
  public void findByAuthorOrderByVisitCountAsc() {
    List<Article> articles = articleRepository.findByAuthorOrderByVisitCountAsc("kcy");
    articles.forEach(article -> {
      System.out.println(article.toString());
    });
  }
 
  /**
   * 自带排序条件
   *
   * @author 孔垂云
   */
  @Test
  public void findByAuthorBySort() {
    List<Article> articles = articleRepository.findByAuthor("kcy", new Sort(Direction.ASC, "VisitCount"));
    articles.forEach(article -> {
      System.out.println(article.toString());
    });
  }
 
  /**
   * 分页查询所有,并且排序
   */
  @Test
  public void findByPage() {
    int page = 1;
    int size = 2;
    Pageable pageable = new PageRequest(page, size, new Sort(Direction.ASC, "VisitCount"));
    Page<Article> pageInfo = articleRepository.findAll(pageable);
    //总数量
    System.out.println(pageInfo.getTotalElements());
    //总页数
    System.out.println(pageInfo.getTotalPages());
    for (Article article : pageInfo.getContent()) {
      System.out.println(article.toString());
    }
  }
}

上面一段代码较长,基本上MongoDB常用的各种例子都讲清楚了,比如增加、批量增加、修改、删除、按id查找、按标题查询、分页等等。

源码下载

本工程详细源码

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:http://www.jianshu.com/p/cba5d31ea70e