给java mongodb 官方driver 增加bean 操作

 
mongodb官方的java driver不支持直接插入java bean,只能使用DbObject的Key,Value形式进行insert,update,(c# mongodb官方driver类似),所以我这里加入了一个利用反射快速操作的类,来支持bean操作。另因为java不支持扩展方法,所以只能用abstract class的类来替代,c#的话可以直接扩展官方driver,会更方便。
 
关于速度,反射(reflection)一般情况下要比直接(native)的方法要慢。先使用的是反射method赋值,平均要比native慢10%左右,所以第二次改用java 的field.set (如果是private,需先设置 field.setAccessible 为true)来进行操作,速度跟native不相上下,在模拟10万,100万数据操作的时候,有时候甚至比native还快。不过这样就舍去了一个功能是可能会在set方法中加入操作,如果需要改为的method的话(hibernate默认做法),只需要修改为method反射即可。
 
 
 
代码很简单,写出来小记一下。 
 
package gsralex;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.net.UnknownHostException;

import org.bson.types.ObjectId;

import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBObject;
import com.mongodb.Mongo;

public abstract class Dao {
    private static final ThreadLocal<Mongo> threadLocal = new ThreadLocal<Mongo>();

    private static final String    connectAddress    = "127.0.0.1";
    private static final int    connectPort    = 27017;

    public static Mongo getMongo()
    {
        Mongo mongo = threadLocal.get();
        if ( mongo == null )
        {
            try {
                mongo = new Mongo( connectAddress, connectPort );
            } catch ( UnknownHostException e ) {
/* TODO Auto-generated catch block */
                e.printStackTrace();
            }
            threadLocal.set( mongo );
        }
        return(mongo);
    }


    public static void close()
    {
        Mongo mongo = threadLocal.get();

        if ( mongo != null )
        {
            mongo.close();
            threadLocal.set( null );
        }
    }


    public static DB getDefaultDb()
    {
        return(getDb( "gsralex" ) );
    }


    public static DB getDb( String dbName )
    {
        Mongo mongo = getMongo();

        if ( mongo != null )
        {
            return(mongo.getDB( dbName ) );
        }

        return(null);
    }


    public static int insert( Object bean )
    {
        Class clazz = bean.getClass();

        Field[] fields = clazz.getDeclaredFields();

        MongoColumn    column;
        DBObject    dbObject = new BasicDBObject();

        try {
            for ( Field field : fields )
            {
                column = field.getAnnotation( MongoColumn.class );
                if ( column == null )
                {
                    continue;
                }

                Object filedValue = field.get( bean );
                dbObject.put( column.name(), filedValue );
            }
        } catch ( Exception e ) {
/* TODO Auto-generated catch block */
            e.printStackTrace();
        }

        MongoCollection collection = (MongoCollection) clazz
                         .getAnnotation( MongoCollection.class );
        return(getDefaultDb().getCollection( collection.name() ).insert( dbObject )
               .getN() > 0 ? 0 : -1);
    }


    public static int update( Object obj, String collectionName )
    {
        Class clazz = obj.getClass();

        Field[] fields = clazz.getDeclaredFields();

        MongoColumn    column;
        DBObject    dbObject = new BasicDBObject();

        try {
            for ( Field field : fields )
            {
                column = field.getAnnotation( MongoColumn.class );
                if ( column == null )
                {
                    continue;
                }

                Object filedValue = field.get( obj );
                dbObject.put( column.name(), filedValue );
            }
        } catch ( Exception e ) {
/* TODO Auto-generated catch block */
            e.printStackTrace();
        }

        ObjectId _id = getObjectId( obj, clazz );
        return(getDefaultDb().getCollection( collectionName ).update(
                   new BasicDBObject( "_id", _id ), dbObject ).getN() > 0 ? 0 : -1);
    }


    private static ObjectId getObjectId( Object obj, Class clazz )
    {
        ObjectId _id = null;
        try {
            _id = (ObjectId) clazz.getField( "_id" ).get( obj );
        } catch ( Exception e ) {
/* TODO Auto-generated catch block */
            e.printStackTrace();
        }

        return(_id);
    }


    public static Object getBean( DBObject dbObject, Class clazz )
    {
        if ( dbObject == null )
        {
            return(null);
        }

        Object obj = null;
        try {
            obj = clazz.newInstance();

            Field[] fields = clazz.getDeclaredFields();


            MongoColumn column;
            for ( Field field : fields )
            {
                column = field.getAnnotation( MongoColumn.class );

                if ( column == null )
                    continue;

                field.setAccessible( true );
                Object filedValue = dbObject.get( column.name() );
                field.set( obj, filedValue );
            }
        } catch ( Exception e ) {
            e.printStackTrace();
        }

        return(obj);
    }
}

 

 
需要增加两个注解:
 
package gsralex;

import java.lang.annotation.ElementType;
import java.lang.annotation.Target;

@Target( { ElementType.TYPE } )
public @interface MongoCollection {
    public String name() default "";
}

package gsralex;

import java.lang.annotation.ElementType;
import java.lang.annotation.Target;


@Target( { ElementType.FIELD, ElementType.METHOD } )
public @interface MongoColumn {
    public String name() default "";
}

 

 

郑州 6月23日 晴

posted @ 2013-06-23 15:17  gsralex  阅读(509)  评论(0编辑  收藏  举报