Spring Data 与MongoDB 集成一:入门篇(开发环境搭建和简单CRUD)

一、简介

                      SpringData 项目提供与MongoDB文档数据库的集成。

二、SpringData 与MongoDB 配置及对应Jar包

1、安装mongodb 数据库,请查考:待补充
2、下载spring-data 关联两个子项目:spring-data-commons和spring-data-mongodb
我下载的jar 文件是:
spring-data-commons-1.7.2.RELEASE.jar
spring-data-mongodb-1.4.2.RELEASE.jar
3、下载mongodb的驱动包.
我下载的jar 文件是:
mongo-java-driver-3.0.4.jar
4、测试mongodb 数据库是否能够连接:两种方式(java代码方式和mongodb 工具方式(Robomongo 0.9.0-RC10))
      
java代码连接方式:
package com.spring.main;

import java.util.Set;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.mongodb.DB;
import com.mongodb.Mongo;

@RunWith(SpringJUnit4ClassRunner.class)  //使用junit4进行测试    
@ContextConfiguration(locations={"classpath*:mongodb.xml"})  
public class MongodbConnection {

	@Test
	public void connection(){
		try{     
            // 连接到 mongodb 服务  
             Mongo mongo = new Mongo("192.168.1.88", 27017);    
            //根据mongodb数据库的名称获取mongodb对象 ,  
             DB db = mongo.getDB( "database" );  
             Set<String> collectionNames = db.getCollectionNames();    
               // 打印出test中的集合    
              for (String name : collectionNames) {    
                    System.out.println("collectionName==="+name);    
              }    
               
          }catch(Exception e){  
             e.printStackTrace();  
          }  
	}

}

测试结果:


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.1.xsd
http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo-1.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
	<!-- Default bean name is 'mongo' -->
	<mongo:mongo host="192.168.1.88" port="27017" />
	<mongo:db-factory dbname="database" mongo-ref="mongo" />
	
	<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
		<constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />		
	</bean>
	
	<bean id="businessDao" class="com.spring.operation.BusinessDao"></bean>
	<bean id="businessPositionDao" class="com.spring.operation.BusinessPositionDao"></bean>
	<bean id="mongoDaoImpl" class="com.spring.operation.MongoDaoImpl"></bean>
</beans>

Robomongo 0.9.0-RC10连接特定mongodb 数据库



三、SpringData 实现Mongodb CRUD简单封装:

1、实现一个基础接口,是比较通用的BaseMongoDao.java类
package com.spring.mongodb;

import java.util.List;
import org.springframework.data.mongodb.core.query.Query;  
import org.springframework.data.mongodb.core.query.Update;  
import com.mongodb.WriteResult;  
  
public interface BaseMongoDao<T> {  
    /** 
     * 插入 
     */  
    public T save(T entity);  
  
    /** 
     * 根据ID查询 
     */  
    public T findById(String id);  
  
    /** 
     * 通过ID获取记录,并且指定了集合名(表的意思) 
     */  
    public T findById(String id, String collectionName);  
  
    /** 
     * 获得所有该类型记录 
     */  
    public List<T> findAll();  
  
    /** 
     * 获得所有该类型记录,并且指定了集合名(表的意思) 
     */  
    public List<T> findAll(String collectionName);  
  
    /** 
     * 根据条件查询 
     */  
    public List<T> find(Query query);  
  
    /** 
     * 根据条件查询一个 
     */  
    public T findOne(Query query);  
  
    /** 
     * 分页查询 
     */  
    public Page<T> findPage(Page<T> page, Query query);  
  
    /** 
     * 根据条件 获得总数 
     */  
    public long count(Query query);  
  
    /** 
     * 根据条件 更新 
     */  
    public WriteResult update(Query query, Update update);  
  
    /** 
     * 更新符合条件并sort之后的第一个文档 并返回更新后的文档 
     */  
    public T updateOne(Query query, Update update);  
  
    /** 
     * 根据传入实体ID更新 
     */  
    public WriteResult update(T entity);  
  
    /** 
     * 根据条件 删除 
     *  
     * @param query 
     */  
    public void remove(Query query);  
}  

2、编写基础通用类BaseMongoDaoImpl ,继承BaseMongoDao

package com.spring.mongodb;

