Saturday, December 21, 2013

ProtoBuf & Thrift



Protocol Buffer არის გუგლის ენა  - მექანიზმი დასასერიალიზირებადი მონაემებისათვის. სხვა სიტყვებით რომ ვთქვათ, საშუალებას გვაძლევს მარტივად და სწრაფად ვიმუშაოთ სტრუქტურიზირებულ მონაცემებთან.  წარმოიდგინეთ XML დოკუმენტი. XML ზე უფრო პატარა გვაქვს  JSON. უფრო პატარას, უფრო სწრაფს და უფრო მარტივს კი გუგლის გვთავაზობს(binary არის ოღონდ).  ერთხელ ვწერთ, თუ როგორი სტრუქტურა გვინდა, შემდეგ კი შესაძლებლობა გვაქვს მონაცემები ჩავწეროთ ან წავიკითხოთ.  ამასთან გვაქვს საშუალება,  სხვადასხვა ენებში მუშაობისა - Java, C++,  Python.

ტესტირებისთვის ჯავას ობიექტი დავასერიალიზე, დაახლოებით 500 byte ზომის გამომივიდა, ProtoBuf ით კი ბაინარი დატა 50 byte.

ამ მექანიზმს, ვისაც ნანახი გაქვთ, Google App Engineც იყენებს, და სხვა გუგლის სერვისები. საკმაოდ ფართოდ გამოყენებადია.

ალტერნატივებიც არსებობს, მაგალითად  Apache Thrift, რომელიც FB-მ შექმნა. ორივე რაღაცით არის კარგი. მაგალითად Thrift ისგან განსხვავებით, პროტოკოლ ბუფერით დასერიალიზირებული მონაცემები 30% ით უფრო მცირე არის. სამაგიეროდ, Thrift-ს სტრუქტურა მეტად დახვეწილი აქვს, მაგალითად შესაძლებელია Map ის აღწერა. კიდე ერთი განსხვავება ის არის რომ Thrift ში პირდაპირ არის ინტეგრირებული RPC , პროტოკოლ ბუფერში კი ცალკე არის გატანილი. ენების მხრიბ Thrift-ს შემდეგ ენებთან აქვს მუშაობის შესაძლებლოვა: Thrift: Java, C++, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, Smalltalk, OCaml, ხოლო რაც შეეხება protobuf-ს მხოლოდ Java, C++, Python. და ბოლოს, რაც მთავარია Protobuf ვრცელდება BSD ლიცენზიით, Thrift-ს კი Apache License ადევს.


Sunday, December 8, 2013

Mapping Persistent Objects

Mapping Persistent Objects

ამ სტატიაში ვისაუბრებთ თუ როგორ ხდება ენთით ბინების  რელაციურ ბაზაში მოთავსება. შევეცდები, ყველაზე მნიშვნელოვან საკითხებზე ვისაუბრო. რასაც ვერ მოვასწრებ, შემდეგ სტატიაში შემოგთავაზებთ. დავიწყოთ.

@javax.persistence.Entity
@Entity ანოტაცია ფერსისთენს პროვაიერს ეუბნება, რომ შესაბამისი კლასი უნდა შეინახოს ბაზაში. ასე გამოიყურება ეს ანოტაცია:

როგორც ვხედავთ, აქ გვაქვს name() მეთოდო მხოლოდ. თუ სახელს არ გადავცემთ , დეფაულთად აიღებს ბინის სახელს.

@javax.persistence.Id 
განსაზღვრავს, თუ კლასის რომელი ველი იყოს ბაზაში promary key.
პატარა მაგალითი:


შესაძლებელია XML შიც გავაკეთოთ იგივე (persistence.xml ში).
მაგალითად:

@javax.persistence.GeneratedValue
რაც შეეხება primary key ს, შეგვიძლია ჩვენ ჩვენთვითონვე განუსაზღვროთ, ან საშვალება მივცეთ რომ თვითონვე დაგენერირდეს.
ასე გამოიყურება ჩვენი შესაძლებლობები:

როგორც ვხედავთ, დეფაულთად AUTO გვიყენია. დანარჩენებზე 3 ზე, დეტალური გარჩევა შეგიძლიათ იხილოთ ამ ლინკზე. მარტივი მაგალითი:

@javax.persistence.Table
ენთითი მენეჯერს ვეუბნებით რომ შესაბამისი ანოტაციის მნიშვნელობა ეხება რელაციური ბაზის ცხრილს. კერძოდ მაგალითად ფხრილის სახელის განსასაზღვრავად.
მთლიანად კი ასე გამოიყურება:

