מדריך לעטפת JDBC של sql2o

1. הקדמה

במדריך זה אנו נסתכל על Sql2o, ספרייה קטנה ומהירה לגישה למסד נתונים יחסי בג'אווה אידיומטית.

ראוי להזכיר שלמרות ש- Sql2o פועלת על ידי מיפוי תוצאות שאילתות ל- POJOs (אובייקטים ישנים של Java), זה לא פתרון ORM שלם כגון Hibernate.

2. התקנת Sql2o

Sql2o הוא קובץ צנצנת יחיד שנוכל להוסיף בקלות לתלות בפרויקט שלנו:

 org.sql2o sql2o 1.6.0 

נשתמש גם ב- HSQL, בסיס הנתונים המשובץ, בדוגמאות שלנו; כדי לעקוב אחרינו, נוכל לכלול אותה גם:

 org.hsqldb hsqldb 2.4.0 מבחן 

Maven Central מארחת את הגרסה האחרונה של sql2o ו- HSQLDB.

3. חיבור למסד הנתונים

כדי ליצור קשר, אנו מתחילים ממופע של ה- Sql2o מעמד:

Sql2o sql2o = Sql2o חדש ("jdbc: hsqldb: mem: testDB", "sa", "");

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

ה Sql2o האובייקט הוא בטוח בחוטים ואנחנו יכולים לשתף אותו בכל היישום.

3.1. באמצעות א מקור מידע

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

Sql2o sql2o = Sql2o חדש (מקור נתונים);

3.2. עבודה עם חיבורים

פשוט מיידית א Sql2o האובייקט אינו יוצר שום קשר למסד הנתונים.

במקום זאת, אנו משתמשים ב- לִפְתוֹחַ שיטה להשיג א חיבור לְהִתְנַגֵד (שים לב שזה לא JDBC חיבור). מאז חיבור הוא ניתן לסגירה אוטומטית, אנחנו יכולים לעטוף אותו בבלוק ניסיון עם משאבים:

