spring集成mongodb

来源:互联网 发布:乐陵淘宝客服 编辑:程序博客网 时间:2024/06/16 21:56

spring-3.1.x以上的相关包(必须是3.1.x以上,否则集成之后运行会报错)

        spring-data-mongodb-1.3.0.M1.jar

        先看配置文件(spring-mongodb.xml)

[html] view plain copy
 print?
  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=    
  7.           "http://www.springframework.org/schema/context    
  8.           http://www.springframework.org/schema/context/spring-context-3.0.xsd    
  9.           http://www.springframework.org/schema/data/mongo    
  10.           http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd    
  11.           http://www.springframework.org/schema/beans    
  12.           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">    
  13.      
  14.   <mongo:db-factory id="mongoDbFactory"  
  15.                   host="${mongo.host}"  
  16.                   port="${mongo.port}"  
  17.                   dbname="${mongo.dbname}"  
  18.                   username="${mongo.username}"  
  19.                   password="${database.password}"/>    
  20.   <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">    
  21.     <constructor-arg name="mongoDbFactory" ref="mongoDbFactory"/>    
  22.     </bean>  
  23.  </beans>    

        其中:host为mongodb服务器地址,port为端口号,dbname为数据库名,username为mongodb用户名,password为mongodb密码,好了,全部配置就在这里。

        接下来就是CRUD封装类

[java] view plain copy
 print?
  1. package cn.sunsharp.alibaba.core.mongo;  
  2.   
  3. import java.util.List;  
  4.   
  5. import org.springframework.data.mongodb.core.query.Query;  
  6. import org.springframework.data.mongodb.core.query.Update;  
  7.   
  8. import cn.sunsharp.alibaba.core.Page;  
  9.   
  10. public interface BaseMongoDAO<T> {  
  11.   
  12.     /** 
  13.      * 通过条件查询实体(集合) 
  14.      *  
  15.      * @param query 
  16.      */  
  17.     public List<T> find(Query query) ;  
  18.   
  19.     /** 
  20.      * 通过一定的条件查询一个实体 
  21.      *  
  22.      * @param query 
  23.      * @return 
  24.      */  
  25.     public T findOne(Query query) ;  
  26.   
  27.     /** 
  28.      * 通过条件查询更新数据 
  29.      *  
  30.      * @param query 
  31.      * @param update 
  32.      * @return 
  33.      */  
  34.     public void update(Query query, Update update) ;  
  35.   
  36.     /** 
  37.      * 保存一个对象到mongodb 
  38.      *  
  39.      * @param entity 
  40.      * @return 
  41.      */  
  42.     public T save(T entity) ;  
  43.   
  44.     /** 
  45.      * 通过ID获取记录 
  46.      *  
  47.      * @param id 
  48.      * @return 
  49.      */  
  50.     public T findById(String id) ;  
  51.   
  52.     /** 
  53.      * 通过ID获取记录,并且指定了集合名(表的意思) 
  54.      *  
  55.      * @param id 
  56.      * @param collectionName 
  57.      *            集合名 
  58.      * @return 
  59.      */  
  60.     public T findById(String id, String collectionName) ;  
  61.       
  62.     /** 
  63.      * 分页查询 
  64.      * @param page 
  65.      * @param query 
  66.      * @return 
  67.      */  
  68.     public Page<T> findPage(Page<T> page,Query query);  
  69.       
  70.     /** 
  71.      * 求数据总和 
  72.      * @param query 
  73.      * @return 
  74.      */  
  75.     public long count(Query query);  
  76.       
  77. }  

实现:

