一、简介

                      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代码连接方式:
[html] view plain copy
  1. package com.spring.main;  
  2.   
  3. import java.util.Set;  
  4. import org.junit.Test;  
  5. import org.junit.runner.RunWith;  
  6. import org.springframework.test.context.ContextConfiguration;  
  7. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;  
  8. import com.mongodb.DB;  
  9. import com.mongodb.Mongo;  
  10.   
  11. @RunWith(SpringJUnit4ClassRunner.class)  //使用junit4进行测试      
  12. @ContextConfiguration(locations={"classpath*:mongodb.xml"})    
  13. public class MongodbConnection {  
  14.   
  15.     @Test  
  16.     public void connection(){  
  17.         try{       
  18.             // 连接到 mongodb 服务    
  19.              Mongo mongo = new Mongo("192.168.1.88", 27017);      
  20.             //根据mongodb数据库的名称获取mongodb对象 ,    
  21.              DB db = mongo.getDB( "database" );    
  22.              Set<String> collectionNames = db.getCollectionNames();      
  23.                // 打印出test中的集合      
  24.               for (String name : collectionNames) {      
  25.                     System.out.println("collectionName==="+name);      
  26.               }      
  27.                  
  28.           }catch(Exception e){    
  29.              e.printStackTrace();    
  30.           }    
  31.     }  
  32.   
  33. }  

测试结果:

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

mongodb.xml 配置文件:

[html] view plain copy
  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" xmlns:context="http://www.springframework.org/schema/context"  
  4.     xmlns:mongo="http://www.springframework.org/schema/data/mongo"  
  5.     xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd  
  6. http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo-1.1.xsd  
  7. http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">  
  8.     <!-- Default bean name is 'mongo' -->  
  9.     <mongo:mongo host="192.168.1.88" port="27017" />  
  10.     <mongo:db-factory dbname="database" mongo-ref="mongo" />  
  11.       
  12.     <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">  
  13.         <constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />          
  14.     </bean>  
  15.       
  16.     <bean id="businessDao" class="com.spring.operation.BusinessDao"></bean>  
  17.     <bean id="businessPositionDao" class="com.spring.operation.BusinessPositionDao"></bean>  
  18.     <bean id="mongoDaoImpl" class="com.spring.operation.MongoDaoImpl"></bean>  
  19. </beans>  

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

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


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

1、实现一个基础接口,是比较通用的BaseMongoDao.java类
[html] view plain copy
  1. package com.spring.mongodb;  
  2.   
  3. import java.util.List;  
  4. import org.springframework.data.mongodb.core.query.Query;    
  5. import org.springframework.data.mongodb.core.query.Update;    
  6. import com.mongodb.WriteResult;    
  7.     
  8. public interface BaseMongoDao<T> {    
  9.     /**   
  10.      * 插入   
  11.      */    
  12.     public T save(T entity);    
  13.     
  14.     /**   
  15.      * 根据ID查询   
  16.      */    
  17.     public T findById(String id);    
  18.     
  19.     /**   
  20.      * 通过ID获取记录,并且指定了集合名(表的意思)   
  21.      */    
  22.     public T findById(String id, String collectionName);    
  23.     
  24.     /**   
  25.      * 获得所有该类型记录   
  26.      */    
  27.     public List<T> findAll();    
  28.     
  29.     /**   
  30.      * 获得所有该类型记录,并且指定了集合名(表的意思)   
  31.      */    
  32.     public List<T> findAll(String collectionName);    
  33.     
  34.     /**   
  35.      * 根据条件查询   
  36.      */    
  37.     public List<T> find(Query query);    
  38.     
  39.     /**   
  40.      * 根据条件查询一个   
  41.      */    
  42.     public T findOne(Query query);    
  43.     
  44.     /**   
  45.      * 分页查询   
  46.      */    
  47.     public Page<T> findPage(Page<T> page, Query query);    
  48.     
  49.     /**   
  50.      * 根据条件 获得总数   
  51.      */    
  52.     public long count(Query query);    
  53.     
  54.     /**   
  55.      * 根据条件 更新   
  56.      */    
  57.     public WriteResult update(Query query, Update update);    
  58.     
  59.     /**   
  60.      * 更新符合条件并sort之后的第一个文档 并返回更新后的文档   
  61.      */    
  62.     public T updateOne(Query query, Update update);    
  63.     
  64.     /**   
  65.      * 根据传入实体ID更新   
  66.      */    
  67.     public WriteResult update(T entity);    
  68.     
  69.     /**   
  70.      * 根据条件 删除   
  71.      *    
  72.      * @param query   
  73.      */    
  74.     public void remove(Query query);    
  75. }    

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

