باستخدام Liquibase لإدارة بنية قاعدة البيانات في تطبيق Spring Boot. الجزء 1

في هذه المقالة ، سأناقش استخدام الأداة المساعدة Liquibase في تطبيقات Spring Boot لإصدار بنية قاعدة بيانات علائقية وترحيل هذه البنية من إصدار إلى آخر. في الجزء الأول ، سنقوم بتحليل المثال الأساسي ، وسنتحدث في الجزء الثاني عن استخدام البرنامج المساعد لـ fluibase-mave-to- roll لاستعادة التغييرات وإنشاء البرامج النصية تلقائيًا من خلال مقارنة هياكل قاعدة البيانات.

لنبدأ بإنشاء أبسط تطبيق على Spring Boot + JPA (السبات). سوف الربيع Initializr مساعدتنا في هذا. من التبعيات ، حدد JPA و MySQL و Web. يمكن أيضًا توصيل Liquibase في هذه الخطوة ، ولكن لفهم أفضل ، سنفعل ذلك يدويًا في وقت لاحق.

إنشاء أساس التطبيق


نضيف فئة كيان إلى طلبنا ، بالإضافة إلى مستودع ووحدة تحكم REST للعمل معها. للتسليم ، سنقوم بتخزين معلومات حول المستخدمين في الكيان الذي تم إنشاؤه.

@Entity @Table(name = "users") public class User implements Serializable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") private Long id; @Column(name = "username", unique = true, nullable = false) private String userName; @Column(name = "password", nullable = false) private String password; @Column(name = "first_name") private String firstName; @Column(name = "last_name") private String lastName; @Column(name = "email") private String email; //    ,    //    Lombok } 

Spring Data تجعل كود المستودع موجزا للغاية

 public interface UserRepository extends JpaRepository<User, Long> { } 

وحدة تحكم REST التي تعرض المحتويات الكاملة لجدول المستخدم

 @RestController public class UserController { private UserRepository userRepository; @Autowired public UserController(UserRepository userRepository) { this.userRepository = userRepository; } @GetMapping("/user/all") public List<User> allUsers() { return userRepository.findAll(); } } 

الإعدادات في ملف application.properties

 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/geek_db?createDatabaseIfNotExist=true&allowPublicKeyRetrieval=true&useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC spring.datasource.username=dbuser spring.datasource.password=dbpassword spring.jpa.show-sql=true spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect 

من المفترض أن جهاز الكمبيوتر الخاص بك يقوم بتشغيل خادم MySQL على منفذ قياسي. إذا لزم الأمر ، اضبط عنوان URL الخاص بالخادم في سلسلة الاتصال ، وكذلك اسم المستخدم وكلمة المرور. من الجدير أيضًا الانتباه إلى المعلمة createDatabaseIfNotExist . بفضله ، عند الاتصال ، سننشئ قاعدة بيانات تسمى geek_db إذا لم تكن موجودة على الخادم.

أضف Liquibase


بالتأكيد لاحظت أن إعدادًا واحدًا لـ Hibernate مفقود ، وهو spring.jpa.hibernate.ddl-auto . في معظم أدلة المبتدئين ، تتم الإشارة إلى قيمة التحديث الخاصة بها ، ويرجع ذلك إلى أن Hibernate سيقوم بإنشاء وتعديل بنية الجدول على الخادم نفسه ، بناءً على فئات الكيانات الموجودة في المشروع. قد يتم استخدام هذا النهج جيدًا إذا كان مخطط البيانات بسيطًا جدًا أو كان المشروع يتدرب ، ولكن مع وجود مخطط معقد إلى حد ما ، من المحتمل أن تبدأ المشكلات ، على الأرجح فقط لأننا لا نستطيع التحكم في عملية إنشاء نصوص إسبات DDL. مشكلة أخرى هي أنه مع هذا النهج لا توجد طريقة سهلة لاستعادة التغييرات التي تم إجراؤها على السبات في بنية قاعدة البيانات.

لحل المشكلات المذكورة أعلاه ، سنستخدم الأداة المساعدة Liquibase . لحسن الحظ بالنسبة لنا ، إنها قادرة تمامًا على الاندماج مع تطبيقات Spring Boot! لبدء استخدامه ، يجب عليك تنفيذ الخطوات التالية

أضف الإعداد إلى ملف application.properties

 spring.jpa.hibernate.ddl-auto=none 

هذا هو التأكد من أن Hibernate لا يتخذ أي إجراء لتعديل الدائرة ، كما سوف Liquibase القيام بها الآن. من الناحية النظرية ، هنا يمكنك أيضًا استخدام قيمة التحقق من الصحة للتحكم الإضافي في صحة بنية الجدول.

أضف تبعية إلى pom.xml

 <dependency> <groupId>org.liquibase</groupId> <artifactId>liquibase-core</artifactId> </dependency> 

بعد إضافته ، سيقوم Spring boot تلقائيًا بإنشاء حبة خاصة تسمى liquibase ، والتي ستنفذ جميع الإجراءات لتكوين مخطط قاعدة البيانات استنادًا إلى البرامج النصية Liquibase في كل مرة يتم فيها تشغيل التطبيق.

الآن تحتاج إلى إضافة البرنامج النصي Liquibase نفسه ، مما سيؤدي إلى إنشاء الجدول الذي نحتاجه. في المجلد / src / main / resources / db / changelog ، قم بإنشاء ملف يسمى db.changelog-master.yaml وأضف المحتويات التالية إليه

 databaseChangeLog: - logicalFilePath: db/changelog/db.changelog-lesson1.yaml - changeSet: id: 1 author: your_liquibase_username changes: - createTable: tableName: users columns: - column: name: id type: BIGINT autoIncrement: true constraints: primaryKey: true nullable: false - column: name: username type: varchar(50) constraints: unique: true nullable: false - column: name: password type: varchar(512) constraints: nullable: false - column: name: first_name type: varchar(50) - column: name: last_name type: varchar(50) - column: name: email type: varchar(50) 

دعنا نحلل محتويات هذا البرنامج النصي. بادئ ذي بدء ، أنه يحتوي على مجموعة واحدة. ChangeSet هو تناظر لالتزام في أنظمة التحكم في الإصدار مثل Git أو SVN. قياسًا على الالتزام ، يمكن إرجاع التغييرات التي تم إجراؤها كجزء من مجموعة واحدة أو إرجاعها إلى خادم قاعدة البيانات. يجب أن يكون لكل changeSet معرف فريد يحدد Liquibase ما إذا كان قد تم ضخ تغيير محدد في قاعدة البيانات هذه أم لا.

يحتوي ChangeSet على أمر لإنشاء جدول ، ويتم وصف بنية الجدول بواسطة Liquibase ، وليس برنامج نصي SQL. بفضل هذا ، يصبح هذا الملف عبر منصة. سوف Liquibase إنشاء برنامج نصي SQL اعتمادا على خادم قاعدة البيانات المستخدمة. بالإضافة إلى ذلك ، إذا كنا بحاجة إلى استعادة مجموعة التغيير المحددة ، فستتمكن Liquibase من إنشاء برنامج نصي تلقائيًا لحذف الجدول المحدد. إذا استخدمنا البرامج النصية لـ SQL ، فسنضطر إلى كتابة نص يدوي لدحر التغييرات. في قسم hanges ، لدينا فريق واحد فقط وهذا يعتبر ممارسة جيدة ، على الرغم من إمكانية وجود أي عدد من الفرق في مجموعة واحدة.

الشفرة المكتوبة كافية لتشغيل البرنامج ، ولكن لرؤية نتائج عمله بشكل أوضح ، دعونا نضيف مجموعة تغيير أخرى ، والتي سوف تملأ الجدول بالبيانات.

  - changeSet: id: 2 author: your_liquibase_username comment: "Create admin user" changes: - insert: tableName: users columns: - column: name: username value: "admin" - column: name: password value: "admin" - column: name: email value: "admin@server.com" - insert: tableName: users columns: - column: name: username value: "guest" - column: name: password value: "guest" - column: name: email value: "guest@server.com" rollback: - delete: tableName: users where: username in ('admin', 'guest') 

في هذه الحالة ، كان علينا بالفعل كتابة كتلة لعمليات الاستعادة يدويًا ، مثل لا يمكن Liquibase إنشاء SQL التراجع تلقائيًا عند العمل مع البيانات. بشكل عام ، لا يعد العمل مع البيانات الموجودة في قاعدة البيانات من بين السمات الرئيسية لـ Liquibase ويقتصر فقط على أبسط عمليات الإدراج أو الحذف أو التغيير. بالمناسبة ، إذا كنت بحاجة إلى المزيد ، يمكنك هنا استخدام الأدوات من شركة Red Gate .

وهكذا ، فلنشغل تطبيقنا ونحاول اتباع الرابط http: // localhost: 8080 / user / all . في حالة بدء تشغيل التطبيق ، سترى استجابة JSON بمعلومات عن المستخدمين الذين تمت إضافتهم إلى الجدول. يجدر أيضًا إلقاء نظرة على سجلات بدء تشغيل التطبيق ، حيث يمكنك مشاهدة البرامج النصية التي ينفذها Liquibase لتهيئة قاعدة البيانات. يجب إيلاء اهتمام خاص لجدول DATABASECHANGELOG . في ذلك يخزن Liquibase سجل التغييرات التي تم إجراؤها على قاعدة البيانات.

هذا كل شيء الآن. بعد بعض الوقت ، أخطط لنشر استمرارية حول استخدام البرنامج المساعد لـ fluibase-maven لإنشاء البرامج النصية تلقائيًا من خلال مقارنة هياكل قاعدة البيانات واستعادة التغييرات التي تم إجراؤها.

سأكون ممتنا لأي إضافات وتعليقات!

سكرتير خاص رمز كامل مكتوب على أساس هذا المقال github.com/usharik/spring-liquibase-demo/tree/part-1

تابع في habr.com/en/post/460907

Source: https://habr.com/ru/post/ar460377/


All Articles