0


IDEA操作MongoDB及安全认证

文章目录

一、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.propertiesspring.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)

  1. read:允许用户读取指定数据库
  2. readWrite:允许用户读写指定数据库
  3. dbAdmin:可以读取任何数据库并对库进行清理、修改、压缩,获取统计信息、执行检查等操作
  4. userAdmin:可以在指定数据库里创建、删除和管理用户
  5. readAnyDatabase:可以读取任何数据库中的数据,除了数据库config和local之外
  6. readWriteAnyDatabase:可以读写任何数据库中的数据。除了数据库config和local之外
  7. userAdminAnyDatabase:可以在任何数据库总创建、删除和管理用户,除了数据库config和local之外
  8. dbAdminAnyDatabase:可以读取任何数据库并对库进行清理、修改、压缩,获取统计信息、执行检查等操作,除了数据库config和local之外
  9. root:超级账号,超级权限
  10. backup:备份数据权限
  11. restore:从备份中恢复数据的权限

3.MongoDB内置角色的访问控制

  • 创建管理员(即root) MongoDB服务端在开启安全检查之前,至少需要有一个管理员账号,admin数据库中的用户都被视为管理员,如果admin库没有任何用户的话,即使在其他数据库创建了用户,启用身份验证,默认的连接方式依然会有超级权限,即仍然可以不验证账号密码,照样能进行CRUD,此时的安全认证失效。 在mongo命令行客户端中,首先use admin,然后创建管理员
db.createUser({
    user: "root",pwd: "123456",
    roles:[{role: "root",db:"admin"}]})
  • 创建普通用户 - 创建有读写权限的用户zhangsan,指定数据库mydbdb.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的读权限

总结:

  1. java连接MongoDB,将MongoDB服务器的Ip地址及端口号再加上一些参数单独写在properties文件中或者通过Edit Ciguration配置,在程序中读出来,通过MongoClients创建连接,再通过MangoClient获取数据库。
  2. springboot连接MongoDB,在配置文件中指定ip地址及端口号和数据库名;调用MongoTemplate函数进行查询操作即可。而不用手动去读取配置文件,再获取数据库及集合。而是交给springboot来做,甚至都不用指定集合,springboot应该是首先通过实体类名去找对应的集合。
  3. SpringBoot整合MongoDB可以使用两种方式,MongoTemplate以及MongoRepository。 MongoTemplate方式需要Dao层的实现类去实现;而MongoRepository方式则不需要定义实现类,但是需要Dao层去继承MongoRepository并指定其实体类及查询条件类型。
  4. 在创建超级权限用户时,需要use admin。 进行权限验证之前,要先use database(对应的数据库),才可以进行权限验证。 更改密码、添加角色、恢复数据等操作需要权限验证。 权限验证后,可以进行show dbs,查看自己有权限的数据库。

本文转载自: https://blog.csdn.net/weixin_49076273/article/details/126541430
版权归原作者 帅得真的是无敌了 所有, 如有侵权,请联系我们删除。

“IDEA操作MongoDB及安全认证”的评论:

还没有评论