[html] view plain copy
  1. package com.spring.mongodb;  
  2.   
  3. import java.lang.reflect.Field;    
  4. import java.util.List;    
  5. import javax.annotation.Resource;      
  6. import org.springframework.data.mongodb.core.MongoTemplate;    
  7. import org.springframework.data.mongodb.core.query.Criteria;    
  8. import org.springframework.data.mongodb.core.query.Query;    
  9. import org.springframework.data.mongodb.core.query.Update;      
  10. import com.mongodb.WriteResult;    
  11.   
  12. public class BaseMongoDaoImpl<T> implements BaseMongoDao<T> {  
  13.   
  14.     /**   
  15.      * spring mongodb 集成操作类    
  16.      */    
  17.     @Resource    
  18.     protected MongoTemplate mongoTemplate;    
  19.     
  20.     /**   
  21.      * 注入mongodbTemplate   
  22.      *    
  23.      * @param mongoTemplate   
  24.      */    
  25.     protected void setMongoTemplate(MongoTemplate mongoTemplate) {    
  26.         this.mongoTemplate = mongoTemplate;    
  27.     }    
  28.     public T save(T entity) {    
  29.         mongoTemplate.insert(entity);    
  30.         return entity;    
  31.     }    
  32.     
  33.     public T findById(String id) {    
  34.         return mongoTemplate.findById(id, this.getEntityClass());    
  35.     }    
  36.     
  37.     public T findById(String id, String collectionName) {    
  38.         return mongoTemplate.findById(id, this.getEntityClass(), collectionName);    
  39.     }    
  40.     
  41.     public List<T> findAll() {    
  42.         return mongoTemplate.findAll(this.getEntityClass());    
  43.     }    
  44.     
  45.     public List<T> findAll(String collectionName) {    
  46.         return mongoTemplate.findAll(this.getEntityClass(), collectionName);    
  47.     }    
  48.     
  49.     public List<T> find(Query query) {    
  50.         return mongoTemplate.find(query, this.getEntityClass());    
  51.     }    
  52.     
  53.     public T findOne(Query query) {    
  54.         return mongoTemplate.findOne(query, this.getEntityClass());    
  55.     }    
  56.     
  57.     public Page<T> findPage(Page<T> page, Query query) {    
  58.         //如果没有条件 则所有全部    
  59.         query=query==null?new Query(Criteria.where("_id").exists(true)):query;    
  60.         long count = this.count(query);    
  61.         // 总数    
  62.         page.setTotalCount((int) count);    
  63.         int currentPage = page.getCurrentPage();    
  64.         int pageSize = page.getPageSize();    
  65.         query.skip((currentPage - 1) * pageSize).limit(pageSize);    
  66.         List<T> rows = this.find(query);    
  67.         page.build(rows);    
  68.         return page;    
  69.     }    
  70.     
  71.     public long count(Query query) {    
  72.         return mongoTemplate.count(query, this.getEntityClass());    
  73.     }    
  74.     
  75.     public WriteResult update(Query query, Update update) {    
  76.         if (update==null) {    
  77.             return null;    
  78.         }    
  79.         return mongoTemplate.updateMulti(query, update, this.getEntityClass());    
  80.     }    
  81.     
  82.     public T updateOne(Query query, Update update) {    
  83.         if (update==null) {    
  84.             return null;    
  85.         }    
  86.         return mongoTemplate.findAndModify(query, update, this.getEntityClass());    
  87.     }    
  88.       
  89.     public WriteResult update(T entity) {    
  90.         Field[] fields = this.getEntityClass().getDeclaredFields();    
  91.         if (fields == null || fields.length <= 0) {    
  92.             return null;    
  93.         }    
  94.         Field idField = null;    
  95.         // 查找ID的field    
  96.         for (Field field : fields) {    
  97.             if (field.getName() != null    
  98.                     && "id".equals(field.getName().toLowerCase())) {    
  99.                 idField = field;    
  100.                 break;    
  101.             }    
  102.         }    
  103.         if (idField == null) {    
  104.             return null;    
  105.         }    
  106.         idField.setAccessible(true);    
  107.         String id=null;    
  108.         try {    
  109.             id = (String) idField.get(entity);    
  110.         } catch (IllegalArgumentException e) {    
  111.             e.printStackTrace();    
  112.         } catch (IllegalAccessException e) {    
  113.             e.printStackTrace();    
  114.         }    
  115.         if (id == null || "".equals(id.trim()))    
  116.             return null;    
  117.         // 根据ID更新    
  118.         Query query = new Query(Criteria.where("_id").is(id));    
  119.         // 更新    
  120.         // Update update = new Update();    
  121.         // for (Field field : fields) {    
  122.         // // 不为空 不是主键 不是序列化号    
  123.         // if (field != null    
  124.         // && field != idField    
  125.         // && !"serialversionuid"    
  126.         // .equals(field.getName().toLowerCase())) {    
  127.         // field.setAccessible(true);    
  128.         // Object obj = field.get(entity);    
  129.         // if (obj == null)    
  130.         // continue;    
  131.         // update.set(field.getName(), obj);    
  132.         // }    
  133.         // }    
  134.         Update update = ReflectionUtils.getUpdateObj(entity);    
  135.         if (update == null) {    
  136.             return null;    
  137.         }    
  138.         return mongoTemplate.updateFirst(query, update, getEntityClass());    
  139.     }    
  140.     
  141.     public void remove(Query query) {    
  142.         mongoTemplate.remove(query, this.getEntityClass());    
  143.     }    
  144.     /**   
  145.      * 获得泛型类   
  146.      */    
  147.     private Class<T> getEntityClass() {          
  148.         return ReflectionUtils.getSuperClassGenricType(getClass());    
  149.     }    
  150.     
  151. }    

