الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

تصميم اصناف لبيانات مخزنه في قاعدة بيانات ؟

مغلق
بدأه - a l t - في 4 يونيو 2006 · 16 رد · 1,326 مشاهدة · في JavaSE
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم ورحمة الله وبركاته

برجاء مساعدتي في فكرة برمجة هذا المشروع.

نبذه بسيطه :

المشروع لحساب المعدل التراكمي

يخزن في قاعدة البيانات بعض التخصصات و لتكن ( حاسب , محاسبة , اداره ... ).

و تحفظ جميع المواد في جدول واحد سواء المواد التخصصيه او العامه.

الهدف من هذه تسهيل عمليه تسجيل المواد في واجهة المستخدم.

يحصل الطالب على المعدل التراكمي عند تسجيله في القاعدة و حفظ المواد التي يدرسها و درجاته التي حصل عليها،

وفي الفصل القادم يضيف الطالب المواد الجديده، و الدرجات التي يتوقع حصوله عليها ليرى المعدل الجديد ....وهكذا..

ER

04_06_06_11_45_04_1149446704alt__1.jpg

تمثيل الجداول في قاعدة بيانات

04_06_06_12_17_22_1149448642alt__.jpg

صنف المواد الدراسية

class Course{
	private String code;  // رمز المادة
	private String courseTitle;	// اسم المادة
	private int creditHours;		// الساعات المعتمدة
}

صنف التخصصات

class Major{ 
	private int no;		// رقم التخصص
	private String name;	// اسم التخصص
	private List<Course>courses;  // جميع مواد هذا التخصص
}

صنف لبيانات مادة تم تجاوزها

class CoursesOfStudent{
	private String code;  // رمز المادة
	private double grade; // درجة المادة
	private String level;	// التقدير
}

صنف الطالب

class DataOfStudent{
	private int id;	//  رقم الطالب
	private List<CoursesOfStudent>courseOfStudent; // مواد تجاوزها الطالب
	private double gpa; // المعدل التراكمي
	private double _gpa;	// المعدل الفصلي
	private int points;	// مجموع النقاط
	private int creaditHours; // الساعات المعتدة - او المكتسبة
}

ارجوا ان تكون الفكره واضحة !

هل احسنت في تصميم الفئات ؟ ام تحتاج الى تغيير ؟

قد يكون في ER بعض القصور ولكن هدفي هو تصميم الاصناف فقط.

ولا احد يدقق في المسميات ;)

وشكرا

11_03_06_12_48_57_1142110137Image(_66).jpg

#2
interface Record {
	public int getID();
	public void save();
	public void delete();

}
interface Course extends Record{
	public String getCode();  
	public String getTitle();	
	public int getCredits();		

	//set methods also
}


interface Major extends Record{
	public String getName();	
	public List<? extends Course>getCourses();  
	public void addCourse(Course c);
	public void removeCourse(Course c);
	//set methods also

}


interface Enrollment extends Record{
	public Course getCourse();  
	public Student getStudent(); 
	public double getGrade();	
	//set methods also
}


interface Student extends Record{
	public List<? extends Enrollemnt>getEnrollment(); 
	public double getGPA(); 
	public int getPoints();	
	public int getCreditHours(); 
	//set methods also
}

1-

interface بدلا من class

2- استخدم طرق بدلا من مكونات،، كما وضحت public double get();

3- فكر في الفئة Record.

4- فكر في إضافة الأوامر الأساسية التي تراها مناسبة.

5- ضع في كل أمر من هذه الأوامر throws DatabaseException تقريبا،،

هذا تحليل بسيط،، وهو ليس بالضرورة أن يكون أفضل تصميم! النقاش والحوار والرأي مطلوب!

ما رأيك؟

#3

1 - الطريقة save, delete هل الغرض منها ارسال نصوص sql لمعالجتها في صنف الاتصال بقاعدة البيانات !!!

مثلا تعود بالنص التالي لصنف MyCourse

public String save(){
	return 
	"INSERT INTO course ( code, courseTitle, creditHours )"+
	"values ( '"+this.getCode()+"', '"+this.getTitle()+"', "+getCredits")"+
	"FROM course;";
}

2 -

MyCourse implements Course

يحتوي الصنف MyCourse على الطريقة

public int getID();

مع ان العمود الرئيسي للجدول course هو code ونوعه نص !

فقد يكون رمز الماده ( 111 حاب ، 215 شبك .....الخ )

فما هي القيمه العائده لهذه الطريقة؟

اعتقد انه يجب على الاستغناء عن هذه الطريقة.

3 -

في MyEnrollment implements Enrollment

استخدمت طريقة getStudent وهي لا تستقبل اي متغيرات ، هل تعني بان الصنف MyEnrollment سيحتوي على متغير

Student std

