تم إعداد ترجمة المقال خصيصًا لطلاب الدورة التدريبية "Developer on the Spring Framework".
في هذه المقالة ، سنغطي أساسيات استخدام Redis خلال Spring Boot باستخدام مكتبة Spring Data Redis.

سننشئ تطبيقًا يوضح كيفية إجراء عمليات CRUD من خلال واجهة ويب. الكود المصدري لهذا المشروع
متاح على جيثب .
ما هو رديس؟
Redis هو مستودع بيانات مفتوح المصدر لهياكل البيانات
ذات القيمة الأساسية التي يمكن استخدامها كقاعدة بيانات وذاكرة تخزين مؤقت ووسيط للرسائل. من حيث التنفيذ ، تعد المتاجر ذات القيمة الرئيسية من بين أكبر وأقدم الممثلين في عالم NoSQL. يدعم Redis هياكل البيانات مثل السلاسل والتجزئة والقوائم والمجموعات والمجموعات المصنفة مع استعلامات النطاق.
يجعل إطار
Spring Data Redis من السهل كتابة تطبيقات Spring التي تستخدم تخزين Redis ، مما يوفر مجموعة مناسبة من تخزين البيانات.
إعداد خادم Redis
الخادم متاح مجانا
هنا .
إذا كنت تستخدم جهاز Mac ، فيمكنك تثبيته باستخدام
homebrew
:
brew install redis
ثم ابدأ الخادم:
mikes-MacBook-Air:~ mike$ redis-server 10699:C 23 Nov 08:35:58.306 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo 10699:C 23 Nov 08:35:58.307 # Redis version=4.0.2, bits=64, commit=00000000, modified=0, pid=10699, just started 10699:C 23 Nov 08:35:58.307 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf 10699:M 23 Nov 08:35:58.309 * Increased maximum number of open files to 10032 (it was originally set to 256). _._ _.-``__ ''-._ _.-`` `. `_. ''-._ Redis 4.0.2 (00000000/0) 64 bit .-`` .-```. ```\/ _.,_ ''-._ ( ' , .-` | `, ) Running in standalone mode |`-._`-...-` __...-.``-._|'` _.-'| Port: 6379 | `-._ `._ / _.-' | PID: 10699 `-._ `-._ `-./ _.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | http://redis.io `-._ `-._`-.__.-'_.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | `-._ `-._`-.__.-'_.-' _.-' `-._ `-.__.-' _.-' `-._ _.-' `-.__.-' 10699:M 23 Nov 08:35:58.312 # Server initialized 10699:M 23 Nov 08:35:58.312 * Ready to accept connections
تبعيات مخضرم
دعنا نعلن التبعيات اللازمة في
pom.xml
للتطبيق الذي سنعمل مع:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
تكوين Redis
نحتاج إلى توصيل تطبيقنا بخادم Redis. لتأسيس اتصال ، نستخدم
Jedis ، تطبيق عميل لـ
Redis .
ترتيب
لنبدأ بتعريف حبوب التكوين:
@Bean JedisConnectionFactory jedisConnectionFactory() { return new JedisConnectionFactory(); } @Bean public RedisTemplate<String, Object> redisTemplate() { final RedisTemplate<String, Object> template = new RedisTemplate<String, Object>(); template.setConnectionFactory(jedisConnectionFactory()); template.setValueSerializer(new GenericToStringSerializer<Object>(Object.class)); return template; }
يتم تقديم
JedisConnectionFactory
، حتى نتمكن من إنشاء
RedisTemplate
لطلب البيانات.
نشر الناشر
باتباع
مبادئ SOLID ، نقوم بإنشاء واجهة
MessagePublisher
:
public interface MessagePublisher { void publish(final String message); }
ننفذ واجهة
MessagePublisher
باستخدام RedisTemplate عالي المستوى لنشر رسالة ، لأن
RedisTemplate
يسمح
RedisTemplate
بإرسال كائنات عشوائية كرسائل:
@Service public class MessagePublisherImpl implements MessagePublisher { @Autowired private RedisTemplate<String, Object> redisTemplate; @Autowired private ChannelTopic topic; public MessagePublisherImpl() { } public MessagePublisherImpl(final RedisTemplate<String, Object> redisTemplate, final ChannelTopic topic) { this.redisTemplate = redisTemplate; this.topic = topic; } public void publish(final String message) { redisTemplate.convertAndSend(topic.getTopic(), message); } }
نحن أيضًا نعرّف ذلك على أنه حبة في
RedisConfig
:
@Bean MessagePublisher redisPublisher() { return new MessagePublisherImpl(redisTemplate(), topic()); }
مستلم الرسالة
للاشتراك في الرسائل ، تحتاج إلى تطبيق واجهة
MessageListener
: في كل مرة تصل رسالة جديدة ، يتم
onMessage
رمز المستخدم الموجود في طريقة
onMessage
. تتيح هذه الواجهة الوصول إلى الرسالة ، القناة التي تم استلامها من خلالها ، وتتيح لك استخدام أي قالب مستخدم للاشتراك في القناة.
@Service public class MessageSubscriber implements MessageListener { public static List<String> messageList = new ArrayList<String>(); public void onMessage(final Message message, final byte[] pattern) { messageList.add(message.toString()); System.out.println("Message received: " + new String(message.getBody())); } }
أيضًا ، يجب تسجيل هذه الفئة
RedisConfig
في
RedisConfig
:
@Bean MessageListenerAdapter messageListener() { return new MessageListenerAdapter(new MessageSubscriber()); }
RedisRepository
الآن وقد قمنا بإعداد التطبيق للتفاعل مع خادم Redis ، سنقوم بإعداد التطبيق لتلقي بيانات الاختبار.
نموذج
في هذا المثال ، نعرّف نموذج
Movie
به حقلان:
private String id; private String name;
مستودع مستودع
بخلاف مشاريع Spring Data الأخرى ، يوفر Spring Data Redis كل ما تحتاجه للعمل على واجهات Spring Data الأخرى. قد يبدو هذا غريبًا بالنسبة للأشخاص ذوي الخبرة في مشاريع Spring Data الأخرى.
غالبًا لا توجد حاجة لكتابة تطبيق واجهة مستودع مع مشاريع Spring Data. نتفاعل فقط مع الواجهة. يوفر Spring Data JPA العديد من واجهات مستودع التخزين التي يمكن تمديدها لتوفير ميزات مثل عمليات CRUD ، والاستعلامات المشتقة ، والصفحات.
لذلك ، للأسف ، نحتاج إلى
كتابة الواجهة الخاصة بنا ، ثم تحديد الأساليب :
public interface RedisRepository { Map<Object, Object> findAllMovies(); void add(Movie movie); void delete(String id); Movie findMovie(String id); }
مستودع التنفيذ
يستخدم الفصل
redisTemplate
المعرفة في
RedisConfig
تكوين
RedisConfig
.
نستخدم
HashOperations
، التي
HashOperations
Spring Data
HashOperations
:
@Repository public class RedisRepositoryImpl implements RedisRepository { private static final String KEY = "Movie"; private RedisTemplate<String, Object> redisTemplate; private HashOperations hashOperations; @Autowired public RedisRepositoryImpl(RedisTemplate<String, Object> redisTemplate){ this.redisTemplate = redisTemplate; } @PostConstruct private void init(){ hashOperations = redisTemplate.opsForHash(); } public void add(final Movie movie) { hashOperations.put(KEY, movie.getId(), movie.getName()); } public void delete(final String id) { hashOperations.delete(KEY, id); } public Movie findMovie(final String id){ return (Movie) hashOperations.get(KEY, id); } public Map<Object, Object> findAllMovies(){ return hashOperations.entries(KEY); } }
دعنا ننتبه إلى طريقة
init()
. في هذه الطريقة ، نستخدم دالة تسمى
opsForHash()
، حيث تقوم بإرجاع العمليات التي يتم تنفيذها باستخدام قيم التجزئة
opsForHash()
بهذا المفتاح. ثم نستخدم
hashOps
، والذي تم تعريفه في
init()
، لجميع عملياتنا CRUD.
واجهة الويب
في هذا القسم ، سننظر في إضافة قدرات Redis CRUD إلى واجهة الويب.
إضافة فيلم
نريد أن نكون قادرين على إضافة فيلم من خلال صفحة ويب. المفتاح هو معرف الفيلم ، والقيمة هي الكائن الفعلي. ومع ذلك ، سنعود إلى هذا لاحقًا ، لذلك يتم عرض اسم الفيلم فقط كقيمة.
لنقم بإضافة نموذج إلى مستند HTML وتعيين الأسماء والمعرفات المناسبة:
<form id="addForm"> <div class="form-group"> <label for="keyInput">Movie ID (key)</label> <input name="keyInput" id="keyInput" class="form-control"/> </div> <div class="form-group"> <label for="valueInput">Movie Name (field of Movie object value)</label> <input name="valueInput" id="valueInput" class="form-control"/> </div> <button class="btn btn-default" id="addButton">Add</button> </form>
نستخدم الآن JavaScript لحفظ القيم عند إرسال النموذج:
$(document).ready(function() { var keyInput = $('#keyInput'), valueInput = $('#valueInput'); refreshTable(); $('#addForm').on('submit', function(event) { var data = { key: keyInput.val(), value: valueInput.val() }; $.post('/add', data, function() { refreshTable(); keyInput.val(''); valueInput.val(''); keyInput.focus(); }); event.preventDefault(); }); keyInput.focus(); });
قمنا بتعيين معلمات
@RequestMapping
لطلب POST ، وطلب المفتاح والقيمة ، وإنشاء كائن
Movie
وحفظه في المستودع:
@RequestMapping(value = "/add", method = RequestMethod.POST) public ResponseEntity<String> add( @RequestParam String key, @RequestParam String value) { Movie movie = new Movie(key, value); redisRepository.add(movie); return new ResponseEntity<>(HttpStatus.OK); }
عرض المحتوى
بمجرد إضافة كائن الفيلم ، نقوم بتحديث الجدول لعرض القيم الجديدة. في كتلة شفرة JavaScript ، أطلقنا على
refreshTable()
. ينفذ طلب GET لاسترداد البيانات الحالية في المستودع:
function refreshTable() { $.get('/values', function(data) { var attr, mainTable = $('#mainTable tbody'); mainTable.empty(); for (attr in data) { if (data.hasOwnProperty(attr)) { mainTable.append(row(attr, data[attr])); } } }); }
تتم معالجة طلب GET بواسطة أسلوب
findAll()
، الذي يسترجع جميع كائنات الفيلم المخزنة في المتجر ثم يحول نوع البيانات من
Map <Object, Object>
إلى
Map <String, String>
:
@RequestMapping("/values") public @ResponseBody Map<String, String> findAll() { Map<Object, Object> aa = redisRepository.findAllMovies(); Map<String, String> map = new HashMap<String, String>(); for(Map.Entry<Object, Object> entry : aa.entrySet()){ String key = (String) entry.getKey(); map.put(key, aa.get(key).toString()); } return map; }
إزالة الفيلم
سنكتب برنامج نصي لتنفيذ طلب POST على طول مسار
/delete
، قم بتحديث الجدول وتبديل تركيز لوحة المفاتيح لإدخال مناسب:
function deleteKey(key) { $.post('/delete', {key: key}, function() { refreshTable(); $('#keyInput').focus(); }); }
نطلب مفتاحًا ونحذف الكائن في
redisRepository
استنادًا إلى هذا المفتاح:
@RequestMapping(value = "/delete", method = RequestMethod.POST) public ResponseEntity<String> delete(@RequestParam String key) { redisRepository.delete(key); return new ResponseEntity<>(HttpStatus.OK); }
عرض
أضفنا هنا فيلمين:

وتم حذف فيلم واحد:

استنتاج
في هذا الدليل ، نظرنا إلى Spring Data Redis وطريقة واحدة لتوصيله بتطبيق ويب لأداء عمليات CRUD.
الكود المصدري للتطبيق
النموذجي موجود على
جيثب .
هذا كل شيء. في انتظار تقليديا لتعليقاتكم.