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
:允許用戶讀寫(xiě)指定數(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
:可以讀寫(xiě)任何數(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ù)端在開(kāi)啟安全檢查之前,至少需要有一個(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)建有讀寫(xiě)權(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的讀寫(xiě)權(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ú)寫(xiě)在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-05Java 兩種延時(shí)thread和timer詳解及實(shí)例代碼
這篇文章主要介紹了Java 兩種延時(shí)thread和timer詳解及實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下2017-02-02Disconf實(shí)現(xiàn)分布式配置管理的原理與設(shè)計(jì)
這篇文章主要為大家介紹了Disconf實(shí)現(xiàn)分布式配置管理的原理與設(shè)計(jì)分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2022-03-03java并發(fā)包工具CountDownLatch源碼分析
這篇文章主要為大家介紹了java并發(fā)包工具CountDownLatch源碼分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10