كيف يمكنني انشاء كائن من الصنف MyEnrollment و الصنف MyStudent يحتوي على MyEnrollment ( كتابيا الموضوع يلخبط ؟؟؟ )

ارجوا منك يابو مازن التوضيع و اعطائي فرصه للتفكير !!!!

11_03_06_12_48_57_1142110137Image(_66).jpg

#4

1- على راحتك،، سواء أفضل أن يكون public void save() throws SomeException

2- معك حق،، اجعل الطريقة هكذا public Object getID();

3- ليس بالضرورة أن يكون في داخل الصنف MyEnrollement متغير من نوع Student أو MyStudent،،

المهم أنك تحصل على public Student getStudent()،،

مثلا،، بدلا من يكون متغير Student داخل الفئة،، اجعل داخل الفئة الرقم التعريفي ID،،

public class MyEnrollement implements Enrollemet{
private int studentID;
private String courseID;

public Student getStudent(){
return myDatabase.loadStudentByID(studentID);

}

}
#5

** يبدوا انك اضفت المشاركه السابقة و انا اكتب هذا المشاركة !!!

تم تعديل هذه المشاركة بواسطة - a l t - في 6 يونيو 2006 في 19:02

11_03_06_12_48_57_1142110137Image(_66).jpg

#6

Record بنفسها تحمل بيانات معينة،، وأنت بدورك تعيد كتابة الأمر save لتسجيل بيانات Record الخاص سواء كان Student أو Course.

بالنسبة ل Connect أفضل أن تكبتها هكذا:

public interface Store{

public Student getStudentByID(int id)throws SomeException;
public Course getCourseByID(String id)throws SomeException;

وإذا كنت ترى تنفيذ save و delete أمر غريب،،

يمكنك أن تكمل Store:

public interface Store{

public void updateStudent(Student s)throws SomeException;
public void deleteStudent(Student s);

... بالمناسبة،،

أيضا لا تنس أن تجعل الطرق التي ترجع مجموعة معينة بأن تكتبها هكذا:

public List<? extends Student> getStudents()throws ....;

أرجو أن يكون واضحا!

#7

هذا كود كنت كتبته مرة لحذف او تخزين String بامكانك تعديله ليخزن ما تريد جربه ولازم يكون dat.txt موجود لانه بخزن ويقرا منه

package majdi.java.arabteam2000;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;

public class Record {

	private final String filename = "data.txt";

	public Record() {

	}

	private ArrayList ReadTemporary() throws FileNotFoundException, IOException {

		ArrayList<String> list = new ArrayList<String>();
		BufferedReader br = new BufferedReader(new FileReader(filename));
		String line;
		while ((line = br.readLine()) != null) {
			list.add(line);
		}
		br.close();

		return list;
	}


	public void Save(String something) throws FileNotFoundException,
			IOException {
		ArrayList<String> list = ReadTemporary();
		list.add(something);
		BufferedWriter bw = new BufferedWriter(new FileWriter(filename));
		for (int i = 0; i < list.size(); i++) {
			bw.write(list.get(i).toString() + "\n");
		}

		bw.close();
		System.out.println("stored succesfully");
	}


	public void Read(String something) throws FileNotFoundException,
			IOException {

		String wasfound = something + "not found";
		ArrayList<String> list = ReadTemporary();
		if (list.size() == 0) {
			System.out.println("no data stored");
			return;
		}
		for (int i = 0; i < list.size(); i++) {
			if (list.get(i).toString().equals(something)) {
				wasfound = something + " found at " + i;
			}

		}
		System.out.println(wasfound);

	}


	public void Delete(String something) throws FileNotFoundException,
			IOException {
		ArrayList<String> list = ReadTemporary();
		String deleted = "can't find" + something;
		for (int i = 0; i < list.size(); i++) {
			if (list.get(i).toString().equals(something)) {
				list.remove(i);
				deleted = something + " deleted";
			}

		}

		System.out.println(deleted);
		WriteNewData(list);
	}

