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框架,可以去查找借鑑下。