3、编写需要存储的实例类Business.java
[html] view plain copy
  1. package com.spring.entity;  
  2.   
  3. import java.io.Serializable;  
  4.   
  5. public class Business implements Serializable {  
  6.   
  7.     /**  
  8.      *   
  9.      */  
  10.     private static final long serialVersionUID = 1L;  
  11.     //维度  
  12.     private double lat;  
  13.     //经度  
  14.     private double lng;  
  15.     //商家编号  
  16.     private int openid;  
  17.       
  18.     //默认构造函数  
  19.     public Business() {  
  20.         super();  
  21.     }  
  22.     //set和get   
  23.     public double getLat() {  
  24.         return lat;  
  25.     }  
  26.     public void setLat(double lat) {  
  27.         this.lat = lat;  
  28.     }  
  29.     public double getLng() {  
  30.         return lng;  
  31.     }  
  32.     public void setLng(double lng) {  
  33.         this.lng = lng;  
  34.     }  
  35.     public int getOpenid() {  
  36.         return openid;  
  37.     }  
  38.     public void setOpenid(int openid) {  
  39.         this.openid = openid;  
  40.     }  
  41.   
  42.       
  43.       
  44.   
  45.   
  46.   
  47. }  

4、编写BuinessDao 类文件,继承BaseMongoDaoImpl<T>,实现对Buiness的CRUD操作。
[html] view plain copy
  1. package com.spring.operation;  
  2.   
  3. import com.spring.entity.Business;  
  4. import com.spring.mongodb.BaseMongoDaoImpl;  
  5.   
  6. public class BusinessDao extends BaseMongoDaoImpl<Business> {  
  7.   
  8. }  


