spring-3.1.x以上的相关包(必须是3.1.x以上,否则集成之后运行会报错)
spring-data-mongodb-1.3.0.M1.jar
先看配置文件(spring-mongodb.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">
- <mongo:db-factory id="mongoDbFactory"
- host="${mongo.host}"
- port="${mongo.port}"
- dbname="${mongo.dbname}"
- username="${mongo.username}"
- password="${database.password}"/>
- <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
- <constructor-arg name="mongoDbFactory" ref="mongoDbFactory"/>
- </bean>
- </beans>
其中:host为mongodb服务器地址,port为端口号,dbname为数据库名,username为mongodb用户名,password为mongodb密码,好了,全部配置就在这里。
接下来就是CRUD封装类
- package cn.sunsharp.alibaba.core.mongo;
- import java.util.List;
- import org.springframework.data.mongodb.core.query.Query;
- import org.springframework.data.mongodb.core.query.Update;
- import cn.sunsharp.alibaba.core.Page;
- public interface BaseMongoDAO<T> {
- /**
- * 通过条件查询实体(集合)
- *
- * @param query
- */
- public List<T> find(Query query) ;
- /**
- * 通过一定的条件查询一个实体
- *
- * @param query
- * @return
- */
- public T findOne(Query query) ;
- /**
- * 通过条件查询更新数据
- *
- * @param query
- * @param update
- * @return
- */
- public void update(Query query, Update update) ;
- /**
- * 保存一个对象到mongodb
- *
- * @param entity
- * @return
- */
- public T save(T entity) ;
- /**
- * 通过ID获取记录
- *
- * @param id
- * @return
- */
- public T findById(String id) ;
- /**
- * 通过ID获取记录,并且指定了集合名(表的意思)
- *
- * @param id
- * @param collectionName
- * 集合名
- * @return
- */
- public T findById(String id, String collectionName) ;
- /**
- * 分页查询
- * @param page
- * @param query
- * @return
- */
- public Page<T> findPage(Page<T> page,Query query);
- /**
- * 求数据总和
- * @param query
- * @return
- */
- public long count(Query query);
- }
实现:
- package cn.sunsharp.alibaba.core.mongo.impl;
- import java.util.List;
- import org.springframework.data.mongodb.core.MongoTemplate;
- import org.springframework.data.mongodb.core.query.Query;
- import org.springframework.data.mongodb.core.query.Update;
- import cn.sunsharp.alibaba.core.Page;
- import cn.sunsharp.alibaba.core.ReflectionUtils;
- import cn.sunsharp.alibaba.core.mongo.BaseMongoDAO;
- public abstract class BaseMongoDAOImpl<T> implements BaseMongoDAO<T>{
- private static final int DEFAULT_SKIP = 0;
- private static final int DEFAULT_LIMIT = 200;
- /**
- * spring mongodb 集成操作类
- */
- protected MongoTemplate mongoTemplate;
- @Override
- public List<T> find(Query query) {
- return mongoTemplate.find(query, this.getEntityClass());
- }
- @Override
- public T findOne(Query query) {
- return mongoTemplate.findOne(query, this.getEntityClass());
- }
- @Override
- public void update(Query query, Update update) {
- mongoTemplate.findAndModify(query, update, this.getEntityClass());
- }
- @Override
- public T save(T entity) {
- mongoTemplate.insert(entity);
- return entity;
- }
- @Override
- public T findById(String id) {
- return mongoTemplate.findById(id, this.getEntityClass());
- }
- @Override
- public T findById(String id, String collectionName) {
- return mongoTemplate.findById(id, this.getEntityClass(), collectionName);
- }
- @Override
- public Page<T> findPage(Page<T> page,Query query){
- long count = this.count(query);
- page.setTotal(count);
- int pageNumber = page.getPageNumber();
- int pageSize = page.getPageSize();
- query.skip((pageNumber - 1) * pageSize).limit(pageSize);
- List<T> rows = this.find(query);
- page.setRows(rows);
- return page;
- }
- @Override
- public long count(Query query){
- return mongoTemplate.count(query, this.getEntityClass());
- }
- /**
- * 获取需要操作的实体类class
- *
- * @return
- */
- private Class<T> getEntityClass(){
- return ReflectionUtils.getSuperClassGenricType(getClass());
- }
- /**
- * 注入mongodbTemplate
- *
- * @param mongoTemplate
- */
- protected abstract void setMongoTemplate(MongoTemplate mongoTemplate);
- }
介于很多童鞋都在问ReflectionUtils类,这里附上
- package com.yingchao.kgou.core;
- 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);
- }
- }
这样,就完成了spring和mongodb的集成,其实很简单的。测试话就直接调用相关方法就可以了。。。