מצגת השיעור - קורס תכנות מתקדם

Download Report

Transcript מצגת השיעור - קורס תכנות מתקדם

‫הקדמה‬
‫הקמת סביבת עבודה‬
‫תוכנית לדוגמא‬
‫‪HQL‬‬
‫הטמעה‬
‫‪ 89-211‬תכנות מתקדם ‪ – 2‬תרגול ‪6‬‬
‫תכנות מתקדם ‪89-211 2‬‬
‫תרגול מספר ‪6‬‬
‫תש"ע ‪2009-2010‬‬
‫‪Java + Hibernate‬‬
‫אליהו חלסצ'י‬
‫‪ 89-211‬תכנות מתקדם ‪ – 2‬תרגול ‪6‬‬
‫הקדמה‬
‫הקדמה‬
‫הקמת סביבת עבודה‬
‫תוכנית לדוגמא‬
‫‪HQL‬‬
‫הטמעה‬
‫• בתוכניות מורכבות המחזיקות מידע רב‪ ,‬נרצה‬
‫להשתמש במסד נתונים ולא להתעסק ברמת‬
‫מבנה הנתונים‪.‬‬
‫• נרצה אף להפריד בין שכבת מסד הנתונים לשכבת‬
‫האפליקציה שעושה בו שימוש‪( .‬ויש לכך‬
‫ארכיטקטורות שונות)‬
‫• נרצה שהקוד שלנו לא ישתנה אם החלטנו להחליף‬
‫למסד נתונים חדש בעל שפת שאילתות אחרת‪.‬‬
‫למשל בין ‪ mysql‬ל ‪.oracle‬‬
‫‪ 89-211‬תכנות מתקדם ‪ – 2‬תרגול ‪6‬‬
‫הקדמה‬
‫הקדמה‬
‫הקמת סביבת עבודה‬
‫תוכנית לדוגמא‬
‫‪HQL‬‬
‫הטמעה‬
‫• בעיה יותר חמורה היא שאנו נרצה לעבוד עם‬
‫אובייקטים כחלק מתוכנית מונחית עצמים – ולא‬
‫לעבוד עם טבלאות רלציוניות‪.‬‬
‫– האם ‪ SQL‬מכיר את המושג ירושה? פולימורפיזם?‬
‫• דרך אחת להתמודדות עם הבעיה תהיה לפתור‬
‫אותה בעצמנו ע"י שימוש ב ‪java.sql‬‬
‫• נצטרך לפתוח תקשורת עם שרת ה ‪ mysql‬למשל‪,‬‬
‫לשלוח לו פקודות בשפתו ולהמיר את המידע‬
‫שהתקבל אל תוך אובייקטים‪...‬‬
‫הקדמה‬
‫הקמת סביבת עבודה‬
‫תוכנית לדוגמא‬
HQL
‫הטמעה‬
6 ‫ – תרגול‬2 ‫ תכנות מתקדם‬89-211
‫הקדמה‬
mysql ‫יצירת תקשורת עם שרת ה‬
Connection connection = null;
try {
//
Load the JDBC driver
String driverName = "org.gjt.mm.mysql.Driver"; // MySQL MM JDBC driver
Class.forName(driverName);
//
‫• דוגמא‬
‫• האם שיטה זו עונה‬
?‫על הצרכים שהגדרנו‬
Create a connection to the database
String serverName = "localhost";
String mydatabase = "mydatabase";
String url = "jdbc:mysql://" + serverName + "/" + mydatabase;
// a JDBC url
‫ וקבלת התוצאות כמחרוזות‬sql ‫שליחת פקודת‬
try {
// Create a result set containing all data from my_table
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM my_table");
String username = "username";
String password = "password";
connection = DriverManager.getConnection(url, username, password);
}
catch (ClassNotFoundException e) {
//
Could not find the database driver
{
//
{
catch (SQLException e) {
Could not connect to the database
// Fetch each row from the result set
while (rs.next()) {
// Get the data from the row using the column index
String s = rs.getString(1);
// Get the data from the row using the column name
s = rs.getString("col_string");
}
}catch (SQLException e) {}
‫הקדמה‬
‫הקמת סביבת עבודה‬
‫תוכנית לדוגמא‬
‫‪HQL‬‬
‫הטמעה‬
‫‪ 89-211‬תכנות מתקדם ‪ – 2‬תרגול ‪6‬‬
‫הקדמה‬
‫• למעשה אנו צריכים תשתית‪.‬‬
‫• תשתית בעלת ארכיטקטורת ‪.ORM‬‬
‫• ‪Object / Relational Mapping‬‬
‫• מתאם אוטומטי בין סכמה רלציונית למחלקה ובין‬
‫תוכן הטבלה למופע של מחלקה זו‪.‬‬
‫• כאן נכנס ‪ Hibernate‬לתמונה‪.‬‬
‫אילוצים‬
‫טיפוס‬
‫שדה‬
‫מפתח ראשי‬
‫מספר‬
‫‪USER_ID‬‬
‫‪-‬‬
‫טקסט‬
‫‪FIRST_NAME‬‬
‫‪-‬‬
‫טקסט‬
‫‪LAST_NAME‬‬
‫‪-‬‬
‫מספר‬
‫‪AGE‬‬
‫‪-‬‬
‫טקסט‬
‫‪EMAIL‬‬
‫{ ‪public class User‬‬
‫; ‪private long userId = 0‬‬
‫;"" = ‪private String firstName‬‬
‫;"" = ‪private String lastName‬‬
‫;‪private int age = 0‬‬
‫;"" = ‪private String email‬‬
‫}‬
‫‪ 89-211‬תכנות מתקדם ‪ – 2‬תרגול ‪6‬‬
‫הקדמה‬
‫הקדמה‬
‫הקמת סביבת עבודה‬
‫תוכנית לדוגמא‬
‫‪HQL‬‬
‫הטמעה‬
‫‪:Hibernate‬‬
‫• קוד פתוח‬
‫• ספריות ‪ ORM‬ל ‪java‬‬
‫• צריך רק להגדיר את הקישור למסד הנתונים ואת מיפוי‬
‫השדות ‪ -‬למשתני מחלקה בקובצי ‪ xml‬וכל העבודה‬
‫מתבצעת באופן שקוף לנו‪.‬‬
‫• אנו עובדים עם אובייקטים שנטענים או נשמרים במסד‬
‫נתונים‪.‬‬
‫• שאילות בשפת ‪HQL‬‬
‫– שפת שאילתות מונחית עצמים‬
‫– אין צורך לשנות את הקוד שלנו אם השתנה מסד הנתונים‬
‫‪ 89-211‬תכנות מתקדם ‪ – 2‬תרגול ‪6‬‬
‫הקמת סביבת העבודה‬
‫הקדמה‬
‫הקמת סביבת עבודה‬
‫תוכנית לדוגמא‬
‫‪HQL‬‬
‫הטמעה‬
‫• נוריד את ה ‪ core package‬מהאתר‬
‫‪ http://www.hibernate.org/6.html‬ונפתח את ה ‪zip‬‬
‫במקום כלשהו‪.‬‬
‫• נפתח פרויקט ‪ java‬חדש בשם ‪HibernateExample‬‬
‫• הוספת ה ‪ jars‬של ‪:Hibernate‬‬
‫– נוסיף ‪ lib‬בשם ‪Hibernate‬‬
‫• מאפייני הפרויקט ‪  build path ‬לשונית ‪libraries‬‬
‫‪new…  user lib…  add lib... ‬‬
‫– נוסיף ‪( jars‬באותו החלון ‪)add jars‬‬
‫– נבחר את ה ‪ jars‬מהמקום בו פתחנו את ה ‪zip‬‬
‫וכן מתת‪-‬התיקייה ‪lib/required‬‬
‫• כמו כן צריך לצרף את ‪ slf4j-jdk14-1.5.2.jar‬מתוך‬
‫‪ http://www.slf4j.org/dist/slf4j-1.5.2.zip‬עבור הלוג‪.‬‬
‫‪ 89-211‬תכנות מתקדם ‪ – 2‬תרגול ‪6‬‬
‫תוכנית לדוגמא‬
‫הקדמה‬
‫הקמת סביבת עבודה‬
‫תוכנית לדוגמא‬
‫‪HQL‬‬
‫הטמעה‬
‫• תחילה ניצור את מסד הנתונים הבא‪:‬‬
‫אילוצים‬
‫טיפוס‬
‫שדה‬
‫מפתח ראשי‬
‫מספר‬
‫‪USER_ID‬‬
‫‪-‬‬
‫טקסט‬
‫‪FIRST_NAME‬‬
‫‪-‬‬
‫טקסט‬
‫‪LAST_NAME‬‬
‫‪-‬‬
‫מספר‬
‫‪AGE‬‬
‫‪-‬‬
‫טקסט‬
‫‪EMAIL‬‬
‫‪mysql‬‬
‫• כעת ניצור את קובץ הקונפיגורציה ל ‪Hibernate‬‬
‫תחת ‪ src‬בשם ‪hibernate.cfg.xml‬‬
‫– תוכן הקובץ ייקשר את הפרויקט למסד הנתונים שיצרנו‬
‫הקדמה‬
‫הקמת סביבת עבודה‬
‫תוכנית לדוגמא‬
HQL
‫הטמעה‬
6 ‫ – תרגול‬2 ‫ תכנות מתקדם‬89-211
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD
3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
jar ‫עלינו לצרף את ה‬
‫המכיל את המחלקה‬
‫שמבצעת את הקישור‬
.mysql ‫עבור‬
:‫ניתן להורדה מ‬
<session-factory>
<property name="connection.url">
jdbc:mysql://localhost:3306/myDatabase
</property>
<property name="connection.driver_class">
com.mysql.jdbc.Driver
</property>
‫כתובת מסד הנתונים‬
mysql ‫שלנו בשרת ה‬
‫המחלקה האחראית על‬
‫על ביצוע הקישור‬
‫– פרטים בצד‬
<property name="connection.username">
http://dev.mysql.com/d
ownloads/connector/j/
5.1.html
root
‫שם המשתמש‬
</property>
<property name="connection.password">
‫סיסמה‬
write here your password
</property>
‫ במקום‬zip ‫פתחו את ה‬
jar ‫כלשהו וצרפו את ה‬
‫ של‬build path ‫ל‬
.‫הפרויקט‬
<!-- Set AutoCommit to true -->
<property name="connection.autocommit">
true
</property>
Auto commit = true
‫שלא נצטרך לבצע ידנית לאחר‬
.‫ אלא אם נרצה בכך‬,‫כל פעולה‬
<!-- SQL Dialect to use. Dialects are database specific -->
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<!-- Mapping files -->
<mapping resource="‫ "נמלא בשקפים הבאים‬/>
</session-factory>
</hibernate-configuration>
‫הפנייה לקובץ המיפוי‬
‫הקדמה‬
‫הקמת סביבת עבודה‬
‫תוכנית לדוגמא‬
HQL
‫הטמעה‬
6 ‫ – תרגול‬2 ‫ תכנות מתקדם‬89-211
‫תוכנית לדוגמא‬
:‫ המתאימה לטבלה‬java ‫• כעת ניצור מחלקה ב‬
public class User {
private long userId = 0 ;
private String firstName = "";
private String lastName = "";
‫שדה‬
‫טיפוס‬
‫אילוצים‬
USER_ID
‫מספר‬
‫מפתח ראשי‬
FIRST_NAME
‫טקסט‬
-
LAST_NAME
‫טקסט‬
-
AGE
‫מספר‬
-
EMAIL
‫טקסט‬
-
private int age = 0;
private String email = "";
}
.‫ מתאימים‬setters ‫ ו‬getters ‫• נוסיף‬
:eclipse ‫• טיפ ל‬
Generate getters and setters…  Source  ‫– קליק ימני על המחלקה‬
‫הקדמה‬
‫הקמת סביבת עבודה‬
‫תוכנית לדוגמא‬
HQL
‫הטמעה‬
6 ‫ – תרגול‬2 ‫ תכנות מתקדם‬89-211
‫תוכנית לדוגמא‬
‫ נקרא‬,‫ האחראי למיפוי השדות‬xml ‫• כעת ניצור את קובץ ה‬
User.hbm.xml ‫לו‬
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping>
‫התאמת מחלקה לטבלה‬
<class name="User" table="USERS" >
<id name="userId" type="java.lang.Long" column="user_id" >
<generator class="increment" />
</id>
‫ מהווה מפתח ראשי‬id ‫השדה‬
‫ – השיטה ליצור מפתח‬generator
<property name="firstName" type="java.lang.String" column="first_name" length="20" />
<property name="lastName" type="java.lang.String" column="last_name" length="20" />
<property name="age" type="java.lang.Integer" column="age" length="-1" />
‫מיפוי שאר השדות‬
<property name="email" type="java.lang.String" column="email" length="40" />
</class>
</hibernate-mapping>
‫ נוסיף את ההפניה לקובץ המיפוי‬hibernate.cfg.xml ‫• ב‬
<mapping resource="User.hbm.xml" />
‫הקדמה‬
‫הקמת סביבת עבודה‬
‫תוכנית לדוגמא‬
HQL
‫הטמעה‬
6 ‫ – תרגול‬2 ‫ תכנות מתקדם‬89-211
‫תוכנית לדוגמא‬
import org.hibernate.Session;
public class UserManager {
private Session session = null;
public UserManager(Session session) {
if(session == null)
throw new
RuntimeException("Invalid session object.");
this.session = session;
}
public void saveUser(User user){
session.save(user);
}
public void updateUser(User user){
public void deleteUser(User user) {
session.delete(user);
}
}
.‫טבלה במסד הנתונים שלנו‬
.‫ לקונפיגורציה‬xml ‫קובץ‬
.java ‫מחלקה תואמת לטבלה ב‬
.‫ למיפוי השדות‬xml ‫קובץ‬
–
–
–
–
‫• כעת נלמד כיצד "לדבר" עם‬
.‫מסד הנתונים שלנו‬
session ‫– לשם כך נצטרך לפתוח‬
.‫ שלנו‬mysql ‫לקוח מול שרת ה‬
org.hibernate.Session ‫– המחלקה‬
.‫עושה עבורנו את העבודה‬
‫ במסד‬User ‫ תנהל אובייקטים של‬UserManager ‫– המחלקה‬
.Session ‫הנתונים שלנו באמצעות‬
session.update(user);
}
:‫• עד כה יצרנו‬
‫הקדמה‬
‫הקמת סביבת עבודה‬
‫תוכנית לדוגמא‬
HQL
‫הטמעה‬
6 ‫ – תרגול‬2 ‫ תכנות מתקדם‬89-211
‫תוכנית לדוגמא‬
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class Main {
public static void main(String[] args) {
User user = new User();
user.setFirstName("Kermit");
user.setLastName("Frog");
user.setAge(54);
user.setEmail("[email protected]");
SessionFactory sessionFactory = new
Configuration().configure().buildSessionFactory();
Session session = sessionFactory.openSession();
UserManager manager = new UserManager(session);
manager.saveUser(user);
System.out.println("User saved with ID = "+
user.getUserId());
session.flush();
}
}
mysql
‫• כעת נראה קוד ששומר אובייקט‬
.‫ במסד הנתונים שלנו‬user
User ‫יצרנו מופע של‬
SessionFactory ‫יצרנו מופע של‬
‫שבעזרתו יצרנו מופע של‬
Session
UserManager ‫יצרנו מופע של‬
saveUser ‫וקראנו ל‬
)1=( ID ‫הדפסנו את ה‬
–
–
–
–
:‫• התוצאה‬
‫הקדמה‬
‫הקמת סביבת עבודה‬
‫תוכנית לדוגמא‬
HQL
‫הטמעה‬
6 ‫ – תרגול‬2 ‫ תכנות מתקדם‬89-211
‫תוכנית לדוגמא‬
User user;
SessionFactory sessionFactory = new
Configuration().configure().buildSessionFactory();
Session session = sessionFactory.openSession();
Query query = session.createQuery("from User");
List <User>list = query.list();
Iterator<User> it=list.iterator();
while (it.hasNext()){
user=it.next();
System.out.println("id: \t\t"+user.getUserId());
System.out.println("age: \t\t"+user.getAge());
System.out.println("first name: \t"+user.getFirstName());
System.out.println("last name: \t"+user.getLastName());
System.out.println("email: \t\t"+user.getEmail());
}
id:
1
age:
54
first name:
Kermit
last name:
Frog
email:
[email protected]
‫• כעת נראה קוד שיוצר‬
‫אובייקטים מתוך הרשומות‬
.‫במסד הנתונים‬
‫– נשתמש במחלקה‬
org.hibernate.Query
‫כדי לכתוב שאילתות ל‬
session
‫– נקבל את רשימת התוצאות‬
‫ונעבור עליה באמצעות‬
iterator
‫הקדמה‬
‫הקמת סביבת עבודה‬
‫תוכנית לדוגמא‬
HQL
‫הטמעה‬
6 ‫ – תרגול‬2 ‫ תכנות מתקדם‬89-211
HQL
User user;
SessionFactory sessionFactory = new
Configuration().configure().buildSessionFactory();
Session session = sessionFactory.openSession();
Query query = session.createQuery("from User");
List <User>list = query.list();
Iterator<User> it=list.iterator();
while (it.hasNext()){
user=it.next();
System.out.println("id: \t\t"+user.getUserId());
System.out.println("age: \t\t"+user.getAge());
System.out.println("first name: \t"+user.getFirstName());
System.out.println("last name: \t"+user.getLastName());
System.out.println("email: \t\t"+user.getEmail());
}
‫ הקוד שלנו‬,‫ניתן להחליף את מסד הנתונים‬
...‫יישאר אותו הדבר‬
Hibernate Query Language
‫• שפת שאילתות שדומה‬
SQL ‫בכוונה ל‬
‫• אך אל תתנו לסינטקס‬
‫ היא שפה‬,‫להטעות אתכם‬
‫בעלת תאימות מלאה ל‬
object oriented
:‫• יכולת הבנה של‬
‫– ירושה‬
‫– פולימורפיזם‬
‫– קשר אסוציאטיבי‬
‫הקדמה‬
‫הקמת סביבת עבודה‬
‫תוכנית לדוגמא‬
HQL
‫הטמעה‬
6 ‫ – תרגול‬2 ‫ תכנות מתקדם‬89-211
HQL
:‫• נראה מספר דוגמאות‬
Cat ‫ השאילתה הבסיסית למופעים של‬: "from Cat” –
: “select u from User u ordered by u.firstName, u.lastName” –
‫ בצורה ממוינת תחילה‬User ‫בחירת כל אובייקט מסוג‬
.lastName ‫ ואח"כ לפי‬firstName ‫לפי‬
"select cat.weight + sum(kitten.weight) from –
Cat cat join cat.kittens kitten group by cat.id,
?‫ מה הקוד הזה נותן‬: "cat.weight
:‫• ניתן לבקר במדריך הבא כדי להכיר את השפה‬
http://docs.jboss.org/hibernate/stable/core/reference/en/html/queryhql.html
‫‪ 89-211‬תכנות מתקדם ‪ – 2‬תרגול ‪6‬‬
‫הטמעה‬
‫•‬
‫•‬
‫•‬
‫•‬
‫הקדמה‬
‫הקמת סביבת עבודה‬
‫תוכנית לדוגמא‬
‫‪HQL‬‬
‫הטמעה‬
‫למה להשתמש ב ‪?hibernate‬‬
‫למה משמשת המחלקה ‪?Session‬‬
‫מהם היתרונות של השימוש ב ‪?HQL‬‬
‫היכנסו ל ‪ tutorial‬הבא‪( :‬ממנו נלקחו הדוגמאות)‬
‫‪http://www.visualbuilder.com/java/hibernate/tutorial/‬‬
‫והמשיכו את הדוגמא כדי לראות כיצד מבצעים‬
‫קשר אסוציאטיבי בין טבלאות שונות‪.‬‬
‫– קשר ‪one to many‬‬
‫– קשר ‪many to many‬‬