5、实例测试
[html] view plain copy
  1. package com.spring.main;  
  2.   
  3. import java.util.List;  
  4. import org.junit.Test;  
  5. import org.junit.runner.RunWith;  
  6. import org.springframework.beans.factory.annotation.Autowired;  
  7. import org.springframework.data.mongodb.core.query.Criteria;  
  8. import org.springframework.data.mongodb.core.query.Query;  
  9. import org.springframework.data.mongodb.core.query.Update;  
  10. import org.springframework.test.context.ContextConfiguration;  
  11. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;  
  12. import com.spring.entity.Business;  
  13. import com.spring.mongodb.Page;  
  14. import com.spring.operation.BusinessDao;  
  15.   
  16.   
  17. @RunWith(SpringJUnit4ClassRunner.class)  //使用junit4进行测试      
  18. @ContextConfiguration(locations={"classpath*:mongodb.xml"})     
  19. public class MongodbMain {  
  20.     @Autowired   
  21.     private BusinessDao businessDao;  
  22.       
  23.      //测试数据插入  
  24.      @Test    
  25.      public void test1(){    
  26.          Business business =new Business();  
  27.          business.setLat(22.588402);  
  28.          business.setLng(113.867822);   
  29.          business.setOpenid(5);        
  30.          businessDao.save(business);  
  31.          System.out.println("数据插入成功");  
  32.      }   
  33.     //测试数据获取(id)  
  34.     @Test  
  35.     public void test2(){  
  36.         Business business = businessDao.findById("582174af6e6407195c0cd10a");  
  37.         System.out.println("商家编号:"+business.getOpenid());  
  38.         System.out.println("经度:"+business.getLat());  
  39.         System.out.println("维度:"+business.getLng());  
  40.           
  41.     }  
  42.       
  43.     //测试数据获取(id,collectionName)  
  44.     @Test  
  45.     public void test3(){  
  46.         Business business = businessDao.findById("582175986e64071f888bee69","business");  
  47.         System.out.println("商家编号:"+business.getOpenid());  
  48.         System.out.println("经度:"+business.getLat());  
  49.         System.out.println("维度:"+business.getLng());  
  50.           
  51.     }  
  52.       
  53.     //测试数据获取(all)  
  54.     @Test  
  55.     public void test4(){  
  56.         List<Business> list = businessDao.findAll();  
  57.         if(list !=null && list.size()>0){  
  58.             for(Business business : list){  
  59.                 System.out.println("商家编号:"+business.getOpenid());  
  60.                 System.out.println("经度:"+business.getLat());  
  61.                 System.out.println("维度:"+business.getLng());  
  62.             }  
  63.         }         
  64.     }  
  65.       
  66.     //测试数据获取(collectionName)  
  67.     @Test  
  68.     public void test5(){  
  69.         List<Business> list = businessDao.findAll("business");  
  70.         if(list !=null && list.size()>0){  
  71.             for(Business business : list){  
  72.                 System.out.println("商家编号:"+business.getOpenid());  
  73.                 System.out.println("经度:"+business.getLat());  
  74.                 System.out.println("维度:"+business.getLng());  
  75.             }  
  76.         }         
  77.     }  
  78.       
  79.     //测试数据获取(query);   注意请求参数属性与实体对象属性一一对应。  
  80.     @Test  
  81.     public void test6(){  
  82.         Query query = new Query(Criteria.where("lng").is(114.038804).and("lat").is(22.669214).and("openid").is(2));  
  83.         List<Business> list = businessDao.find(query);  
  84.         if(list !=null && list.size()>0){  
  85.             for(Business business : list){  
  86.                 System.out.println("商家编号:"+business.getOpenid());  
  87.                 System.out.println("经度:"+business.getLat());  
  88.                 System.out.println("维度:"+business.getLng());  
  89.             }  
  90.         }         
  91.     }  
  92.       
  93.     //测试数据获取(query);   注意请求参数属性与实体对象属性一一对应。  
  94.     @Test  
  95.     public void test7(){  
  96.         Query query = new Query(Criteria.where("lng").is(114.038804).and("lat").is(22.669214).and("openid").is(2));  
  97.         Business business = businessDao.findOne(query);  
  98.         if(business !=null){              
  99.                 System.out.println("商家编号:"+business.getOpenid());  
  100.                 System.out.println("经度:"+business.getLat());  
  101.                 System.out.println("维度:"+business.getLng());              
  102.         }         
  103.     }  
  104.       
  105.     //测试数据获取(page);  
  106.     @Test  
  107.     public void test8(){  
  108.         Query query = new Query();  
  109.         Page<Business> page = new Page<Business>();  
  110. //      page.setPageSize(2); //设置分页记录数  
  111. //      page.setCurrentPage(3); //设置当前页面      
  112.         Page<Business> pages = businessDao.findPage(page, query);  
  113.         List<Business> list = pages.getRows();  
  114.         if(list !=null && list.size()>0){  
  115.             for(Business business :list){  
  116.                 System.out.println("商家编号:"+business.getOpenid());  
  117.                 System.out.println("经度:"+business.getLat());  
  118.                 System.out.println("维度:"+business.getLng());              
  119.         }         
  120.     }  
  121. }  
  122.       
  123.     //测试数据获取(total)  
  124.     @Test  
  125.     public void test9(){  
  126.         Query query = new Query();    
  127.         long num = businessDao.count(query);  
  128.         System.out.println("记录总数:"+num);          
  129.     }  
  130.       
  131.     //测试数据修改(update)  注意:修改返回的实体对象是之前存储的数据信息  
  132.     @Test  
  133.     public void test10(){  
  134.         Query query = new Query(Criteria.where("openid").is(2));      
  135.         Update  update =new Update();  
  136.         update.set("lng", 110.649865);  
  137.         Business business = businessDao.updateOne(query, update);  
  138.         if(business !=null){              
  139.             System.out.println("商家编号:"+business.getOpenid());  
  140.             System.out.println("经度:"+business.getLat());  
  141.             System.out.println("维度:"+business.getLng());              
  142.             }     
  143.     }  
  144.       
  145.       
  146.       
  147.       
  148.       
  149.       
  150.   
  151.           
  152.       
  153.   
  154. }  

