مرحبًا بك في مثال Spring Boot MongoDB . Spring Boot هو أسهل طريقة لبدء مشروع Spring بسرعة و MongoDB هو قاعدة بيانات NoSQL الأكثر شهرة. دعنا نرى كيفية دمج الربيع مع قاعدة بيانات MongoDB.
Spring Boot MongoDB
نحتاج إلى الواجهات البرمجية التطبيقية التالية للعمل مع Spring Boot وقاعدة بيانات MongoDB.
- بيانات Spring MongoDB
- Spring Boot
هناك طريقتان يمكننا من خلالهما الاتصال بقاعدة بيانات MongoDB – MongoRepository
و MongoTemplate
. سنحاول إقرار ما يقدمه API واحد على الآخر ومتى يجب اختيار أحدهما لحالتك. سنستخدم أداة Spring Initializr لإعداد المشروع بسرعة. لذا، دعونا نبدأ.
إعداد مشروع Spring Boot MongoDB
سنستخدم أداة Spring Initializr لإعداد المشروع بسرعة. سنستخدم فقط تبعياتان كما هو موضح أدناه: قم بتنزيل المشروع وفك الضغط عنه. ثم قم بتوريده إلى برنامج التطوير المفضل لديك – إكليبس أو IntelliJ IDEA.
تبعيات مافن
رغم أننا أكملنا الإعداد بالفعل باستخدام الأداة، إذا كنت ترغب في إعدادها يدويًا، فإننا نستخدم نظام تجميع مافن لهذا المشروع وفيما يلي التبعيات التي استخدمناها:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.journaldev.spring</groupId>
<artifactId>spring-boot-mongodb</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>spring-boot-mongodb</name>
<description>Spring Boot MongoDB Example</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
تأكد من استخدام الإصدار الثابت لـSpring Boot من الوسيط المركزي لمافن.
فئة نموذج MongoDB في Spring Boot
لدينا فئة نموذج بسيطة User.java
.
package com.journaldev.bootifulmongodb.model;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
@Document
public class User {
@Id
private String userId;
private String name;
private Date creationDate = new Date();
private Map<String, String> userSettings = new HashMap<>();
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getCreationDate() {
return creationDate;
}
public void setCreationDate(Date creationDate) {
this.creationDate = creationDate;
}
public Map<String, String> getUserSettings() {
return userSettings;
}
public void setUserSettings(Map<String, String> userSettings) {
this.userSettings = userSettings;
}
}
واجهات برمجة تطبيقات MongoDB في Spring Boot
سنقوم بتنفيذ الوظائف التالية والتفاعل مع قاعدة البيانات في تطبيقنا.
- الحصول على جميع المستخدمين
- الحصول على مستخدم برقم تعريفي
- الحصول على إعدادات المستخدم
- الحصول على مفتاح معين من الخريطة
- إضافة/تحديث إعداد المستخدم
بيانات الربيع في مونغو – MongoRepository
الآن سنستخدم مستودع بيانات Spring Data MongoDB للوصول إلى بياناتنا. يوفر لنا Spring Data MongoRepository وظائف شائعة يمكننا توصيلها واستخدامها بسهولة. دعونا نحدد واجهة مستودعنا.
package com.journaldev.bootifulmongodb.dal;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;
import com.journaldev.bootifulmongodb.model.User;
@Repository
public interface UserRepository extends MongoRepository<User, String> {
}
تحديد خصائص MongoDB
قبل أن نقوم بتصميم وحدة التحكم الخاصة بنا، من المهم أن نقوم بالاتصال بنسخة محلية من MongoDB. سنستخدم خصائص Spring Boot للقيام بذلك.
# تكوين MongoDB المحلي
spring.data.mongodb.authentication-database=admin
spring.data.mongodb.username=root
spring.data.mongodb.password=root
spring.data.mongodb.database=user_db
spring.data.mongodb.port=27017
spring.data.mongodb.host=localhost
# تكوين التطبيق
server.port=8102
spring.application.name=BootMongo
server.context-path=/user
لذا، سيتم تشغيل التطبيق على المنفذ 8102 والاتصال بنسخة محلية من MongoDB باستخدام بيانات الاعتماد المقدمة. إذا كان لديك نسخة محلية بدون تفويض ممكّن، يمكنك ببساطة إزالة السطور الثلاثة الأولى من التكوين.
تحديد تحكم Spring
دعونا في النهاية ننتقل إلى إنشاء فئة تحكمنا.
package com.journaldev.bootifulmongodb.controller;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.journaldev.bootifulmongodb.dal.UserRepository;
import com.journaldev.bootifulmongodb.model.User;
@RestController
@RequestMapping(value = "/")
public class UserController {
private final Logger LOG = LoggerFactory.getLogger(getClass());
private final UserRepository userRepository;
public UserController(UserRepository userRepository) {
this.userRepository = userRepository;
}
}
لقد أعدنا تضمين تبعية واجهة المستودع وسنستخدمها فيما بعد.
تعريف الواجهات البرمجية للتطبيقات
بالنسبة للوظائف التي ذكرناها، سنقوم الآن بإنشاء واجهات برمجية والوصول إلى تبعية userRepository التي ستستخدم داخليًا واجهة Spring Data MongoRepository API. لاحظ أنه ليس علينا كتابة أي كود تفاعل مع قاعدة البيانات في الواجهة حيث تقوم Spring Data بذلك كله بالنسبة لنا.
الحصول على جميع المستخدمين
@RequestMapping(value = "", method = RequestMethod.GET)
public List<User> getAllUsers() {
LOG.info("Getting all users.");
return userRepository.findAll();
}
findAll()
هو مجرد طريقة توفرها Spring Data MongoRepository داخليًا.
الحصول على مستخدم بواسطة الهوية
الآن، دعنا نحصل على مستخدم معين بواسطة معرف.
@RequestMapping(value = "/{userId}", method = RequestMethod.GET)
public User getUser(@PathVariable String userId) {
LOG.info("Getting user with ID: {}.", userId);
return userRepository.findOne(userId);
}
findOne()
هو مجرد طريقة توفرها Spring Data MongoRepository داخليًا للحصول على كائن بواسطة معرف.
إضافة مستخدم جديد
سنقوم بإضافة مستخدم جديد في الوظيفة أدناه.
@RequestMapping(value = "/create", method = RequestMethod.POST)
public User addNewUsers(@RequestBody User user) {
LOG.info("Saving user.");
return userRepository.save(user);
}
الحصول على إعدادات المستخدم
الآن بعد أن قمنا بإضافة بيانات عينة إلى قاعدة البيانات، دعونا نحاول استخراج جزء منها.
@RequestMapping(value = "/settings/{userId}", method = RequestMethod.GET)
public Object getAllUserSettings(@PathVariable String userId) {
User user = userRepository.findOne(userId);
if (user != null) {
return user.getUserSettings();
} else {
return "User not found.";
}
}
الحصول على إعداد معين للمستخدم
@RequestMapping(value = "/settings/{userId}/{key}", method = RequestMethod.GET)
public String getUserSetting(@PathVariable String userId, @PathVariable String key) {
User user = userRepository.findOne(userId);
if (user != null) {
return user.getUserSettings().get(key);
} else {
return "User not found.";
}
}
لاحظ في الاستعلام أعلاه، حصلنا على كائن المستخدم، ثم استخرجنا الخريطة الكاملة للإعدادات (التي قد تحتوي على الآلاف من الكائنات) وأخيرًا حصلنا على قيمتنا الخاصة. هذا عيب لاستعلام Spring Data عندما نستخدمه كواجهة برمجية مباشرة.
إضافة إعداد مستخدم جديد
لنحاول إضافة بعض البيانات إلى مستخدم موجود:
@RequestMapping(value = "/settings/{userId}/{key}/{value}", method = RequestMethod.GET)
public String addUserSetting(@PathVariable String userId, @PathVariable String key, @PathVariable String value) {
User user = userRepository.findOne(userId);
if (user != null) {
user.getUserSettings().put(key, value);
userRepository.save(user);
return "Key added";
} else {
return "User not found.";
}
}
من خلال كل الكود الذي كتبناه، من الواضح أنه لم يكن لدينا حاجة لكتابة سطر واحد من الكود للوصول إلى قاعدة البيانات بخلاف تحديد واجهة المستودع وتضمين الاعتمادات تلقائيا. هذا هو السهولة التي يقدمها لنا واجهة برمجة التطبيقات لبيانات Spring Data MongoRepository ولكن لديها أيضًا بعض العيوب. سنوضح هذا عندما نحدد النسخة MongoTemplate أيضًا. لنبدأ بذلك أيضًا.
بيانات Spring MongoDB – MongoTemplate
سنقوم بتحديد استعلامات قاعدة البيانات MongoTemplate هنا. مع MongoTemplate، سترى أن لدينا مزيد من التحكم التفصيلي في ما نستعلم عنه وما البيانات المضمنة في النتائج.
تحديد واجهة الوصول إلى قاعدة البيانات (DAL)
لتوفير عقد في طبقة الوصول إلى قاعدة البيانات، سنبدأ بتحديد واجهة تعمل تمامًا مثل أساليب Spring Data المدمجة لدينا.
package com.journaldev.bootifulmongodb.dal;
import java.util.List;
import com.journaldev.bootifulmongodb.model.User;
public interface UserDAL {
List<User> getAllUsers();
User getUserById(String userId);
User addNewUser(User user);
Object getAllUserSettings(String userId);
String getUserSetting(String userId, String key);
String addUserSetting(String userId, String key, String value);
}
تنفيذ واجهة DAL
لننتقل قدماً ونحدد هذه الأساليب.
package com.journaldev.bootifulmongodb.dal;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Repository;
import com.journaldev.bootifulmongodb.model.User;
@Repository
public class UserDALImpl implements UserDAL {
@Autowired
private MongoTemplate mongoTemplate;
@Override
public List getAllUsers() {
return mongoTemplate.findAll(User.class);
}
@Override
public User getUserById(String userId) {
Query query = new Query();
query.addCriteria(Criteria.where("userId").is(userId));
return mongoTemplate.findOne(query, User.class);
}
@Override
public User addNewUser(User user) {
mongoTemplate.save(user);
// الآن، سيحتوي كائن المستخدم على الهوية أيضًا
return user;
}
@Override
public Object getAllUserSettings(String userId) {
Query query = new Query();
query.addCriteria(Criteria.where("userId").is(userId));
User user = mongoTemplate.findOne(query, User.class);
return user != null ? user.getUserSettings() : "User not found.";
}
@Override
public String getUserSetting(String userId, String key) {
Query query = new Query();
query.fields().include("userSettings");
query.addCriteria(Criteria.where("userId").is(userId).andOperator(Criteria.where("userSettings." + key).exists(true)));
User user = mongoTemplate.findOne(query, User.class);
return user != null ? user.getUserSettings().get(key) : "Not found.";
}
@Override
public String addUserSetting(String userId, String key, String value) {
Query query = new Query();
query.addCriteria(Criteria.where("userId").is(userId));
User user = mongoTemplate.findOne(query, User.class);
if (user != null) {
user.getUserSettings().put(key, value);
mongoTemplate.save(user);
return "Key added.";
} else {
return "User not found.";
}
}
}
تستخدم تنفيذات الأساليب في الصف أعلاه تبعية MongoTemplate. انظر كيف يحصل الأسلوب `getUserById(…)` على المستخدم. نقوم ببناء استعلام وتمرير المعلمات المطلوبة. ما سيثير اهتمامك أكثر هو استعلام `getUserSetting`. دعنا نفهم ما حدث أعلاه:
- قمنا بإنشاء استعلامات بمعايير لفحص التساوي.
- تتضمن طريقة الـ include الحقول التي يجب أن تكون النتيجة تحتوي عليها عند استخراجها من قاعدة البيانات. وهذا يعني، في هذه الحالة، سيتم استخراج مفتاح userSettings الذي سيوفر الكثير من البيانات التي لا حاجة لاسترجاعها
- أيضًا، قمنا بالاستعلام عن كل من مفتاح المستخدم والخريطة. إذا لم يتم العثور على أيٍ منهما، نقوم بإرجاع بيانات فارغة، مما يعني أن المفتاح المطلوب لم يتم العثور عليه. وهذا يوفر حتى من استرجاع كائن المستخدم تمامًا إذا لم يتم العثور على المفتاح المطلوب
تشغيل اختبار Spring Data MongoDB
يمكننا تشغيل هذا التطبيق ببساطة باستخدام أمر واحد:
mvn spring-boot:run
بمجرد تشغيل التطبيق، يمكننا محاولة حفظ مستخدم جديد باستخدام هذا الواجه البرمجي:
https://localhost:8102/user/create
نظرًا لأن هذا سيكون طلب POST، سنقوم بإرسال بيانات JSON أيضًا:
{
"name" : "Shubham",
"userSettings" : {
"bike" : "pulsar"
}
}
نظرًا لأننا نعيد استجابة Mongo نفسها، سنحصل على شيء مثل:
{
"userId": "5a5f28cc3178058b0fafe1dd",
"name": "Shubham",
"creationDate": 1516165830856,
"userSettings": {
"bike" : "pulsar"
}
}
يمكنك الحصول على جميع المستخدمين باستخدام الواجهة البرمجية كطلب GET:
https://localhost:8102/user/
سنحصل على شيء مثل:
[
{
"userId": "5a5f28cc3178058b0fafe1dd",
"name": "Shubham",
"creationDate": 1516165830856,
"userSettings": {
"bike" : "pulsar"
}
}
]
إذا رأيت أعلاه فئة
UserController
، لم نقم بربط MongoTemplate للاستخدام. يوضح مقطع الشيفرة التالي التغييرات المطلوبة لاستخدام MongoTemplate لقراءة إعدادات المستخدم.
//تعريف كائن طبقة الوصول إلى البيانات
private final UserDAL userDAL;
//تهيئة كائن DAL عبر الحقن التلقائي للبناء
public UserController(UserRepository userRepository, UserDAL userDAL) {
this.userRepository = userRepository;
this.userDAL = userDAL;
}
//تغيير تنفيذ الطريقة لاستخدام DAL وبالتالي MongoTemplate
@RequestMapping(value = "/settings/{userId}", method = RequestMethod.GET)
public Object getAllUserSettings(@PathVariable String userId) {
User user = userRepository.findOne(userId);
if (user != null) {
return userDAL.getAllUserSettings(userId);
} else {
return "User not found.";
}
}
//تغيير تنفيذ الطريقة لاستخدام DAL وبالتالي MongoTemplate
@RequestMapping(value = "/settings/{userId}/{key}", method = RequestMethod.GET)
public String getUserSetting(
@PathVariable String userId, @PathVariable String key) {
return userDAL.getUserSetting(userId, key);
}
أعد تشغيل التطبيق وتشغيل السيناريوهات للحصول على جميع إعدادات المستخدم وللحصول على أي مفتاح محدد. توضح الصورة أدناه الناتج من تطبيق Postman.
قالب MongoTemplate مقابل الإمكانات MongoRepository
- قالب MongoTemplate يوفر لنا مزيدًا من التحكم عندما يتعلق الأمر باستعلام البيانات وما هي البيانات التي يجب استخراجها من قاعدة البيانات.
- توفر مستودعات Spring Data لنا نظرة مريحة على كيفية استرجاع البيانات.
- قالب MongoTemplate يعتمد على قاعدة بيانات. ما يعني ذلك هو أنه باستخدام مستودعات Spring Data ، يمكنك التبديل بسهولة إلى قاعدة بيانات مختلفة تمامًا عن طريق استخدام مستودعات Spring Data مختلفة لـ MySQL أو Neo4J أو أي شيء آخر. هذا ليس ممكنًا باستخدام MongoTemplate.
ملخص Spring Boot MongoDB
في هذا الدرس، نظرنا في كيف يمكن لـ MongoTemplate أن يوفر لنا مزيدًا من التحكم في مستودعات بيانات Spring ولكن قد يكون أيضًا معقدًا قليلاً عندما يتعلق الأمر بالاستعلامات العميقة. لذا، هذا قرارك تمامًا ماذا تختار عند تطوير فكرتك. لا تتردد في ترك تعليقات أدناه. قم بتنزيل كود المصدر من الرابط أدناه. يرجى التأكد من تغيير بيانات اعتماد MongoDB قبل تشغيل التطبيق المقدم.
Source:
https://www.digitalocean.com/community/tutorials/spring-boot-mongodb