通过java反射实现简单的关于MongoDB的对象关系映射(ORM).

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了通过java反射实现简单的关于MongoDB的对象关系映射(ORM).相关的知识,希望对你有一定的参考价值。

    通过阅读MongoDB  3.2.1的官方文档中关于java 编程发现最新的文档并没有实现对对象到Document的映射,所以自己有了利用反射实现简单的关系映射.

  1.定义抽象类:AbstractMongoSession

import java.util.List;

import org.bson.Document;
import org.bson.conversions.Bson;

import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;

/*
 * 创建一个会话实现对mongoDB的原子操作
 * 
 * @author:maybo
 * 
 * @date:2016-2-1
 */
public abstract class AbstractMongoSession {
    private MongoDatabase db;
    private Class<?> clazz;
    private MongoCollection<Document> collection;

    public MongoCollection<Document> getCollection() {
        return this.collection;
    }

    public Class<?> getClazz() {
        return clazz;
    }

    public void setDb(MongoDatabase db) {
        this.db = db;
    }

    public MongoDatabase getDb() {
        return db;
    }

    protected MongoCollection<Document> Collection(Class<?> clazz) {
        this.clazz = clazz;
        Table table = (Table) clazz.getAnnotation(Table.class);
        String col = null;
        if (null != table && null != table.name()) {
            col = table.name();
        } else {
            col = clazz.getName();
        }
        this.collection = db.getCollection(col);
        return this.collection;
    }

    /*
     * 保存
     * 
     * @param:实体
     * 
     * @return:void
     */
    public abstract void save(Object obj);

    public abstract void saveMany(List<Object> obj);

    // 删除数据
    public abstract long delete(Object obj) throws Exception;

    public abstract long delete(Bson bson) throws Exception;

    // 删除数据
    public abstract long deleteMany(List<Object> objs);

    public abstract long deleteMany(Bson bson);

    // 修改数据
    public abstract long upate(Bson bson, Object obj);

    public abstract long update(Object obj);

    public abstract long upateMany(Bson bson, Object obj);

    public abstract long upateMany(Bson bson, List<Object> objs);

    public abstract long upateMany(List<Object> objs);

    // 查询数据
    public abstract Object find(Object obj);

    // 获取所有的数据
    public abstract List<Object> finds();

    // 条件查询数据
    public abstract List<Object> query(Bson bson);

    public abstract Object queryOne(Bson bson);

    public abstract List<Object> query(Bson bson, Bson sort);

    public abstract Object queryOne(Bson bson, Bson sort);

    public abstract List<Object> query(Bson bson, Bson sort, int limit);

    public abstract List<Object> query(Bson bson, Bson sort, int limit, int skip);

    public abstract List<Object> query(Bson bson, Bson sort, Bson filter);

    public abstract Object queryOne(Bson bson, Bson sort, Bson Filter);

    public abstract long count();

    public abstract long count(Bson bson);

}

2. 实现类MongoSession

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;

import org.bson.Document;
import org.bson.conversions.Bson;

import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.Filters;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult;

public class MongoSession extends AbstractMongoSession {
    public MongoSession(Class<?> clazz, MongoDatabase db) {
        this.setDb(db);
        this.Collection(clazz);
    }

