MongoDB从入门到删库跑路 ---mongo原生java驱动整合及简单CRUD

首先,cmd命令行打开MongoDB连接,use使用test(自行更换自己使用的库)库。查看owner表内上一篇中创建的数据。这里贴一个测试数据的json数据结构。

var owner1 = {
	name: "张三",
	age: 25,
	books: {
		name: "天涯明月刀",
		author: "古龙"
	},
	favorites: {
		movies: ["盗梦空间", "杀破狼", "羞羞的铁拳"],
		cites: ["北京", "上海", "深圳"]
	},
	salary: NumberDecimal("100.05")
};

 

--- java程序获取mongoDB数据库及集合连接

1.程序pom文件引入mongoDB原生java驱动包。更新并clean项目。

<!-- mongoDB原生java驱动 -->
<!-- 3.5之后的版本,新增了对java的pojo的支持 -->
<dependency>
	<groupId>org.mongodb</groupId>
	<artifactId>mongo-java-driver</artifactId>
	<version>3.5.0</version>
</dependency>

 2.建立测试service类。声明3个变量:MongoClient、MongoDatabase、MongoCollection,如图:

import org.bson.Document;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.mongodb.MongoClient;

/**
 * mongodb连接池
 */
private MongoClient client;

/**
 * mongoDB库
 */
private MongoDatabase db;

/**
 * mongoDB集合,泛型为mongoDB文档
 */
private MongoCollection<Document> mongoCollection;

首先。mongoClient为mongoDB提供的连接client,内部提供了mongoDB连接池,不需要再引用第三方依赖,并且在官方文档中详细说明了:这个client是线程安全的,因此大部分情况下,jvm中只需要存在一个client实例。

从mongoClient中可以获取目标库,继而连接目标集合。

MongoCollection<Document>,泛型类型为Document。在mongoDB原生驱动内,所有数据元素均为文档--Document。文档并不限制具体类型,也不限制文档内属性数量及属性类型。与java的model参照对比理解。

3.通过mongoClient获取目标mongo实例连接,并拿到目标库及集合连接。

    @Before // junit测试使用注解
	public void init() {
		// mongoDB实例ip, 端口(默认27017)
		client = new MongoClient("localhost", 27017);
		// 目标库
		db = client.getDatabase("las");
		// 目标集合
		mongoCollection = db.getCollection("users");
	}

mongoDB连接及库和集合都初始化完毕后,开始java代码中对数据的简单CRUD实现。

--- 使用原生java驱动,操作Document文档,实现简单CRUD

5.新增insert。数据格式参照本文开头json数据格式。

    @Test
	public void insert() {
		Document doc = new Document();
		// -------- 基本属性 --------
		doc.append("name", "李六");
		doc.append("age", 17);
		doc.append("salary", new BigDecimal("5000.21"));

		// ------- 属性值为简单对象 -------
		Map<String, String> books = new HashMap<>();
		books.put("name", "北平往事");
		books.put("author", "不知道");
		doc.append("books", books);

		// ------------ 属性值为对象,内包含不同数据类型。数组集合等 ----------
		Map<String, Object> favorites = new HashMap<>();
		favorites.put("movies", Arrays.asList("三体", "人工智能", "终结者"));
		favorites.put("cites", Arrays.asList("河南", "湖南", "海南"));
		doc.append("favorites", favorites);

		// 使用init()方法内获取的目标集合连接实例,向该集合内插入一个文档
		mongoCollection.insertOne(doc);
	}

junit测试运行insert方法,在cmd中查询db.owner.find(),成功添加一条记录。

6.删除delete。注释采用关系型sql语言说明目的,并将mongoDB中实现相同目的代码贴出。

import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.model.Filters;    

    @Test
	public void delete() {
		// delete from owner where name = "张三"
        Bson f1 = Filters.eq("name", "张三");
        // 删除满足条件的所有文档
		DeleteResult result1 = mongoCollection
				.deleteMany(f1);
		LOG.info("删除了:: " + String.valueOf(result1));

		// delete from owner where age > 25 or age < 5
        Bson f2 = Filters.gt("age", 25)
        Bson f3 = Filters.lt("age", 5)
        Bson f4 = Filters.or(f2, f3)
        // 删除满足条件的所有文档
		DeleteResult result2 = mongoCollection.deleteMany(f4);
		LOG.info("第二次删除了 ::::  " + String.valueOf(result2));
	}