import java.lang.reflect.Field;  
import java.util.List;  
import javax.annotation.Resource;    
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 com.mongodb.WriteResult;  

public class BaseMongoDaoImpl<T> implements BaseMongoDao<T> {

	/** 
     * spring mongodb 集成操作类  
     */  
    @Resource  
    protected MongoTemplate mongoTemplate;  
  
    /** 
     * 注入mongodbTemplate 
     *  
     * @param mongoTemplate 
     */  
    protected void setMongoTemplate(MongoTemplate mongoTemplate) {  
        this.mongoTemplate = mongoTemplate;  
    }  
    public T save(T entity) {  
        mongoTemplate.insert(entity);  
        return entity;  
    }  
  
    public T findById(String id) {  
        return mongoTemplate.findById(id, this.getEntityClass());  
    }  
  
    public T findById(String id, String collectionName) {  
        return mongoTemplate.findById(id, this.getEntityClass(), collectionName);  
    }  
  
    public List<T> findAll() {  
        return mongoTemplate.findAll(this.getEntityClass());  
    }  
  
    public List<T> findAll(String collectionName) {  
        return mongoTemplate.findAll(this.getEntityClass(), collectionName);  
    }  
  
    public List<T> find(Query query) {  
        return mongoTemplate.find(query, this.getEntityClass());  
    }  
  
    public T findOne(Query query) {  
        return mongoTemplate.findOne(query, this.getEntityClass());  
    }  
  
    public Page<T> findPage(Page<T> page, Query query) {  
        //如果没有条件 则所有全部  
        query=query==null?new Query(Criteria.where("_id").exists(true)):query;  
        long count = this.count(query);  
        // 总数  
        page.setTotalCount((int) count);  
        int currentPage = page.getCurrentPage();  
        int pageSize = page.getPageSize();  
        query.skip((currentPage - 1) * pageSize).limit(pageSize);  
        List<T> rows = this.find(query);  
        page.build(rows);  
        return page;  
    }  
  
    public long count(Query query) {  
        return mongoTemplate.count(query, this.getEntityClass());  
    }  
  
    public WriteResult update(Query query, Update update) {  
        if (update==null) {  
            return null;  
        }  
        return mongoTemplate.updateMulti(query, update, this.getEntityClass());  
    }  
  
    public T updateOne(Query query, Update update) {  
        if (update==null) {  
            return null;  
        }  
        return mongoTemplate.findAndModify(query, update, this.getEntityClass());  
    }  
    
    public WriteResult update(T entity) {  
        Field[] fields = this.getEntityClass().getDeclaredFields();  
        if (fields == null || fields.length <= 0) {  
            return null;  
        }  
        Field idField = null;  
        // 查找ID的field  
        for (Field field : fields) {  
            if (field.getName() != null  
                    && "id".equals(field.getName().toLowerCase())) {  
                idField = field;  
                break;  
            }  
        }  
        if (idField == null) {  
            return null;  
        }  
        idField.setAccessible(true);  
        String id=null;  
        try {  
            id = (String) idField.get(entity);  
        } catch (IllegalArgumentException e) {  
            e.printStackTrace();  
        } catch (IllegalAccessException e) {  
            e.printStackTrace();  
        }  
        if (id == null || "".equals(id.trim()))  
            return null;  
        // 根据ID更新  
        Query query = new Query(Criteria.where("_id").is(id));  
        // 更新  
        // Update update = new Update();  
        // for (Field field : fields) {  
        // // 不为空 不是主键 不是序列化号  
        // if (field != null  
        // && field != idField  
        // && !"serialversionuid"  
        // .equals(field.getName().toLowerCase())) {  
        // field.setAccessible(true);  
        // Object obj = field.get(entity);  
        // if (obj == null)  
        // continue;  
        // update.set(field.getName(), obj);  
        // }  
        // }  
        Update update = ReflectionUtils.getUpdateObj(entity);  
        if (update == null) {  
            return null;  
        }  
        return mongoTemplate.updateFirst(query, update, getEntityClass());  
    }  
  
    public void remove(Query query) {  
        mongoTemplate.remove(query, this.getEntityClass());  
    }  
    /** 
     * 获得泛型类 
     */  
    private Class<T> getEntityClass() {        
        return ReflectionUtils.getSuperClassGenricType(getClass());  
    }  
  
}  