    /*
     * (non-Javadoc)
     * 
     * @see AbstractMongoSession#save(java.lang.Object)
     */
    @Override
    public void save(Object obj) {
        try {
            this.getCollection().insertOne(BsonUtil.toBson(obj));
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    @Override
    public long delete(Object obj) throws Exception {
        try {
            DeleteResult result = this.getCollection().deleteOne(
                    BsonUtil.toBson(obj));
            long count = result.getDeletedCount();
            return count;
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return 0;
    }

    @Override
    public void saveMany(List<Object> obj) {
        try {
            this.getCollection().insertMany(BsonUtil.toBsons(obj));
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    @Override
    public long delete(Bson bson) throws Exception {
        DeleteResult deleteResult = this.getCollection().deleteOne(bson);
        return deleteResult.getDeletedCount();
    }

    @Override
    public long deleteMany(List<Object> objs) {
        List<Document> documents;
        int count = 0;
        try {
            documents = BsonUtil.toBsons(objs);
            for (int i = 0; null != documents && i < documents.size(); i++) {
                DeleteResult deleteResult = this.getCollection().deleteOne(
                        documents.get(i));
                count += deleteResult.getDeletedCount();
            }
            return count;
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return count;
    }

    @Override
    public long deleteMany(Bson bson) {
        DeleteResult deleteResult = this.getCollection().deleteMany(bson);
        return deleteResult.getDeletedCount();
    }

    @Override
    public long upate(Bson bson, Object obj) {
        try {
            UpdateResult result = this.getCollection().updateOne(bson,
                    new Document("$set", BsonUtil.toBson(obj)));
            return result.getMatchedCount();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return 0;
    }

    @Override
    public long update(Object obj) {
        Document document;
        try {
            document = BsonUtil.toBson(obj);
            UpdateResult updateResult = this.getCollection().updateOne(
                    Filters.eq("_id", document.get("_id")),
                    new Document("$set", document));
            return updateResult.getMatchedCount();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return 0;
    }

    @Override
    public long upateMany(Bson bson, Object obj) {
        try {
            UpdateResult updateResult = this.getCollection().updateMany(bson,
                    new Document("$set", BsonUtil.toBson(obj)));
            return updateResult.getMatchedCount();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return 0;
    }

    @Override
    public long upateMany(Bson bson, List<Object> obj) {
        for (int i = 0; null != obj && i < obj.size(); i++) {
            try {
                UpdateResult result = this.getCollection().updateMany(bson,
                        new Document("$set", BsonUtil.toBson(obj)));
                return result.getMatchedCount();
            } catch (IllegalArgumentException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (SecurityException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (NoSuchFieldException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return 0;
    }

    @Override
    public long upateMany(List<Object> objs) {
        long count = 0;
        for (int i = 0; null != objs && i < objs.size(); i++) {
            try {
                UpdateResult result = this.getCollection().updateMany(
                        Filters.eq("_id",
                                BsonUtil.toBson(objs.get(i)).get("_id")),
                        new Document("$set", BsonUtil.toBson(objs.get(i))));
                count += result.getMatchedCount();
            } catch (IllegalArgumentException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (SecurityException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (NoSuchFieldException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return count;
    }

    @Override
    public Object find(Object obj) {
        try {
            Document document = this.getCollection()
                    .find(Filters.eq("_id", BsonUtil.toBson(obj).get("_id")))
                    .first();
            return BsonUtil.toBean(document, this.getClazz());
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public List<Object> finds() {
        FindIterable<Document> doIterable = this.getCollection().find();
        MongoCursor<Document> cursor = doIterable.iterator();
        List<Object> objects = new ArrayList<Object>();
        while (cursor.hasNext()) {
            Document document = cursor.next();
            try {
                objects.add(BsonUtil.toBean(document, this.getClazz()));
            } catch (IllegalArgumentException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (InstantiationException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return objects;
    }

    @Override
    public List<Object> query(Bson bson) {
        FindIterable<Document> doIterable = this.getCollection().find(bson);
        MongoCursor<Document> cursor = doIterable.iterator();
        List<Object> objects = new ArrayList<Object>();
        while (cursor.hasNext()) {
            Document document = cursor.next();
            try {
                objects.add(BsonUtil.toBean(document, this.getClazz()));
            } catch (IllegalArgumentException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (InstantiationException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return objects;
    }

    @Override
    public Object queryOne(Bson bson) {
        Document document = this.getCollection().find(bson).first();
        try {
            return BsonUtil.toBean(document, this.getClazz());
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public List<Object> query(Bson bson, Bson sort) {
        FindIterable<Document> doIterable = this.getCollection().find(bson)
                .sort(sort);
        MongoCursor<Document> cursor = doIterable.iterator();
        List<Object> objects = new ArrayList<Object>();
        while (cursor.hasNext()) {
            Document document = cursor.next();
            try {
                objects.add(BsonUtil.toBean(document, this.getClazz()));
            } catch (IllegalArgumentException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (InstantiationException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return objects;
    }

    @Override
    public Object queryOne(Bson bson, Bson sort) {
        Document document = this.getCollection().find(bson).sort(sort).first();
        try {
            return BsonUtil.toBean(document, this.getClazz());
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public List<Object> query(Bson bson, Bson sort, int limit) {
        FindIterable<Document> doIterable = this.getCollection().find(bson)
                .sort(sort);
        if (limit > 0) {
            doIterable = doIterable.limit(limit);
        }
        MongoCursor<Document> cursor = doIterable.iterator();
        List<Object> objects = new ArrayList<Object>();
        while (cursor.hasNext()) {
            Document document = cursor.next();
            try {
                objects.add(BsonUtil.toBean(document, this.getClazz()));
            } catch (IllegalArgumentException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (InstantiationException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return objects;
    }

    @Override
    public List<Object> query(Bson bson, Bson sort, int limit, int skip) {
        FindIterable<Document> doIterable = this.getCollection().find(bson)
                .sort(sort);
        if (limit > 0) {
            doIterable = doIterable.limit(limit);
        }
        if (skip > 0) {
            doIterable = doIterable.skip(skip);
        }
        MongoCursor<Document> cursor = doIterable.iterator();
        List<Object> objects = new ArrayList<Object>();
        while (cursor.hasNext()) {
            Document document = cursor.next();
            try {
                objects.add(BsonUtil.toBean(document, this.getClazz()));
            } catch (IllegalArgumentException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (InstantiationException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return objects;
    }

    @Override
    public List<Object> query(Bson bson, Bson sort, Bson filter) {
        FindIterable<Document> doIterable = this.getCollection().find(bson)
                .sort(sort).filter(filter);
        MongoCursor<Document> cursor = doIterable.iterator();
        List<Object> objects = new ArrayList<Object>();
        while (cursor.hasNext()) {
            Document document = cursor.next();
            try {
                objects.add(BsonUtil.toBean(document, this.getClazz()));
            } catch (IllegalArgumentException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (InstantiationException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return objects;
    }

    @Override
    public Object queryOne(Bson bson, Bson sort, Bson Filter) {
        Document document = this.getCollection().find(bson).sort(sort)
                .filter(Filter).first();

        try {
            return BsonUtil.toBean(document, this.getClazz());
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public long count() {

        return this.getCollection().count();
    }

    @Override
    public long count(Bson bson) {
        // TODO Auto-generated method stub
        return this.getCollection().count(bson);
    }
}

3. 帮助类:实现Document到Object 以及Object到Document的转换.使用反射技术和注解.

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.List;

import org.bson.Document;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;

/*
 * 将mongo的文档转化为对象将对象转化为mongo文档
 * @author:maybo
 * @data:2016-2-1
 */
public class BsonUtil {
    public static <T> List<T> toBeans(List<Document> documents, Class<T> clazz)
            throws IllegalArgumentException, InstantiationException,
            IllegalAccessException, InvocationTargetException {
        List<T> list = new ArrayList<T>();
        for (int i = 0; null != documents && i < documents.size(); i++) {
            list.add(toBean(documents.get(i), clazz));
        }
        return list;
    }

    /*
     * 将Bson 转化为对象
     * 
     * @param:Bson文档
     * 
     * @param:类pojo
     * 
     * @param:返回对象
     */
    public static <T> T toBean(Document document, Class<T> clazz)
            throws InstantiationException, IllegalAccessException,
            IllegalArgumentException, InvocationTargetException {
        T obj = clazz.newInstance();// 声明一个对象
        Field[] fields = clazz.getDeclaredFields();// 获取所有属性
        Method[] methods = clazz.getMethods();// 获取所有的方法
        /*
         * 查找所有的属性,并通过属性名和数据库字段名通过相等映射
         */
        for (int i = 0; i < fields.length; i++) {
            String fieldName = fields[i].getName();
            Column column = fields[i].getAnnotation(Column.class);
            Object bson = null;
            if (null != column && null != column.name()) {
                bson = document.get(column.name());
            } else if ("id".equals(fieldName)) {
                bson = document.get("_id");
            } else {
                bson = document.get(fieldName);
            }
            if (null == bson) {
                continue;
            } else if (bson instanceof Document) {// 如果字段是文档了递归调用
                bson = toBean((Document) bson, fields[i].getType());
            } else if (bson instanceof MongoCollection) {// 如果字段是文档集了调用colTOList方法

                bson = colToList(bson, fields[i]);
            }
            for (int j = 0; j < methods.length; j++) {// 为对象赋值
                String metdName = methods[j].getName();
                if (equalFieldAndSet(fieldName, metdName)) {
                    methods[j].invoke(obj, bson);
                    break;
                }
            }
        }
        return obj;
    }

    public static List<Document> toBsons(List<Object&

以上是关于通过java反射实现简单的关于MongoDB的对象关系映射(ORM).的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB数据库常用操作

java中如何通过反射获取类的属性

Java反射之剖析方法

关于用java反射调用一个类里面的方法并执行

Java关于反射

Java反射+简单工厂模式总结