您的位置:首页 > 数据库 > Mongodb

大数据之mongodb --> (2)java集成 MongoDB 3.2,使用Spring-data-mongodb进行集成

2017-02-23 04:09 781 查看
Java集成MongoDB有很多方式,可以直接用mongodb的java驱动程序来发送语句到mongodb服务器,也可以用第三方的工具包来做。

(1) 选择版本

选择的就是springdata集成的mongodb(spring-data-mongodb)

1.1 spring-data-mongodb版本

gradle坐标:org.springframework.data:spring-data-mongodb:1.7.2.RELEASEmaven 坐标
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>1.7.2.RELEASE</version>
</dependency>
1
2
3
4
5
1
2
3
4
5

1.2 java驱动器版本

gradle坐标:org.mongodb:mongo-java-driver:3.2.0maven 坐标
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>3.2.0</version>
</dependency>
1
2
3
4
5
6
1
2
3
4
5
6

(2) 集成

2.1 spring 配置文件

新建文件 mongodb-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <!-- mongodb 的基本配置 -->
<mongo:mongo id="mongo"  host="192.168.1.202" port="27017"  />

<!-- 权限配置 -->
<bean id="userCredentials" class="org.springframework.data.authentication.UserCredentials">
<constructor-arg name="username"  value="root"/>
<constructor-arg name="password"  value="root"/>
</bean>

<!-- template 配置 -->
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg ref="mongo" />
<!-- 数据库名称 -->
<constructor-arg value="demodb" />
<!-- 权限  -->
<constructor-arg ref="userCredentials" />
</bean>

</beans>
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
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
集成到spring的基础配置文件中即可 
spring的主配置文件插入如下代码
<!-- 导入mongodb的配置文件 -->
<import resource="mongodb-context.xml"/>
1
2
1
2

(3) 编写基础类

3.1 Dao 基础操作类 MongodbDao

其他的dao类都可以继承改类
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Repository;

import com.github.pagehelper.PageInfo;

/**
* mongodb 基础操作类
* @author chenpengye 2015年12月21日 下午11:33:06
* @param <T>
*/
@Repository
public class MongodbDao<T extends IdEntity> {

private static final Logger logger = LoggerFactory.getLogger(MongodbDao.class);

private static final int DEFAULT_SKIP = 0;
private static final int DEFAULT_LIMIT = 200;

@Autowired
protected MongoTemplate mongoTemplate;

// ======= 增 ============
public void save(T t) {
mongoTemplate.save(t);
logger.debug("save entity: {}", t);
}

public void insertAll(List<T> list) {
mongoTemplate.insertAll(list);
}

// ======= 删 ============
/**
* 删除对象
*
* @param t
*/
public void delete(T t) {
mongoTemplate.remove(t);
}

/**
* 根据id 删除对象
*
* @param id
*/
public void deleteById(String id) {
Criteria criteria = Criteria.where("id").is(id);
Query query = new Query(criteria);
mongoTemplate.remove(query, this.getEntityClass());
}

/**
* 根据条件删除
*/
public void delete(Query query) {
mongoTemplate.remove(query, this.getEntityClass());
}

/**
* 删除该collection 的所有的数据
*/
public void deleteAll() {
mongoTemplate.dropCollection(this.getEntityClass());
}

// ======= 改 ============
public void update(Query query, Update update) {
mongoTemplate.findAndModify(query, update, this.getEntityClass());
}

// ======= 查 ============
public List<T> findAll(){
return mongoTemplate.findAll(this.getEntityClass());
}
/**
* 根据查询query 查找list
*
* @param query
* @return
*/
public List<T> find(Query query) {
return mongoTemplate.find(query, this.getEntityClass());
}

/**
* 按照字段排序 - 顺序  <br/>
* @param query        查询条件  <br/>
* @param properties   排序字段  <br/>
* @return
*/
public List<T> findWithOrderAsc(Query query, String... properties){
Sort sort = new Sort(Direction.ASC, properties);
query.with(sort);
return mongoTemplate.find(query, this.getEntityClass());
}

/**
* 按照字段排序 - 逆序 <br/>
* @param query        查询条件  <br/>
* @param properties   排序字段  <br/>
* @return
*/
public List<T> findWithOrderDesc(Query query, String... properties){
Sort sort = new Sort(Direction.DESC, properties);
query.with(sort);
return mongoTemplate.find(query, this.getEntityClass());
}

/**
* 根据查询query 查找一个对象
*
* @param query
* @return
*/
public T findOne(Query query) {
return mongoTemplate.findOne(query, this.getEntityClass());
}

/**
* 根据 id 查询对象
*
* @param id
* @return
*/
public T findById(String id) {
return mongoTemplate.findById(id, this.getEntityClass());
}

/**
* 根据id 和 集合名字查询对象
*
* @param id
* @param collectionName
* @return
*/
public T findById(String id, String collectionName) {
return mongoTemplate.findById(id, this.getEntityClass(), collectionName);
}

/**
* 查询分页  tips:[不要skip 太多的页数,如果跳过太多会严重影响效率。最大不要skip 20000页]
* @param page
* @param query
* @return
*/
public PageInfo<T> findPage(PageInfo<T> page, Query query) {
long count = this.count(query);
page.setTotal(count);
int pageNumber = page.getPageNum();
int pageSize = page.getPageSize();
query.skip((pageNumber - 1) * pageSize).limit(pageSize);
List<T> list = this.find(query);
page.setList(list);
return page;
}

public long count(Query query) {
return mongoTemplate.count(query, this.getEntityClass());
}

/**
* 获取需要操作的实体类class <br/>
* 例如: StudentScoreDao extends MongodbDao <b><StudentScore></b> <br/>
* 返回的是 <b>StudentScore</b> 的Class
*
* @return
*/
private Class<T> getEntityClass() {
return ReflectionUtils.getSuperClassGenricType(getClass());
}

/**
* 获取collection的名字,默认是dao范型T的名字 <br/>
* 例如: StudentScoreDao extends MongodbDao <b><StudentScore></b> <br/>
* 则返回的名字是:<b>StudentScore</b>
*
* @return
*/
private String getCollectionName() {
return getEntityClass().getSimpleName();
}

}
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
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
由于现行项目使用mybatis,并且分页采用了pagehelper:pagehelper:4.0.3,因此这里的分页类也采用里pagehelper里面的分页类。如果要分页,请也引入pagehelper的jar包 
gradle坐标
compile 'com.github.jsqlparser:jsqlparser:0.9.4'
compile 'com.github.pagehelper:pagehelper:4.0.3'
1
2
1
2
maven坐标
<dependency>
<groupId>com.github.jsqlparser</groupId>
<artifactId>jsqlparser</artifactId>
<version>0.9.4</version>
</dependency>