6、相关工具类封装(Page.java[java分页工具类])和(ReflectionUtils(反射工具类))
[html] view plain copy
  1. package com.spring.mongodb;  
  2.   
  3. import java.io.Serializable;    
  4. import java.util.List;      
  5.     
  6. public class Page<T> implements Serializable {    
  7.     private static final long serialVersionUID = 5760097915453738435L;    
  8.     public static final int DEFAULT_PAGE_SIZE = 10;    
  9.     /**   
  10.      * 每页显示个数   
  11.      */    
  12.     private int pageSize;    
  13.     /**   
  14.      * 当前页数   
  15.      */    
  16.     private int currentPage;    
  17.     /**   
  18.      * 总页数   
  19.      */    
  20.     private int totalPage;    
  21.     /**   
  22.      * 总记录数   
  23.      */    
  24.     private int totalCount;    
  25.     /**   
  26.      * 结果列表   
  27.      */    
  28.     private List<T> rows;    
  29.         
  30.     public Page(){    
  31.          this.currentPage = 1;    
  32.          this.pageSize = DEFAULT_PAGE_SIZE;    
  33.     }    
  34.     public Page(int currentPage,int pageSize){    
  35.         this.currentPage=currentPage<=0?1:currentPage;    
  36.         this.pageSize=pageSize<=0?1:pageSize;    
  37.     }    
  38.     public int getPageSize() {    
  39.         return pageSize;    
  40.     }    
  41.     public void setPageSize(int pageSize) {    
  42.         this.pageSize = pageSize;    
  43.     }    
  44.     public int getCurrentPage() {    
  45.         return currentPage;    
  46.     }    
  47.     public void setCurrentPage(int currentPage) {    
  48.         this.currentPage = currentPage;    
  49.     }    
  50.     public int getTotalPage() {    
  51.         return totalPage;    
  52.     }    
  53.     public void setTotalPage(int totalPage) {    
  54.         this.totalPage = totalPage;    
  55.     }    
  56.     public int getTotalCount() {    
  57.         return totalCount;    
  58.     }    
  59.     public void setTotalCount(int totalCount) {    
  60.         this.totalCount = totalCount;    
  61.     }    
  62.     
  63.     /**   
  64.      * 设置结果 及总页数   
  65.      * @param list   
  66.      */    
  67.      public void build(List<T> rows) {      
  68.             this.setRows(rows);      
  69.             int count =  this.getTotalCount();      
  70.             int divisor = count / this.getPageSize();      
  71.             int remainder = count % this.getPageSize();      
  72.             this.setTotalPage(remainder == 0 ? divisor == 0 ? 1 : divisor : divisor + 1);      
  73.         }    
  74.     public List<T> getRows() {    
  75.         return rows;    
  76.     }    
  77.     public void setRows(List<T> rows) {    
  78.         this.rows = rows;    
  79.     }      
  80. }    


