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

你猜 阅读:177 2021-03-31 21:42:09 评论:0

一、简介

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

项目源码:待补充。


声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

发表评论
搜索
排行榜
关注我们

一个IT知识分享的公众号