JavaRush /Kurslar /All lectures for AZ purposes /PreparedStatement ilə İş

PreparedStatement ilə İş

All lectures for AZ purposes
Səviyyə , Dərs
Mövcuddur

Bəyannamələr Növləri

Ən sadə interface Statement artıq görmüşük. Baxmayaraq ki, o, işləmək üçün uyğun, mürəkkəb sorğular üçün o qədər də münasib deyil. Bəzi mənbələrdə belə fikir var ki, Statement ümumiyyətlə istifadə olunmamalıdır — onun yerinə daha mürəkkəb və daha funksional zəngin interfeyslər uyğundur.

  • PreparedStatement
  • CallableStatement

Axı, bu interfeyslər niyə lazımdır? Gəlin başa düşək.

Əvvəlcə PreparedStatement interfeysinə və JDBC-nin digər imkanlarına baxacağıq. CallableStatement interfeysini bir az sonra nəzərdən keçirəcəyik — onun istifadəsi, birincisi, o qədər də tez-tez rast gəlinmir, ikincisi — onun haqqında danışmaq artıq kifayət qədər qısa ola bilər.

Bundan əlavə, PreparedStatement SQL Injection adlanan məşhur bir verilənlər bazasını sındırma yanaşmasından qurtulmağa da kömək edir.

Ancaq bu barədə bir az sonra daha ətraflı danışacağıq.

PreparedStatement

PreparedStatement'in adını tərcümə etməyə çalışsaq, "hazırlanmış operator" kimi bir şey əldə edərik. Burada ən vacib olan "hazırlanmış" sözüdür. "Hazırlanmışlıq" nədən ibarətdir?

Bu suala baxmazdan əvvəl təklif edirəm ki, çox tez-tez yaranan və rahatlıq baxımından olduqca vacib bir məqamı görək. Beləliklə, hər hansı bir tətbiqdə CONTACT cədvəlinə əlaqə məlumatlarını daxil etməliyik. Bunun üçün bizdə belə bir sorğu hazırlamaq lazımdır:

INSERT INTO
  JC_CONTACT (FIRST_NAME, LAST_NAME, PHONE, EMAIL)
VALUES
  (
    'Harry',
    'Potter',
    '+79112345678',
    'harry@example.com'
  );

İlk baxışda elə görünür ki, hər şey çox da çətin və qorxunc deyil. Bizə lazım olan sətiri parametrlərdən: ad, soyad, ünvan və telefon toplamaq üçün kod yazmalıyıq. Yalnız unutmaq lazım deyil ki, bütün sətir məlumatlarını tək tırnaq işarəsi ilə əhatə etməliyik.

Bunu ayrı bir funksiyada etdikdə isə belə bir şey alınır:


public String buildInsert(String firstName,, String lastName, String phone, String email) {
    String sql = "INSERT INTO JC_CONTACT (FIRST_NAME, LAST_NAME, PHONE, EMAIL) “+
             	”VALUES ('" + firstName + "','" + lastName + "','" + phone + "','" + email + ")";
    return sql;
}

Funksiyaya parametr olaraq ad, soyad, telefon və ünvan veririk və onlardan SQL sorğusunun sətirini tərtib edirik. Tırnaq işarələri bir qədər mənzərəni pozur, amma hələlik qorxulu deyil.

Yaxşı, bəs rəqəmlərlə nə etməli? Onları tırnaq işarəsi ilə əhatə etmək lazım deyil. Vay, bir halda tırnaq lazımdır, digər halda isə lazım deyil. Vəziyyət çətinləşir.

İndi daha bir problem əlavə edək — bəs sətirin içində tək tırnaq işarəsi (hətta bir neçə) varsa? Belə tırnaqları əvvəlcədən axtarıb emal etmək lazımdır. Mdaaa. Özümüzü bir az narahat hiss etməyə başlayırıq.

İndi tarixlərin emalını da bura əlavə etsək, iş daha da sıxıcı olur — çoxlu iş görmək lazım olur. Tarixlərlə ümumiyyətlə xoşagəlməzdir — müxtəlif SQL serverləri tarixlər üçün müxtəlif formatlar qəbul edir.

Görürük ki, əgər sorğunun içində parametrlərdən istifadə etmək lazım gəlsə, sorğunun əl ilə tərtib olunması çox xoşagəlməz bir iş olur. Həm də təkcə xoşagəlməz deyil — darıxdırıcıdır da. Çox sayda halları nəzərə almaq lazımdır, və bu çox darıxdırıcı bir işdir. Əslində, belə hallar üçün PreparedStatement interfeysi təklif edildi.

Bu sorğu sizə iki şey etməyə imkan verir:

  • Parametrlərin yerləşdiriləcəyi yerləri göstərən sorğunu əvvəlcədən hazırlayın
  • Müəyyən növ parametrləri təyin edin və bundan sonra parametrizasiya edilmiş sorğunu icra edin

PreparedStatement-dən istifadə nümunəsi

Bizim parametr qurma variantımıza uyğun olaraq PreparedStatement üçün konstruksiya belə görünəcək:


// Nümunə üçün dəyişənlər
String firstName = "Harry";
String lastName = "Potter";
String phone = "+12871112233";
String email = "harry@example.com";
 
// Məlumatların daxil olacağı yerlər üçün "?" işarəsi ilə sorğu
String sql = "INSERT INTO JC_CONTACT (FIRST_NAME, LAST_NAME, PHONE, EMAIL) VALUES (?, ?, ?, ?)";
 
// Sorğunun yaradılması. Dəyişən con — Connection tipli bir obyekt
PreparedStatement stmt = con.prepareStatement(sql);
 
// Parametrlərin təyini
stmt.setString(1, firstName);
stmt.setString(2, lastName);
stmt.setString(3, phone);
stmt.setString(4, email);
 
// Sorğunun icrası
stmt.executeUpdate();

Gördüyün kimi, hər şey asanlıqla alınır.

Birincisi, SQL sorğusu yazılarkən parametrlərin yerləşdirilməsi lazım olan yerlərə sual işarəsi qoyulur - “?”.

İkincisi — sorğu con.prepareStatement() çağırışı vasitəsilə yaradılır.

Üçüncüsü — parametrlərin qurulması nömrə və dəyər göstərməklə həyata keçirilir. Diqqət et ki, parametr nömrələri 0-dan deyil, 1-dən başlayır, necə ki, massivlər və kolleksiyalarla işləyərkən öyrəşdiyimiz kimi deyil.

PreparedStatement interfeysi sətirlər üçün metodlara malikdir — setString(), rəqəmlər üçün — setInt(), setLong(), setDouble(), tarixlər üçün — setDate(). Və daha mürəkkəb tipləri — bunları sənəddə görə bilərsiniz.

Dördüncüsü — stmt.executeUpdate() çağırışı artıq sorğu sətirini göstərmədən icra edilir.

Həqiqətən də, PreparedStatement ilə dost olunmasını çox tövsiyə edirəm — bu çox effektiv bir vasitədir.

Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION