maven文件引用
<!-- mongodb引入 -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>1.3.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>2.11.1</version>
</dependency>
spring-mongdb配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
xsi:schemaLocation="http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/data/mongo
http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<!-- 加载mongodb的属性配置文件 -->
<context:property-placeholder location="classpath:mongodb.properties" />
<!-- 定义mongo对象,对应的是mongodb官方jar包中的Mongo,replica-set设置集群副本的ip地址和端口 -->
<mongo:mongo id="mongo" replica-set="${mongo.hostport}">
<!-- 一些连接属性的设置 -->
<mongo:options
connections-per-host="${mongo.connectionsPerHost}"
threads-allowed-to-block-for-connection-multiplier="${mongo.threadsAllowedToBlockForConnectionMultiplier}"
connect-timeout="${mongo.connectTimeout}"
max-wait-time="${mongo.maxWaitTime}"
auto-connect-retry="${mongo.autoConnectRetry}"
socket-keep-alive="${mongo.socketKeepAlive}"
socket-timeout="${mongo.socketTimeout}"
slave-ok="${mongo.slaveOk}"
write-number="1"
write-timeout="0"
write-fsync="true"/>
</mongo:mongo>
<mongo:db-factory dbname="database" mongo-ref="mongo" />
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg ref="mongo" />
<constructor-arg name="databaseName" value="db_mongo" />
</bean>
</beans>
配置参数 mongodb.properties
mongo.hostport=127.0.0.1:27017
mongo.connectionsPerHost=8
mongo.threadsAllowedToBlockForConnectionMultiplier=4
#\u8FDE\u63A5\u8D85\u65F6\u65F6\u95F4
mongo.connectTimeout=1000
#\u7B49\u5F85\u65F6\u95F4
mongo.maxWaitTime=1500
mongo.autoConnectRetry=true
mongo.socketKeepAlive=true
#Socket\u8D85\u65F6\u65F6\u95F4
mongo.socketTimeout=1500
mongo.slaveOk=true
Dao层接口
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);
}
Dao层实现
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;
import com.trustsaving.common.base.util.ReflectionUtils;
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() {
// Type genType = getClass().getGenericSuperclass();
// if (!(genType instanceof ParameterizedType)) {
// return (Class<T>) Object.class;
// }
// // 返回表示此类型实际类型参数的 Type 对象的数组。
// Type[] params = ((ParameterizedType)
// genType).getActualTypeArguments();
// if (!(params[0] instanceof Class)) {
// return (Class<T>) Object.class;
// }
// return (Class<T>) params[0];
return ReflectionUtils.getSuperClassGenricType(getClass());
}
}
反射工具类
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));
<pre name="code" class="java">continue;
} query.addCriteria(Criteria.where(field.getName()).is(value)); } } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException 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; } public static void main(String[] a) { // Smslog p = new Smslog(); // p.setBusinessNo("123"); // p.setMobileNo("18521"); // p.setCreateDate(new Date()); // Update u = ReflectionUtils.getUpdateObj(p);// String ab="begin".substring(5);// System.out.println("begin".substring(5));// if (ab.isEmpty()) {// System.out.println("aaa");// }// System.out.println(StringUtil.toLowerCaseFirstOne("ASSS")); String string="sss aa"; int i=string.indexOf(" "); System.out.println(i); System.out.println(string.substring(0,i)); System.out.println(string.substring(i+1).trim()); Map<String, String> map=new HashMap<String, String>(); map.put("a", "123"); map.put("b", "456"); System.out.println(map.get("a")); map.put("a", "444"); System.out.println(map.get("a")); System.out.println(map.get("c")); }}
封装的分页参数 与上个版本修改名称
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;
}
}