<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>4.0.3</version>
</dependency>
1
2
3
4
5
6
7
8
9
10
11
1
2
3
4
5
6
7
8
9
10
11

3.2 工具类 ReflectionUtils

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Assert;

/**
* 反射工具类.
*
* 提供访问私有变量,获取泛型类型Class, 提取集合中元素的属性, 转换字符串到对象等Util函数.
*
*/
public class ReflectionUtils {

private static Logger logger = LoggerFactory.getLogger(ReflectionUtils.class);

/**
* 调用Getter方法.
*/
public static Object invokeGetterMethod(Object obj, String propertyName) {
String getterMethodName = "get" + StringUtils.capitalize(propertyName);
return invokeMethod(obj, getterMethodName, new Class[] {}, new Object[] {});
}

/**
* 调用Setter方法.使用value的Class来查找Setter方法.
*/
public static void invokeSetterMethod(Object obj, String propertyName, Object value) {
invokeSetterMethod(obj, propertyName, value, null);
}

/**
* 调用Setter方法.
*
* @param propertyType 用于查找Setter方法,为空时使用value的Class替代.
*/
public static void invokeSetterMethod(Object obj, String propertyName, Object value, Class<?> propertyType) {
Class<?> type = propertyType != null ? propertyType : value.getClass();
String setterMethodName = "set" + StringUtils.capitalize(propertyName);
invokeMethod(obj, setterMethodName, new Class[] { type }, new Object[] { value });
}

/**
* 直接读取对象属性值, 无视private/protected修饰符, 不经过getter函数.
*/
public static Object getFieldValue(final Object obj, final String fieldName) {
Field field = getAccessibleField(obj, fieldName);

if (field == null) {
throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + obj + "]");
}

Object result = null;
try {
result = field.get(obj);
} catch (IllegalAccessException e) {
logger.error("不可能抛出的异常{}", e.getMessage());
}
return result;
}

/**
* 直接设置对象属性值, 无视private/protected修饰符, 不经过setter函数.
*/
public static void setFieldValue(final Object obj, final String fieldName, final Object value) {
Field field = getAccessibleField(obj, fieldName);

if (field == null) {
throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + obj + "]");
}

try {
field.set(obj, value);
} catch (IllegalAccessException e) {
logger.error("不可能抛出的异常:{}", e.getMessage());
}
}

/**
* 循环向上转型, 获取对象的DeclaredField,   并强制设置为可访问.
*
* 如向上转型到Object仍无法找到, 返回null.
*/
public static Field getAccessibleField(final Object obj, final String fieldName) {
Assert.notNull(obj, "object不能为空");
Assert.hasText(fieldName, "fieldName");
for (Class<?> superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) {
try {
Field field = superClass.getDeclaredField(fieldName);
field.setAccessible(true);
return field;
} catch (NoSuchFieldException e) {//NOSONAR
// Field不在当前类定义,继续向上转型
}
}
return null;
}

