מימוש
המימוש של שני הרבדים צריך לייצג את השוני הבסיסי בתפקודם בעוד שהבסיסי מכיל רשימת מלאי של מחלקות שכל אחד מהם מחולק לתפקודים כלליים שמממשים set, get, insert, update, select, delete. עקרונית ניתן לממש מחלקה אבסטרקטית שמממשת את כל הסט. הרובד הדינאמי מורכב ממחלקות עצמאיות שכל מחלקה מייצגת מודל נתונים מורכב ללא כל דמיון בין אחת לשניה. מומלץ למקם את שני הרבדים במרחב שמות אחד או כמרחבי שמות מקוננים. לדוגמא: afs.dal.base וafs.dal.custom
המימוש של הרובד הבסיסי צריך להיות מחולל
חילול DAL
הDAL מעצם טבעו וכל הפחות הרובד הבסיסי שלו קשורים קשר הדוק למבנה בסיס הנתונים כאשר כל מחלקה מייצגת טבלה או אובייקט בסיס נתונים אחר. ניתן עקרונית לכתוב כל מחלקה בנפרד בבסיס נתונים קטן ולא משתנה אולם לבסיס נתונים גדול ודינאמי, מומלץ לחולל את האובייקטים הבסיסיים בצורה פרוגרמתית. על מנת לעשות כן צריך לשאוב את המידע הרלבנטי מבסיס הנתונים. בבסיס הנתונים מצויים כל המאפיינים הנדרשים לחילול האובייקטים.
לפי כך לצורך העמדת רובד בסיסי של גישה לבסיס הנתונים יש לכתוב תכנית שמקבלת בתור קלט את בסיס הנתונים (Connection String) ושואבת ממנו את המידע הנדרש לגבי מבנה בסיס הנתונים והמפתחות ומייצרת את הרובד הבסיסי של ה DAL. פעילות זאת יכולה לחזור בכל מצב שבו בסיס הנתונים ישתנה.
נתונים נדרשים
לצורך חילול מחלקה אוטומטי נדרשים הנתונים הבאים:
- שם הטבלה – יהפוך לשם המחלקה
- שדות וסוגם – יהפכו למאפיינים במחלקה
- מפתח ראשי – ישמש ליצירת שיטת DELETE/UPDATE/SELECT ובמידה וכולל מספר שדות, גם לSELECT מדורג
לדוגמא, ניקח טבלה פשוטה של מחלקות בארגון כאשר כל רשומה מזוהה בעזרת מספר המחלקה ומספר המחלקה הממונה עליה:
Field Name | Type | Key Column |
ID | Int | 2 |
ParentId | Int | 1 |
Dep_name | Varchar |
שם טבלה: departments
המחלקה שתיוצר תכיל את המאפיינים הבאים:
{
int id;
int parentId;
string depname;
}
ניתן לייצר שיטה של אתחול כללי או לייצר בנאי שמקבל כפרמטרים את המאפיינים:public departments (int _id, int _parentid, string _depname)
כמו כן אם כבנאי או כשיטה עצמאית תחולל שיטת SELECT שמקבלת את המפתח בתור פרמטר: public bool selectByKey(int kid, int kparentid)
שיטות הINSERT, UPDATE והDELETE תוגדרנה ללא פרמטרים : public bool insert(), public bool delete(), public bool update()
ממבנה הנתונים ניתן גם לחלל שיטה נוספת על שיטת הSELECT לפי מפתח :public int selectByParentId(int parentId,ref int[] id, ref string[] dep_name)
השיטות
מאחורי כל שיטה שאוזכרה למעט הבנאי או המאתחל שפשוט מאתחלים את מאפייני המחלקה עומדת פקודת SQL עם פרמטרים כאשר בפקודות הINSERT, UPDATE, DELETE הן לוקחות משתנים מתוך המחלקה וקושרות אותן לפרמטרים לדוגמא: UPDATE departments Dep_name=? where ID=? And parentID=?; השיטה UPDATE תקשור את המשתנים הקיימים לפרמטרים בשאילתא, תבצע את השאילתא ותחזיר מחווה הצלחה בוליאני.
שאילתות הSELECT גם מכילות SQL שמכיל פרמטרים לקישור (מפתח מלא או חלקי) אבל לאחר הביצוע כותבות את המידע המתקבל לתוך משתני המחלקה או מערך של ערכים.
כל השיטות הללו מחוללות על סמך האינפורמציה ששאבנו מבסיס הנתונים בלבד.
נקודות חשובות:
* לעיתים נרצה כי שאילתא של SELECT לפי מפתח חלקי תחזיר רשימה מקושרת של מחלקות. לצורך מימוש זה יש להגדיר מחלקה נוספת שמכילה שיטות לאחזור זה, שיטות אלו, יפעילו את המחלקה department, יקבלו את מערכי התוצאות ויצרו בעבור כל שורה מוחזרת מחלקה מסוג department, יקשרו אותן לרשימה אחת שתוחזר בסוף.
* במצבים כאשר ישנם ערכים המוגדרים על ידי טריגרים הנתונים שנמצאים במחלקה אינם מדוייקים אחרי הפעלת INSERT או UPDATE ולכן מומלץ בסוף ביצוע השיטות הללו להפעיל שיטת selectByKey על מנת לשמור על המידע שנמצא במחלקה עדכני.
* שיטת INSERT לעיתים תדרוש דבר נוסף, במספר בסיסי נתונים ניתן להגדיר(IC) IDENTITY Columns שדות שהערך שלהם נקבע בעת הכנסת הרשומה. כל עוד הערך אינו חלק מהמפתח, הפעלת selectByKey תשמור על המחלקה מסונכרנת עם בסיס הנתונים. כאשר הנתון שהוא IC הוא חלק מהמפתח נדרש טיפול קצת שונה: לאחר פעולת הINSERT מתבצעת שאילתא נוספת המגלה את ערך השדה שהוגדר כIC ומעודכן.
אפשרויות חילול קוד
הדרך הפשוטה ביותר לחלל את הקוד לDAL היא לכתוב קובץ במבנה של תוכנית ואז ידנית לקמפל אותה. מתודה זו תעבוד בכל שפת תכנות או סביבה. בסביבת הדוט נט קיים לFRAMEWORK מרחב שמות מיוחד שמאפשר לעשות משהו אחר קצת. ספריית ה CODEDOM מאפשרת לחולל את הקוד כמחלקה וכשכזו כבר לקמפל ולקשר אותה לידי DLL ולידי ומלא.