3、编写需要存储的实例类Business.java
package com.spring.entity;

import java.io.Serializable;

public class Business implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	//维度
	private double lat;
	//经度
	private double lng;
	//商家编号
	private int openid;
	
	//默认构造函数
	public Business() {
		super();
	}
	//set和get 
	public double getLat() {
		return lat;
	}
	public void setLat(double lat) {
		this.lat = lat;
	}
	public double getLng() {
		return lng;
	}
	public void setLng(double lng) {
		this.lng = lng;
	}
	public int getOpenid() {
		return openid;
	}
	public void setOpenid(int openid) {
		this.openid = openid;
	}

	
	



}

4、编写BuinessDao 类文件,继承BaseMongoDaoImpl<T>,实现对Buiness的CRUD操作。
package com.spring.operation;

import com.spring.entity.Business;
import com.spring.mongodb.BaseMongoDaoImpl;

public class BusinessDao extends BaseMongoDaoImpl<Business> {

}


5、实例测试
package com.spring.main;

import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
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.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.spring.entity.Business;
import com.spring.mongodb.Page;
import com.spring.operation.BusinessDao;


@RunWith(SpringJUnit4ClassRunner.class)  //使用junit4进行测试    
@ContextConfiguration(locations={"classpath*:mongodb.xml"})   
public class MongodbMain {
	@Autowired 
	private BusinessDao businessDao;
	
     //测试数据插入
	 @Test  
	 public void test1(){  
		 Business business =new Business();
		 business.setLat(22.588402);
		 business.setLng(113.867822); 
		 business.setOpenid(5);		 
		 businessDao.save(business);
		 System.out.println("数据插入成功");
	 } 
	//测试数据获取(id)
	@Test
	public void test2(){
		Business business = businessDao.findById("582174af6e6407195c0cd10a");
		System.out.println("商家编号:"+business.getOpenid());
		System.out.println("经度:"+business.getLat());
		System.out.println("维度:"+business.getLng());
		
	}
	
	//测试数据获取(id,collectionName)
	@Test
	public void test3(){
		Business business = businessDao.findById("582175986e64071f888bee69","business");
		System.out.println("商家编号:"+business.getOpenid());
		System.out.println("经度:"+business.getLat());
		System.out.println("维度:"+business.getLng());
		
	}
	
	//测试数据获取(all)
	@Test
	public void test4(){
		List<Business> list = businessDao.findAll();
		if(list !=null && list.size()>0){
			for(Business business : list){
				System.out.println("商家编号:"+business.getOpenid());
				System.out.println("经度:"+business.getLat());
				System.out.println("维度:"+business.getLng());
			}
		}		
	}
	
	//测试数据获取(collectionName)
	@Test
	public void test5(){
		List<Business> list = businessDao.findAll("business");
		if(list !=null && list.size()>0){
			for(Business business : list){
				System.out.println("商家编号:"+business.getOpenid());
				System.out.println("经度:"+business.getLat());
				System.out.println("维度:"+business.getLng());
			}
		}		
	}
	
	//测试数据获取(query);   注意请求参数属性与实体对象属性一一对应。
	@Test
	public void test6(){
		Query query = new Query(Criteria.where("lng").is(114.038804).and("lat").is(22.669214).and("openid").is(2));
		List<Business> list = businessDao.find(query);
		if(list !=null && list.size()>0){
			for(Business business : list){
				System.out.println("商家编号:"+business.getOpenid());
				System.out.println("经度:"+business.getLat());
				System.out.println("维度:"+business.getLng());
			}
		}		
	}
	
	//测试数据获取(query);   注意请求参数属性与实体对象属性一一对应。
	@Test
	public void test7(){
		Query query = new Query(Criteria.where("lng").is(114.038804).and("lat").is(22.669214).and("openid").is(2));
		Business business = businessDao.findOne(query);
		if(business !=null){			
				System.out.println("商家编号:"+business.getOpenid());
				System.out.println("经度:"+business.getLat());
				System.out.println("维度:"+business.getLng());			
		}		
	}
	
