0

0

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

php是最好的语言

php是最好的语言

发布时间:2018-07-30 13:47:34

|

3702人浏览过

|

来源于php中文网

原创

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

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

/**
     * 通过反射获取非空字段信息
     * @param record
     * @param 
     * @return
     */
    private  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 
     * @return
     */
    private  Q parseToObject(Document document, Class 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  List queryByCondition(BaseQuery query,boolean up) {
        Q record = query.getQuery();
        BasicDBObject cond = getCondition(record);
        FindIterable 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 iterator = findIterable.iterator();
        List 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 {
    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 query = new BaseQuery<>();
        query.setQuery(record);

        BaseMongoDao dao = new BaseMongoDao("test");
        List result = dao.queryByCondition(query, true);
        for (User_info user : result) {
            System.out.println(user);
        }
    }

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

1.png

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

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

        BaseMongoDao dao = new BaseMongoDao("test");
        List result = dao.queryByCondition(query, true);
        for (User_info user : result) {
            System.out.println(user);
        }
    }

输出:

2.png

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

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

2.public Integer queryCoditionCount(BaseQuery query)

3.public boolean insertOne(Q record)

4.public boolean insertList(List records)

5.public boolean deleteById(Integer id)

6.public  boolean deleteByIds(List ids)

7.public 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 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 thisCollection() {
        return mongo.getCollection(colName);
    }


    public  List queryByCondition(BaseQuery query,boolean up) {
        Q record = query.getQuery();
        BasicDBObject cond = getCondition(record);
        FindIterable 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 iterator = findIterable.iterator();
        List result = new ArrayList<>();
        while (iterator.hasNext()) {
            Document document = iterator.next();
            result.add((Q) parseToObject(document, record.getClass()));
        }
        iterator.close();
        return result;
    }

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

    public  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  boolean insertList(List records) {
        try {
            List 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 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 
     */
    public  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 
     * @return
     */
    private  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 
     * @return
     */
    private  Q parseToObject(Document document, Class 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 
     * @return
     */
    private  boolean changeIds(List 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增删改查

相关视频:

ima.copilot
ima.copilot

腾讯大混元模型推出的智能工作台产品,提供知识库管理、AI问答、智能写作等功能

下载

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

立即学习Java免费学习笔记(深入)”;

相关文章

java速学教程(入门到精通)
java速学教程(入门到精通)

java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
excel制作动态图表教程
excel制作动态图表教程

本专题整合了excel制作动态图表相关教程,阅读专题下面的文章了解更多详细教程。

20

2025.12.29

freeok看剧入口合集
freeok看剧入口合集

本专题整合了freeok看剧入口网址,阅读下面的文章了解更多网址。

65

2025.12.29

俄罗斯搜索引擎Yandex最新官方入口网址
俄罗斯搜索引擎Yandex最新官方入口网址

Yandex官方入口网址是https://yandex.com;用户可通过网页端直连或移动端浏览器直接访问,无需登录即可使用搜索、图片、新闻、地图等全部基础功能,并支持多语种检索与静态资源精准筛选。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

197

2025.12.29

python中def的用法大全
python中def的用法大全

def关键字用于在Python中定义函数。其基本语法包括函数名、参数列表、文档字符串和返回值。使用def可以定义无参数、单参数、多参数、默认参数和可变参数的函数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

16

2025.12.29

python改成中文版教程大全
python改成中文版教程大全

Python界面可通过以下方法改为中文版:修改系统语言环境:更改系统语言为“中文(简体)”。使用 IDE 修改:在 PyCharm 等 IDE 中更改语言设置为“中文”。使用 IDLE 修改:在 IDLE 中修改语言为“Chinese”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

16

2025.12.29

C++的Top K问题怎么解决
C++的Top K问题怎么解决

TopK问题可通过优先队列、partial_sort和nth_element解决:优先队列维护大小为K的堆,适合流式数据;partial_sort对前K个元素排序,适用于需有序结果且K较小的场景;nth_element基于快速选择,平均时间复杂度O(n),效率最高但不保证前K内部有序。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

12

2025.12.29

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

134

2025.12.29

抖音网页版入口在哪(最新版)
抖音网页版入口在哪(最新版)

抖音网页版可通过官网https://www.douyin.com进入,打开浏览器输入网址后,可选择扫码或账号登录,登录后同步移动端数据,未登录仅可浏览部分推荐内容。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

63

2025.12.29

快手直播回放在哪看教程
快手直播回放在哪看教程

快手直播回放需主播开启功能才可观看,主要通过三种路径查看:一是从“我”主页进入“关注”标签再进主播主页的“直播”分类;二是通过“历史记录”中的“直播”标签页找回;三是进入“个人信息查阅与下载”里的“直播回放”选项。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

18

2025.12.29

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 2.1万人学习

MongoDB 教程
MongoDB 教程

共17课时 | 1.7万人学习

C# 教程
C# 教程

共94课时 | 5.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号