	private void WriteNewData(ArrayList list) throws FileNotFoundException,
			IOException {

		BufferedWriter bw = new BufferedWriter(new FileWriter(filename));
		for (int i = 0; i < list.size(); i++) {
			bw.write(list.get(i).toString() + "\n");
		}

		bw.close();
	}

}

لست متواجد بشكل يومي

#8

شكرا مجدي ، على الاضافة ..

غيرت الاسماء في Record فقط لتوحيد الاسماء في المشروع ..

اكتفيت مبدئيا بانشاء الكائن MyCourse & MyMajor

* اضافه و تعديل ...الخ

* عندما اضيف مواد جديده للقسم فانها تضاف تلقائيا في الجدول majorAndCourse

interface Record{	
	public Object getID();
	public void add();
	public void set();
	public void remove();	
//	public Record get(Object id);
}

interface Course extends Record{	
//	public String getCode();
	public String getTitle();
	public int getCredits();
	// set methods also
	public void add(int idMajor);
	public void setTitle(String value);
	public int getHours();
	public void setID(String value);
}

interface Major extends Record{
	public String getName();
	public List<? extends Course> getCourses();
	public void addCourse(Course c);
	public void setCourse(Course c);
	public void removeCourse(Course c);
	// set methods also	
	public Course getCourse(int indexInList);
	public Course getCourse(String codeCourse);
	public void setName(String name);
	public void setCourses(List<? extends Course> value);
}

interface Connect{
	// ---> Major
	public List<? extends Major> getMajors() throws SQLException;
	public Major getMajor(int idMajor) throws SQLException;
	public void setMajor(Major major) throws SQLException;
	public void addMajor(Major major) throws SQLException;
	public void removeMajor(int idMajor) throws SQLException;
	// <---

	// ---> Course
	public List<? extends Course> getCourses(int idMajor);
	public Course getCourse(String code);
	public void setCourse(Course course);
	public void addCourses(List<? extends Course>courses, int idMajor);
	public void addCourse(Course course, int idMajor);
	public void addCourse(Course course);
	public void removeCourse(String codeCourse);
	// <---

	public void showdown() throws SQLException;
}

الملف المرفق يحتوي الاصناف + BD

ارجوا ان تتطلع عليه يابو مازن ، وتبدي ملاحظاتك ..

v1.rar

11_03_06_12_48_57_1142110137Image(_66).jpg

#9

ولله الحمد صرت على وشك الانتهاء من البرنامج ..

و ساحاول تصميم الواجهه بال JSP لتكون تجربه اولي لي في هذه اللغة .

11_03_06_12_48_57_1142110137Image(_66).jpg

#10

ما شاء الله عليك، تطبيقك ممتاز،،

وهاك بعض الاقتراحات الطفيفة:

1- التسمية لبعض الأوامر غريبة بعض الشيء مثل add و set،، في Record ،، ربما تقصد save و update،، عموما،، وعندك أيضا addCourse و setCourse،، وهما غريبان!

2- افرض مثلا أني ناديت على أمر getMajors مرتين فسأحصل على مجموعتين مختلفتين يحتويان على نفس البيانات مكررة،، يعني مثلا لو المستخدم الأول غير في Major فلن يشعر بذلك المستخدم الثاني لأنه عنده نسخة أخرى من Major،، طبعا أفضل شيء أن ترجع نفس الMajors للطلبين بحيث تكون عندك نسخة واحدة من التخصص في الذاكرة الواحدة..

لتنفيذ هذه الفكرة تحتاج قليلا من التفكير،، وتكمن في تخزين أي Record من القاعدة في مجموعة خاصة قابلة للتنظيف من قبل مجمع النفايات GC،، فلو كان Record غير موجود في هذه المجموعة، قرأناها من القاعدة وإلا استرجعنا التي في المجموعة الخاصة!

بالتوفيق!

#11

شكرا على المجامله ،،

اقتباس
2- افرض مثلا أني ناديت على أمر getMajors مرتين فسأحصل على مجموعتين مختلفتين يحتويان على نفس البيانات مكررة،، يعني مثلا لو المستخدم الأول غير في Major فلن يشعر بذلك المستخدم الثاني لأنه عنده نسخة أخرى من Major،، طبعا أفضل شيء أن ترجع نفس الMajors للطلبين بحيث تكون عندك نسخة واحدة من التخصص في الذاكرة الواحدة..

حصيلتي الدراسيه تعطيني حل بسيط لا اعرف مدى صحته و جدواه، وهو

ان يكون في صنف ConnectImplement المتغير التالي

public static List<? extends Record> majors=null;

عند طلب majors فانه ينفذ الامر التالي

if(majors==null)majors=getMajors();
return majors

اما بالنسبه لمجمع النفايات فما اعرفه هو اسم الطريقة ()finalize فقط

وانها تعمل تلقائيا ، او شئ من هذا.

ارجوا أن تعذني يا أبو مازن لو ثقلت عليك .

11_03_06_12_48_57_1142110137Image(_66).jpg

#12

طريقتك جيدة،، للحصول على نفس البيانات، لكن عليك مراعاة أنك إذا أردت إضافة Major جديد فعليك إضافة هذا الMajor إلى هذه المجموعة بعد إضافتها في قاعدة البيانات.

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

أقصد أنك ربما تريد أن تعدل على جميع الMajors مثلا،، وبعدها تريد أن تلتفت على Courses لاحظ أن Majors مازالت في الذاكرة لأنها في List<? extends Major> وأنت لم تعد تستخدمها،، ولهذا عليك بتعلم كيف تجعل مجمع النفايات يتعامل مع البيانات التي لم تعد في حاجة إليها.

لا تكترث بهذا الكلام حاليا،، لكن بعد أن تنتهي من الإصدار الأول من برنامجك فكر في هذا الأمر ليكون في الإصدار الثاني،، وبإذن الله ستجد المعونة في تنفيذ هذا!

بالتوفيق!

تم تعديل هذه المشاركة بواسطة حسام الملحم أبومازن في 15 يونيو 2006 في 16:43

#13

حل آخر لتوحيد الكائنات.

قمت بغيير بسيط في صنف MyMajor

//class MyMajor implements Major

