一、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,添加如下代码
public class MongoDBExample { public static void main(String[] args) { //获取mongodb连接地址 String connectionString = System.getProperty("mongodb.uri"); try { MongoClient mongoClient = MongoClients.create(connectionString); ArrayList<Document> databases = mongoClient.listDatabases().into(new ArrayList<>()); 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,添加如下代码:
public class MongoDBExample2 { public static void main(String[] args) { Properties properties = new Properties(); 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(new ArrayList<>()); databases.forEach(db-> System.out.println(db.toJson())); } catch (IOException e) { throw new RuntimeException(e); } } }
-
在resources目录下,创建配置文件config.properties,添加如下配置:
mongodb.uri=mongodb://192.168.126.16:27017/?maxPoolSize=2&w=majority
2.java操作MongoDB
-
新建一个类,MongoDBCRUD,将获取MongoClient对象的部分封装到方法中
public class MongoDBCRUD { public static void main(String[] args) { try { MongoClient mongoClient = getMongoClient("config.properties"); } catch (IOException e) { throw new RuntimeException(e); }finally { mongoClient.close(); } } /** * 获取MongoClient对象 * @param propertyFileName * @return * @throws IOException */ private static MongoClient getMongoClient(String propertyFileName) throws IOException { Properties properties = new Properties(); //使用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数据库对象mydb MongoDatabase 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 = new Document(); expectSalary.append("expectSalary", -1); FindIterable<Document> findIterable = collection.find().sort(expectSalary); for (Document doc:findIterable) { System.out.println(doc); }
-
查询指定条件的文档
//按指定的属性值查询 FindIterable<Document> documents = collection.find(new Document("expectSalary", new Document("$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启动类,代码如下:
@SpringBootApplication public class MongodbTestApplication { public static void main(String[] args) { SpringApplication.run(MongodbTestApplication.class, args); } }
-
在mongodb-test子模块中的resources目录下创建配置文件application.properties
spring.data.mongodb.host=192.168.126.16 spring.data.mongodb.port=27017 spring.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,代码如下
import lombok.*; import java.io.Serializable; import java.util.Date; @Data @EqualsAndHashCode @NoArgsConstructor @ToString public class Orders implements Serializable { private String _id; private String name; private String size; private Integer price; private Integer quantity; private Date date; }
2.1 注入MongoTemplate使用MongoDB
-
在com.zzx包下,创建包dao,在该包下创建dao层接口OrderDao,代码如下:
public interface OrderDao{ //根据订单名称查询订单集合 List<Orders> findOrdersByName(String name); }
-
在com.zzx.dao包下,创建包impl,在该包下创建实现类OrderDaoImpl,代码如下:
@Repository public class OrderDaoImpl implements OrderDao { @Autowired private MongoTemplate mongoTemplate; /** * 按订单名称查询 * @param name * @return */ @Override public List<Orders> findOrdersByName(String name) { Query query = new Query(); query.addCriteria(Criteria.where("name").is(name)); return mongoTemplate.find(query,Orders.class); } }
-
在com.zzx包下,创建包service,在该包下创建service层接口OrderService,代码如下:
public interface OrderService { // 按订单名称查询 List<Orders> findOrdersByName(String name); }
-
在com.zzx.service包下,创建包impl,在该包下创建实现类OrderServiceImpl,代码如下:
@Service public class OrderServiceImpl implements OrderService { @Autowired private OrderDao orderDao; @Override public List<Orders> findOrdersByName(String name) { return orderDao.findOrdersByName(name); } }
-
在com.zzx包下,创建包controller,在该包下创建controller层OrderController,代码如下:
@RestController @RequestMapping("orders") public class OrderController { @Autowired private OrderService orderService; @GetMapping("/getOrders") public List<Orders> findOrdersByName(String name) { return orderService.findOrdersByName(name); } }
2.2 继承MongoRepository使用MongoDB
-
在com.zzx包下,创建包repository,在该包下创建接口OrdersRepository,代码如下:
public interface OrdersRepository extends MongoRepository<Orders,String> { /** * 按订单名称查询订单 * @param name * @return */ List<Orders> findOrdersByName(String name); }
MongoRepository相当于MybatisPlus。
-
在OrderService接口中,加入如下代码:
List<Orders> findOrdersByName_2(String name);
-
在OrderServiceImpl实现类中,加入如下代码:
@Autowired private OrdersRepository ordersRepository; @Override public List<Orders> findOrdersByName_2(String name) { return ordersRepository.findOrdersByName(name); }
-
在OrderController类中,添加如下代码:
@GetMapping("/getOrders2") public List<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登录用户以及分配权限的方式文章来源:https://www.toymoban.com/news/detail-456176.html
db.createUser({
user: "root",
pwd: "123456",
roles:[{role: "root",db:"admin"}]
})
参数:
roles:为用户分配的角色,不同的角色拥有不同的权限,参数是数组,可以同时设置多个
role:角色,MongoDB已经约定好的角色,不同角色对应不同的权限。
db:数据库名称,MongoDB默认自带的有admin、local、config、test等,即为数据库实例设置用户文章来源地址https://www.toymoban.com/news/detail-456176.html
- 验证用户后可以更改密码、添加角色、恢复数据等操作:
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,指定数据库mydb
db.createUser({ user: "lisi", pwd: "123456", roles:[{role: "read",db:"mydb"}] })
- 创建有读写权限的用户zhangsan,指定数据库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的读权限
- 查询集合c1所有文档:
总结:
- 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,查看自己有权限的数据库。
到了这里,关于IDEA操作MongoDB及安全认证的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!