7.更新update。

import com.mongodb.client.result.UpdateResult;
import com.mongodb.client.model.Updates;

    @Test
	public void update() {
		// update owner set age = 4 where name = "王五"

        // 使用替换更新。注意此处与操作符更新区别。
        // Document doc = new Document("age", 4);
        // 使用操作符更新。注意此处与替换更新区别。
        Document doc = new Document("$set", new Document("age", 4));

        // 执行更新。
		UpdateResult result1 = mongoCollection.updateMany(
				Filters.eq("name", "王五"), doc);
        // 打印日志:匹配数量,更新数量。
		LOG.info(String.valueOf(result1.getMatchedCount()), "   ",
				String.valueOf(result1.getModifiedCount()));
        // -------------------------------------------------------------------------------

		// update owner set favorites.movies add "大片1" "大片2"  ---并非有效sql语句,仅为说明目的
		// where favorites.cites has "北京" or "纽约"
        // 使用Updates的addEachToSet方法,将传入的list内的每一个元素都add进目标属性的list最后
        Bson arrayToAdd = Updates.addEachToSet("favorites.movies",
						Arrays.asList("大片1", "大片2"));

        // 执行更新
		UpdateResult result2 = mongoCollection.updateMany(
				Filters.or(Filters.eq("favorites.cites", "北京"),
						Filters.eq("favorites.cites", "纽约")), arrayToAdd );
		LOG.info(String.valueOf(result2.getMatchedCount()), "   ",
				String.valueOf(result2.getModifiedCount()));
	}

注:替换更新new Document("age", 4),会将name = “王五”的文档,更新为只有 "age"属性并且值为4的文档。

       操作符更新new Document("$set", new Document("age", 4)),才会仅修改name = "王五"的文档内age属性值为4。

8.查询find。重点。所有的更新、删除、都需要查询作为条件。

import com.mongodb.Block;
import com.mongodb.client.FindIterable;

    @Test
	public void find() {
        // 查询结果集合。必须使用final声明
		final List<Document> resultList = new ArrayList<>();
		// 查询结果块。Document类型
		Block<Document> block = new Block<Document>() {
			// 调用,将每一个Document传入此中
			@Override
			public void apply(Document t) {
				LOG.info(t.toJson());
				resultList.add(t);
			}
		};

		// select * from owner where favorites.cites has "上海" "华盛顿"
		FindIterable<Document> result1 = mongoCollection.find(
				Filters.all("favorites.cites", Arrays.asList("深圳", "北京")));

        // find()方法查到返回的结果为游标,需要将此遍历并使用Block接受转换为Document
		result1.forEach(block);
		LOG.info("查询1---------------------");
		LOG.info(String.valueOf(resultList.size()));

		// 清空查询结果集合
		resultList.clear();

		// select * from owner
		// where name like '%李%'
		// and (favorites.cites has '印度' or favorites.cites has 纽约)
		String regex = ".*李.*"; // mongoDB内的like模糊查询。使用正则表达式完成
		Bson f1 = Filters.regex("name", regex);

		Bson f2 = Filters.or(Filters.eq("favorites.cites", "印度"),
				Filters.eq("favorites.cites", "纽约"));

		FindIterable<Document> result2 = mongoCollection
				.find(Filters.and(f1, f2));
		result2.forEach(block);

		LOG.info("查询2---------------------");
		LOG.info(String.valueOf(resultList.size()));
	}

9.上述方法中,使用到的Filters,Updates等包括后面将会用到的一些,mongoDB提供的数据操作类,在类的说明上也有标明:建议静态导入所有的方法,在使用该类内提供的静态方法时可省略类名。

注:慎重使用删除和替换更新,防止数据丢失!!! 如若不慎手滑,请参照本文标题解决~~。

猜你喜欢

转载自my.oschina.net/u/3087155/blog/1646772
今日推荐