PDA

View Full Version : الگویی برای اتصال سریع و مدیریت شده با دیتابیس ( لطفاً مشاهده کنید و نظر خودتونو اعلام کنید )



deathdemon
جمعه 16 اسفند 1392, 12:05 عصر
سلام و خسته نباشید اساتید محترم ، ...
از اونجایی که من تو جاوا و مخصوصاً اندروید یه تازه کار به تمام معنا محسوب میشم و فرصت کمی هم دارم و باید دوتا پروژه بزرگ که مدام با دیتابیس هم درگیر هستن و تا ماکس دوماه دیگه تحویل بدم فکر کردم که بهتره از اساتید محترم در مورد الگویی که برای دیتا بیس در نظر گرفتم نظر خواهی کنم ، و ببینم راهی که در پیش گرفتم جواب میده یا راه های ساده تر ( و البته بهتر ) که برای یه پروژه بزرگ جواب بده وجود داره یا نه ...

خوب برم سراغ شرح پلنی که انتخاب کردم
من در نظر گرفتم که شی اصلی دیتابیس که قراره باهاش کار کنم یکتا باشه و واسه همین سعی کردم الگوی سینگلتون و پیاده کنم روش ، این کلاس اصلی تنها کاری که می کنه پیاده سازی دیتابیسه ، و نکته اصلی هم که داره اینه که باید تمام کلاس های قابل ذخیره سازی ( اونایی که قرار داخل دیتابیس ذخیره بشن ) بهش قلاب بشن از طریق سازندش

public class BDatabase extends SQLiteOpenHelper{
//basic
private static BDatabase SingleDb=null;

//Custom
private static final String DATABASE_NAME = "MyDb4.db";
private static final int DATABASE_VERSION = 1;
private ArrayList<StorgableModel> Tables=new ArrayList<StorgableModel>();
private BDatabase(Context context) {
super(context.getApplicationContext(), DATABASE_NAME, null, DATABASE_VERSION);
Tables.add(new UserModel());
}
public static BDatabase GetInstance(Context Cntx){
if(SingleDb==null)
SingleDb=new BDatabase(Cntx);
return SingleDb;
}
public void CloseDb(){
SingleDb.close();
SingleDb=null;
}
@Override
public void onCreate(SQLiteDatabase Db) {
for(StorgableModel Sm:Tables)
Db.execSQL(Sm.GetTableScript());
}


@Override
public void onUpgrade(SQLiteDatabase Db, int OldVersion, int NewVersion) {
for(StorgableModel Sm:Tables)
Db.execSQL(String.format("DROP TABLE IF EXISTS %s", Sm.GetTableName()));
this.onCreate(Db);
}
}


و بعد از اون یه کلاس دستیار در نظر گرفتم برای تنظیم Context و این که بعداً توابع مورد نظر خودمو بهش تزریق کنم و از کار کردن مستقیم با توابع اصلی هلپر خود sqlite اجتناب کنم ( برای تغییرات احتمالی در آینده و قابل نگهداری بودن ) به این شکل


public class DbAssistant{
protected static SQLiteDatabase Database=null;
public void SetContext(Context Cntx){
if(Database==null)
Database=BDatabase.GetInstance(Cntx).getWritableDa tabase();
}
public SQLiteDatabase GetDbAccess(){
return Database;
}
}

و در آخر یک کلاس مجرد تعریف کردم که نوع قابل ذخیره سازی در نظر گرفته شده ، در واقع هر کلاسی که بخواد با دیتابیس کار کنه باید اونو پیاده سازی کنه به این شکل

public abstract class StorableModel extends DbAssistant{

protected final String C_Id="_id";
public int P_Id;
public abstract String GetTableScript();
public abstract String GetTableName();
protected abstract ContentValues RtnValues();

public Boolean Insert() {

Database.beginTransaction();
try{
Database.insert(GetTableName(), null, this.RtnValues());
insert_hook();
Database.setTransactionSuccessful();
return true;
}catch(Exception Err){
return false;
}finally{
Database.endTransaction();
}
}

public Boolean Update(StorgableModel Model) {
Database.beginTransaction();
try{
Database.update(this.GetTableName(),
this.RtnValues(),
String.format("%s = ?", this.C_Id),
new String[]{Model.P_Id+""});
update_hook();
Database.setTransactionSuccessful();
return true;
}catch(Exception Err){
return false;
}finally{
Database.endTransaction();
}
}

public Boolean Delete(StorgableModel Model) {
Database.beginTransaction();
try{
Database.delete(this.GetTableName(),
String.format("%s = ?", this.C_Id),
new String[]{Model.P_Id+""});
delete_hook();
Database.setTransactionSuccessful();
return true;
}catch(Exception Err){
return false;
}finally{
Database.endTransaction();
}
}

protected void insert_hook(){}
protected void update_hook(){}
protected void delete_hook(){}
}



توضیح راجب این کلاس هم این می تونه باشه که برای در نظر گرفته حالت پدر و فرزندی تو کلاس های آینده 3 تا قلاب در نظر گرفتم که فرزندها می تونن با بازنویسی اون ها خودشونو به تابع Insert یا .. پدر وصل کنن و با افزوده یا .. شدن پدر اونا هم اجرا بشن

اینم یه نمونه از کلاس با این الگو کار می کنه


public class UserModel extends StorableModel{
public String P_Name;
private final String C_Name="name";

public String P_Family;
private final String C_Family="family";
@Override
protected ContentValues RtnValues(){
ContentValues Val=new ContentValues();
Val.put(this.C_Name, this.P_Name);
Val.put(this.C_Family,this.P_Family);
return Val;
}
@Override
public String GetTableScript() {
return String.format("Create Table %s (" +
"%s INTEGER PRIMARY KEY AUTOINCREMENT," +
"%s nvarchar(50)," +
"%s nvarchar(50)" +
")", this.GetTableName(),this.C_Id,this.C_Name,this.C_F amily);
}

@Override
public String GetTableName() {
return "User";
}
}

خوب دوستان خوشحال میشم نظرتونو بدونم، این الگو حاصل 2 ساعت کاره و طبیعتاً اشکالات زیادی داره ...