	static MyMajor myMajor = new MyMajor();

	private MyMajor(){
	}


	public static Major create(){
		return myMajor;
	}
	public static Major create(int _id, String na, List<? extends Course> co){
		myMajor.setID(_id);
		myMajor.setName(na);
		myMajor.setCourses(co);
		return myMajor;
	}

لم اجرب هذا الاسلوب على هذا الصنف ، ولكنى لازلت ابحث عن مجمع النفايات Garbage Collector و ان شاء الله سآتي بالحل الثالث قريبا .

11_03_06_12_48_57_1142110137Image(_66).jpg

#14

شكلي لخبطتك،،

أنصحك بالتركيز على ترتيب الفئات والتأكد منها وعرضها أخيرا هنا،، وتشغيل الإصدار الأول،، وإن كان برنامجك يحتاج عدم تكرار البيانات بسبب تعدد المستخدمين، فأنصحك بالتفكير في هذا في الإصدار الثاني!

#15

اعتقد باني لن اتمكن من اكمال الاصدار الاول قبل شهرين بسبب التدريب التعاوني ( التطبيق )،

لذلك احببت معرفت كيفيه تنفيذ ما اشرت اليه ،

وهذه هي الطريقه الثالثه و اعتقد انه افضل من الطرق السابقه

فقد استخدمت كائن من النوع

Map<String, java.lang.ref.Reference>

MyConnect2.java

package test;

import java.util.*;
import java.sql.*;
import java.lang.ref.*;

public class MyConnect2 {

	private Connection conn;
	private PreparedStatement selectSQL,selectSQLWheteID,
								updateSQL,deleteSQL,insertSQL;
	private Map<String, java.lang.ref.Reference> references;

	public MyConnect2() throws ClassNotFoundException, SQLException {
		// code connection
		references= new HashMap<String, Reference>();
	}
	private void prepareStatement() throws SQLException {
		// code	
	}
	private void createMajors() throws SQLException{
		List<Major>majors=new Vector<Major>();
		// selectSQL.executeQuery();
		references.put("majors", new SoftReference(majors));
	}
	public List<Major> getMajors() throws SQLException {
		if( !references.containsKey("majors") ){createMajors();}
		return (List<Major>)(references.get("majors")).get();
	}
	public Major getMajors(int idMajor) throws SQLException{
		// selectSQLWheteID.executeQuery();
		return null;//majorImplementes;
	}
	public void setMajor(int idMajor, Major major) throws SQLException{
		// updateSQL.exeuteUpdate();
		references.remove("majors");
		createMajors();
	}
	public void removeMajor(int idMajor) throws SQLException {
		// deleteSQL.exeuteUpdate();
		references.remove("majors");
		createMajors();
	}
}

11_03_06_12_48_57_1142110137Image(_66).jpg

#16

فنان!!!

ما شاء الله عليك،، فعلا هذا ما قصدته،، أنت تقترب رويدا رويدا إلى ما أقصده عموما،،

إذا كنت تنوي تطوير مشروعك،، يمكنك استخدام ObjectDatabase،، التي صممتها وتجدها هنا!

/index.ph...c=87020&hl=

ربما أرفق في هذا الأسبوع الإصدار الجديد،،

كما يمكنك أن تجد هذه الحزمة في SourceForge

https://sourceforge.net/projects/objectdatabase/

وهو مفتوح المصدر،، وستجد كيف استخدمت Map<String, Reference> التي استنتجتها أنت.

بهذه الحزمة،، تستطيع أن تتعامل مباشرة بتصميم فئاتك وإلحاقها بقاعدة البيانات التي تستخدمها!

ربما أيضا،، أكتب مثالا في كيفية استخدامها في مشروعك الذي وصفته.

#17

لم اتمكن من الحصول على شفرة ObjectBatabase من الموقع المذكور.

ما اريد التاكد منه هل الشفره الاخيره ( في المشاركه 15 ) ناجحه ام تحتاج الى تطوير .

وشكرا جزيلا..

11_03_06_12_48_57_1142110137Image(_66).jpg

هذا الموضوع مغلق.

مواضيع مشابهة