[java] view plain copy
 print?
  1. package cn.sunsharp.alibaba.core.mongo.impl;  
  2.   
  3. import java.util.List;  
  4.   
  5. import org.springframework.data.mongodb.core.MongoTemplate;  
  6. import org.springframework.data.mongodb.core.query.Query;  
  7. import org.springframework.data.mongodb.core.query.Update;  
  8.   
  9. import cn.sunsharp.alibaba.core.Page;  
  10. import cn.sunsharp.alibaba.core.ReflectionUtils;  
  11. import cn.sunsharp.alibaba.core.mongo.BaseMongoDAO;  
  12.   
  13. public abstract class BaseMongoDAOImpl<T> implements BaseMongoDAO<T>{  
  14.   
  15.     private static final int DEFAULT_SKIP = 0;  
  16.     private static final int DEFAULT_LIMIT = 200;  
  17.       
  18.     /** 
  19.      * spring mongodb 集成操作类  
  20.      */  
  21.     protected MongoTemplate mongoTemplate;  
  22.   
  23.     @Override  
  24.     public List<T> find(Query query) {  
  25.         return mongoTemplate.find(query, this.getEntityClass());  
  26.     }  
  27.   
  28.     @Override  
  29.     public T findOne(Query query) {  
  30.         return mongoTemplate.findOne(query, this.getEntityClass());  
  31.     }  
  32.   
  33.     @Override  
  34.     public void update(Query query, Update update) {  
  35.         mongoTemplate.findAndModify(query, update, this.getEntityClass());  
  36.     }  
  37.   
  38.     @Override  
  39.     public T save(T entity) {  
  40.         mongoTemplate.insert(entity);  
  41.         return entity;  
  42.     }  
  43.   
  44.     @Override  
  45.     public T findById(String id) {  
  46.         return mongoTemplate.findById(id, this.getEntityClass());  
  47.     }  
  48.   
  49.     @Override  
  50.     public T findById(String id, String collectionName) {  
  51.         return mongoTemplate.findById(id, this.getEntityClass(), collectionName);  
  52.     }  
  53.       
  54.     @Override  
  55.     public Page<T> findPage(Page<T> page,Query query){  
  56.         long count = this.count(query);  
  57.         page.setTotal(count);  
  58.         int pageNumber = page.getPageNumber();  
  59.         int pageSize = page.getPageSize();  
  60.         query.skip((pageNumber - 1) * pageSize).limit(pageSize);  
  61.         List<T> rows = this.find(query);  
  62.         page.setRows(rows);  
  63.         return page;  
  64.     }  
  65.       
  66.     @Override  
  67.     public long count(Query query){  
  68.         return mongoTemplate.count(query, this.getEntityClass());  
  69.     }  
  70.       
  71.   
  72.     /** 
  73.      * 获取需要操作的实体类class 
  74.      *  
  75.      * @return 
  76.      */  
  77.     private Class<T> getEntityClass(){  
  78.         return ReflectionUtils.getSuperClassGenricType(getClass());  
  79.     }  
  80.   
  81.     /** 
  82.      * 注入mongodbTemplate 
  83.      *  
  84.      * @param mongoTemplate 
  85.      */  
  86.     protected abstract void setMongoTemplate(MongoTemplate mongoTemplate);  
  87.   
  88. }  

介于很多童鞋都在问ReflectionUtils类,这里附上

