文章目录
一、Java整合MongoDB
1.java连接MongoDB
- 在new project那里创建一个普通的maven项目mongodbexample。
- 引入java整合MongoDB的依赖
<!-- 引入java整合MongoDB的依赖 --><dependency><groupId>org.mongodb</groupId><artifactId>mongo-java-driver</artifactId><version>3.12.11</version></dependency>
- 在java根目录的com.zzx的包下,创建类MongoDBExample,添加如下代码
publicclassMongoDBExample{publicstaticvoidmain(String[] args){//获取mongodb连接地址String connectionString =System.getProperty("mongodb.uri");try{MongoClient mongoClient =MongoClients.create(connectionString);ArrayList<Document> databases = mongoClient.listDatabases().into(newArrayList<>()); databases.forEach(db->System.out.println(db.toJson()));}catch(Exception e){ e.printStackTrace();}}}
即连接到mongodb并输出所有数据库 - 点击Alt+Shift+F10,选择Edit Configuration,然后选择modify options->选择Add VM options,在框内输入该参数:
-Dmongodb.uri="mongodb://192.168.126.16:27017/?maxPoolSize=2&w=majority"
,最后点击run即可。 - 在java根目录的com.zzx的包下,创建类MongoDBExample2,添加如下代码:
publicclassMongoDBExample2{publicstaticvoidmain(String[] args){Properties properties =newProperties();try{//使用classLoader加载properties文件生成对应的输入流InputStream resourceAsStream =MongoDBExample2.class.getClassLoader().getResourceAsStream("config.properties");//使用properties对象加载输入流 properties.load(resourceAsStream);//获取属性对应的value值String connectionString = properties.getProperty("mongodb.uri");System.out.println(connectionString);//获取MongoClient对象MongoClient mongoClient =MongoClients.create(connectionString);ArrayList<Document> databases = mongoClient.listDatabases().into(newArrayList<>()); databases.forEach(db->System.out.println(db.toJson()));}catch(IOException e){thrownewRuntimeException(e);}}}
- 在resources目录下,创建配置文件config.properties,添加如下配置:
mongodb.uri=mongodb://192.168.126.16:27017/?maxPoolSize=2&w=majority
2.java操作MongoDB
- 新建一个类,MongoDBCRUD,将获取MongoClient对象的部分封装到方法中
publicclassMongoDBCRUD{publicstaticvoidmain(String[] args){try{MongoClient mongoClient =getMongoClient("config.properties");}catch(IOException e){thrownewRuntimeException(e);}finally{ mongoClient.close();}}/** * 获取MongoClient对象 * @param propertyFileName * @return * @throws IOException */privatestaticMongoClientgetMongoClient(String propertyFileName)throwsIOException{Properties properties =newProperties();//使用classLoader加载properties文件生成对应的输入流InputStream resourceAsStream =MongoDBCRUD.class.getClassLoader().getResourceAsStream(propertyFileName);//使用properties对象加载输入流 properties.load(resourceAsStream);//获取属性对应的value值String connectionString = properties.getProperty("mongodb.uri");//获取MongoClient对象MongoClient mongoClient =MongoClients.create(connectionString);return mongoClient;}}
- 创建集合,即在获取MongoClient对象后面添加如下两行
//获取database数据库对象mydbMongoDatabase mydb = mongoClient.getDatabase("mydb");//创建集合mydb.createCollection("exampleCollection");
- 添加文档,代码如下:
//获取集合对象MongoCollection<Document> collection = mydb.getCollection("exampleCollection");//创建文档对象Document document =Document.parse("{name: 'zhangsan',city: 'beijing',birthday: new ISODate('2000-04-02'),expectSalary: 18000}");//插入文档collection.insertOne(document);
- 查询文档
//创建文档对象Document document =Document.parse("{name: 'zhangtao',city: 'beijing',birthday: new ISODate('2000-04-02'),expectSalary: 13000}");Document document2 =Document.parse("{name: 'lisi',city: 'beijing',birthday: new ISODate('2000-04-02'),expectSalary: 12000}");Document document3 =Document.parse("{name: 'wangwu',city: 'beijing',birthday: new ISODate('2000-04-02'),expectSalary: 16000}");//插入文档 collection.insertOne(document); collection.insertOne(document2); collection.insertOne(document3);//按照expectSalary倒排Document expectSalary =newDocument(); expectSalary.append("expectSalary",-1);FindIterable<Document> findIterable = collection.find().sort(expectSalary);for(Document doc:findIterable){System.out.println(doc);}
- 查询指定条件的文档
//按指定的属性值查询FindIterable<Document> documents = collection.find(newDocument("expectSalary",newDocument("$eq",16000)));for(Document doc:documents){System.out.println(doc);}
- 查询过滤文档
//过滤查询 gt大于,gte大于等于FindIterable<Document> filtersexpectSalary = collection.find(Filters.gte("expectSalary",13000)).sort(expectSalary);for(Document doc:filtersexpectSalary){System.out.println(doc);}
二、SpringBoot整合MongoDB
1.搭建MongoDB的web项目
- 创建一个SpringBoot项目mongodb-springboot,在pom文件中添加如下配置:
<properties><java.version>11</java.version><spring-boot-version>2.7.3</spring-boot-version></properties><dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${spring-boot-version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement>
- 删除父项目的src模块,并把pom文件的dependencies标签的文件全部删除,也就是springboot和springboottest的启动依赖。
- 通过new Module,在mongodb-springboot项目中创建web子项目mongodb-test,并在子项目的pom文件中引入如下依赖
<!-- 引入springboot的web依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- 引入springboot整合mongodb的依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId></dependency>
同时父类的pom文件会自动更新为pom类型,并出现modules标签,内部有mongodb-test子模块。 - 在mongodb-test子模块中的java根目录下,创建包com.zzx,并在包下创建springboot启动类,代码如下:
@SpringBootApplicationpublicclassMongodbTestApplication{publicstaticvoidmain(String[] args){SpringApplication.run(MongodbTestApplication.class, args);}}
- 在mongodb-test子模块中的resources目录下创建配置文件application.properties
spring.data.mongodb.host=192.168.126.16spring.data.mongodb.port=27017spring.data.mongodb.database=mydb
2.访问MongoDB的业务代码实现
- 在父工程的pom文件的dependencyManagement中引入lombok依赖进行版本管理
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>${lombok-version}</version></dependency>
- 在子项目的pom文件中引入lombok依赖
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency>
- 在com.zzx包下,创建包entity,在该包下创建实体类Orders,代码如下
importlombok.*;importjava.io.Serializable;importjava.util.Date;@Data@EqualsAndHashCode@NoArgsConstructor@ToStringpublicclassOrdersimplementsSerializable{privateString _id;privateString name;privateString size;privateInteger price;privateInteger quantity;privateDate date;}
2.1 注入MongoTemplate使用MongoDB
- 在com.zzx包下,创建包dao,在该包下创建dao层接口OrderDao,代码如下:
publicinterfaceOrderDao{//根据订单名称查询订单集合List<Orders>findOrdersByName(String name);}
- 在com.zzx.dao包下,创建包impl,在该包下创建实现类OrderDaoImpl,代码如下:
@RepositorypublicclassOrderDaoImplimplementsOrderDao{@AutowiredprivateMongoTemplate mongoTemplate;/** * 按订单名称查询 * @param name * @return */@OverridepublicList<Orders>findOrdersByName(String name){Query query =newQuery(); query.addCriteria(Criteria.where("name").is(name));return mongoTemplate.find(query,Orders.class);}}
- 在com.zzx包下,创建包service,在该包下创建service层接口OrderService,代码如下:
publicinterfaceOrderService{// 按订单名称查询List<Orders>findOrdersByName(String name);}
- 在com.zzx.service包下,创建包impl,在该包下创建实现类OrderServiceImpl,代码如下:
@ServicepublicclassOrderServiceImplimplementsOrderService{@AutowiredprivateOrderDao orderDao;@OverridepublicList<Orders>findOrdersByName(String name){return orderDao.findOrdersByName(name);}}
- 在com.zzx包下,创建包controller,在该包下创建controller层OrderController,代码如下:
@RestController@RequestMapping("orders")publicclassOrderController{@AutowiredprivateOrderService orderService;@GetMapping("/getOrders")publicList<Orders>findOrdersByName(String name){return orderService.findOrdersByName(name);}}
2.2 继承MongoRepository使用MongoDB
- 在com.zzx包下,创建包repository,在该包下创建接口OrdersRepository,代码如下:
publicinterfaceOrdersRepositoryextendsMongoRepository<Orders,String>{/** * 按订单名称查询订单 * @param name * @return */List<Orders>findOrdersByName(String name);}
MongoRepository相当于MybatisPlus。 - 在OrderService接口中,加入如下代码:
List<Orders> findOrdersByName_2(String name);
- 在OrderServiceImpl实现类中,加入如下代码:
@AutowiredprivateOrdersRepository ordersRepository;@OverridepublicList<Orders>findOrdersByName_2(String name){return ordersRepository.findOrdersByName(name);}
- 在OrderController类中,添加如下代码:
@GetMapping("/getOrders2")publicList<Orders>findOrdersByName_2(String name){return orderService.findOrdersByName_2(name);}
三、MongoDB的安全认证及内置角色
1.MongoDB的安全认证
- MongoDB默认是没有账号的,可以直接连接,无须身份验证。实际项目中肯定要权限验证,否则后果不堪设想。
- 进入到容器中,备份数据:
mongodump -h 127.0.0.1:27017 -d mydb -o /usr/local
- 进入到容器中,备份全部数据:
mongodump
即所有数据库备份文件创建在当前目录的/dump目录下 - 将mongo的dump目录,复制到/usr/local目录:
docker cp mongo5:/dump /usr/local/
- 关闭mongo5容器:
docker stop mongo5
- 以auth方式启动MongoDB:
docker run -itd --name mongo6 -p 27017:27017 mongo:5.0.11-focal --auth
- 将备份复制到mongo6:
docker cp /usr/local/dump/ mongo6:/dump
- 进入到mongo6容器:
docker exec -it mongo6 bash
- 进入到mongo命令行客户端,切换到admin数据库。创建MongoDB登录用户以及分配权限的方式
db.createUser({
user: "root",pwd: "123456",
roles:[{role: "root",db:"admin"}]})
参数:
roles:为用户分配的角色,不同的角色拥有不同的权限,参数是数组,可以同时设置多个
role:角色,MongoDB已经约定好的角色,不同角色对应不同的权限。
db:数据库名称,MongoDB默认自带的有admin、local、config、test等,即为数据库实例设置用户
- 验证用户后可以更改密码、添加角色、恢复数据等操作:
db.auth("root","123456")
返回1,即验证成功 - 删除用户:
db.dropUser("用户名")
- 修改密码:
db.changeUserPassword("root","root")
- 添加角色:
db.grantRolesToUser("用户名",[{role: "角色名",db: "数据库名"}])
- 恢复数据:
mongorestore -h localhost -u root -p 123456 --db mydb /dump/mydb --authenticationDatabase admin
- NoSQLBooster可视化连接:
2.MongoDB内置角色(role)
- read:允许用户读取指定数据库
- readWrite:允许用户读写指定数据库
- dbAdmin:可以读取任何数据库并对库进行清理、修改、压缩,获取统计信息、执行检查等操作
- userAdmin:可以在指定数据库里创建、删除和管理用户
- readAnyDatabase:可以读取任何数据库中的数据,除了数据库config和local之外
- readWriteAnyDatabase:可以读写任何数据库中的数据。除了数据库config和local之外
- userAdminAnyDatabase:可以在任何数据库总创建、删除和管理用户,除了数据库config和local之外
- dbAdminAnyDatabase:可以读取任何数据库并对库进行清理、修改、压缩,获取统计信息、执行检查等操作,除了数据库config和local之外
- root:超级账号,超级权限
- backup:备份数据权限
- restore:从备份中恢复数据的权限
3.MongoDB内置角色的访问控制
- 创建管理员(即root) MongoDB服务端在开启安全检查之前,至少需要有一个管理员账号,admin数据库中的用户都被视为管理员,如果admin库没有任何用户的话,即使在其他数据库创建了用户,启用身份验证,默认的连接方式依然会有超级权限,即仍然可以不验证账号密码,照样能进行CRUD,此时的安全认证失效。 在mongo命令行客户端中,首先use admin,然后创建管理员
db.createUser({
user: "root",pwd: "123456",
roles:[{role: "root",db:"admin"}]})
- 创建普通用户 - 创建有读写权限的用户zhangsan,指定数据库mydb
db.createUser({ user: "zhangsan",pwd: "123456", roles:[{role: "readWrite",db:"mydb"}]})
- 创建有读权限的用户lisi,指定数据库mydbdb.createUser({ user: "lisi",pwd: "123456", roles:[{role: "read",db:"mydb"}]})
- 验证用户zhangsan,此时需要先退出客户端重新进入,否则会出现验证2个用户名的错误:
db.auth("zhangsan","123456")
- 插入数据:db.c1.insert({name:"testdb1"})
- 查询集合c1所有文档:db.c1.find()
即只有mydb的读写权限 - 先use mydb,验证用户lisi:
db.auth("lisi","123456")
- 查询集合c1所有文档:db.c1.find()
即只有mydb的读权限
总结:
- java连接MongoDB,将MongoDB服务器的Ip地址及端口号再加上一些参数单独写在properties文件中或者通过Edit Ciguration配置,在程序中读出来,通过MongoClients创建连接,再通过MangoClient获取数据库。
- springboot连接MongoDB,在配置文件中指定ip地址及端口号和数据库名;调用MongoTemplate函数进行查询操作即可。而不用手动去读取配置文件,再获取数据库及集合。而是交给springboot来做,甚至都不用指定集合,springboot应该是首先通过实体类名去找对应的集合。
- SpringBoot整合MongoDB可以使用两种方式,MongoTemplate以及MongoRepository。 MongoTemplate方式需要Dao层的实现类去实现;而MongoRepository方式则不需要定义实现类,但是需要Dao层去继承MongoRepository并指定其实体类及查询条件类型。
- 在创建超级权限用户时,需要use admin。 进行权限验证之前,要先use database(对应的数据库),才可以进行权限验证。 更改密码、添加角色、恢复数据等操作需要权限验证。 权限验证后,可以进行show dbs,查看自己有权限的数据库。
版权归原作者 帅得真的是无敌了 所有, 如有侵权,请联系我们删除。