	//测试数据获取(page);
	@Test
	public void test8(){
		Query query = new Query();
		Page<Business> page = new Page<Business>();
//		page.setPageSize(2); //设置分页记录数
//		page.setCurrentPage(3);	//设置当前页面	
		Page<Business> pages = businessDao.findPage(page, query);
		List<Business> list = pages.getRows();
		if(list !=null && list.size()>0){
			for(Business business :list){
				System.out.println("商家编号:"+business.getOpenid());
				System.out.println("经度:"+business.getLat());
				System.out.println("维度:"+business.getLng());			
		}		
	}
}
	
	//测试数据获取(total)
	@Test
	public void test9(){
		Query query = new Query();	
		long num = businessDao.count(query);
		System.out.println("记录总数:"+num);		
	}
	
	//测试数据修改(update)  注意:修改返回的实体对象是之前存储的数据信息
	@Test
	public void test10(){
		Query query = new Query(Criteria.where("openid").is(2));	
		Update  update =new Update();
		update.set("lng", 110.649865);
		Business business = businessDao.updateOne(query, update);
		if(business !=null){			
			System.out.println("商家编号:"+business.getOpenid());
			System.out.println("经度:"+business.getLat());
			System.out.println("维度:"+business.getLng());			
			}	
	}
	
	
	
	
	
	

		
	

}

6、相关工具类封装(Page.java[java分页工具类])和(ReflectionUtils(反射工具类))
package com.spring.mongodb;

import java.io.Serializable;  
import java.util.List;    
  
public class Page<T> implements Serializable {  
    private static final long serialVersionUID = 5760097915453738435L;  
    public static final int DEFAULT_PAGE_SIZE = 10;  
    /** 
     * 每页显示个数 
     */  
    private int pageSize;  
    /** 
     * 当前页数 
     */  
    private int currentPage;  
    /** 
     * 总页数 
     */  
    private int totalPage;  
    /** 
     * 总记录数 
     */  
    private int totalCount;  
    /** 
     * 结果列表 
     */  
    private List<T> rows;  
      
    public Page(){  
         this.currentPage = 1;  
         this.pageSize = DEFAULT_PAGE_SIZE;  
    }  
    public Page(int currentPage,int pageSize){  
        this.currentPage=currentPage<=0?1:currentPage;  
        this.pageSize=pageSize<=0?1:pageSize;  
    }  
    public int getPageSize() {  
        return pageSize;  
    }  
    public void setPageSize(int pageSize) {  
        this.pageSize = pageSize;  
    }  
    public int getCurrentPage() {  
        return currentPage;  
    }  
    public void setCurrentPage(int currentPage) {  
        this.currentPage = currentPage;  
    }  
    public int getTotalPage() {  
        return totalPage;  
    }  
    public void setTotalPage(int totalPage) {  
        this.totalPage = totalPage;  
    }  
    public int getTotalCount() {  
        return totalCount;  
    }  
    public void setTotalCount(int totalCount) {  
        this.totalCount = totalCount;  
    }  
  
    /** 
     * 设置结果 及总页数 
     * @param list 
     */  
     public void build(List<T> rows) {    
            this.setRows(rows);    
            int count =  this.getTotalCount();    
            int divisor = count / this.getPageSize();    
            int remainder = count % this.getPageSize();    
            this.setTotalPage(remainder == 0 ? divisor == 0 ? 1 : divisor : divisor + 1);    
        }  
    public List<T> getRows() {  
        return rows;  
    }  
    public void setRows(List<T> rows) {  
        this.rows = rows;  
    }    
}  


