本文实现一个通用泛型封装实现类,需要给定一个集合对象,类似mysql中与java对应的表;思想就是把给定的对象解析出所有非空字段,保存到一个BasicDBObject中,这里一定要保证java对象与mongodb中的文档字段名字一样,因为代码为了实现通用,是默认以java对象的字段为BasicDBObject的查询字段。

核心代码1:这是将java对象转换为查询条件。

/**
     * 通过反射获取非空字段信息
     * @param record
     * @param <Q>
     * @return
     */
    private <Q> BasicDBObject getCondition(Q record) {
        BasicDBObject cond = new BasicDBObject();
        Class clazz = record.getClass();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            try {
                field.setAccessible(true);
                Object value = field.get(record);
                if (value != null)
                    cond.put(field.getName(), value);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return cond;
    }
登录后复制

核心代码2:这是将查询到的文档转换为java对象,这里也是默认java对象的字段和数据库文档字段一样,也是利用java的反射动态获取用户自定义对象的所有字段,然后进行赋值,我在赋值过程中单独判断了int和long型,因为插入mongodb的时候一般是以double存的,这样就会造成转型错误。

/**
     * 将结果转化为自定义对象
     * @param document
     * @param target
     * @param <Q>
     * @return
     */
    private <Q> Q parseToObject(Document document, Class<Q> target) {
        try {
            Q result = target.newInstance();
            Field[] fields = target.getDeclaredFields();
            for (Field f : fields) {
                f.setAccessible(true);
                Object value = document.get(f.getName());
                if (value == null)
                    continue;
                else if (f.getType() == Integer.class)
                    f.set(result, ((Number) value).intValue());
                else if (f.getType() == Long.class)
                    f.set(result, ((Number) value).longValue());
                else
                    f.set(result, document.get(f.getName(), f.getType()));
            }
            return result;
        } catch (IllegalAccessException e) {
            e.printStackTrace();
            return null;
        } catch (InstantiationException e) {
            e.printStackTrace();
            return null;
        }
    }
登录后复制

调用方法:先转换查询参数,查询的时候是以id来判断正序倒序,所以默认数据库中一定要有id的标识字段。

public <Q> List<Q> queryByCondition(BaseQuery<Q> query,boolean up) {
        Q record = query.getQuery();
        BasicDBObject cond = getCondition(record);
        FindIterable<Document> findIterable;
        if (query.getStart() != null && query.getRows() != null)
            findIterable = thisCollection().find(cond)
                    .sort(new BasicDBObject("id", up ? 1 : -1))
                    .skip((query.getStart() - 1) * query.getRows())
                    .limit(query.getRows());
        else
            findIterable = thisCollection().find(cond)
                    .sort(new BasicDBObject("id", up ? 1 : -1));
        MongoCursor<Document> iterator = findIterable.iterator();
        List<Q> result = new ArrayList<>();
        while (iterator.hasNext()) {
            Document document = iterator.next();
            result.add((Q) parseToObject(document, record.getClass()));
        }
        iterator.close();
        return result;
    }
登录后复制

这里传入的BaseQuery如下:里面的query就是个需要查询的java对象,start&rows是为了用来分页的。这里是用到了lombok的插件,这样简化很多的gettter&setter等代码。

@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Data
@Accessors(chain = true)
public class BaseQuery<Q> {
    private Integer start;
    private Integer rows;
    private Q query;

    public BaseQuery(Class clazz) {
        try {
            this.query = (Q) clazz.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}
登录后复制

测试条件查询方法:这里用到的实体如下:

@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class User_info {
    private Integer id;

    private String name;

    private Integer age;

    private Integer role;
}
登录后复制
public static void main(String[] args) {
        User_info record = new User_info();
        BaseQuery<User_info> query = new BaseQuery<>();
        query.setQuery(record);

        BaseMongoDao dao = new BaseMongoDao("test");
        List<User_info> result = dao.queryByCondition(query, true);
        for (User_info user : result) {
            System.out.println(user);
        }
    }
登录后复制

因为这里用到的查询条件为空,所有会匹配数据库的所有项:

java实现对mongodb,泛型封装增删查改、条件查询等操作-LMLPHP

现在测试一下设置权限为1的数据:

public static void main(String[] args) {
        User_info record = new User_info();
        record.setRole(1);
        BaseQuery<User_info> query = new BaseQuery<>();
        query.setQuery(record);

        BaseMongoDao dao = new BaseMongoDao("test");
        List<User_info> result = dao.queryByCondition(query, true);
        for (User_info user : result) {
            System.out.println(user);
        }
    }
登录后复制

输出:

java实现对mongodb,泛型封装增删查改、条件查询等操作-LMLPHP

这个条件查询方法是一个例子,其他的删除,增加,修改都是这个原理,下面带有:

1.public <Q> List<Q> queryByCondition(BaseQuery<Q> query,boolean up)

2.public <Q> Integer queryCoditionCount(BaseQuery<Q> query)

3.public <Q> boolean insertOne(Q record)

4.public <Q> boolean insertList(List<Q> records)

5.public boolean deleteById(Integer id)

6.public boolean deleteByIds(List<Integer> ids)

7.public <Q> void updateById(Q record)

放上所有代码:

package cn.wzy.dao;

import com.mongodb.*;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;
import org.bson.Document;
import org.cn.wzy.query.BaseQuery;
import org.cn.wzy.util.PropertiesUtil;

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

/**
 * Create by Wzy
 * on 2018/7/28 18:15
 * 不短不长八字刚好
 */
public class BaseMongoDao {

    private static final MongoClient mongoClient;

    private static final MongoDatabase mongo;

    static {
        MongoClientOptions options = MongoClientOptions.builder()
                .connectionsPerHost(150)
                .maxWaitTime(2000)
                .socketTimeout(2000)
                .maxConnectionLifeTime(5000)
                .connectTimeout(5000).build();
        ServerAddress serverAddress = new ServerAddress(PropertiesUtil.StringValue("mongo.host"),
                PropertiesUtil.IntegerValue("mongo.port"));
        List<ServerAddress> addrs = new ArrayList<>();
        addrs.add(serverAddress);
        MongoCredential credential = MongoCredential.createScramSha1Credential(
                PropertiesUtil.StringValue("mongo.user")
                , PropertiesUtil.StringValue("mongo.db")
                , PropertiesUtil.StringValue("mongo.pwd").toCharArray());
        mongoClient = new MongoClient(addrs, credential, options);
        mongo = mongoClient.getDatabase(PropertiesUtil.StringValue("mongo.db"));
    }

    public BaseMongoDao(String colName) {
        this.colName = colName;
    }

    private String colName;

    private MongoCollection<Document> thisCollection() {
        return mongo.getCollection(colName);
    }


    public <Q> List<Q> queryByCondition(BaseQuery<Q> query,boolean up) {
        Q record = query.getQuery();
        BasicDBObject cond = getCondition(record);
        FindIterable<Document> findIterable;
        if (query.getStart() != null && query.getRows() != null)
            findIterable = thisCollection().find(cond)
                    .sort(new BasicDBObject("id", up ? 1 : -1))
                    .skip((query.getStart() - 1) * query.getRows())
                    .limit(query.getRows());
        else
            findIterable = thisCollection().find(cond)
                    .sort(new BasicDBObject("id", up ? 1 : -1));
        MongoCursor<Document> iterator = findIterable.iterator();
        List<Q> result = new ArrayList<>();
        while (iterator.hasNext()) {
            Document document = iterator.next();
            result.add((Q) parseToObject(document, record.getClass()));
        }
        iterator.close();
        return result;
    }

    public <Q> Integer queryCoditionCount(BaseQuery<Q> query) {
        Q record = query.getQuery();
        BasicDBObject cond = getCondition(record);
        return (int) thisCollection().countDocuments(cond);
    }

    public <Q> boolean insertOne(Q record) {
        BasicDBObject cond = getCondition(record);
        try {
            int top = getTop();
            cond.put("id",++top);
            thisCollection().insertOne(new Document(cond));
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    public <Q> boolean insertList(List<Q> records) {
        try {
            List<Document> list = new ArrayList<>(records.size());
            if (!changeIds(records))
                return false;
            for (Q record : records) {
                list.add(new Document(getCondition(record)));
            }
            thisCollection().insertMany(list);
            return true;
        }catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    public boolean deleteById(Integer id) {
        try {
            if (id == null)
                return false;
            thisCollection().deleteOne(new BasicDBObject("id",id));
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    public  boolean deleteByIds(List<Integer> ids) {
        BasicDBObject cond = new BasicDBObject("id",new BasicDBObject("$in",ids.toArray()));
        try {
            thisCollection().deleteMany(cond);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 只通过id更改,查询就只是搜索id
     * @param record
     * @param <Q>
     */
    public <Q> void updateById(Q record) {
        BasicDBObject cond = getCondition(record);
        BasicDBObject update = new BasicDBObject("$set",cond);
        BasicDBObject query = new BasicDBObject("id",cond.get("id"));
        thisCollection().updateOne(query,update);
    }

    /**
     * 通过反射获取非空字段信息
     * @param record
     * @param <Q>
     * @return
     */
    private <Q> BasicDBObject getCondition(Q record) {
        BasicDBObject cond = new BasicDBObject();
        Class clazz = record.getClass();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            try {
                field.setAccessible(true);
                Object value = field.get(record);
                if (value != null)
                    cond.put(field.getName(), value);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return cond;
    }

    /**
     * 将结果转化为自定义对象
     * @param document
     * @param target
     * @param <Q>
     * @return
     */
    private <Q> Q parseToObject(Document document, Class<Q> target) {
        try {
            Q result = target.newInstance();
            Field[] fields = target.getDeclaredFields();
            for (Field f : fields) {
                f.setAccessible(true);
                Object value = document.get(f.getName());
                if (value == null)
                    continue;
                else if (f.getType() == Integer.class)
                    f.set(result, ((Number) value).intValue());
                else if (f.getType() == Long.class)
                    f.set(result, ((Number) value).longValue());
                else
                    f.set(result, document.get(f.getName(), f.getType()));
            }
            return result;
        } catch (IllegalAccessException e) {
            e.printStackTrace();
            return null;
        } catch (InstantiationException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 使id自增
     * @param records
     * @param <Q>
     * @return
     */
    private <Q> boolean changeIds(List<Q> records) {
        if (records == null || records.size() == 0)
            return false;
        Class clazz = records.get(0).getClass();
        try {
            Field id = clazz.getDeclaredField("id");
            id.setAccessible(true);
            int top = getTop();
            for (Q record: records) {
                id.set(record,++top);
            }
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
            return false;
        } catch (IllegalAccessException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 查找顶针
     * @return
     */
    private int getTop() {
        return ((Number) thisCollection().find().sort(new BasicDBObject("id",-1)).first().get("id")).intValue();
    }

}
登录后复制

相关文章:

java操作mongodb:基本的增删改查

MongoDB(六)java操作mongodb增删改查

相关视频:

黑马云课堂mongodb实操视频教程

以上就是java实现对mongodb,泛型封装增删查改、条件查询等操作的详细内容,更多请关注Work网其它相关文章!

08-22 12:54