java实现mongodb的dbutils

mongodb用起来了,但是操作返回数据调用find方法 返回 需要处理,很是不爽,借鉴了下commons-dbutils对java数据库的操作,自己也对mongodb的返回数据实现封装。里面用到java 内省和反射.
技术分享

接下来贴源码 和简单的注释

Person.java
package com.zk.bean;
/**
* 用户实体
* @author zk
* @time 2015-4-24 下午1:49:45
* @version 1.0
* @todo
*/
public class Person {
private String id;
private String name;

public String getId() {
    return id;
}

public void setId(String id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

@Override
public String toString() {
    return "Person [id=" + id + ", name=" + name + "]";
}

}

ResultSetHandler.java

package com.zk.db.ResultHandler;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Set;

import com.mongodb.DBCursor;
import com.mongodb.DBObject;
/**
 * 通过接口 实现数据回调
 * @author  zk
 * @time    2015-4-24 下午1:27:25
 * @version 1.0
 * @todo
 */
public interface ResultSetHandler<T> {

    /**
     * 用户自己封装数据处理
     * @param cursor
     * @return
     * @throws Exception
     */
    public T handler(DBCursor cursor) throws Exception;
}

BaseHandler.java

package com.zk.db.ResultHandler;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.Set;
import com.mongodb.DBObject;
/**
 * 返回数据处理 基类 实现 内省封装
 * @author  zk
 * @time    2015-4-24 下午4:07:52
 * @version 1.0
 * @todo
 */
public class BaseHandler<T> {
    private Class clazz;
    public BaseHandler(Class clazz) {
        this.clazz=clazz;
        // TODO Auto-generated constructor stub
    }
    public void populate(T t, Set<String> set, DBObject object) throws Exception {
        // 完成该数据的封装
        BeanInfo info = Introspector.getBeanInfo(clazz);
        PropertyDescriptor [] pds = info.getPropertyDescriptors();
        for (PropertyDescriptor pd : pds) {
            // 先获取到属性的名称    proName
            String proName = pd.getName();
            if(set.contains(proName)){
                // 获取到该属性的写方法
                Method m = pd.getWriteMethod();
                // 执行之
                m.invoke(t, object.get(proName));
            }
            if(set.contains("_"+proName)){
                // 获取到该属性的写方法
                Method m = pd.getWriteMethod();
                // 执行之
                m.invoke(t,object.get("_"+proName));
            }
        }
    }
}

BeanHandler.java
package com.zk.db.ResultHandler;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;

/**
 * 返回单一记录实体的处理
 * 
 * @author zk
 * @time 2015-4-24 下午3:51:32
 * @version 1.0
 * @todo
 */
public class BeanHandler<T> extends BaseHandler<T> implements
        ResultSetHandler<T> {
    private Class clazz;

    public BeanHandler(Class clazz) {
        super(clazz);
        this.clazz = clazz;
    }
   /**
    * 回调处理 核心方法
    */
    public T handler(DBCursor cursor) throws Exception {
        try {
            if (cursor.hasNext()) {
                //反射机制
                T t = (T) this.clazz.newInstance();
                DBObject object = cursor.next();
                Set<String> set = object.keySet();
                populate(t, set, object);
                return t;
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
**BeanListHandler.java**
package com.zk.db.ResultHandler;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;

/**
 * 返回list 泛型集合的处理
 * 
 * @author zk
 * @time 2015-4-24 下午3:50:19
 * @version 1.0
 * @todo
 */
public class BeanListHandler<T> extends BaseHandler<T> implements ResultSetHandler<List<T>> {
    private Class clazz;

    public BeanListHandler(Class clazz) {
        super(clazz);
        this.clazz = clazz;
    }
    /**
     * 回调数据处理 核心方法
     */
    public List<T> handler(DBCursor cursor) throws Exception {
        try {

            List<T> list = new ArrayList<T>();
            while (cursor.hasNext()) {
                //反射
                T t = (T) this.clazz.newInstance();
                DBObject object = cursor.next();
                Set<String> set = object.keySet();
                populate(t, set, object);
                list.add(t);
            }
            return list;

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

}

MongoDb.java 以后就可以直接调用这个方法 就好了,需要优化处理

package com.zk.db;
import java.net.UnknownHostException;
import java.sql.SQLException;
import java.util.List;
import java.util.Set;
import org.bson.types.ObjectId;
import org.junit.Test;
import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.mongodb.Mongo;
import com.mongodb.MongoException;
import com.zk.bean.Person;
import com.zk.db.ResultHandler.BeanListHandler;
import com.zk.db.ResultHandler.ResultSetHandler;

public class MongoDb {
// 1.建立一个Mongo的数据库连接对象
static Mongo connection = null;
// 2.创建相关数据库的连接
static DB db = null;
public MongoDb(String dbName) throws UnknownHostException, MongoException {
    connection = new Mongo("127.0.0.1:27017");
    db = connection.getDB(dbName);
}
public static void main(String[] args) throws UnknownHostException,
        MongoException {
    MongoDb mongoDb = new MongoDb("one");
    DBObject query = new BasicDBObject();
    //看看这个地方 是不是很像 dbutils调用的方法哟。。。。。
    List<Person> plist = mongoDb.find(query, new BeanListHandler<Person>(
            Person.class), "person");
    for (Person person : plist) {
        System.out.println(person);
    }
}
   /**
    * 分页查询 返回 封装集合
    * @param query
    * @param rsh
    * @param collName
    * @return
    */
public <T> T find(DBObject query, ResultSetHandler<T> rsh, String collName) {
    try {
        MongoDb mongoDb = new MongoDb("one");
        // mongoDb.f
        DBCursor cursor = mongoDb.find(null, null, 0, 6, collName);
        // 关键,用户决定怎么来封装rs的对象 List Map Account ...
        T t = rsh.handler(cursor);
        return t;
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        throw new RuntimeException(e);
    } // 调用封装结果的方法,返回的封装的结果。
}


/**
 * 查询器(分页)
 * 
 * @param ref
 * @param keys
 * @param start
 * @param limit
 * @return
 */
public DBCursor find(DBObject ref, DBObject keys, int start, int limit,
        String collName) {
    DBCursor cur = find(ref, keys, collName);
    return cur.limit(limit).skip(start);
}

/**
 * 查询器(不分页)
 * 
 * @param ref
 * @param keys
 * @param start
 * @param limit
 * @param collName
 * @return
 */
public DBCursor find(DBObject ref, DBObject keys, String collName) {
    // 1.得到集合
    DBCollection coll = db.getCollection(collName);
    DBCursor cur = coll.find(ref, keys);
    return cur;
}
}

注意:
BaseHandler 类 返回数据处理 基类 实现 内省封装
ResultSetHandler接口 通过接口 实现数据回调
BeanHandler类 返回单一记录实体的处理
BeanListHandler返回list 泛型集合的处理
MongoDb类 核心处理 public T find(DBObject query, ResultSetHandler rsh, String collName)把这几个类接口连接起来,当调用该方法时,需要传入一个实现了ResultSetHandler接口的类,该类可以是BaseHandler[返回单一实体],BeanListHandler[返回list集合],在方法内部可以调用具体实现类的handler 方法,实现具体的解析, 返回。BaseHandler 可以帮助BeanListHandler,BeanHandler这2个实现类 利用反射 封装数据的作用。
该实现借鉴了开源工具类 dbutils的实现。面向接口编程,接口注入,反射 内省的运用在这里面都可也体现。
另外网上也有一些开源的操作mongodb的 dbtuils 和orm框架,可以去查找借鉴下。

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。