package com.spring.mongodb;

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 java.util.HashMap;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
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.util.Assert;
import org.springframework.util.StringUtils;

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

	/**
	 * 根据对象获得mongodb Update语句 除id字段以外,所有被赋值的字段都会成为修改项
	 */
	public static Update getUpdateObj(final Object obj) {
		if (obj == null)
			return null;
		Field[] fields = obj.getClass().getDeclaredFields();
		Update update = null;
		boolean isFirst = true;
		for (Field field : fields) {
			field.setAccessible(true);
			try {
				Object value = field.get(obj);
				if (value != null) {
					if ("id".equals(field.getName().toLowerCase())
							|| "serialversionuid".equals(field.getName()
									.toLowerCase()))
						continue;
					if (isFirst) {
						update = Update.update(field.getName(), value);
						isFirst = false;
					} else {
						update = update.set(field.getName(), value);
					}
				}

			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		}
		return update;
	}

	/**
	 * 根据对象获得mongodb Query语句
	 * 
	 * 1.时间范围查询:在时间字段前增加begin或end,为这两个字段分别赋值 例:private Date createDate; 开始时间
	 * private Date beginCreateDate; 结束时间 private Date endCreateDate;
	 * 分析后结果:where createDate >= beginCreateDate and createDate <
	 * beginCreateDate
	 * 
	 * 2.排序 定义并赋值VO中 orderBy 字段,以英文“,”分割多个排序,以空格分隔排序方向 asc可不写 例:private String
	 * orderBy; orderBy="createDate desc,sendDate asc,id" 分析结构:order by
	 * createDate desc,sendDate asc,id asc
	 * 
	 * 3.固定值搜索 定义并赋值VO中的任意字段,搜索时会把以赋值的字段当作为搜索条件
	 */

	public static Query getQueryObj(final Object obj) {
		if (obj == null)
			return null;
		Field[] fields = obj.getClass().getDeclaredFields();
		// Sort sort=new Sort(new Order(Direction.DESC,"createDate"));
		Query query = new Query();
		// 存放日期范围或者确定日期
		Map<String, Criteria> dateMap = new HashMap<String, Criteria>();
		String sortStr = null;
		for (Field field : fields) {
			field.setAccessible(true);
			try {
				Object value = field.get(obj);
				if (value != null) {
					if ("serialversionuid"
							.equals(field.getName().toLowerCase())) {
						continue;
					}
					if ("orderby".equals(field.getName().toLowerCase())) {
						sortStr = String.valueOf(value);
						continue;
					}
					if (field.getType().getSimpleName().equals("Date")) {
						if (field.getName().toLowerCase().startsWith("begin")) {
							String beginName = field.getName().substring(5);
							if (beginName.isEmpty()) {
								dateMap.put("begin", Criteria.where("begin")
										.is(value));
							} else {
//								beginName = StringUtil
//										.toLowerCaseFirstOne(beginName);
								Criteria criteria = dateMap.get(beginName) == null ? Criteria
										.where(beginName).gte(value) : dateMap
										.get(beginName).gte(value);
								dateMap.put(beginName, criteria);
							}
							continue;
						}
						if (field.getName().toLowerCase().startsWith("end")) {
							String endName = field.getName().substring(3);
							if (endName.isEmpty()) {
								dateMap.put("end",
										Criteria.where("end").is(value));
							} else {
//								endName = StringUtil
//										.toLowerCaseFirstOne(endName);
								Criteria criteria = dateMap.get(endName) == null ? Criteria
										.where(endName).lt(value) : dateMap
										.get(endName).lt(value);
								dateMap.put(endName, criteria);
							}
							continue;
						}
						dateMap.put(field.getName(),
								Criteria.where(field.getName()).is(value));
						continue;
					}
					query.addCriteria(Criteria.where(field.getName()).is(value));
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		// 日期类型查询条件
		for (String key : dateMap.keySet()) {
			if (dateMap.get(key) != null) {
				query.addCriteria(dateMap.get(key));
			}
		}
		// 排序
		if (sortStr != null && !sortStr.trim().isEmpty()) {
			Sort sort = null;
			String[] strs = sortStr.split(",");
			for (String str : strs) {
				str = str.trim();
				if (str.isEmpty()) {
					continue;
				}
				int i = str.indexOf(" ");
				if (i < 0) {
					if (sort == null) {
						sort = new Sort(Direction.ASC, str);
					} else {
						sort = sort.and(new Sort(Direction.ASC, str));
					}
				} else {
					String name = str.substring(0, i);
					String dire = str.substring(i + 1).trim();
					Sort sn = null;
					if ("desc".equals(dire.toLowerCase())) {
						sn = new Sort(Direction.DESC, name);
					} else {
						sn = new Sort(Direction.ASC, name);
					}
					if (sort == null) {
						sort = sn;
					} else {
						sort = sort.and(sn);
					}
				}
			}
			if (sort != null) {
				query.with(sort);
			}
		}
		return query;
	}

}

项目源码:待补充。


  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值