[java] view plain copy
 print?
  1. package com.yingchao.kgou.core;  
  2.   
  3. import java.lang.reflect.Field;  
  4. import java.lang.reflect.InvocationTargetException;  
  5. import java.lang.reflect.Method;  
  6. import java.lang.reflect.ParameterizedType;  
  7. import java.lang.reflect.Type;  
  8.   
  9. import org.apache.commons.lang.StringUtils;  
  10. import org.slf4j.Logger;  
  11. import org.slf4j.LoggerFactory;  
  12. import org.springframework.util.Assert;  
  13.   
  14. /** 
  15.  * 反射工具类. 
  16.  *  
  17.  * 提供访问私有变量,获取泛型类型Class, 提取集合中元素的属性, 转换字符串到对象等Util函数. 
  18.  *  
  19.  */  
  20. public class ReflectionUtils {  
  21.   
  22.     private static Logger logger = LoggerFactory.getLogger(ReflectionUtils.class);  
  23.   
  24.     /** 
  25.      * 调用Getter方法. 
  26.      */  
  27.     public static Object invokeGetterMethod(Object obj, String propertyName) {  
  28.         String getterMethodName = "get" + StringUtils.capitalize(propertyName);  
  29.         return invokeMethod(obj, getterMethodName, new Class[] {}, new Object[] {});  
  30.     }  
  31.   
  32.     /** 
  33.      * 调用Setter方法.使用value的Class来查找Setter方法. 
  34.      */  
  35.     public static void invokeSetterMethod(Object obj, String propertyName, Object value) {  
  36.         invokeSetterMethod(obj, propertyName, value, null);  
  37.     }  
  38.   
  39.     /** 
  40.      * 调用Setter方法. 
  41.      *  
  42.      * @param propertyType 用于查找Setter方法,为空时使用value的Class替代. 
  43.      */  
  44.     public static void invokeSetterMethod(Object obj, String propertyName, Object value, Class<?> propertyType) {  
  45.         Class<?> type = propertyType != null ? propertyType : value.getClass();  
  46.         String setterMethodName = "set" + StringUtils.capitalize(propertyName);  
  47.         invokeMethod(obj, setterMethodName, new Class[] { type }, new Object[] { value });  
  48.     }  
  49.   
  50.     /** 
  51.      * 直接读取对象属性值, 无视private/protected修饰符, 不经过getter函数. 
  52.      */  
  53.     public static Object getFieldValue(final Object obj, final String fieldName) {  
  54.         Field field = getAccessibleField(obj, fieldName);  
  55.   
  56.         if (field == null) {  
  57.             throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + obj + "]");  
  58.         }  
  59.   
  60.         Object result = null;  
  61.         try {  
  62.             result = field.get(obj);  
  63.         } catch (IllegalAccessException e) {  
  64.             logger.error("不可能抛出的异常{}", e.getMessage());  
  65.         }  
  66.         return result;  
  67.     }  
  68.   
  69.     /** 
  70.      * 直接设置对象属性值, 无视private/protected修饰符, 不经过setter函数. 
  71.      */  
  72.     public static void setFieldValue(final Object obj, final String fieldName, final Object value) {  
  73.         Field field = getAccessibleField(obj, fieldName);  
  74.   
  75.         if (field == null) {  
  76.             throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + obj + "]");  
  77.         }  
  78.   
  79.         try {  
  80.             field.set(obj, value);  
  81.         } catch (IllegalAccessException e) {  
  82.             logger.error("不可能抛出的异常:{}", e.getMessage());  
  83.         }  
  84.     }  
  85.   
  86.     /** 
  87.      * 循环向上转型, 获取对象的DeclaredField,   并强制设置为可访问. 
  88.      *  
  89.      * 如向上转型到Object仍无法找到, 返回null. 
  90.      */  
  91.     public static Field getAccessibleField(final Object obj, final String fieldName) {  
  92.         Assert.notNull(obj, "object不能为空");  
  93.         Assert.hasText(fieldName, "fieldName");  
  94.         for (Class<?> superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) {  
  95.             try {  
  96.                 Field field = superClass.getDeclaredField(fieldName);  
  97.                 field.setAccessible(true);  
  98.                 return field;  
  99.             } catch (NoSuchFieldException e) {//NOSONAR  
  100.                 // Field不在当前类定义,继续向上转型  
  101.             }  
  102.         }  
  103.         return null;  
  104.     }  
  105.   
  106.     /** 
  107.      * 直接调用对象方法, 无视private/protected修饰符. 
  108.      * 用于一次性调用的情况. 
  109.      */  
  110.     public static Object invokeMethod(final Object obj, final String methodName, final Class<?>[] parameterTypes,  
  111.             final Object[] args) {  
  112.         Method method = getAccessibleMethod(obj, methodName, parameterTypes);  
  113.         if (method == null) {  
  114.             throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + obj + "]");  
  115.         }  
  116.   
  117.         try {  
  118.             return method.invoke(obj, args);  
  119.         } catch (Exception e) {  
  120.             throw convertReflectionExceptionToUnchecked(e);  
  121.         }  
  122.     }  
  123.   
  124.     /** 
  125.      * 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问. 
  126.      * 如向上转型到Object仍无法找到, 返回null. 
  127.      *  
  128.      * 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args) 
  129.      */  
  130.     public static Method getAccessibleMethod(final Object obj, final String methodName,  
  131.             final Class<?>... parameterTypes) {  
  132.         Assert.notNull(obj, "object不能为空");  
  133.   
  134.         for (Class<?> superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) {  
  135.             try {  
  136.                 Method method = superClass.getDeclaredMethod(methodName, parameterTypes);  
  137.   
  138.                 method.setAccessible(true);  
  139.   
  140.                 return method;  
  141.   
  142.             } catch (NoSuchMethodException e) {//NOSONAR  
  143.                 // Method不在当前类定义,继续向上转型  
  144.             }  
  145.         }  
  146.         return null;  
  147.     }  
  148.   
  149.     /** 
  150.      * 通过反射, 获得Class定义中声明的父类的泛型参数的类型. 
  151.      * 如无法找到, 返回Object.class. 
  152.      * eg. 
  153.      * public UserDao extends HibernateDao<User> 
  154.      * 
  155.      * @param clazz The class to introspect 
  156.      * @return the first generic declaration, or Object.class if cannot be determined 
  157.      */  
  158.     @SuppressWarnings({ "unchecked""rawtypes" })  
  159.     public static <T> Class<T> getSuperClassGenricType(final Class clazz) {  
  160.         return getSuperClassGenricType(clazz, 0);  
  161.     }  
  162.   
  163.     /** 
  164.      * 通过反射, 获得Class定义中声明的父类的泛型参数的类型. 
  165.      * 如无法找到, 返回Object.class. 
  166.      *  
  167.      * 如public UserDao extends HibernateDao<User,Long> 
  168.      * 
  169.      * @param clazz clazz The class to introspect 
  170.      * @param index the Index of the generic ddeclaration,start from 0. 
  171.      * @return the index generic declaration, or Object.class if cannot be determined 
  172.      */  
  173.     @SuppressWarnings("rawtypes")  
  174.     public static Class getSuperClassGenricType(final Class clazz, final int index) {  
  175.   
  176.         Type genType = clazz.getGenericSuperclass();  
  177.   
  178.         if (!(genType instanceof ParameterizedType)) {  
  179.             logger.warn(clazz.getSimpleName() + "'s superclass not ParameterizedType");  
  180.             return Object.class;  
  181.         }  
  182.   
  183.         Type[] params = ((ParameterizedType) genType).getActualTypeArguments();  
  184.   
  185.         if (index >= params.length || index < 0) {  
  186.             logger.warn("Index: " + index + ", Size of " + clazz.getSimpleName() + "'s Parameterized Type: "  
  187.                     + params.length);  
  188.             return Object.class;  
  189.         }  
  190.         if (!(params[index] instanceof Class)) {  
  191.             logger.warn(clazz.getSimpleName() + " not set the actual class on superclass generic parameter");  
  192.             return Object.class;  
  193.         }  
  194.   
  195.         return (Class) params[index];  
  196.     }  
  197.   
  198.     /** 
  199.      * 将反射时的checked exception转换为unchecked exception. 
  200.      */  
  201.     public static RuntimeException convertReflectionExceptionToUnchecked(Exception e) {  
  202.         if (e instanceof IllegalAccessException || e instanceof IllegalArgumentException  
  203.                 || e instanceof NoSuchMethodException) {  
  204.             return new IllegalArgumentException("Reflection Exception.", e);  
  205.         } else if (e instanceof InvocationTargetException) {  
  206.             return new RuntimeException("Reflection Exception.", ((InvocationTargetException) e).getTargetException());  
  207.         } else if (e instanceof RuntimeException) {  
  208.             return (RuntimeException) e;  
  209.         }  
  210.         return new RuntimeException("Unexpected Checked Exception.", e);  
  211.     }  
  212. }  


这样,就完成了spring和mongodb的集成,其实很简单的。测试话就直接调用相关方法就可以了。。。
原创粉丝点击