נסה (חיבור חיבור = sql2o.open ()) {// השתמש בחיבור}

4. הכנס ועדכן הצהרות

עכשיו בואו ניצור מסד נתונים ונכניס אליו כמה נתונים. במהלך ההדרכה נשתמש בטבלה פשוטה הנקראת פּרוֹיֶקט:

connection.createQuery ("צור פרויקט טבלה" + "(זהות שלמה מזהה, שם varchar (50), url varchar (100))"). executeUpdate ();

executeUpdate מחזירה את חיבור להתנגד כך שנוכל לשרשר מספר שיחות. ואז, אם אנו רוצים לדעת את מספר השורות המושפעות, אנו משתמשים getResult:

assertEquals (0, connection.getResult ());

נשתמש בדפוס שראינו זה עתה - createQuery ו executeUpdate -לכל הצהרות DDL, INSERT ו- UPDATE.

4.1. קבלת ערכי מפתח נוצרים

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

אנו עושים זאת בשני שלבים. ראשית, עם פרמטר נוסף ל- createQuery:

שאילתת שאילתה = connection.createQuery ("הכנס לפרויקט (שם, url)" + "ערכים ('tutorials', 'github.com/eugenp/tutorials')", נכון);

ואז, בקריאה להשיג מפתח על החיבור:

assertEquals (0, query.executeUpdate (). getKey ());

אם המקשים הם יותר מאחד, אנו משתמשים getKeys במקום זאת, המחזיר מערך:

assertEquals (1, query.executeUpdate (). getKeys () [0]);

5. חילוץ נתונים ממסד הנתונים

בואו עכשיו נגיע לליבת העניין: בחר שאילתות ומיפוי קבוצות תוצאות לאובייקטים של Java.

ראשית, עלינו להגדיר שיעור POJO עם גטרים וקובעים שייצגו את טבלת הפרויקטים שלנו:

פרויקט בכיתה ציבורית {id id; שם מחרוזת פרטי; כתובת מחרוזת פרטית; // סטרים וקובעים סטנדרטיים}

ואז, כמו בעבר, נכתוב את השאילתה שלנו:

שאילתת שאילתה = connection.createQuery ("בחר * מסדר הפרויקט לפי מזהה");

עם זאת, הפעם נשתמש בשיטה חדשה, executeAndFetch:

רשימת רשימה = query.executeAndFetch (Project.class);

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

5.1. מיפוי עמודות

Sql2o ממפה עמודות למאפייני JavaBean לפי שם, חסר רישיות.

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

פרויקט בכיתה ציבורית {id id; שם מחרוזת פרטי; כתובת מחרוזת פרטית; פרטי תאריך יצירת תאריך; // סטרים וקובעים סטנדרטיים}

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

כמובן, אנו יכולים לכנות זאת בשאלות שלנו:

שאילתת שאילתה = connection.createQuery ("בחר שם, url, creation_date כ- creationDate מתוך פרויקט");

עם זאת, זה מייגע ואנחנו מאבדים את האפשרות להשתמש בו בחר *.

אפשרות נוספת היא להורות ל- Sql2o למפות תאריך היווצרות ל תאריך היווצרות. כלומר, אנו יכולים לספר את השאילתה על המיפוי:

connection.createQuery ("בחר * מתוך פרויקט") .addColumnMapping ("creation_date", "creationDate");

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

למרבה המזל, אנחנו יכולים גם ציין מיפויים ברחבי העולם:

מיפוי מפות = HashMap חדש (); mappings.put ("CREATION_DATE", "creationDate"); sql2o.setDefaultColumnMappings (מיפויים);

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

5.2. תוצאות סקלר

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

במקרים אלה, הגדרת מחלקה וחזרה על רשימה שידוע לנו שהיא מכילה אלמנט יחיד היא יתר על המידה. לכן, Sql2o כולל את executeScalar שיטה:

שאילתת שאילתה = connection.createQuery ("בחר ספירה (*) מפרויקט"); assertEquals (2, query.executeScalar (Integer.class));

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

5.3. תוצאות מורכבות

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

לכן, Sql2o מאפשר גם מיפוי דינמי ברמה נמוכה יותר למבני נתונים טבלאיים. אנו מקבלים גישה לכך באמצעות ה- executeAndFetchTable שיטה:

שאילתת שאילתה = connection.createQuery ("בחר * מסדר הפרויקט לפי מזהה"); טבלת טבלה = query.executeAndFetchTable ();

לאחר מכן נוכל לחלץ רשימת מפות:

רשימה list = table.asList (); assertEquals ("tutorials", list.get (0) .get ("name"));

לחלופין, אנו יכולים למפות את הנתונים לרשימה של שׁוּרָה אובייקטים, שהם מיפוי משמות עמודות לערכים, הדומים ל ResultSets:

רשימת שורות = table.rows (); assertEquals ("tutorials", rows.get (0) .getString ("name"));

6. פרמטרים מחייבים של שאילתות

לשאילתות SQL רבות יש מבנה קבוע עם כמה חלקים פרמטרים. אנו עשויים לכתוב בתמימות שאילתות דינמיות חלקיות עם שרשור מחרוזות.

עם זאת, Sql2o מאפשר שאילתות עם פרמטרים, כך:

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

לכן, אנו יכולים להשתמש בפרמטרים בעלי שם עם Sql2o כדי להשיג את כל האמור לעיל. אנו מכניסים פרמטרים עם נקודתיים ומאגדים אותם עם ה- addParameter שיטה:

שאילתת שאילתה = connection.createQuery ("הכנס לפרויקט (שם, url) ערכים (: שם,: url)") .addParameter ("שם", "REST עם אביב") .addParameter ("url", "github.com / eugenp / REST-With-Spring "); assertEquals (1, query.executeUpdate (). getResult ());

6.1. מחייב מ POJO

Sql2o מציע דרך חלופית לחייב פרמטרים: כלומר, באמצעות POJOs כמקור. טכניקה זו מתאימה במיוחד כאשר לשאילתה יש פרמטרים רבים וכולם מתייחסים לאותה ישות. אז בואו נציג ה לִקְשׁוֹר שיטה:

פרויקט פרויקט = פרויקט חדש (); project.setName ("נח עם אביב"); project.setUrl ("github.com/eugenp/REST-With-Spring"); connection.createQuery ("הכנס לתוך ערכי הפרויקט (שם, url) (: שם,: url)") .bind (פרויקט) .executeUpdate (); assertEquals (1, connection.getResult ());

7. עסקאות ושאילתות אצווה

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

על מנת לפתוח עסקה, אנו משתמשים ב- beginTransaction שיטה במקום לִפְתוֹחַ שיטה בה השתמשנו עד כה:

נסה (חיבור חיבור = sql2o.beginTransaction ()) {// כאן, העסקה פעילה}

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

7.1. התחייבות ידנית והחזר

למרות זאת, אנו יכולים לבצע את העסקה או להחזיר אותה במפורש בשיטות המתאימות:

נסה (Connection connection = sql2o.beginTransaction ()) {transaction booleanSuccessful = false; // לבצע פעולות מסוימות אם (transactionSuccessful) {connection.commit (); } אחר {connection.rollback (); }}

ציין זאת שניהם לְבַצֵעַ ו גלגל לאחור לסיים את העסקה. הצהרות לאחר מכן יופעלו ללא עסקה, ולכן הן לא יוחזרו אוטומטית בסוף החסימה.

עם זאת, אנו יכולים לבצע או להחזיר את העסקה מבלי לסיים אותה:

נסה (Connection connection = sql2o.beginTransaction ()) {List list = connection.createQuery ("select * from project") .executeAndFetchTable () .asList (); assertEquals (0, list.size ()); // הכנס או עדכן חיבור נתונים כלשהו. rollback (false); // בצע שאילתות הוספה או עדכון אחרות} // ניסה להחזיר מלים (Connection connection = sql2o.beginTransaction ()) {List list = connection.createQuery ("select * from project") .executeAndFetchTable () .asList (); assertEquals (0, list.size ()); }

7.2. פעולות אצווה

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

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

  • ראשית, אנו יוצרים את השאילתה פעם אחת בלבד
  • לאחר מכן, אנו קושרים את הפרמטרים וקוראים addToBatch עבור כל מופע של השאילתה
  • לבסוף, אנו מתקשרים executeBatch:
נסה (Connection connection = sql2o.beginTransaction ()) {שאילתת שאילתה = connection.createQuery ("הכנס לפרויקט (שם, url)" + "ערכים (: שם,: url)"); עבור (int i = 0; i <1000; i ++) {query.addParameter ("שם", "הדרכות" + i); query.addParameter ("url", "//github.com/eugenp/tutorials" + i); query.addToBatch (); } query.executeBatch (); connection.commit (); } נסה (Connection connection = sql2o.beginTransaction ()) {assertEquals (1000L, connection.createQuery ("בחר ספירה (*) מהפרויקט"). executeScalar ()); }

7.3. אחלה עצלן

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

אז, Sql2o תומך במצב עצלן, שבו שורות מוחזרות ומפותות אחת בכל פעם:

שאילתת שאילתה = connection.createQuery ("בחר * מתוך פרויקט"); נסה (ResultSetIterable projects = query.executeAndFetchLazy (Project.class)) {for (Project p: projects) {// עשה משהו עם הפרויקט}}

ציין זאת ResultSetIterable הוא ניתן לסגירה אוטומטית ונועד לשמש עם נסה עם משאבים כדי לסגור את הבסיס ResultSet בסיום.

8. מסקנות

במדריך זה הצגנו סקירה כללית של ספריית Sql2o ודפוסי השימוש הנפוצים ביותר שלה. מידע נוסף ניתן למצוא בוויקי Sql20 ב- GitHub.

כמו כן, ניתן למצוא את היישום של כל הדוגמאות וקטעי הקוד בפרויקט GitHub, שהוא פרויקט Maven, כך שיהיה קל לייבא ולהפעיל אותו כמות שהוא.


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