利用反射构建mongodb操作基础类

来源:互联网 发布:电影cms解析收费 编辑:程序博客网 时间:2024/06/06 01:42

基础类:

package cn.com.mx.gome.flash.dao.impl;import java.util.List;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.mongodb.core.MongoTemplate;import org.springframework.data.mongodb.core.query.Query;import org.springframework.data.mongodb.core.query.Update;import cn.com.mx.gome.flash.dao.BaseMongoDAO;import cn.com.mx.gome.flash.util.Page;import cn.com.mx.gome.flash.util.ReflectionUtils;public class BaseMongoDAOImpl<T> implements BaseMongoDAO<T> {    /**     * spring mongodb 集成操作类      */    @Autowired    protected MongoTemplate mongoTemplate;    @Override    public List<T> find(Query query) {        return mongoTemplate.find(query, this.getEntityClass());    }    @Override    public T findOne(Query query) {        return mongoTemplate.findOne(query, this.getEntityClass());    }    @Override    public void update(Query query, Update update) {        mongoTemplate.findAndModify(query, update, this.getEntityClass());    }    @Override    public T save(T entity) {        mongoTemplate.insert(entity);        return entity;    }    @Override    public T findById(String id) {        return mongoTemplate.findById(id, this.getEntityClass());    }    @Override    public T findById(String id, String collectionName) {        return mongoTemplate.findById(id, this.getEntityClass(), collectionName);    }    @Override    public Page<T> findPage(Page<T> page, Query query) {        long count = this.count(query);        page.setTotal(count);        int pageNumber = page.getPageNumber();        int pageSize = page.getPageSize();        query.skip((pageNumber - 1) * pageSize).limit(pageSize);        List<T> rows = this.find(query);        page.setRows(rows);        return page;    }    @Override    public long count(Query query) {        return mongoTemplate.count(query, this.getEntityClass());    }    /**     * 获取需要操作的实体类class     *      * @return     */    private Class<T> getEntityClass() {        return ReflectionUtils.getSuperClassGenricType(getClass());    }}

反射工具类:

package cn.com.mx.gome.flash.util;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 org.apache.commons.lang.StringUtils;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.util.Assert;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);    }}






1 0
原创粉丝点击