מבוא ל- ORMLite

1. סקירה כללית

ORMLite היא ספריית ORM קלה עבור יישומי Java. הוא מספק תכונות סטנדרטיות של כלי ORM למקרי השימוש הנפוצים ביותר, ללא תוספת המורכבות והתקורה של מסגרות ORM אחרות.

התכונות העיקריות שלה הן:

  • הגדרת שיעורי ישויות באמצעות הערות Java
  • ניתן להרחבה DAO שיעורים
  • א QueryBuilder מחלקה ליצירת שאילתות מורכבות
  • נוצר כיתות ליצירת ושחרור טבלאות מסדי נתונים
  • תמיכה בעסקאות
  • תמיכה ביחסי ישות

בחלקים הבאים נבחן כיצד אנו יכולים להקים את הספרייה, להגדיר שיעורי ישות ולבצע פעולות במסד הנתונים באמצעות הספרייה.

2. תלות Maven

כדי להתחיל להשתמש ב- ORMLite, עלינו להוסיף את ה- ormlite-jdbc תלות שלנו pom.xml:

 com.j256.ormlite ormlite-jdbc 5.0 

כברירת מחדל, זה מכניס גם את ה- h2 תלות. בדוגמאות שלנו נשתמש ב- H2 מסד נתונים בזיכרון, כך שאיננו זקוקים למנהל התקן אחר של JDBC.

אם ברצונך להשתמש במסד נתונים אחר, תזדקק גם לתלות המתאימה.

3. הגדרת כיתות ישויות

כדי להגדיר את שיעורי המודל שלנו להתמדה עם ORMLite, ישנן שתי הערות עיקריות שבהן אנו יכולים להשתמש:

  • @DatabaseTable עבור מעמד הישות
  • @DatabaseField עבור הנכסים

נתחיל בהגדרת א סִפְרִיָה ישות עם שֵׁם שדה ו libraryId שדה שהוא גם מפתח ראשי:

@DatabaseTable (tableName = "ספריות") ספרייה בכיתה ציבורית {@DatabaseField (generatedId = true) LibraryId פרטי ארוך; @DatabaseField (canBeNull = false) שם מחרוזת פרטי; ספרייה ציבורית () {} // getters, setters סטנדרטיים}

ה @DatabaseTable להערה יש אופציונלי שם שולחן תכונה המציינת את שם הטבלה אם איננו רוצים להסתמך על שם מחלקה המוגדר כברירת מחדל.

עבור כל שדה שנרצה להימשך כעמודה בטבלת מסד הנתונים, עלינו להוסיף את השדה @DatabaseField ביאור.

ניתן לסמן את המאפיין שישמש כמפתח ראשי לטבלה תְעוּדַת זֶהוּת, שנוצר מזהה אוֹ generatedSequence תכונות. בדוגמה שלנו, אנו בוחרים את generatedId = נכון המאפיין כך שהמפתח הראשי יוגדל אוטומטית.

כמו כן, שים לב כי בכיתה צריך להיות בונה ללא ויכוח עם לפחות היקף חבילה רְאוּת.

כמה תכונות מוכרות אחרות שאנו יכולים להשתמש בהן לתצורת השדות הן columnName, סוג מידע, ערך ברירת מחדל, canBeNull, ייחודי.

3.1. באמצעות JPA ביאורים

בנוסף להערות הספציפיות ל- ORMLite, אנחנו יכולים גם להשתמש בסגנון JPA ביאורים להגדרת ישויותינו.

המקבילה של סִפְרִיָה ישות שהגדרנו לפני השימוש JPA ההערות הסטנדרטיות יהיו:

@Entity מחלקה ציבורית LibraryJPA {@Id @GeneratedValue (אסטרטגיה = GenerationType.IDENTITY) LibraryId פרטי ארוך; @Column פרטי שם מחרוזת; // גטרים סטנדרטיים, סטרים}

למרות ש- ORMLite מזהה הערות אלה, אנו עדיין צריכים להוסיף את ה- javax.persistence-api תלות להשתמש בהם.

הרשימה המלאה של התומכים JPA ההערות היא @יֵשׁוּת, @תְעוּדַת זֶהוּת,@טור,@GeneratedValue, @אחד לאחד, @ManyToOne, @הצטרף לעמוד, @גִרְסָה.

4. ConnectionSource

לעבודה עם האובייקטים שהוגדרו, עלינו להקים א ConnectionSource.

לשם כך, אנו יכולים להשתמש ב- JdbcConnectionSource מחלקה שיוצרת חיבור יחיד, או JdbcPooledConnectionSource המייצג מקור חיבור פשוט ומאוחד:

JdbcPooledConnectionSource connectionSource = חדש JdbcPooledConnectionSource ("jdbc: h2: mem: myDb"); // לעבוד עם connectionSource connectionSource.close ();

ניתן להשתמש במקור נתונים חיצוני אחר עם ביצועים טובים יותר, על ידי עטיפתם ב- DataSourceConnectionSource לְהִתְנַגֵד.

5. TableUtils מעמד

מבוסס על ה ConnectionSource, אנו יכולים להשתמש בשיטות סטטיות מה- TableUtils בכיתה לביצוע פעולות בסכימת מסד הנתונים:

  • createTable () - ליצור טבלה המבוססת על הגדרת כיתת ישות או a DatabaseTableConfig לְהִתְנַגֵד
  • createTableIfNotExists () - בדומה לשיטה הקודמת, אלא שהיא תיצור את הטבלה רק אם היא לא קיימת; זה עובד רק על בסיסי נתונים התומכים בכך
  • dropTable () - למחיקת טבלה
  • שולחן ברור() - למחיקת הנתונים מטבלה

בואו נראה איך נוכל להשתמש TableUtils ליצור את השולחן עבורנו סִפְרִיָה מעמד:

TableUtils.createTableIfNotExists (connectionSource, Library.class);

6. DAO חפצים

ORMLite מכיל א DaoManager כיתה שיכולה ליצור DAO אובייקטים עבורנו עם פונקציונליות CRUD:

Dao libraryDao = DaoManager.createDao (connectionSource, Library.class);

ה DaoManager לא מחדש את הכיתה לכל שיחה שלאחר מכן createDao (), אלא במקום לעשות בו שימוש חוזר לצורך ביצועים טובים יותר.

בשלב הבא נוכל לבצע פעולות CRUD סִפְרִיָה חפצים:

ספריית ספרייה = ספרייה חדשה (); library.setName ("הספרייה שלי"); libraryDao.create (ספרייה); תוצאת הספרייה = libraryDao.queryForId (1L); library.setName ("הספרייה האחרת שלי"); libraryDao.update (ספרייה); libraryDao.delete (ספרייה);

ה DAO הוא גם איטרטור שיכול לעבור על כל הרשומות:

libraryDao.forEach (lib -> {System.out.println (lib.getName ());});

עם זאת, ORMLite יסגור את משפט SQL הבסיסי רק אם הלולאה תגיע עד הסוף. חריג או הצהרת החזר עלולים לגרום לדליפת משאבים בקוד שלך.

מסיבה זו, תיעוד ה- ORMLite ממליץ לנו להשתמש ישירות באיטרטור:

נסה (CloseableWrappedIterable wrappedIterable = libraryDao.getWrappedIterable ()) {wrappedIterable.forEach (lib -> {System.out.println (lib.getName ());}); }

בדרך זו אנו יכולים לסגור את האיטרטור באמצעות a נסה עם משאבים או א סוף כל סוף לחסום ולהימנע מכל דליפת משאבים.

6.1. מחלקת DAO מותאמת אישית

אם אנחנו רוצים להרחיב את ההתנהגות של DAO אם אנו מספקים אובייקטים, אנו יכולים ליצור ממשק חדש המרחיב את דאו סוּג:

ממשק ציבורי LibraryDao מרחיב את דאו {רשימה ציבורית findByName (שם מחרוזת) זורק SQLException; }

לאחר מכן, נוסיף מחלקה המיישמת ממשק זה ומרחיבה את ה- BaseDaoImpl מעמד:

מחלקה ציבורית LibraryDaoImpl מרחיב את BaseDaoImpl מיישם את LibraryDao {public LibraryDaoImpl (ConnectionSource connectionSource) זורק SQLException {super (connectionSource, Library.class); } @ רישום ציבורי @ findByName (שם מחרוזת) זורק SQLException {להחזיר super.queryForEq ("שם", שם); }}

שים לב שאנחנו צריכים שיהיה בנאי טופס זה.

לבסוף, כדי להשתמש במנהג שלנו DAO, עלינו להוסיף את שם הכיתה ל- סִפְרִיָה הגדרת כיתה:

@DatabaseTable (tableName = "ספריות", daoClass = LibraryDaoImpl.class) ספריית מחלקה ציבורית {// ...}

זה מאפשר לנו להשתמש ב- DaoManager כדי ליצור מופע של המחלקה המותאמת אישית שלנו:

LibraryDao customLibraryDao = DaoManager.createDao (connectionSource, Library.class);

אז נוכל להשתמש בכל השיטות מהתקן DAO בכיתה, כמו גם השיטה המותאמת אישית שלנו:

ספריית ספרייה = ספרייה חדשה (); library.setName ("הספרייה שלי"); customLibraryDao.create (ספרייה); assertEquals (1, customLibraryDao.findByName ("הספרייה שלי"). גודל ());

7. הגדרת יחסי ישות

ORMLite משתמש במושג אובייקטים או אוספים "זרים" כדי להגדיר קשרים בין ישויות לצורך התמדה.

בואו נסתכל כיצד אנו יכולים להגדיר כל סוג של שדה.

7.1. שדות אובייקט זר

אנו יכולים ליצור קשר חד-כיווני חד-כיווני בין שתי מחלקות ישויות באמצעות ה- זר = נכון תכונה בשדה עם הערה @DatabaseField. השדה חייב להיות מסוג שנמשך גם במסד הנתונים.

ראשית, נגדיר מחלקת ישות חדשה בשם כתובת:

@DatabaseTable (tableName = "כתובות") כתובת ציבורית בכיתה {@DatabaseField (generatedId = true) addressId פרטי ארוך; @DatabaseField (canBeNull = false) כתובת מחרוזת פרטית; // גטרים סטנדרטיים, סטרים}

לאחר מכן נוכל להוסיף שדה מסוג כתובת שלנו סִפְרִיָה כיתה המסומנת כ- זָר:

@DatabaseTable (tableName = "ספריות") ספריית מחלקה ציבורית {// ... @DatabaseField (Foreign = true, foreignAutoCreate = true, foreignAutoRefresh = true) כתובת כתובת פרטית; // גטרים סטנדרטיים, סטרים}

שימו לב שהוספנו גם שתי תכונות נוספות ל- @DatabaseField ביאור: ForeignAutoCreate ו ForeignAutoRefresh, שניהם מוגדרים ל נָכוֹן.

ה ForeignAutoCreate = נכון התכונה פירושה שכאשר אנו שומרים א סִפְרִיָה חפץ עם כתובת שדה, האובייקט הזר יישמר גם כן בתנאי שהוא תְעוּדַת זֶהוּת אינו אפס ויש לו generatedId = נכון תְכוּנָה.

אם נקבע ForeignAutoCreate ל שֶׁקֶר, שהוא ערך ברירת המחדל, אז נצטרך להחזיק את האובייקט הזר במפורש לפני שמירת ה- סִפְרִיָה אובייקט שמפנה אליו.

באופן דומה, ה ForeignAutoRefresh=נָכוֹן תכונה מציין כי בעת אחזור a סִפְרִיָה האובייקט, האובייקט הזר המשויך יאוחזר גם הוא. אחרת, נצטרך לרענן אותו ידנית.

בואו נוסיף חדש סִפְרִיָה חפץ עם כתובת שדה וקרא libraryDao להתמיד בשניהם:

ספריית ספרייה = ספרייה חדשה (); library.setName ("הספרייה שלי"); library.setAddress (כתובת חדשה ("רחוב ראשי מספר 20"); Dao libraryDao = DaoManager.createDao (connectionSource, Library.class); libraryDao.create (ספרייה);

ואז נוכל להתקשר ל addressDao כדי לוודא שה- כתובת נשמר גם:

Dao addressDao = DaoManager.createDao (connectionSource, Address.class); assertEquals (1, addressDao.queryForEq ("addressLine", "Main Street nr 20") .size ());

7.2. אוספים זרים

בשביל ה רב בצד של מערכת יחסים, נוכל להשתמש בסוגים אוסף זר אוֹ אוסף עם @ForeignCollectionField ביאור.

בואו ניצור חדש סֵפֶר ישות כמו אלה שלמעלה, ואז הוסף קשר אחד לרבים ב- סִפְרִיָה מעמד:

@DatabaseTable (tableName = "ספריות") ספריה בכיתה ציבורית {// ... @ForeignCollectionField (להוט = שקר) ספרי ForeignCollection פרטיים; // גטרים סטנדרטיים, סטרים}

בנוסף לכך, נדרש להוסיף שדה מסוג סִפְרִיָה בתוך ה סֵפֶר מעמד:

@DatabaseTable מחלקה ציבורית ספר {// ... @DatabaseField (Foreign = true, foreignAutoRefresh = true) ספריית ספרייה פרטית; // גטרים סטנדרטיים, סטרים}

ה אוסף זר יש ל לְהוֹסִיף() ו לְהַסִיר() שיטות הפועלים לפי רשומות הסוג סֵפֶר:

ספריית ספרייה = ספרייה חדשה (); library.setName ("הספרייה שלי"); libraryDao.create (ספרייה); libraryDao.refresh (ספרייה); library.getBooks (). הוסף (ספר חדש ("1984"));

הנה, יצרנו סִפְרִיָה ואז הוסיף חדש סֵפֶר התנגדות ל ספרים שדה, אשר ממשיך אותו גם למסד הנתונים.

שים לב שמכיוון שהאוסף שלנו מסומן כעמוס בעצלנות (להוט = שקר), אנחנו צריכים להתקשר ל לְרַעֲנֵן() שיטה לפני שתוכל להשתמש בשדה הספר.

אנו יכולים גם ליצור את הקשר על ידי הגדרת ה- סִפְרִיָה שדה ב סֵפֶר מעמד:

ספר ספרים = ספר חדש ("זה"); book.setLibrary (ספרייה); bookDao.create (ספר);

כדי לוודא ששניהם סֵפֶר אובייקטים מתווספים ל- סִפְרִיָה אנחנו יכולים להשתמש ב- queryForEq () שיטה למצוא את כל סֵפֶר רשומות עם הנתון ספריית_יד:

assertEquals (2, bookDao.queryForEq ("library_id", library) .size ());

הנה ה ספריית_יד הוא שם ברירת המחדל של עמודת המפתח הזר, והמפתח הראשי נגזר מ- סִפְרִיָה לְהִתְנַגֵד.

8. QueryBuilder

כל אחד DAO ניתן להשתמש בהם כדי להשיג QueryBuilder התנגדות שנוכל למנף לבניית שאילתות חזקות יותר.

מחלקה זו מכילה שיטות התואמות לפעולות נפוצות המשמשות בשאילתת SQL כגון: selectColumns (), where (), groupBy (),בעל (), countOf (), נבדל (), orderBy (), להצטרף ().

בואו נראה דוגמה כיצד אנו יכולים למצוא את כל ה סִפְרִיָה רשומות שיש בהן יותר מאחד סֵפֶר קשור ל:

רשימת ספריות = libraryDao.queryBuilder () .where () .in ("libraryId", bookDao.queryBuilder () .selectColumns ("library_id") .groupBy ("library_id") .having ("count (*)> 1") ) .שאילתא();

9. מסקנה

במאמר זה ראינו כיצד אנו יכולים להגדיר ישויות המשתמשות ב- ORMLite, כמו גם את התכונות העיקריות של הספרייה בהן אנו יכולים להשתמש כדי לטפל באובייקטים ובמאגרי היחס הקשורים אליהם.

קוד המקור המלא של הדוגמה נמצא ב- GitHub.


$config[zx-auto] not found$config[zx-overlay] not found