/**
* 直接调用对象方法, 无视private/protected修饰符.
* 用于一次性调用的情况.
*/
public static Object invokeMethod(final Object obj, final String methodName, final Class<?>[] parameterTypes,
final Object[] args) {
Method method = getAccessibleMethod(obj, methodName, parameterTypes);
if (method == null) {
throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + obj + "]");
}

try {
return method.invoke(obj, args);
} catch (Exception e) {
throw convertReflectionExceptionToUnchecked(e);
}
}

/**
* 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问.
* 如向上转型到Object仍无法找到, 返回null.
*
* 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args)
*/
public static Method getAccessibleMethod(final Object obj, final String methodName,
final Class<?>... parameterTypes) {
Assert.notNull(obj, "object不能为空");

for (Class<?> superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) {
try {
Method method = superClass.getDeclaredMethod(methodName, parameterTypes);

method.setAccessible(true);

return method;

} catch (NoSuchMethodException e) {//NOSONAR
// Method不在当前类定义,继续向上转型
}
}
return null;
}

/**
* 通过反射, 获得Class定义中声明的父类的泛型参数的类型.
* 如无法找到, 返回Object.class.
* eg.
* public UserDao extends HibernateDao<User>
*
* @param clazz The class to introspect
* @return the first generic declaration, or Object.class if cannot be determined
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public static <T> Class<T> getSuperClassGenricType(final Class clazz) {
return getSuperClassGenricType(clazz, 0);
}

/**
* 通过反射, 获得Class定义中声明的父类的泛型参数的类型.
* 如无法找到, 返回Object.class.
*
* 如public UserDao extends HibernateDao<User,Long>
*
* @param clazz clazz The class to introspect
* @param index the Index of the generic ddeclaration,start from 0.
* @return the index generic declaration, or Object.class if cannot be determined
*/
@SuppressWarnings("rawtypes")
public static Class getSuperClassGenricType(final Class clazz, final int index) {

Type genType = clazz.getGenericSuperclass();

if (!(genType instanceof ParameterizedType)) {
logger.warn(clazz.getSimpleName() + "'s superclass not ParameterizedType");
return Object.class;
}

Type[] params = ((ParameterizedType) genType).getActualTypeArguments();

if (index >= params.length || index < 0) {
logger.warn("Index: " + index + ", Size of " + clazz.getSimpleName() + "'s Parameterized Type: "
+ params.length);
return Object.class;
}
if (!(params[index] instanceof Class)) {
logger.warn(clazz.getSimpleName() + " not set the actual class on superclass generic parameter");
return Object.class;
}

return (Class) params[index];
}

/**
* 将反射时的checked exception转换为unchecked exception.
*/
public static RuntimeException convertReflectionExceptionToUnchecked(Exception e) {
if (e instanceof IllegalAccessException || e instanceof IllegalArgumentException
|| e instanceof NoSuchMethodException) {
return new IllegalArgumentException("Reflection Exception.", e);
} else if (e instanceof InvocationTargetException) {
return new RuntimeException("Reflection Exception.", ((InvocationTargetException) e).getTargetException());
} else if (e instanceof RuntimeException) {
return (RuntimeException) e;
}
return new RuntimeException("Unexpected Checked Exception.", e);
}
}
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
200
201
202
203
204
205
206
207
208
209
210
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
200
201
202
203
204
205
206
207
208
209
210

3.3 基础实体类 IdEntity

import java.io.Serializable;

/**
* mongodb 基础id类,id都是字符串型的
* @author chenpengye
* 2015年12月21日 下午4:53:45
*/
public class IdEntity implements Serializable {

private static final long serialVersionUID = 33633625616087044L;
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

3.4 实体类 StudentScore

import java.io.Serializable;
import java.util.List;

/**
* 测试实体类
* @author chenpengye
* 2015年12月21日 下午11:59:02
*/
public class StudentScore extends IdEntity implements Serializable {

private static final long serialVersionUID = 8743196073520676022L;

/**
* 学生姓名
*/
private String username;

/**
* 学生成绩
*/
private List<Double> scoreList;

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public List<Double> getScoreList() {
return scoreList;
}

public void setScoreList(List<Double> scoreList) {
this.scoreList = scoreList;
}

}
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
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

3.5 实体类的dao操作类 StudentScoreDao

import org.springframework.stereotype.Repository;

/**
* 继承MongodbDao<br/>
* 此类对StudentScore对增删改查和分页方法都已经有了<br/>
* @author chenpengye
* 2016年1月4日 下午10:04:25
*/
@Repository
public class StudentScoreDao extends MongodbDao<StudentScore> {

}
1
2
3
4
5
6
7
8
9
10
11
12
1
2
3
4
5
6
7
8
9
10
11
12
有需要的同学可以参考我的上一篇博客,关于mongodb的安装 
---(1)在ubuntu上安装mongodb ------欢迎探讨,如有疑问请发邮件到chenpengye1861@163.com
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: