java操作MongoDB

本文详细介绍了如何使用Java的原生MongoDB API进行数据库操作,包括连接、插入、查询、更新和删除数据。通过示例代码展示了如何创建MongoDB连接、获取数据库对象以及执行CRUD操作,适合MongoDB初学者学习。

Java 操作MongoDB,一般有两种方式,第一就是Spring Data MongoDB,第二是MongoDB原生API操作。现在都流行Spring Boot,故在实际开发中基本都用Spring Data MongoDB;但是对于初学者,乃至学生,就不推荐使用Spring Data MongoDB了,学习时候要知其然,而知其所以然。有学生就偷懒,使用Spring Data MongoDB,不知其所以然,导致老师问的时候一问三不知,根本解析不清楚MongoTemplate是啥玩意儿。
本篇讲解使用原生API操作MongoDB,也是为了解决有些学生刚学MongoDB时候的烦恼。
引入MongoDB驱动包,这里用maven坐标(非Maven工程直接下载jar包即可):

<dependency>
    <groupId>org.mongodb</groupId>
    <artifactId>mongo-java-driver</artifactId>
    <version>3.12.10</version>
</dependency>

创建链接MongoDB的类:

package mongodb;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.ObjectUtils.Null;

import com.mongodb.MongoClient;
import com.mongodb.MongoClientOptions;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import com.mongodb.client.MongoDatabase;

/**
 * MongoDB 操作类连接
 * @author hlinfo.net
 *
 */
public class MongodbConn {
	//MongoDB数据库地址
	private static String host="192.168.1.2";
	// Mongodb端口号, 默认是27017
	private static int port = 27017;
	//Mongodb 用户名,没有设置可以为空
	private static String userName="";
	//mongoDB 密码,没有设置可以为空
	private static String password="";
	//MongoDB 默认链接的数据库
	private static String databaseName="demo";
	/**
     * MongoDB连接对象
     */
    private MongoClient client;
    
    /**
     * 不需要认证获取连接对象
     */
    public void mongoClient(){
        try {
            //获取mongodb连接对象
            client = new MongoClient(host,port);
        } catch (Exception e) {
            System.out.println("不需要认证获取连接对象失败:"+e);
        }
    }

    /**
     * 需要认证获取连接对象
     */
    public void certifyMongoClient(){
        try {
              //连接到MongoDB
            //ServerAddress()两个参数分别为 服务器地址 和 端口
            ServerAddress serverAddress = new ServerAddress(host,port);
            List<ServerAddress> addrs = new ArrayList<ServerAddress>();
            addrs.add(serverAddress);

            //createScramSha1Credential()三个参数分别为 用户名,数据库名,密码
            MongoCredential credential = MongoCredential.createScramSha1Credential(userName, databaseName, password.toCharArray());
            //List<MongoCredential> credentials = new ArrayList<MongoCredential>();
            //credentials.add(credential);
            MongoClientOptions options = MongoClientOptions.builder().build();
            //通过连接认证获取MongoDB连接
            client = new MongoClient(addrs,credential,options);
        } catch (Exception e) {
        	System.out.println("需要认证的获取连接对象失败:"+e);
        }
    }
    
    /**
     * 获取数据库对象
     * @param databaseName  数据库名
     * @return  MongoDatabase
     */
    public MongoDatabase getDatabase(){
        if(client == null){
        	//没有配置用户名和密码的情况
        	if(userName==null || "".equals(userName) || password==null || "".equals(password)) {        		
        		mongoClient();
        	}else {
        		//配置用户名和密码的情况
        		certifyMongoClient();
        	}
        }
        MongoDatabase database = client.getDatabase(databaseName);
        return database;
    }
    
    /**
     * 关闭连接对象
     */
    public void close(){
        if(client != null){
            client.close();
        }
       client = null;
    }

}

MongoDB操作类:

package mongodb;


import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.bson.Document;
import org.bson.conversions.Bson;
import org.bson.types.ObjectId;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mongodb.BasicDBObject;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.Filters;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.lang.Nullable;

import cn.hutool.core.bean.BeanUtil;

/**
 * MongoDB 操作类
 * @author hadoop
 *
 */
public class MongodbHelper {
	
	private MongoDatabase db;
	private MongodbConn conn;

	public MongodbHelper() {
		super();
		//获取数据库对象
		if(db==null || conn ==null) {
			conn = new MongodbConn();
			db = conn.getDatabase();
		}
	}
	/**
	 * 关闭连接对象
	 */
	public void closeDb() {
		if(db!=null) {
			conn.close();
		}
	}
	/**
	 * //获取指定文档集合对象
	 * @param coll
	 * @return
	 */
	public MongoCollection<Document> getColl(String coll) {
		MongoCollection<Document> mongocoll = db.getCollection(coll);
		return mongocoll;
	}
	/**
	 * 保存一条数据
	 * @param coll,表名
	 * @param map
	 */
	public void insertOne(String coll,Map<String,Object> map) {
		//获取文档集合对象
		MongoCollection<Document> doc = getColl(coll);
		//将map转换为Document
		Document document = new Document(map);
		//插入文档
		doc.insertOne(document);
	}
	
	/**
	 * 保存一条数据
	 * @param coll,表名
	 * @param json JSON对象字符串数据
	 */
	public void insertOne(String coll,String json) {
		//获取文档集合对象
		MongoCollection<Document> doc = getColl(coll);
		//将map转换为Document
		Document document = Document.parse(json);
		//插入文档
		doc.insertOne(document);
	}
	
	/**
	 * 将一个对象插入到一个数据源。
	 * @param obj 要被插入的对象
	 *             <p>
      *            它可以是:
     *            <ul>
     *            <li>普通 POJO
     *            <li>List集合
     *            </ul>
     *            <b style=color:red>注意:</b> 如果是list,所有的对象必须类型相同,否则可能会出错
      * 
	 */
	public boolean insert(Object obj) {
		if(obj==null) {
			return false;
		}
		if(BeanUtil.isBean(obj.getClass())) {			
			//获取文档集合对象
			MongoCollection<Document> doc = getColl(getClazzName(obj));
			//将map转换为Document
			Document document = Document.parse(JSON.toJSONString(obj));
			//插入文档
			doc.insertOne(document);
		}else if(obj instanceof ArrayList || obj instanceof LinkedList) {
			Object firstObj = first(obj);
			List<Document> list = new ArrayList<Document>();
			Collection parseObj = (Collection) obj;
			parseObj.forEach(item->{
				Document doc = Document.parse(JSON.toJSONString(item));
				list.add(doc);
			});
			insertMany(getClazzName(firstObj), list);
		}
		return true;
	}
	
	/**
	 * 保存多条数据
	 * @param coll 表名
	 * @param list 多个Document集合
	 */
	public void insertMany(String coll,List<Document> list) {
		//获取文档集合对象
		MongoCollection<Document> doc = getColl(coll);
		//插入文档
		doc.insertMany(list);
	}
	/**
	 * 删除单条数据
	 * @param coll 表名
	 * @param params 筛选条件对象
	 * @return
	 */
	public long deleteById(String coll,BasicDBObject params) {
		//获取文档集合对象
		MongoCollection<Document> doc = getColl(coll);
		//删除单条数据
		DeleteResult result = doc.deleteOne(params);
		return result.getDeletedCount();
	}
	/**
	 * 删除单条数据
	 @param clazz 对象类型
	 @param params 筛选条件对象
	 @return
	 */
	public long deleteById(Class<?> clazz,BasicDBObject params) {
		return deleteById(getClazzName(clazz),params);
	}
	/**
	 * 删除单条数据
	 @param clazz 对象类型
	 @param key 删除的主键名
	 @param value 删除的条件值
	 @return
	 */
	public long deleteById(Class<?> clazz,String key,Object value) {
		if(clazz==null || key==null || value==null) {
			return -1;
		}
		//设置条件参数
		BasicDBObject params = new BasicDBObject(key, value);
		return deleteById(getClazzName(clazz),params);
	}
	
	/**
	 * 删除多条数据
	 * @param coll 表名
	 * @param params 筛选条件对象
	 * @return
	 */
	public long delete(String coll,BasicDBObject params) {
		//获取文档集合对象
		MongoCollection<Document> doc = getColl(coll);
		//删除多条数据
		DeleteResult result = doc.deleteMany(params);
		return result.getDeletedCount();
	}
	/**
	 * 查询所有数据
	 * @param coll 表名
	 * @return
	 */
	public FindIterable<Document> query(String coll) {
		//获取文档集合对象
		MongoCollection<Document> doc = getColl(coll);
		return doc.find();
	}
	
	public <T> FindIterable<Document> query(Class<T> clazz) {
		//获取文档集合对象
		MongoCollection<Document> doc = getColl(getClazzName(clazz));
		return doc.find();
	}
	
	/**
	 * 根据条件查询数据
	 * @param coll 表名
	 * @param params 查询条件
	 * @return
	 */
	public FindIterable<Document> query(String coll,BasicDBObject params) {
		//获取文档集合对象
		MongoCollection<Document> doc = getColl(coll);
		return doc.find(params);
	}
	public FindIterable<Document> query(Class<?> clazz,Bson filter) {
		//获取文档集合对象
		MongoCollection<Document> doc = getColl(getClazzName(clazz));
		return doc.find(filter);
	}
	/**
	 * 根据主键_id查找对象
	 @param coll
	 @param id
	 @return
	 */
	public Document findById(String coll, String id) {
		 ObjectId _idobj = null;
		 try {
		 	_idobj = new ObjectId(id);
		 } catch (Exception e) {
			 return null;
		 }
		 //获取文档集合对象
		 MongoCollection<Document> doc = getColl(coll);
		 Document myDoc = doc.find(Filters.eq("_id", _idobj)).first();
		 return myDoc;
	}
	/**
	 * 分页查询
	 @param coll
	 @param params
	 @param page
	 @param limit
	 @return
	 */
    public MongoCursor<Document> queryByPage(String coll,BasicDBObject params, int page, int limit) {
    	MongoCollection<Document> doc = getColl(coll);
    	//排序
    	Bson orderBy = new BasicDBObject("_id", 1);
    	FindIterable<Document> docfilter =  params==null?doc.find():doc.find(params);
        return docfilter.sort(orderBy).skip((page - 1) * page).limit(limit).iterator();
    }
    /**
     * 
     @param clazz 对象类型
     @param filter 过滤条件,如:Filters.eq("name", "张三")
     @param page
     @param limit
     @return
     */
    public <T> List<T> queryByPage(Class<T> clazz,Bson filter, int page, int limit) {
    	MongoCollection<Document> doc = getColl(getClazzName(clazz));
    	//排序
    	Bson orderBy = new BasicDBObject("_id", 1);
    	FindIterable<Document> docfilter =  filter==null?doc.find():doc.find(filter);
    	MongoCursor<Document> result = docfilter.sort(orderBy).skip((page - 1) * page).limit(limit).iterator();
    	List<T> list = new ArrayList<T>();
    	while(result.hasNext()) {
    		JSONObject json = JSON.parseObject(result.next().toJson());
    		json.remove("_id");
    		T item = JSON.toJavaObject(json, clazz);
    		list.add(item);
    	}
    	return list;
    }
    /**
     * 
     @param clazz 对象类型
     @param filter 过滤条件,如:filter = Filters.eq("name", "张三")
     @param orderBy 排序,如:orderBy = new BasicDBObject("date", 1);1升序,-1表示倒序
     @param page
     @param limit
     @return
     */
    public <T> List<T> queryByPage(Class<T> clazz,Bson filter,Bson orderBy, int page, int limit) {
    	MongoCollection<Document> doc = getColl(getClazzName(clazz));
    	//排序
    	if(orderBy==null) {
    		orderBy = new BasicDBObject("_id", 1);
    	}
    	FindIterable<Document> docfilter =  filter==null?doc.find():doc.find(filter);
    	MongoCursor<Document> result = docfilter.sort(orderBy).skip((page - 1) * page).limit(limit).iterator();
    	List<T> list = new ArrayList<T>();
    	while(result.hasNext()) {
    		JSONObject json = JSON.parseObject(result.next().toJson());
    		json.remove("_id");
    		T item = JSON.toJavaObject(json, clazz);
    		list.add(item);
    	}
    	return list;
    }
    /**
     * 查询所有数据
     @param clazz 对象类型
     @param filter 过滤条件,如:Filters.eq("name", "张三")
     @return
     */
    @SuppressWarnings("hiding")
	public <T> List<T> queryAllList(Class<T> clazz,Bson filter) {
    	MongoCollection<Document> doc = getColl(getClazzName(clazz));
    	//排序
    	Bson orderBy = new BasicDBObject("_id", 1);
    	FindIterable<Document> docfilter =  filter==null?doc.find():doc.find(filter);
    	MongoCursor<Document> result = docfilter.sort(orderBy).iterator();
    	List<T> list = new ArrayList<T>();
    	while(result.hasNext()) {
    		JSONObject json = JSON.parseObject(result.next().toJson());
    		json.remove("_id");
    		T item = JSON.toJavaObject(json, clazz);
    		list.add(item);
    	}
    	return list;
    }
	/**
	 *  统计总数 
	 *  @param coll 集合名
	 */
    public long count(String coll) {
    	//获取文档集合对象
		MongoCollection<Document> doc = getColl(coll);
		return doc.countDocuments();
    }
    /**
     * 统计总数
     @param clazz JavaBean类
     @return
     */
    public long count(Class<?> clazz) {
    	//获取文档集合对象
		MongoCollection<Document> doc = getColl(getClazzName(clazz));
		return doc.countDocuments();
    }
    /**
     * 根据条件查询数量 
     @param coll
     @param params
     @return
     */
    public long count(String coll,BasicDBObject params) {
    	//获取文档集合对象
		MongoCollection<Document> doc = getColl(coll);
		return doc.countDocuments(params);
    }
    /**
     * 根据条件查询数量 
     @param clazz JavaBean类
     @param params 参数
     @return
     */
    public long count(Class<?> clazz,BasicDBObject params) {
    	//获取文档集合对象
		MongoCollection<Document> doc = getColl(getClazzName(clazz));
		return doc.countDocuments(params);
    }
	/**
	 * 修改一条数据
	 * @param coll 表名
	 * @param params 参数(类似于sql中的where条件)
	 * @param document 需要操作的文档对象
	 * <pre>
	 *  //设置条件参数
	 * BasicDBObject params = new BasicDBObject("id", 5);
	 *  //实例化修改对象:
	 * Document document = new Document();
	 * //添加修改内容:
	 * document.append("$set",new Document("sex","男"));
	 * </pre>
	 */
	public void update(String coll,BasicDBObject params,Document document) {
		//获取文档集合对象
		MongoCollection<Document> doc = getColl(coll);
		doc.updateOne(params,document);
	}
	/**
	  * 修改一条数据
	 *@param clazz JavaBean类
	 * @param params 参数(类似于sql中的where条件)
	 * @param document 需要操作的文档对象
	 * <pre>
	 * //设置条件参数
	 * BasicDBObject params = new BasicDBObject("id", 5);
	 *  //实例化修改对象:
	 * Document document = new Document();
	 * //添加修改内容:
	 * document.append("$set",new Document("sex","男"));
	 * </pre>
	 */
	public void update(Class<?> clazz,BasicDBObject params,Document document) {
		//获取文档集合对象
		MongoCollection<Document> doc = getColl(getClazzName(clazz));
		doc.updateOne(params,document);
	}
	
	/**
	 * 修改多条数据
	 * @param coll 表名
	 * @param params 参数(类似于sql中的where条件)
	 * @param document 需要操作的文档对象
	 * <pre>
	 * 实例化修改对象:
	 * Document document = new Document();
	 * //添加修改内容:
	 * document.append("$set",new Document("sex","男"));
	 * </pre>
	 */
	public void updateMany(String coll,BasicDBObject params,Document document) {
		//获取文档集合对象
		MongoCollection<Document> doc = getColl(coll);
		doc.updateMany(params,document);
	}
	/**
	 * 设置mongodb修改数据,通过反射获取javaBean的属性名和值
	 @param obj 数据对象
	 @param document 修改对象
	 @param filterField 需要过滤的字段,格式为javaBean实体属性名,多个用竖线|分隔,如:id|userPasswd
	 @return
	 */
	public Document updateSetFieldVal(Object obj,Document document,String filterField) {
		if(obj==null) {return document;}
		try {
			//构造修改数据对象,mongodb修改数据命令为:db.news.update({'id':11},{$set:{'name':'111',"title":"标题"}},{multi:true})
			Document doc = new Document();
			for (Field field : obj.getClass().getDeclaredFields()) {
				field.setAccessible(true);
				Object value = field.get(obj);
				Nullable nb = field.getAnnotation(Nullable.class);
				//判断需要过滤的属性
				if(filterField!=null && !"".equals(filterField)) {
					String[] filterFields = filterField.split("\\|");
					if(Arrays.asList(filterFields).contains(field.getName())) {
						continue;
					}
				}
				if(nb !=null) {
					doc.append(field.getName(),value);
				}else {
					if (value!=null) {
						doc.append(field.getName(),value);
					}
				}
			}
			document.append("$set",doc);
			return document;
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("对象属性为空异常" + e);
			return document;
		}
	}
	/**
	*获取指定对象的类名,并将首字母转为小写
	*/
	private String getClazzName(Object obj) {
		String clazzName = obj.getClass().getSimpleName();
		String firstChar=clazzName.substring(0,1);
		clazzName=clazzName.replaceFirst(firstChar, firstChar.toLowerCase());
		return clazzName;
	}
	/**
	*获取指定类的类名,并将首字母转为小写
	*/
	private String getClazzName(Class<?> clazz) {
		String clazzName = clazz.getSimpleName();
		String firstChar=clazzName.substring(0,1);
		clazzName=clazzName.replaceFirst(firstChar, firstChar.toLowerCase());
		return clazzName;
	}
	/**
	*获取集合的第一个元素
	*/
	public static Object first(Object obj) {
        if (null == obj)
            return obj;

        if (obj instanceof Collection<?>) {
            Iterator<?> it = ((Collection<?>) obj).iterator();
            return it.hasNext() ? it.next() : null;
        }

        if (obj.getClass().isArray())
            return Array.getLength(obj) > 0 ? Array.get(obj, 0) : null;

        return obj;
    }
	
	
}


其中用到了:fastjson,hutool的BeanUtil等工具
测试一下:

public static void main(String[] args) {
	MongodbHelper mongodbHelper = new MongodbHelper();
	Map<String,Object> map = new HashMap<>();
	map.put("id",100);
	map.put("name","张三");
	map.put("age",18);
	map.put("stuNo", "2106050540000");
	map.put("sex","女");
	mongodbHelper.insertOne("userInfo", map);
	
	FindIterable<Document> list = mongodbHelper.query("userInfo");
	for(Document doc:list) {
		System.out.println(doc);
	}
	/////////////////对象操作示例/////////////////////////////////
	DemoData demoData = new DemoData();
	demoData.setId(UUID.randomUUID().toString().replace("-", ""));
	demoData.setCode("200");
	demoData.setDate(LocalDateTime.now().toString());
	demoData.setName("李四");
	demoData.setDoubleData(2022)
	//增加
	mongodbHelper.insert(demoData);
	
	//////修改开始///////////////
	//实例化修改对象:
	Document document = new Document();
	//添加修改内容:		
	mongodbHelper.updateSetFieldVal(demoData, document, "id");
	//执行修改
	BasicDBObject params = new BasicDBObject("id", "682afe866bbf43e9bf4a62c8f3cdda7c");
	mongodbHelper.update(DemoData.class, params, document);
	//////修改结束///////////////
	
	//查询
	Bson param = Filters.eq("name", "张三");
	List<DemoData> rslist = mongodbHelper.queryByPage(DemoData.class, param,1,5);
	System.out.println(rslist);
}

DemoData实体类为:

package mongodb.demo;
import com.alibaba.fastjson.JSON;

public class DemoData {
	private String id;
	
	//标题
    private String name;
	
	//日期
    private String date;
	
	//数量
    private int doubleData;
	
	private String code;
	
	public DemoData() {
		super();
		// TODO Auto-generated constructor stub
	}
	public DemoData(String id, String name, String date, int doubleData, String code) {
		super();
		this.id = id;
		this.name = name;
		this.date = date;
		this.doubleData = doubleData;
		this.code = code;
	}
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getCode() {
		return code;
	}
	public void setCode(String code) {
		this.code = code;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getDate() {
		return date;
	}
	public void setDate(String date) {
		this.date = date;
	}
	public int getDoubleData() {
		return doubleData;
	}
	public void setDoubleData(int doubleData) {
		this.doubleData = doubleData;
	}
	@Override
	public String toString() {
		return JSON.toJSONString(this, true);
	}
}
### Java 操作 MongoDB 的基础 为了实现对MongoDB操作,在Java程序中通常会引入`mongodb-driver-sync`库。此库提供了同步驱动器,允许开发者执行基本的CRUD操作以及更复杂的查询。 #### 创建连接并获取数据库实例 建立与MongoDB服务器的连接是任何交互的第一步。这可以通过`MongoClients.create()`方法完成,该方法返回一个表示客户端连接的对象。对于本地运行的服务,默认情况下监听27017端口[^2]: ```java import com.mongodb.client.MongoClient; import com.mongodb.client.MongoClients; // 创建一个新的 MongoClient 实例用于连接默认地址 (localhost) 和端口 (27017) MongoClient mongoClient = MongoClients.create(); ``` 接着可以利用获得的客户端对象调用`getDatabase(String dbName)`函数来选定特定名称下的数据库作为工作区: ```java com.mongodb.client.MongoDatabase database = mongoClient.getDatabase("test"); ``` #### 执行 CRUD 操作 ##### 插入文档 向集合内添加新记录涉及构建BSON格式的数据结构并通过适当的方法提交给目标集合。下面的例子展示了怎样往名为“users”的集合里加入一条新的用户信息[^3]: ```java import org.bson.Document; public void insertUser() { Document userDoc = new Document("name", "Alice").append("age", 30); database.getCollection("users").insertOne(userDoc); } ``` ##### 查询文档 检索已存数据同样依赖于Document类定义条件表达式,并传递至find()或findOneAndDelete()等查找接口。这里给出一段简单的代码片段用来展示如何读取所有用户的姓名列表: ```java for (Document doc : database.getCollection("users").find()) { System.out.println(doc.getString("name")); } ``` ##### 更新现有条目 当需要修改某些字段的内容时,则应该准备更新指令连同匹配模式一起交给updateMany()或者replaceOne()这样的命令处理。下述例子说明了更改年龄大于等于30岁的所有人职业为工程师的过程[^5]: ```java database.getCollection("users") .updateMany( Filters.gte("age", 30), Updates.set("job", "engineer") ); ``` ##### 删除指定项 最后如果想要移除符合条件的一条或多条记录,可借助deleteOne()或是deleteMany()来进行相应设置。比如删除名字叫Bob的所有条目的方式如下所示: ```java database.getCollection("users").deleteMany(new Document("name", "Bob")); ``` 以上就是关于使用Java语言控制MongoDB的一些基础知识和技术要点概述[^4]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值