IDEA操作MongoDB及安全認(rèn)證方式
一、Java整合MongoDB
1.java連接MongoDB
在new project那里創(chuàng)建一個(gè)普通的maven項(xiàng)目mongodbexample。
引入java整合MongoDB的依賴
<!-- 引入java整合MongoDB的依賴 -->
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>3.12.11</version>
</dependency>
在java根目錄的com.zzx的包下,創(chuàng)建類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并輸出所有數(shù)據(jù)庫(kù)
點(diǎn)擊Alt+Shift+F10,選擇Edit Configuration,然后選擇modify options->選擇Add VM options,在框內(nèi)輸入該參數(shù):
-Dmongodb.uri="mongodb://192.168.126.16:27017/?maxPoolSize=2&w=majority"
最后點(diǎn)擊run即可。
在java根目錄的com.zzx的包下,創(chuàng)建類MongoDBExample2,添加如下代碼:
public class MongoDBExample2 {
public static void main(String[] args) {
Properties properties = new Properties();
try {
//使用classLoader加載properties文件生成對(duì)應(yīng)的輸入流
InputStream resourceAsStream = MongoDBExample2.class.getClassLoader().getResourceAsStream("config.properties");
//使用properties對(duì)象加載輸入流
properties.load(resourceAsStream);
//獲取屬性對(duì)應(yīng)的value值
String connectionString = properties.getProperty("mongodb.uri");
System.out.println(connectionString);
//獲取MongoClient對(duì)象
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目錄下,創(chuàng)建配置文件config.properties,添加如下配置:
mongodb.uri=mongodb://192.168.126.16:27017/?maxPoolSize=2&w=majority
2.java操作MongoDB
新建一個(gè)類,MongoDBCRUD,將獲取MongoClient對(duì)象的部分封裝到方法中
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對(duì)象
* @param propertyFileName
* @return
* @throws IOException
*/
private static MongoClient getMongoClient(String propertyFileName) throws IOException {
Properties properties = new Properties();
//使用classLoader加載properties文件生成對(duì)應(yīng)的輸入流
InputStream resourceAsStream = MongoDBCRUD.class.getClassLoader().getResourceAsStream(propertyFileName);
//使用properties對(duì)象加載輸入流
properties.load(resourceAsStream);
//獲取屬性對(duì)應(yīng)的value值
String connectionString = properties.getProperty("mongodb.uri");
//獲取MongoClient對(duì)象
MongoClient mongoClient = MongoClients.create(connectionString);
return mongoClient;
}
}
創(chuàng)建集合,即在獲取MongoClient對(duì)象后面添加如下兩行
//獲取database數(shù)據(jù)庫(kù)對(duì)象mydb
MongoDatabase mydb = mongoClient.getDatabase("mydb");
//創(chuàng)建集合
mydb.createCollection("exampleCollection");
添加文檔,代碼如下:
//獲取集合對(duì)象
MongoCollection<Document> collection = mydb.getCollection("exampleCollection");
//創(chuàng)建文檔對(duì)象
Document document = Document.parse("{name: 'zhangsan',city: 'beijing',birthday: new ISODate('2000-04-02'),expectSalary: 18000}");
//插入文檔
collection.insertOne(document);
查詢文檔
//創(chuàng)建文檔對(duì)象
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);
}
查詢過(guò)濾文檔
//過(guò)濾查詢 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項(xiàng)目
創(chuàng)建一個(gè)SpringBoot項(xiàng)目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>
刪除父項(xiàng)目的src模塊,并把pom文件的dependencies標(biāo)簽的文件全部刪除,也就是springboot和springboottest的啟動(dòng)依賴。
通過(guò)new Module,在mongodb-springboot項(xiàng)目中創(chuàng)建web子項(xiàng)目mongodb-test,并在子項(xiàng)目的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>
同時(shí)父類的pom文件會(huì)自動(dòng)更新為pom類型,并出現(xiàn)modules標(biāo)簽,內(nèi)部有mongodb-test子模塊。
在mongodb-test子模塊中的java根目錄下,創(chuàng)建包c(diǎn)om.zzx,并在包下創(chuàng)建springboot啟動(dòng)類,代碼如下:
@SpringBootApplication
public class MongodbTestApplication {
public static void main(String[] args) {
SpringApplication.run(MongodbTestApplication.class, args);
}
}
在mongodb-test子模塊中的resources目錄下創(chuàng)建配置文件application.properties
spring.data.mongodb.host=192.168.126.16 spring.data.mongodb.port=27017 spring.data.mongodb.database=mydb
2.訪問(wèn)MongoDB的業(yè)務(wù)代碼實(shí)現(xiàn)
在父工程的pom文件的dependencyManagement中引入lombok依賴進(jìn)行版本管理
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok-version}</version>
</dependency>
在子項(xiàng)目的pom文件中引入lombok依賴
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
在com.zzx包下,創(chuàng)建包entity,在該包下創(chuàng)建實(shí)體類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包下,創(chuàng)建包dao,在該包下創(chuàng)建dao層接口OrderDao,代碼如下:
public interface OrderDao{
//根據(jù)訂單名稱查詢訂單集合
List<Orders> findOrdersByName(String name);
}
在com.zzx.dao包下,創(chuàng)建包impl,在該包下創(chuàng)建實(shí)現(xiàn)類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包下,創(chuàng)建包service,在該包下創(chuàng)建service層接口OrderService,代碼如下:
public interface OrderService {
// 按訂單名稱查詢
List<Orders> findOrdersByName(String name);
}
在com.zzx.service包下,創(chuàng)建包impl,在該包下創(chuàng)建實(shí)現(xiàn)類OrderServiceImpl,代碼如下:
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private OrderDao orderDao;
@Override
public List<Orders> findOrdersByName(String name) {
return orderDao.findOrdersByName(name);
}
}
在com.zzx包下,創(chuàng)建包c(diǎn)ontroller,在該包下創(chuàng)建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包下,創(chuàng)建包repository,在該包下創(chuàng)建接口OrdersRepository,代碼如下:
public interface OrdersRepository extends MongoRepository<Orders,String> {
/**
* 按訂單名稱查詢訂單
* @param name
* @return
*/
List<Orders> findOrdersByName(String name);
}
MongoRepository相當(dāng)于MybatisPlus。
在OrderService接口中,加入如下代碼:
List<Orders> findOrdersByName_2(String name);
在OrderServiceImpl實(shí)現(xiàn)類中,加入如下代碼:
@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的安全認(rèn)證及內(nèi)置角色
1.MongoDB的安全認(rèn)證
MongoDB默認(rèn)是沒(méi)有賬號(hào)的,可以直接連接,無(wú)須身份驗(yàn)證。實(shí)際項(xiàng)目中肯定要權(quán)限驗(yàn)證,否則后果不堪設(shè)想。
- 進(jìn)入到容器中,備份數(shù)據(jù):
mongodump -h 127.0.0.1:27017 -d mydb -o /usr/local
- 進(jìn)入到容器中,備份全部數(shù)據(jù):
mongodump - 即所有數(shù)據(jù)庫(kù)備份文件創(chuàng)建在當(dāng)前目錄的/dump目錄下
- 將mongo的dump目錄,復(fù)制到/usr/local目錄:
docker cp mongo5:/dump /usr/local/
- 關(guān)閉mongo5容器:
docker stop mongo5
- 以auth方式啟動(dòng)MongoDB:
docker run -itd --name mongo6 -p 27017:27017 mongo:5.0.11-focal --auth
- 將備份復(fù)制到mongo6:
docker cp /usr/local/dump/ mongo6:/dump
- 進(jìn)入到mongo6容器:
docker exec -it mongo6 bash
- 進(jìn)入到mongo命令行客戶端,切換到admin數(shù)據(jù)庫(kù)。創(chuàng)建MongoDB登錄用戶以及分配權(quán)限的方式
db.createUser({
user: "root",
pwd: "123456",
roles:[{role: "root",db:"admin"}]
})
參數(shù):
roles:為用戶分配的角色,不同的角色擁有不同的權(quán)限,參數(shù)是數(shù)組,可以同時(shí)設(shè)置多個(gè)role:角色,MongoDB已經(jīng)約定好的角色,不同角色對(duì)應(yīng)不同的權(quán)限。db:數(shù)據(jù)庫(kù)名稱,MongoDB默認(rèn)自帶的有admin、local、config、test等,即為數(shù)據(jù)庫(kù)實(shí)例設(shè)置用戶
驗(yàn)證用戶后可以更改密碼、添加角色、恢復(fù)數(shù)據(jù)等操作:db.auth("root","123456")
返回1,即驗(yàn)證成功
- 刪除用戶:db.dropUser("用戶名")
- 修改密碼:db.changeUserPassword("root","root")
- 添加角色:db.grantRolesToUser("用戶名",[{role: "角色名",db: "數(shù)據(jù)庫(kù)名"}])
- 恢復(fù)數(shù)據(jù):mongorestore -h localhost -u root -p 123456 --db mydb /dump/mydb --authenticationDatabase admin
- NoSQLBooster可視化連接:

2.MongoDB內(nèi)置角色(role)
read:允許用戶讀取指定數(shù)據(jù)庫(kù)readWrite:允許用戶讀寫指定數(shù)據(jù)庫(kù)dbAdmin:可以讀取任何數(shù)據(jù)庫(kù)并對(duì)庫(kù)進(jìn)行清理、修改、壓縮,獲取統(tǒng)計(jì)信息、執(zhí)行檢查等操作userAdmin:可以在指定數(shù)據(jù)庫(kù)里創(chuàng)建、刪除和管理用戶readAnyDatabase:可以讀取任何數(shù)據(jù)庫(kù)中的數(shù)據(jù),除了數(shù)據(jù)庫(kù)config和local之外readWriteAnyDatabase:可以讀寫任何數(shù)據(jù)庫(kù)中的數(shù)據(jù)。除了數(shù)據(jù)庫(kù)config和local之外userAdminAnyDatabase:可以在任何數(shù)據(jù)庫(kù)總創(chuàng)建、刪除和管理用戶,除了數(shù)據(jù)庫(kù)config和local之外dbAdminAnyDatabase:可以讀取任何數(shù)據(jù)庫(kù)并對(duì)庫(kù)進(jìn)行清理、修改、壓縮,獲取統(tǒng)計(jì)信息、執(zhí)行檢查等操作,除了數(shù)據(jù)庫(kù)config和local之外root:超級(jí)賬號(hào),超級(jí)權(quán)限backup:備份數(shù)據(jù)權(quán)限restore:從備份中恢復(fù)數(shù)據(jù)的權(quán)限
3.MongoDB內(nèi)置角色的訪問(wèn)控制
創(chuàng)建管理員(即root)
MongoDB服務(wù)端在開啟安全檢查之前,至少需要有一個(gè)管理員賬號(hào),admin數(shù)據(jù)庫(kù)中的用戶都被視為管理員,如果admin庫(kù)沒(méi)有任何用戶的話,即使在其他數(shù)據(jù)庫(kù)創(chuàng)建了用戶,啟用身份驗(yàn)證,默認(rèn)的連接方式依然會(huì)有超級(jí)權(quán)限,即仍然可以不驗(yàn)證賬號(hào)密碼,照樣能進(jìn)行CRUD,此時(shí)的安全認(rèn)證失效。
在mongo命令行客戶端中,首先use admin,然后創(chuàng)建管理員
db.createUser({
user: "root",
pwd: "123456",
roles:[{role: "root",db:"admin"}]
})
創(chuàng)建普通用戶
創(chuàng)建有讀寫權(quán)限的用戶zhangsan,指定數(shù)據(jù)庫(kù)mydb
db.createUser({
user: "zhangsan",
pwd: "123456",
roles:[{role: "readWrite",db:"mydb"}]
})
創(chuàng)建有讀權(quán)限的用戶lisi,指定數(shù)據(jù)庫(kù)mydb
db.createUser({
user: "lisi",
pwd: "123456",
roles:[{role: "read",db:"mydb"}]
})
驗(yàn)證用戶zhangsan,此時(shí)需要先退出客戶端重新進(jìn)入,否則會(huì)出現(xiàn)驗(yàn)證2個(gè)用戶名的錯(cuò)誤:db.auth("zhangsan","123456")
- 插入數(shù)據(jù):
db.c1.insert({name:"testdb1"}) - 查詢集合c1所有文檔:
db.c1.find() - 即只有mydb的讀寫權(quán)限
先use mydb,驗(yàn)證用戶lisi:db.auth("lisi","123456")
- 查詢集合c1所有文檔:
db.c1.find() - 即只有mydb的讀權(quán)限
總結(jié)
java連接MongoDB,將MongoDB服務(wù)器的Ip地址及端口號(hào)再加上一些參數(shù)單獨(dú)寫在properties文件中或者通過(guò)Edit Ciguration配置,在程序中讀出來(lái),通過(guò)MongoClients創(chuàng)建連接,再通過(guò)MangoClient獲取數(shù)據(jù)庫(kù)。
springboot連接MongoDB,在配置文件中指定ip地址及端口號(hào)和數(shù)據(jù)庫(kù)名;調(diào)用MongoTemplate函數(shù)進(jìn)行查詢操作即可。而不用手動(dòng)去讀取配置文件,再獲取數(shù)據(jù)庫(kù)及集合。而是交給springboot來(lái)做,甚至都不用指定集合,springboot應(yīng)該是首先通過(guò)實(shí)體類名去找對(duì)應(yīng)的集合。
SpringBoot整合MongoDB可以使用兩種方式,MongoTemplate以及MongoRepository。
MongoTemplate方式需要Dao層的實(shí)現(xiàn)類去實(shí)現(xiàn);而MongoRepository方式則不需要定義實(shí)現(xiàn)類,但是需要Dao層去繼承MongoRepository并指定其實(shí)體類及查詢條件類型。
在創(chuàng)建超級(jí)權(quán)限用戶時(shí),需要use admin。
進(jìn)行權(quán)限驗(yàn)證之前,要先use database(對(duì)應(yīng)的數(shù)據(jù)庫(kù)),才可以進(jìn)行權(quán)限驗(yàn)證。
更改密碼、添加角色、恢復(fù)數(shù)據(jù)等操作需要權(quán)限驗(yàn)證。
權(quán)限驗(yàn)證后,可以進(jìn)行show dbs,查看自己有權(quán)限的數(shù)據(jù)庫(kù)。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Mybatis操作多數(shù)據(jù)源的實(shí)現(xiàn)
本文主要介紹了Mybatis操作多數(shù)據(jù)源,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05
Java 兩種延時(shí)thread和timer詳解及實(shí)例代碼
這篇文章主要介紹了Java 兩種延時(shí)thread和timer詳解及實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下2017-02-02
Disconf實(shí)現(xiàn)分布式配置管理的原理與設(shè)計(jì)
這篇文章主要為大家介紹了Disconf實(shí)現(xiàn)分布式配置管理的原理與設(shè)計(jì)分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2022-03-03
java并發(fā)包工具CountDownLatch源碼分析
這篇文章主要為大家介紹了java并發(fā)包工具CountDownLatch源碼分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10

