SpringData MongoDB¶
整合MongoDB的框架还有Morphia,有兴趣的可以上网看看,网上也有别的乱七八糟框架的,这里简单地说下SpringData。
项目git地址:https://code.csdn.net/qq_16313365/demo-springdata-mongo/tree/master。
官方文档:https://docs.spring.io/spring-data/mongodb/docs/1.7.0.RELEASE/reference/html/。
spring Data MongoDB 项目提供与mongodb文档数据库的集成。Spring Data MongoDB POJO的关键功能区域为中心的模型与MongoDB的DBCollection轻松地编写一个存储库交互数据访问。
【pom.xml】
1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3. <modelVersion>4.0.0</modelVersion>
4.
5. <groupId>com.jastar</groupId>
6. <artifactId>demo</artifactId>
7. <version>0.0.1-SNAPSHOT</version>
8. <packaging>jar</packaging>
9.
10. <name>demo</name>
11. <url>http://www.jastar-wang.tech</url>
12.
13. <!-- 版本配置 -->
14. <properties>
15. <spring.version>4.1.4.RELEASE</spring.version>
16. <spring.data.version>1.7.0.RELEASE</spring.data.version>
17. <log4j.version>1.2.17</log4j.version>
18. </properties>
19.
20. <dependencies>
21. <!-- 单元测试包 -->
22. <dependency>
23. <groupId>junit</groupId>
24. <artifactId>junit</artifactId>
25. <version>4.10</version>
26. <scope>test</scope>
27. </dependency>
28.
29. <!-- spring核心包 -->
30. <dependency>
31. <groupId>org.springframework</groupId>
32. <artifactId>spring-core</artifactId>
33. <version>${spring.version}</version>
34. </dependency>
35. <dependency>
36. <groupId>org.springframework</groupId>
37. <artifactId>spring-context</artifactId>
38. <version>${spring.version}</version>
39. </dependency>
40. <dependency>
41. <groupId>org.springframework</groupId>
42. <artifactId>spring-beans</artifactId>
43. <version>${spring.version}</version>
44. </dependency>
45. <dependency>
46. <groupId>org.springframework</groupId>
47. <artifactId>spring-tx</artifactId>
48. <version>${spring.version}</version>
49. </dependency>
50. <dependency>
51. <groupId>org.springframework</groupId>
52. <artifactId>spring-webmvc</artifactId>
53. <version>${spring.version}</version>
54. </dependency>
55. <dependency>
56. <groupId>org.springframework</groupId>
57. <artifactId>spring-aop</artifactId>
58. <version>${spring.version}</version>
59. </dependency>
60. <dependency>
61. <groupId>org.springframework</groupId>
62. <artifactId>spring-test</artifactId>
63. <version>${spring.version}</version>
64. </dependency>
65.
66. <!-- 关系型数据库整合时需配置 如hibernate jpa等 -->
67. <dependency>
68. <groupId>org.springframework</groupId>
69. <artifactId>spring-orm</artifactId>
70. <version>${spring.version}</version>
71. </dependency>
72.
73. <!-- spring aop 关联 -->
74. <dependency>
75. <groupId>org.aspectj</groupId>
76. <artifactId>aspectjweaver</artifactId>
77. <version>1.8.7</version>
78. </dependency>
79.
80. <!-- log4j -->
81. <dependency>
82. <groupId>log4j</groupId>
83. <artifactId>log4j</artifactId>
84. <version>${log4j.version}</version>
85. </dependency>
86.
87. <!-- spring整合MongoDB -->
88. <dependency>
89. <groupId>org.springframework.data</groupId>
90. <artifactId>spring-data-mongodb</artifactId>
91. <version>${spring.data.version}</version>
92. </dependency>
93.
94. </dependencies>
95.
96. <repositories>
97. <repository>
98. <id>spring-milestone</id>
99. <name>Spring Maven MILESTONE Repository</name>
100. <url>http://repo.spring.io/libs-milestone</url>
101. </repository>
102. </repositories>
103.
104. <build>
105. <plugins>
106. <plugin>
107. <groupId>org.apache.maven.plugins</groupId>
108. <artifactId>maven-compiler-plugin</artifactId>
109. <configuration>
110. <source>1.7</source>
111. <target>1.7</target>
112. </configuration>
113. </plugin>
114. </plugins>
115. </build>
116. </project>
实体类【UserInfo.java】
1. package com.jastar.demo.entity;
2.
3. import java.io.Serializable;
4. import java.sql.Timestamp;
5.
6. import org.springframework.data.annotation.Id;
7. import org.springframework.data.mongodb.core.index.IndexDirection;
8. import org.springframework.data.mongodb.core.index.Indexed;
9. import org.springframework.data.mongodb.core.mapping.Document;
10. import org.springframework.data.mongodb.core.mapping.Field;
11.
12. /**
13. * 用户实体类
14. * <p>
15. * ClassName: UserInfo
16. * </p>
17. * <p>
18. * Description:本类用来展示MongoDB实体类映射的使用
19. * </p>
20. * <p>
21. * Copyright: (c)2017 Jastar·Wang,All rights reserved.
22. * </p>
23. *
24. * @author Jastar·Wang
25. * @date 2017年4月12日
26. */
27. @Document(collection = "coll_user")
28. public class UserInfo implements Serializable {
29.
30. /** serialVersionUID */
31. private static final long serialVersionUID = 1L;
32.
33. // 主键使用此注解
34. @Id
35. private String id;
36.
37. // 字段使用此注解
38. @Field
39. private String name;
40.
41. // 字段还可以用自定义名称
42. @Field("myage")
43. private int age;
44.
45. // 还可以生成索引
46. @Indexed(name = "index_birth", direction = IndexDirection.DESCENDING)
47. @Field
48. private Timestamp birth;
49.
50. public String getId() {
51. return id;
52. }
53.
54. public void setId(String id) {
55. this.id = id;
56. }
57.
58. public String getName() {
59. return name;
60. }
61.
62. public void setName(String name) {
63. this.name = name;
64. }
65.
66. public int getAge() {
67. return age;
68. }
69.
70. public void setAge(int age) {
71. this.age = age;
72. }
73.
74. public Timestamp getBirth() {
75. return birth;
76. }
77.
78. public void setBirth(Timestamp birth) {
79. this.birth = birth;
80. }
81.
82. }
- 附录:
- @Id - 用于字段级别,标记这个字段是一个主键,默认生成的名称是“_id”
- @Document - 用于类,以表示这个类需要映射到数据库,您也可以指定映射到数据库的集合名称
- @DBRef - 用于字段,以表示它将使用com.mongodb.DBRef进行存储。
- @Indexed - 用于字段,表示该字段需要如何创建索引
- @CompoundIndex - 用于类,以声明复合索引
- @GeoSpatialIndexed - 用于字段,进行地理位置索引
- @TextIndexed - 用于字段,标记该字段要包含在文本索引中
- @Language - 用于字段,以设置文本索引的语言覆盖属性。
- @Transient - 默认情况下,所有私有字段都映射到文档,此注解将会去除此字段的映射
- @PersistenceConstructor - 标记一个给定的构造函数,即使是一个protected修饰的,在从数据库实例化对象时使用。构造函数参数通过名称映射到检索的DBObject中的键值。
- @Value 这个注解是Spring框架的一部分。在映射框架内,它可以应用于构造函数参数。这允许您使用Spring表达式语言语句来转换在数据库中检索的键值,然后再用它来构造一个域对象。为了引用给定文档的属性,必须使用以下表达式:@Value(“#root.myProperty”),root要指向给定文档的根。
- @Field - 用于字段,并描述字段的名称,因为它将在MongoDB BSON文档中表示,允许名称与该类的字段名不同。
- @Version - 用于字段锁定,保存操作时检查修改。初始值是0,每次更新时自动触发。
【db.properties】
1. ###---The mongodb settings---
2. mongo.dbname=demo
3. mongo.host=localhost
4. mongo.port=27017
5. mongo.connectionsPerHost=8
6. mongo.threadsAllowedToBlockForConnectionMultiplier=4
7. mongo.connectTimeout=1000
8. mongo.maxWaitTime=1500
9. mongo.autoConnectRetry=true
10. mongo.socketKeepAlive=true
11. mongo.socketTimeout=1500
12. mongo.slaveOk=true
13. mongo.writeNumber=1
14. mongo.writeTimeout=0
15. mongo.writeFsync=true
【spring-mgo.xml】
1. <?xml version="1.0" encoding="UTF-8"?>
2. <beans xmlns="http://www.springframework.org/schema/beans"
3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4. xmlns:context="http://www.springframework.org/schema/context"
5. xmlns:mongo="http://www.springframework.org/schema/data/mongo"
6. xsi:schemaLocation="http://www.springframework.org/schema/context
7. http://www.springframework.org/schema/context/spring-context-3.0.xsd
8. http://www.springframework.org/schema/data/mongo
9. http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd
10. http://www.springframework.org/schema/beans
11. http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
12.
13. <!-- 读取属性文件 -->
14. <context:property-placeholder location="classpath:db.properties" />
15.
16. <!-- 启用注解支持 -->
17. <context:annotation-config />
18.
19. <!-- 扫描组件包 -->
20. <context:component-scan base-package="com.jastar.demo" />
21.
22. <!-- SpringData类型转换器 -->
23. <mongo:mapping-converter id="mongoConverter">
24. <mongo:custom-converters>
25. <mongo:converter>
26. <bean class="com.jastar.demo.converter.TimestampConverter" />
27. </mongo:converter>
28. </mongo:custom-converters>
29. </mongo:mapping-converter>
30.
31. <!--
32. MongoDB配置部分
33. 1.mongo:连接配置
34. 2.db-factory:相当于sessionFactory
35. 3.mongoTemplate:与数据库接口交互的主要实现类
36. -->
37. <mongo:mongo host="${mongo.host}" port="${mongo.port}">
38. <mongo:options
39. connections-per-host="${mongo.connectionsPerHost}"
40. threads-allowed-to-block-for-connection-multiplier="${mongo.threadsAllowedToBlockForConnectionMultiplier}"
41. connect-timeout="${mongo.connectTimeout}"
42. max-wait-time="${mongo.maxWaitTime}"
43. auto-connect-retry="${mongo.autoConnectRetry}"
44. socket-keep-alive="${mongo.socketKeepAlive}"
45. socket-timeout="${mongo.socketTimeout}"
46. slave-ok="${mongo.slaveOk}"
47. write-number="${mongo.writeNumber}"
48. write-timeout="${mongo.writeTimeout}"
49. write-fsync="${mongo.writeFsync}" />
50. </mongo:mongo>
51.
52. <mongo:db-factory id="mongoDbFactory" dbname="${mongo.dbname}" mongo-ref="mongo" />
53.
54. <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
55. <constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />
56. <constructor-arg name="mongoConverter" ref="mongoConverter" />
57. </bean>
58.
59. </beans>
- 说明:
- mongo:options - 用于配置一些数据库连接设置信息
- mongo:db-factory - 相当于Hibernate中的SessionFactory
- mongoTemplate - 非常重要,整个与数据库的交互操作全是靠他,相当于Hibernate的HibernateTemplate
另外,以上配置中有一个类型转换器,因为Spring Data MongoDB本身默认时间类型是java.util.Date,如果实体字段含有java.sql.Timestamp类型,需要自定义转换器进行转换,否则后续操作会报错
【BaseDaoImpl.Java】
1. package com.jastar.demo.dao.impl;
2.
3. import static org.springframework.data.mongodb.core.query.Criteria.where;
4.
5. import java.io.Serializable;
6. import java.lang.reflect.Field;
7. import java.lang.reflect.Method;
8. import java.lang.reflect.Modifier;
9. import java.util.ArrayList;
10. import java.util.HashMap;
11. import java.util.List;
12. import java.util.Map;
13.
14. import org.springframework.beans.factory.annotation.Autowired;
15. import org.springframework.data.annotation.Id;
16. import org.springframework.data.domain.Sort;
17. import org.springframework.data.domain.Sort.Direction;
18. import org.springframework.data.domain.Sort.Order;
19. import org.springframework.data.mongodb.core.MongoTemplate;
20. import org.springframework.data.mongodb.core.query.Query;
21. import org.springframework.data.mongodb.core.query.Update;
22.
23. import com.jastar.demo.dao.IBaseDao;
24. import com.jastar.demo.util.EmptyUtil;
25. import com.jastar.demo.util.PageModel;
26.
27. /**
28. * 基本操作接口MongoDB数据库实现类
29. * <p>
30. * ClassName: BaseDaoImpl
31. * </p>
32. * <p>
33. * Description:本实现类适用于MongoDB数据库,以下代码仅供参考,本人水平有限,可能会存在些许问题(如有更好方案可告知我,一定虚心学习),
34. * 再次提醒,仅供参考!!
35. * </p>
36. * <p>
37. * Copyright: (c)2017 Jastar·Wang,All rights reserved.
38. * </p>
39. *
40. * @author Jastar·Wang
41. * @date 2017年4月12日
42. */
43. public abstract class BaseDaoImpl<T> implements IBaseDao<T> {
44.
45. protected abstract Class<T> getEntityClass();
46.
47. @Autowired
48. protected MongoTemplate mgt;
49.
50. @Override
51. public void save(T entity) {
52. mgt.save(entity);
53. }
54.
55. @Override
56. public void update(T entity) {
57.
58. // 反向解析对象
59. Map<String, Object> map = null;
60. try {
61. map = parseEntity(entity);
62. } catch (Exception e) {
63. e.printStackTrace();
64. }
65.
66. // ID字段
67. String idName = null;
68. Object idValue = null;
69.
70. // 生成参数
71. Update update = new Update();
72. if (EmptyUtil.isNotEmpty(map)) {
73. for (String key : map.keySet()) {
74. if (key.indexOf("{") != -1) {
75. // 设置ID
76. idName = key.substring(key.indexOf("{") + 1, key.indexOf("}"));
77. idValue = map.get(key);
78. } else {
79. update.set(key, map.get(key));
80. }
81. }
82. }
83. mgt.updateFirst(new Query().addCriteria(where(idName).is(idValue)), update, getEntityClass());
84. }
85.
86. @Override
87. public void delete(Serializable... ids) {
88. if (EmptyUtil.isNotEmpty(ids)) {
89. for (Serializable id : ids) {
90. mgt.remove(mgt.findById(id, getEntityClass()));
91. }
92. }
93.
94. }
95.
96. @Override
97. public T find(Serializable id) {
98. return mgt.findById(id, getEntityClass());
99. }
100.
101. @Override
102. public List<T> findAll() {
103. return mgt.findAll(getEntityClass());
104. }
105.
106. @Override
107. public List<T> findAll(String order) {
108. List<Order> orderList = parseOrder(order);
109. if (EmptyUtil.isEmpty(orderList)) {
110. return findAll();
111. }
112. return mgt.find(new Query().with(new Sort(orderList)), getEntityClass());
113. }
114.
115. @Override
116. public List<T> findByProp(String propName, Object propValue) {
117. return findByProp(propName, propValue, null);
118. }
119.
120. @Override
121. public List<T> findByProp(String propName, Object propValue, String order) {
122. Query query = new Query();
123. // 参数
124. query.addCriteria(where(propName).is(propValue));
125. // 排序
126. List<Order> orderList = parseOrder(order);
127. if (EmptyUtil.isNotEmpty(orderList)) {
128. query.with(new Sort(orderList));
129. }
130. return mgt.find(query, getEntityClass());
131. }
update方法不像关系型数据库那样,给个实体类就能更新,需要自己去想办法搞定。(所以MongoDB都是用来读写的,存储一些信息的)
【TestUseService.java】
1. package com.jastar.test;
2.
3. import java.sql.Timestamp;
4. import java.util.List;
5.
6. import org.junit.Test;
7. import org.junit.runner.RunWith;
8. import org.springframework.beans.factory.annotation.Autowired;
9. import org.springframework.test.context.ContextConfiguration;
10. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
11.
12. import com.jastar.demo.entity.UserInfo;
13. import com.jastar.demo.service.UserService;
14. import com.jastar.demo.util.PageModel;
15.
16. @RunWith(SpringJUnit4ClassRunner.class)
17. @ContextConfiguration(locations = "classpath:spring-mgo.xml")
18. public class TestUserService {
19.
20. @Autowired
21. private UserService service;
22.
23. @Test
24. public void save() {
25. UserInfo user = new UserInfo();
26. user.setName("张三");
27. user.setAge(25);
28. user.setBirth(Timestamp.valueOf("2017-4-12 16:52:00"));
29. service.save(user);
30. System.out.println("已生成ID:" + user.getId());
31. }
32.
33. @Test
34. public void find() {
35. UserInfo user = service.find("58edf1b26f033406394a8a61");
36. System.out.println(user.getName());
37. }
38.
39. @Test
40. public void update() {
41. UserInfo user = service.find("58edf1b26f033406394a8a61");
42. user.setAge(18);
43. service.update(user);
44. }
45.
46. @Test
47. public void delete() {
48. service.delete("58edef886f03c7b0fdba51b9");
49. }
50.
51. @Test
52. public void findAll() {
53. List<UserInfo> list = service.findAll("age desc");
54. for (UserInfo u : list) {
55. System.out.println(u.getName());
56. }
57. }
58.
59. @Test
60. public void findByProp() {
61. List<UserInfo> list = service.findByProp("name", "张三");
62. for (UserInfo u : list) {
63. System.out.println(u.getName());
64. }
65. }
66.
67. @Test
68. public void findByProps() {
69. List<UserInfo> list = service.findByProps(new String[] { "name", "age" }, new Object[] { "张三", 18 });
70. for (UserInfo u : list) {
71. System.out.println(u.getName());
72. }
73. }