[html] view plain copy
  1. package com.spring.mongodb;  
  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. import java.util.HashMap;  
  9. import java.util.Map;  
  10. import org.slf4j.Logger;  
  11. import org.slf4j.LoggerFactory;  
  12. import org.springframework.data.domain.Sort;  
  13. import org.springframework.data.domain.Sort.Direction;  
  14. import org.springframework.data.mongodb.core.query.Criteria;  
  15. import org.springframework.data.mongodb.core.query.Query;  
  16. import org.springframework.data.mongodb.core.query.Update;  
  17. import org.springframework.util.Assert;  
  18. import org.springframework.util.StringUtils;  
  19.   
  20. public class ReflectionUtils {  
  21.     private static Logger logger = LoggerFactory  
  22.             .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[] {},  
  30.                 new Object[] {});  
  31.     }  
  32.   
  33.     /**  
  34.      * 调用Setter方法.使用value的Class来查找Setter方法.  
  35.      */  
  36.     public static void invokeSetterMethod(Object obj, String propertyName,  
  37.             Object value) {  
  38.         invokeSetterMethod(obj, propertyName, value, null);  
  39.     }  
  40.   
  41.     /**  
  42.      * 调用Setter方法.  
  43.      *   
  44.      * @param propertyType  
  45.      *            用于查找Setter方法,为空时使用value的Class替代.  
  46.      */  
  47.     public static void invokeSetterMethod(Object obj, String propertyName,  
  48.             Object value, Class<?> propertyType) {  
  49.         Class<?> type = propertyType != null ? propertyType : value.getClass();  
  50.         String setterMethodName = "set" + StringUtils.capitalize(propertyName);  
  51.         invokeMethod(obj, setterMethodName, new Class[] { type },  
  52.                 new Object[] { value });  
  53.     }  
  54.   
  55.     /**  
  56.      * 直接读取对象属性值, 无视private/protected修饰符, 不经过getter函数.  
  57.      */  
  58.     public static Object getFieldValue(final Object obj, final String fieldName) {  
  59.         Field field = getAccessibleField(obj, fieldName);  
  60.   
  61.         if (field == null) {  
  62.             throw new IllegalArgumentException("Could not find field ["  
  63.                     + fieldName + "] on target [" + obj + "]");  
  64.         }  
  65.   
  66.         Object result = null;  
  67.         try {  
  68.             result = field.get(obj);  
  69.         } catch (IllegalAccessException e) {  
  70.             logger.error("不可能抛出的异常{}", e.getMessage());  
  71.         }  
  72.         return result;  
  73.     }  
  74.   
  75.     /**  
  76.      * 直接设置对象属性值, 无视private/protected修饰符, 不经过setter函数.  
  77.      */  
  78.     public static void setFieldValue(final Object obj, final String fieldName,  
  79.             final Object value) {  
  80.         Field field = getAccessibleField(obj, fieldName);  
  81.   
  82.         if (field == null) {  
  83.             throw new IllegalArgumentException("Could not find field ["  
  84.                     + fieldName + "] on target [" + obj + "]");  
  85.         }  
  86.   
  87.         try {  
  88.             field.set(obj, value);  
  89.         } catch (IllegalAccessException e) {  
  90.             logger.error("不可能抛出的异常:{}", e.getMessage());  
  91.         }  
  92.     }  
  93.   
  94.     /**  
  95.      * 循环向上转型, 获取对象的DeclaredField, 并强制设置为可访问.  
  96.      *   
  97.      * 如向上转型到Object仍无法找到, 返回null.  
  98.      */  
  99.     public static Field getAccessibleField(final Object obj,  
  100.             final String fieldName) {  
  101.         Assert.notNull(obj, "object不能为空");  
  102.         Assert.hasText(fieldName, "fieldName");  
  103.         for (Class<?> superClass = obj.getClass(); superClass != Object.class; superClass = superClass  
  104.                 .getSuperclass()) {  
  105.             try {  
  106.                 Field field = superClass.getDeclaredField(fieldName);  
  107.                 field.setAccessible(true);  
  108.                 return field;  
  109.             } catch (NoSuchFieldException e) {// NOSONAR  
  110.                 // Field不在当前类定义,继续向上转型  
  111.             }  
  112.         }  
  113.         return null;  
  114.     }  
  115.   
  116.     /**  
  117.      * 直接调用对象方法, 无视private/protected修饰符. 用于一次性调用的情况.  
  118.      */  
  119.     public static Object invokeMethod(final Object obj,  
  120.             final String methodName, final Class<?>[] parameterTypes,  
  121.             final Object[] args) {  
  122.         Method method = getAccessibleMethod(obj, methodName, parameterTypes);  
  123.         if (method == null) {  
  124.             throw new IllegalArgumentException("Could not find method ["  
  125.                     + methodName + "] on target [" + obj + "]");  
  126.         }  
  127.   
  128.         try {  
  129.             return method.invoke(obj, args);  
  130.         } catch (Exception e) {  
  131.             throw convertReflectionExceptionToUnchecked(e);  
  132.         }  
  133.     }  
  134.   
  135.     /**  
  136.      * 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问. 如向上转型到Object仍无法找到, 返回null.  
  137.      *   
  138.      * 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object...  
  139.      * args)  
  140.      */  
  141.     public static Method getAccessibleMethod(final Object obj,  
  142.             final String methodName, final Class<?>... parameterTypes) {  
  143.         Assert.notNull(obj, "object不能为空");  
  144.   
  145.         for (Class<?> superClass = obj.getClass(); superClass != Object.class; superClass = superClass  
  146.                 .getSuperclass()) {  
  147.             try {  
  148.                 Method method = superClass.getDeclaredMethod(methodName,  
  149.                         parameterTypes);  
  150.   
  151.                 method.setAccessible(true);  
  152.   
  153.                 return method;  
  154.   
  155.             } catch (NoSuchMethodException e) {// NOSONAR  
  156.                 // Method不在当前类定义,继续向上转型  
  157.             }  
  158.         }  
  159.         return null;  
  160.     }  
  161.   
  162.     /**  
  163.      * 通过反射, 获得Class定义中声明的父类的泛型参数的类型. 如无法找到, 返回Object.class. eg. public UserDao  
  164.      * extends HibernateDao<User>  
  165.      *   
  166.      * @param clazz  
  167.      *            The class to introspect  
  168.      * @return the first generic declaration, or Object.class if cannot be  
  169.      *         determined  
  170.      */  
  171.     @SuppressWarnings({ "unchecked", "rawtypes" })  
  172.     public static <T> Class<T> getSuperClassGenricType(final Class clazz) {  
  173.         return getSuperClassGenricType(clazz, 0);  
  174.     }  
  175.   
  176.     /**  
  177.      * 通过反射, 获得Class定义中声明的父类的泛型参数的类型. 如无法找到, 返回Object.class.  
  178.      *   
  179.      * 如public UserDao extends HibernateDao<User,Long>  
  180.      *   
  181.      * @param clazz  
  182.      *            clazz The class to introspect  
  183.      * @param index  
  184.      *            the Index of the generic ddeclaration,start from 0.  
  185.      * @return the index generic declaration, or Object.class if cannot be  
  186.      *         determined  
  187.      */  
  188.     @SuppressWarnings("rawtypes")  
  189.     public static Class getSuperClassGenricType(final Class clazz,  
  190.             final int index) {  
  191.   
  192.         Type genType = clazz.getGenericSuperclass();  
  193.   
  194.         if (!(genType instanceof ParameterizedType)) {  
  195.             logger.warn(clazz.getSimpleName()  
  196.                     + "'s superclass not ParameterizedType");  
  197.             return Object.class;  
  198.         }  
  199.   
  200.         Type[] params = ((ParameterizedType) genType).getActualTypeArguments();  
  201.   
  202.         if (index >= params.length || index < 0) {  
  203.             logger.warn("Index: " + index + ", Size of "  
  204.                     + clazz.getSimpleName() + "'s Parameterized Type: "  
  205.                     + params.length);  
  206.             return Object.class;  
  207.         }  
  208.         if (!(params[index] instanceof Class)) {  
  209.             logger.warn(clazz.getSimpleName()  
  210.                     + " not set the actual class on superclass generic parameter");  
  211.             return Object.class;  
  212.         }  
  213.   
  214.         return (Class) params[index];  
  215.     }  
  216.   
  217.     /**  
  218.      * 将反射时的checked exception转换为unchecked exception.  
  219.      */  
  220.     public static RuntimeException convertReflectionExceptionToUnchecked(  
  221.             Exception e) {  
  222.         if (e instanceof IllegalAccessException  
  223.                 || e instanceof IllegalArgumentException  
  224.                 || e instanceof NoSuchMethodException) {  
  225.             return new IllegalArgumentException("Reflection Exception.", e);  
  226.         } else if (e instanceof InvocationTargetException) {  
  227.             return new RuntimeException("Reflection Exception.",  
  228.                     ((InvocationTargetException) e).getTargetException());  
  229.         } else if (e instanceof RuntimeException) {  
  230.             return (RuntimeException) e;  
  231.         }  
  232.         return new RuntimeException("Unexpected Checked Exception.", e);  
  233.     }  
  234.   
  235.     /**  
  236.      * 根据对象获得mongodb Update语句 除id字段以外,所有被赋值的字段都会成为修改项  
  237.      */  
  238.     public static Update getUpdateObj(final Object obj) {  
  239.         if (obj == null)  
  240.             return null;  
  241.         Field[] fields = obj.getClass().getDeclaredFields();  
  242.         Update update = null;  
  243.         boolean isFirst = true;  
  244.         for (Field field : fields) {  
  245.             field.setAccessible(true);  
  246.             try {  
  247.                 Object value = field.get(obj);  
  248.                 if (value != null) {  
  249.                     if ("id".equals(field.getName().toLowerCase())  
  250.                             || "serialversionuid".equals(field.getName()  
  251.                                     .toLowerCase()))  
  252.                         continue;  
  253.                     if (isFirst) {  
  254.                         update = Update.update(field.getName(), value);  
  255.                         isFirst = false;  
  256.                     } else {  
  257.                         update = update.set(field.getName(), value);  
  258.                     }  
  259.                 }  
  260.   
  261.             } catch (IllegalArgumentException e) {  
  262.                 e.printStackTrace();  
  263.             } catch (IllegalAccessException e) {  
  264.                 e.printStackTrace();  
  265.             }  
  266.         }  
  267.         return update;  
  268.     }  
  269.   
  270.     /**  
  271.      * 根据对象获得mongodb Query语句  
  272.      *   
  273.      * 1.时间范围查询:在时间字段前增加begin或end,为这两个字段分别赋值 例:private Date createDate; 开始时间  
  274.      * private Date beginCreateDate; 结束时间 private Date endCreateDate;  
  275.      * 分析后结果:where createDate >= beginCreateDate and createDate <  
  276.      * beginCreateDate  
  277.      *   
  278.      * 2.排序 定义并赋值VO中 orderBy 字段,以英文“,”分割多个排序,以空格分隔排序方向 asc可不写 例:private String  
  279.      * orderBy; orderBy="createDate desc,sendDate asc,id" 分析结构:order by  
  280.      * createDate desc,sendDate asc,id asc  
  281.      *   
  282.      * 3.固定值搜索 定义并赋值VO中的任意字段,搜索时会把以赋值的字段当作为搜索条件  
  283.      */  
  284.   
  285.     public static Query getQueryObj(final Object obj) {  
  286.         if (obj == null)  
  287.             return null;  
  288.         Field[] fields = obj.getClass().getDeclaredFields();  
  289.         // Sort sort=new Sort(new Order(Direction.DESC,"createDate"));  
  290.         Query query = new Query();  
  291.         // 存放日期范围或者确定日期  
  292.         Map<String, Criteria> dateMap = new HashMap<String, Criteria>();  
  293.         String sortStr = null;  
  294.         for (Field field : fields) {  
  295.             field.setAccessible(true);  
  296.             try {  
  297.                 Object value = field.get(obj);  
  298.                 if (value != null) {  
  299.                     if ("serialversionuid"  
  300.                             .equals(field.getName().toLowerCase())) {  
  301.                         continue;  
  302.                     }  
  303.                     if ("orderby".equals(field.getName().toLowerCase())) {  
  304.                         sortStr = String.valueOf(value);  
  305.                         continue;  
  306.                     }  
  307.                     if (field.getType().getSimpleName().equals("Date")) {  
  308.                         if (field.getName().toLowerCase().startsWith("begin")) {  
  309.                             String beginName = field.getName().substring(5);  
  310.                             if (beginName.isEmpty()) {  
  311.                                 dateMap.put("begin", Criteria.where("begin")  
  312.                                         .is(value));  
  313.                             } else {  
  314. //                              beginName = StringUtil  
  315. //                                      .toLowerCaseFirstOne(beginName);  
  316.                                 Criteria criteria = dateMap.get(beginName) == null ? Criteria  
  317.                                         .where(beginName).gte(value) : dateMap  
  318.                                         .get(beginName).gte(value);  
  319.                                 dateMap.put(beginName, criteria);  
  320.                             }  
  321.                             continue;  
  322.                         }  
  323.                         if (field.getName().toLowerCase().startsWith("end")) {  
  324.                             String endName = field.getName().substring(3);  
  325.                             if (endName.isEmpty()) {  
  326.                                 dateMap.put("end",  
  327.                                         Criteria.where("end").is(value));  
  328.                             } else {  
  329. //                              endName = StringUtil  
  330. //                                      .toLowerCaseFirstOne(endName);  
  331.                                 Criteria criteria = dateMap.get(endName) == null ? Criteria  
  332.                                         .where(endName).lt(value) : dateMap  
  333.                                         .get(endName).lt(value);  
  334.                                 dateMap.put(endName, criteria);  
  335.                             }  
  336.                             continue;  
  337.                         }  
  338.                         dateMap.put(field.getName(),  
  339.                                 Criteria.where(field.getName()).is(value));  
  340.                         continue;  
  341.                     }  
  342.                     query.addCriteria(Criteria.where(field.getName()).is(value));  
  343.                 }  
  344.             } catch (Exception e) {  
  345.                 e.printStackTrace();  
  346.             }  
  347.         }  
  348.         // 日期类型查询条件  
  349.         for (String key : dateMap.keySet()) {  
  350.             if (dateMap.get(key) != null) {  
  351.                 query.addCriteria(dateMap.get(key));  
  352.             }  
  353.         }  
  354.         // 排序  
  355.         if (sortStr != null && !sortStr.trim().isEmpty()) {  
  356.             Sort sort = null;  
  357.             String[] strs = sortStr.split(",");  
  358.             for (String str : strs) {  
  359.                 str = str.trim();  
  360.                 if (str.isEmpty()) {  
  361.                     continue;  
  362.                 }  
  363.                 int i = str.indexOf(" ");  
  364.                 if (i < 0) {  
  365.                     if (sort == null) {  
  366.                         sort = new Sort(Direction.ASC, str);  
  367.                     } else {  
  368.                         sort = sort.and(new Sort(Direction.ASC, str));  
  369.                     }  
  370.                 } else {  
  371.                     String name = str.substring(0, i);  
  372.                     String dire = str.substring(i + 1).trim();  
  373.                     Sort sn = null;  
  374.                     if ("desc".equals(dire.toLowerCase())) {  
  375.                         sn = new Sort(Direction.DESC, name);  
  376.                     } else {  
  377.                         sn = new Sort(Direction.ASC, name);  
  378.                     }  
  379.                     if (sort == null) {  
  380.                         sort = sn;  
  381.                     } else {  
  382.                         sort = sort.and(sn);  
  383.                     }  
  384.                 }  
  385.             }  
  386.             if (sort != null) {  
  387.                 query.with(sort);  
  388.             }  
  389.         }  
  390.         return query;  
  391.     }  
  392.   
  393. }  

项目源码:
经过个人整理修改,用的maven,分享地址为:
链接: https://pan.baidu.com/s/1eSS8BQE 密码: awj3

相关文章:

  • 2021-11-19
  • 2021-09-13
  • 2022-12-23
  • 2022-12-23
  • 2021-05-23
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2021-12-04
  • 2021-12-05
  • 2021-04-22
  • 2021-07-03
  • 2021-12-31
相关资源
相似解决方案