@javax.persistence.Column
სვეტებზე სამუშაო ანოტაცია. სულ ეს მეთოდები გვაქვს:


რელიციური ბაზები ვინც იცის, ადვილად მიხვდება ყოველივეს. მაგალითად, name განსაზღვრავს სვეტის სახელს.  table გამოიყენებას ახლა არ გავნმარტავ დეტაულად, თორე სხვა თემაზე მომიწევს გადახტომა- კერძოდ Multitable მეფინგის დროს გამოიყენება. მაგალითად, თუ გვინდა რაღაც ველები პარალელურად სხვა ცხრილშიც ჩავწეროთ. VARCHAR ის ზომას length განსაზღვრავს. დანარჩენიც ადვილი მისახვედრია ვინც რელაციური ბაზები იცით და აღარ გავაგრძელებ.




@Basic and FetchType

@Basic  ანოტაცია არის დეფაულთი მონაცემების ჩამწერი შემდეგი ტიპის მონაცემებისთივს:  java.lang.String, byte[], Byte[], char[], Character[], java.math.BigInteger, java.math.BigDecimal, java.util.Date, java.util.Calendar, java.sql.Date, java.sql.Time ,  java.sql.Timestamp .

არ არის საჭირო ჩვენ ვუთხრათ ფერსისთენს მენეჯერს თუ როგორ ჩაწეროს მონაცემები, ის ავტომატურად ჩაწერს ისე როგორც საჭიროდ ჩათვლის.

აგერ ვიხილოთ ჩაწერის სახეებიც.



თუ fetch() ატრიბუტი არის LAY, შესაბამისი ფროფერთის ინიციალიზება არ მოხდება მანამ, სანამ მასზე წვდომას არ მოვახდენთ.   თუმცა აქ ერთი დეტალია გასათვალისწინებელი, ზოგადად @basic ანოტაცია არ არის პირდაპირ და ცალსახად განმსაზღვრელი თუ როგორ ვამუშაოთ პროგრამა. ეს უფრო მიმათითებელი არის, რომელიც შესაძლოა შესრულდეს სხვანაერადაც. ზოგმა JPA -ს იმპლემენტაციამ შეიძლება ეს აღიქვას, როგორც პირდაპირ განსაზღვრულად, ზოგმა შეიძლება არა. ანუ იმას ვამბობ რომ შეიძლება LAZY მივუთითოთ მაგრამ ინიციალიზება მაინც გაუკეთოს( ანუ EAGRLY სავით მოიქცეს). ეს მხოლოდ იმიტომ , რომ ოპტიმიზაციის გამო კარგად იმუშაოს - თვითნ ხვდება რომელი არის უკეთესი.
მოვიყვანოთ მაგალითი

XML შიც შეიძლება იგივე გავაკეთოთ:

@Temporal

საშუალებას გვაძლევს, რომ დამატებითი ინფორმაცია მივცემთ ფერსისთენს პროვაიდერს java.util.Date ან java.util.Calendar ზე. ანუ ამ ანოტაციის წყალობით შეგვიძლია შევინახოთ ბაზაში DATE, TIME, TIMESTAMP. მაგალითად გვინდა შევინახოთ ენთითს შექმნის თაღირი. ამაზე მაგალითსაც შემოგთავაზებთ ქვემოთ (სათითაოდ რომ არ ვწერო @Lob ზე და @Enumarated-ზე, ერთად დავწერ).

@Lob

ზოგჯერ არის შემთხვევები, როდესაც დიდი ინფორმაცია გვაქვს შესანახი ბაზაში. ამისათვის JDBC ში არის, მაგალითად, სპეციალური ტიპები ობიექტებისთვის. მაგალითად, ჩვენ ვიცით რომ java.sql.Blob არის binary მონაემებისთვის, ხოლო java.sql.Clob არის character მონაცემებისათვის. javax.persistence.Lob ანოტაცია არის სწირედ იმისთვის რომ შევინახოთ ესეთი ტიპის დიდი მონაცემები. (მაქალითს ქვემოთ დავწერ)

 @Enumerated

ეს ანოტაცია საშვალებას გვაძლევს შევიანახოთ ენამის ტიპის მონაცემები ბაზაში.

ამ ბოლო სამ ანოტაციაზე მაგალითი კი ეს არის:

ახლა მოვრჩები წერას :) კიდევ აუცილებელი და მნიშვნელოვანი საკითხებია @Embeddable ობიექტები,   Primary-Key კლასები, რელაციები ბაზებს შორის და ასე შემდეგ.   როცა დრო მექნება გავაგრძელებ წერას:)