უკვე ღამის ოთხი საათა და ობიექტური მიზეზების გამო ჯერაც არ მძინავს. სანამ ჩემ ფუმფულა ბალიშზე თავს დავდებდი, გადავწყვიტე, არც მეტი არც ნაკლები 2-3 წუთი დამეთმო ამ სტატიისთვის. უძინარის კვალობაზე, გრამატიკულ შეცდომებს თუ შეამჩნევთ, არ გაიკვირვოთ. :)
ალბათ გექნებათ ნანახი აპლიკაციები, რომლებიც გაშვებული არიან JVM ის შემდეგი პარამეტრით: "-server" ან "-client".
ორივე შემთხვევაში, ვიყენებთ ჩვენ -server თუ client პარამეტრს, JVM იქცევა სხვადასხვანაგვარად. -server ის დროს JVM მეტ ოპტიმიზაციას ანხორციელებს (JIT ზე ვსაუბრობ აქ), აპლიკაციის დასტარტვის დრო ცოტა ნელია თუმცა საბოლოო ჯამში მეტად ოპტიმიზირებული შედეგი მიიღება. -client შემთხვევაში კი მსუბუქად უკეთებს ოპტიმიზაციას კოდის ისეთ ნაწილებს სადაც JVM-ს მეტად მძიმე, დატვურთული, მუშაობა ჭირდება.
ორივეს ფლაგს თავისი ადგილი და მიზანი აქვს. მაგალითად, როდესაც რაიმე სერვერს ვსტარტავთ, აუცილებლად -server პარამეტრი უნდა გამოვიყენოთ. ამას ბევრი მიზეზი აქვს. ერთერთო ის, რომ სერვერის დასტარტვის დროზე მეტად, ჩვენთვის მნიშვნელოვანია სერვერის საბოლოო ჩქარი მუშაობა. რაც შეეხება -client-ს ის შეილება გამოვიყენოთ, მაგალითად GUI აპლიკაციის გასაშვებად - ეშვება სწრაფად და სამუდამოდაც არ იქნება დასტარტული.
შენიშვნა Thread Visibility -ზე წინა ერთერთ სტატიაში (შეგიძლიათ გახსათ lazy init, dc locking, volatile) დავწერე Volatile-ცვლადების სპეციფიურ ქცევაზე. მაგალითი იყო შემდეგი: გვაქვს 2 სრედი, პირველი ნაკადი უყურებს whilte(flag){}-ს მეორე კი flag ზე ახდენს მოდიფიცირებას -მნიშვნელობას უცვლის ისე რომ ციკლი გააჩეროს. ერთ შემთხვევაში flag არის volatile მეორეში კი უბრალოდ მარტივი, კოტხტა, ლამაზი და მშვენიერი boolean - რომელიც თავისთვის არის და არის, ცხოვრობს თავის თბილ სახლში, heap ად წოდებულში.
წარმოვიდგინოთ, ზემოთ აღნიშნული კოდი წერია ერთერთ აპლიკაციაში რომელიც გაშვებულია სერვერზე - Tomcat მაგალითად, ან Jetty (ეს უკანასკნელი ძალიან კარგი ბიჭია asynchronous რექუესთების დამუშავებაში). ჩვენ უკვე ვიცით რომ, რომ სერვერ აპლიკაციები ყოველთვის უნდა იყვნენ დასტარტულები -server ბრძანებით. მაგრამ Oops! -server ის წყალობით , უფრო კი მისი ოპტიმიზაცთ, JVM მა შესაძლოა ციკლში არსებული არამოდიფიცირებადი ცვლადებისადმი ხედვის არიალი გადაიტანოს ციკლის გარეთ - უფრო გასაგები რომ იყოს, ციკლის შიგნით არ ხდება flag მნიშვნელობის შეცვლა, ამან კი შესაძლოა JVM დაარწმუნის, რომ ოპტიმიზაციისთვის ხედვის არეალი შეცვალოს. გილოცავთ, ეს არის უსასრულო ციკლი! შედეგად, შესაძლოა კოდმა იმუშაოს -client გარემოში, და არ იმუშაოს -server ში. დებაგირების დროსაც თუ -server-ს გამოვიყენებთ, პროდაქშენზე დადებამდე, ამით შემდეგი ტიპის გაჟონვებს თავიდან ავიცილებთ - ტესტირების დროსვე დავიჭერთ შეცდომას.
ოპტიმიზაცია ამასთან გულისხმობს არამარტო სხვადასხვა ალგორითმის თვალით დამუშავებულ კოდის ნაწილებს, არამედ მეხსიარების გამოყოფის სხვადასხვა მექანიზმებსაც, JVM ის მიერ განსხვავებულ დამოკიდებულებას gc-ს მიმართ, და ასე შემდეგ.
Monday, October 27, 2014
Friday, October 10, 2014
NoSQL 'n CAP
NoSQL მოიცავს ისეთ ბაზებს როგორებიცაა: Mongo, Neoj4, Cassandra, Riak, Hadoop (HDFS ხოლო რეალ თაიმ ბაზა HBase) და ასე შემდეგ, ისინი ერთმანეთისგან სტრუქტურულად განსხვავდებიან (ჰადუპის ეკო სისტემაზე სხვა დროს დეტალურად ვისაუბრებ). მაგალითად არსებობს, გრაფებზე აგებული ბაზები (Neo4j), Key Value სტრუქტურის მქონენი (Cassandra, Redis), Mongo სა და CouchDB– ში დოკუმენტების შენახვა JSON ობიექტებით ხდება
საბოლოოდ, მათში ინახება უსქემო მონაცემები*, ადვილია მათი დაკლასტერება, ეს სისტემები გამოირჩევიან დიდი სისწრაფით და ამარტივებენ ამოცანის გადაჭრას. NoSQL მონაცემთა ბაზა არ იყენებს SQL–ს, თუმცა ზოგი მათგანი query ენას გვაძლევს – მაგალითად Cassandra CQL.
*სიტყვა „უსქემო“ ხშირად დამაბნეველია, მაგალითად, როდესაც იგებენ, რომ მონგოს აქვს დიამიური სქემა- მასში შეგვიძლია შევქმნათ ქოლექშენები ისე რომ წინასწარ სტრუქტურა არ გვქონდეს აღწერლი.
ბაზებთან მუშაობისას შესაძლოა გვქონდეს“ network partition”–ები, რომლებიც გულსიხმობენ კლასტერში ნოუდებს შორის კომუნიკაციის დაკარგვას და შესაბამისად ინფორმაციის არასინქრონულობას.
შესაბამისად ბაზას ყოფენ შემდეგი ტიპებად, რომელთაგან მხოლოდ 2 შეგვიძლია შევინარჩუნოთ.
Consistency (მუდმივობა) - ჩანაწერები იგივეა კლასტერის ყველა node ში.
Availability – თუ რომელიმე Node არის ჩავარდნილი, მაინც შესაძლებელია კლასტერთან წვდომა.
Partition Tolerance – კლასტერი განაგრძობს ფუნქციონალობას მაშინაც კი როდესაც node ებს შორის არის კომუნიკაციის პრობლემა.
ამ სამზე (CAP) დეტალურ მაგალითებს, ქვემოთ მოვიყვან.
1. ან დავუშვათ რომ არასინქრონირებული მნაცემები იყვნენ ბაზაში (დავივიწყოთ Consistency)
2. ჩავთვალოთ რომ კლასტერი დაზიანდა, ანუ დავივიწყოთ Availability
ყველა კომბინაცია ასე გამოიყურება:
CA ერთიდაიგივე მონაცემებია ყველა node ში. თუ რაიმე კომუნიკაციის პრობლემა დაფიქსირდა node ებს შორის (partition ), მონაცემები იქნება არასინქრონირებული სანამ პრობლემა არ გადაიჭრება. ანუ node ებს შორის სხვადასხვა მონაცემები იქნება.
CP აქაც მონაცემები მუდმივია ყველა node ში. მაგალითად, დაფიქსირდა დაფიქსირდა კომუნიკაციის პრობლემა. ამ დროს არასინქრონული რომ არ იყოს მონაცემები შესაბამისი node გახდება გაუქმებული ანუ წაკითხვა/ჩაწერა იქნება გაჩერებული შესაბამის node ში. აქ თავი გვაქ დაცული იმისგან რომ სხვადასხვა მონაცემები არ გვეწეროს ბაზაში.
AP იგივე მაგალითი – დაფისქირდა პრობლემა node ებს შორის. აქ დაზიანებული node ები არ არიან გაუქმებულები. ისინი დამოუკიდებლად განაგრძობენ მუშაობას. როდესაც კომუნიკაციის პრობლემა აღდგება დაიწყება სინქრონიზაცია მონაცემების, თუმცა გარანტია არ გვაქვს რომ ყველა მონაცემი იგივე იქნება ნოუდებს შორის.
Wednesday, May 14, 2014
RBS Drools (PART I, BASICS)
Rule-based systems - წესებზე/ბრძანებებზე დაფუძნებული სისტემა– ძირითადად ისეთი ამოცანების გადაჭრაში გამოიყენება სადაც ხელოვნური ინტელექტია საჭირო ან მძლავრი გამოთვლებია განსახორციელებელი. მაგალითად: მგზავრობა მაქსიმალურად ბევრ ქალაქში ისე რომ მაქსიმალურად ცოტა თანხა დავხარჯოთ, ჭადრაკი ან თუნდაც სუდოკუ...
RBS–სათვის ბევრი პროექტები არის შექმნილი, ერთერთი არის Jboss Drools. ეს გახლავთ openSource პროექტი, რომელსაც სხვადასხვა შვილობილი (sub) პროექტები გააჩნია – Drools Expert, Drools Fusion, Drools Guvnor, Drools Planner და ასე შემდეგ.
გამახსენდა კიდევ Scala, ან IBM –ს აქვს Jrules პროექტი. Jrules ფასიანია, თუ ფული არ გვაქვს, უბრალოდ უნდა დავკმაყოფილდეთ იმით რაც გვაქვს. ამჯერად ამ სტატიაში Drools ზე ვისაუბრებთ.
სინტაქსი
მარტივი სინტაქსია. თუ სახელი ექვივალენტურია მარიამის, მაშინ
then ში გადავდივართ. კომპილერი ჭკვიანია და იცის რომ == იგივეა რაც String.equals
Person კლასის სხვა ველების შემოწმებაც შეგვიძლია და ასეთი სინტაქსი გვექნება:
ამ შემთხვევში p არის reference variable. აქვე პერსონის ობიექტიდან nickName ველი ამოვიღე და nick ცვლადში ჩავწერე (რათქმაუნდა სქოუფი შეზღუდული აქ ამ ცვლადს).
პროგრამის გასაშვებად 2 გზა გვაქვს. პირველი ესაა ფლაგინის დაყენება IDE ში.
ვერსიები შეგიძლიათ აქედან ამოირჩიოთ:
თუმცა მე ყოველთვის ბოლო განახლებულს ვიღებ, ანუ შეგიძლიათ დააინსტალიროთ ეკლიფსში შემდეგი ლინკიდან :
მეორე გზაა მავენის (ანუ იგივე მავნე) დეფენდენსებში დავამატოთ:
rule ბის დასაწერად შექმენით სახელი.drl ფაილი რესურსებში. გასაშვებად კი Drools და jBPM ის მიერ შემოთავაზებული KIE API გამოგვადგება.
განვიხილოთ ცოტა დახვეწილი მაგალითი. მაგალითად, ფიბანაჩის მიმდევრობაზე:
ჩვენ ვიცით რომ
თავიდან -1 მნიშვნელობები მივანიჭოთ (–1 ით ავღნიშნოთ ჯერ გამოუთვლელი მნიშვნელობები )
when –> თუ Fibonacci ობიექტში მნიშვნელობა არის -1 (ჩვენ შექმნისას –1 მივანიჭეთ, შესაბამისად არის), მაშინ –> შევქმნათ ახალი ობიექტი , ერთით ნაკლები მიმდევრობის ნომრით.
ყველა შემთხვევაში ვიცით რომ 1 –ს უდრის F(1) , F(2). ამიტომ: როცა sequence==1 ან sequence==2 , მაშინ გადავაკეთოთ მნიშვნელობები 1 ით. ამასთან value == -1 პირობაც დავამატოთ, თორემ ჩავიციკლებით.
და ბოლოს გამოვთვალოთ:
შედეგი
RBS–სათვის ბევრი პროექტები არის შექმნილი, ერთერთი არის Jboss Drools. ეს გახლავთ openSource პროექტი, რომელსაც სხვადასხვა შვილობილი (sub) პროექტები გააჩნია – Drools Expert, Drools Fusion, Drools Guvnor, Drools Planner და ასე შემდეგ.
გამახსენდა კიდევ Scala, ან IBM –ს აქვს Jrules პროექტი. Jrules ფასიანია, თუ ფული არ გვაქვს, უბრალოდ უნდა დავკმაყოფილდეთ იმით რაც გვაქვს. ამჯერად ამ სტატიაში Drools ზე ვისაუბრებთ.
სინტაქსი
rule "HelloPersons" when Person( firstName == "mariam" ) then // შესრულება end
მარტივი სინტაქსია. თუ სახელი ექვივალენტურია მარიამის, მაშინ
then ში გადავდივართ. კომპილერი ჭკვიანია და იცის რომ == იგივეა რაც String.equals
Person კლასის სხვა ველების შემოწმებაც შეგვიძლია და ასეთი სინტაქსი გვექნება:
rule "CheckPerson" when p: Person(age >= 18, country == "Georgia", nick: nickName) then System.out.println( "Hello Mariam" ); end
ამ შემთხვევში p არის reference variable. აქვე პერსონის ობიექტიდან nickName ველი ამოვიღე და nick ცვლადში ჩავწერე (რათქმაუნდა სქოუფი შეზღუდული აქ ამ ცვლადს).
პროგრამის გასაშვებად 2 გზა გვაქვს. პირველი ესაა ფლაგინის დაყენება IDE ში.
ვერსიები შეგიძლიათ აქედან ამოირჩიოთ:
http://download.jboss.org/drools/release/
თუმცა მე ყოველთვის ბოლო განახლებულს ვიღებ, ანუ შეგიძლიათ დააინსტალიროთ ეკლიფსში შემდეგი ლინკიდან :
http://download.jboss.org/drools/release/latest/org.drools.updatesite/
მეორე გზაა მავენის (ანუ იგივე მავნე) დეფენდენსებში დავამატოთ:
<dependency> <groupId>org.drools</groupId> <artifactId>drools-compiler</artifactId> <version> [ვერსია]</version> </dependency> <dependency>
rule ბის დასაწერად შექმენით სახელი.drl ფაილი რესურსებში. გასაშვებად კი Drools და jBPM ის მიერ შემოთავაზებული KIE API გამოგვადგება.
KieServices ks = KieServices.Factory.get(); KieContainer kContainer = ks.getKieClasspathContainer(); KieSession kSession = kContainer.newKieSession("ksession-rules"); Person p= new Person(); ... kSession.insert(p); kSession.fireAllRules();
განვიხილოთ ცოტა დახვეწილი მაგალითი. მაგალითად, ფიბანაჩის მიმდევრობაზე:
ჩვენ ვიცით რომ
F(n)=F(n-1) + F(n+2)ამასთან
F(1) =1, და F(2)=1;
public static class Fibonacci { private int sequence; private long value; public Fibonacci(int sequence) { this.setSequence(sequence); this.setValue(-1); } //... }
თავიდან -1 მნიშვნელობები მივანიჭოთ (–1 ით ავღნიშნოთ ჯერ გამოუთვლელი მნიშვნელობები )
rule "ფიბანაჩის ობიექტების შექმნა" when f : Fibonacci ( value == -1 ) not ( Fibonacci ( sequence == 1 ) ) then insert( new Fibonacci( f.sequence - 1 ) ); System.out.println( "recurse for " + f.sequence ); end
when –> თუ Fibonacci ობიექტში მნიშვნელობა არის -1 (ჩვენ შექმნისას –1 მივანიჭეთ, შესაბამისად არის), მაშინ –> შევქმნათ ახალი ობიექტი , ერთით ნაკლები მიმდევრობის ნომრით.
rule "F(1) , F(2) ის ინიციალიზება"
when
f : Fibonacci( sequence==1 || ==2, value == -1 )
then
modify ( f ){
value = 1
};
System.out.println( f.sequence + " და " + f.value );
end
ყველა შემთხვევაში ვიცით რომ 1 –ს უდრის F(1) , F(2). ამიტომ: როცა sequence==1 ან sequence==2 , მაშინ გადავაკეთოთ მნიშვნელობები 1 ით. ამასთან value == -1 პირობაც დავამატოთ, თორემ ჩავიციკლებით.
და ბოლოს გამოვთვალოთ:
rule "გამოთვლა"
when
f1 : Fibonacci( s1 : sequence, value != -1)
f2 : Fibonacci( s2: sequence == (s1+1), value != -1 )
f3 : Fibonacci( s3 : sequence == (f1.sequence+2 ), value == -1 )
then
modify ( f3 ) {
value = f1.value + f2.value
};
System.out.println( s3 + " == " + f3.value );
end
შედეგი
1 = 1 2 = 1 3 == 2 4 == 3 5 == 5 6 == 8 7 == 13 8 == 21 9 == 34 10 == 55 11 == 89 12 == 144 13 == 233 14 == 377 15 == 610 16 == 987 17 == 1597 18 == 2584 19 == 4181 20 == 6765 21 == 10946 22 == 17711 23 == 28657 24 == 46368 25 == 75025 26 == 121393 27 == 196418 28 == 317811 29 == 514229 30 == 832040 31 == 1346269 32 == 2178309 33 == 3524578 34 == 5702887 35 == 9227465 36 == 14930352 37 == 24157817 38 == 39088169 39 == 63245986 40 == 102334155 41 == 165580141 42 == 267914296 43 == 433494437 44 == 701408733 45 == 1134903170 46 == 1836311903 47 == 2971215073 48 == 4807526976 49 == 7778742049 50 == 12586269025 51 == 20365011074 52 == 32951280099 53 == 53316291173 54 == 86267571272 55 == 139583862445 56 == 225851433717 57 == 365435296162 58 == 591286729879 59 == 956722026041 60 == 1548008755920 61 == 2504730781961 62 == 4052739537881 63 == 6557470319842 64 == 10610209857723 65 == 17167680177565 66 == 27777890035288 67 == 44945570212853 68 == 72723460248141 69 == 117669030460994 70 == 190392490709135 71 == 308061521170129 72 == 498454011879264 73 == 806515533049393 74 == 1304969544928657 75 == 2111485077978050 76 == 3416454622906707 77 == 5527939700884757 78 == 8944394323791464 79 == 14472334024676221 80 == 23416728348467685 81 == 37889062373143906 82 == 61305790721611591 83 == 99194853094755497 84 == 160500643816367088 85 == 259695496911122585 86 == 420196140727489673 87 == 679891637638612258 88 == 1100087778366101931 89 == 1779979416004714189 90 == 2880067194370816120 91 == 4660046610375530309 92 == 7540113804746346429 ... ... ...
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.
პატარა მაგალითი:
თუ fetch() ატრიბუტი არის LAY, შესაბამისი ფროფერთის ინიციალიზება არ მოხდება მანამ, სანამ მასზე წვდომას არ მოვახდენთ. თუმცა აქ ერთი დეტალია გასათვალისწინებელი, ზოგადად @basic ანოტაცია არ არის პირდაპირ და ცალსახად განმსაზღვრელი თუ როგორ ვამუშაოთ პროგრამა. ეს უფრო მიმათითებელი არის, რომელიც შესაძლოა შესრულდეს სხვანაერადაც. ზოგმა JPA -ს იმპლემენტაციამ შეიძლება ეს აღიქვას, როგორც პირდაპირ განსაზღვრულად, ზოგმა შეიძლება არა. ანუ იმას ვამბობ რომ შეიძლება LAZY მივუთითოთ მაგრამ ინიციალიზება მაინც გაუკეთოს( ანუ EAGRLY სავით მოიქცეს). ეს მხოლოდ იმიტომ , რომ ოპტიმიზაციის გამო კარგად იმუშაოს - თვითნ ხვდება რომელი არის უკეთესი.
ამ ბოლო სამ ანოტაციაზე მაგალითი კი ეს არის:
ახლა მოვრჩები წერას :) კიდევ აუცილებელი და მნიშვნელოვანი საკითხებია @Embeddable ობიექტები, Primary-Key კლასები, რელაციები ბაზებს შორის და ასე შემდეგ. როცა დრო მექნება გავაგრძელებ წერას:)
ამ სტატიაში ვისაუბრებთ თუ როგორ ხდება ენთით ბინების რელაციურ ბაზაში მოთავსება. შევეცდები, ყველაზე მნიშვნელოვან საკითხებზე ვისაუბრო. რასაც ვერ მოვასწრებ, შემდეგ სტატიაში შემოგთავაზებთ. დავიწყოთ.
@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 .
არ არის საჭირო ჩვენ ვუთხრათ ფერსისთენს მენეჯერს თუ როგორ ჩაწეროს მონაცემები, ის ავტომატურად ჩაწერს ისე როგორც საჭიროდ ჩათვლის.
აგერ ვიხილოთ ჩაწერის სახეებიც.
არ არის საჭირო ჩვენ ვუთხრათ ფერსისთენს მენეჯერს თუ როგორ ჩაწეროს მონაცემები, ის ავტომატურად ჩაწერს ისე როგორც საჭიროდ ჩათვლის.
აგერ ვიხილოთ ჩაწერის სახეებიც.
მოვიყვანოთ მაგალითი
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 კლასები, რელაციები ბაზებს შორის და ასე შემდეგ. როცა დრო მექნება გავაგრძელებ წერას:)
Monday, November 18, 2013
PRS MNG FlushModes
ამ სტატიაში ვისაუბრებთ FlushModeType-ზე.
ენამი გამოიყურება შემდეგნაირად:
შესაბამისი მისამრთი:
იმის შემდეგ რაც persist(), merge(), remove() გამოვიყენებთ, ცვლილებები ბაზაში არ აისახება მანამ სანამ ენთითი მენეჯერი არ გააუკეთებს flush-ს. ჩვენ შეგვიძლია იძულებით მოვახდინოთ დასინქრონიზირება, თუ გამოვიყენებთ flush() მეთოდს. ზოგადად, დეფაულთად ისე არის კონფიგურირებული რომ, flush ხდება მაშინ, როდესაც ტრანზაქცია მთავრდება და ასევე მაშინაც, როდესაც რაიმე ქუერის ეგზექიუთს გავუკეთებთ - აქ დასაზუსტებელია query ში რას ვგულისხმობთ და რა გამონაკლისები არსებობს: მაგალითად, მოვახდინეთ რაიმე ობიექტის persist და შემდეგ find() ით დავაბრუნოთ შესაბამისი ობიექტი. შედეგი ის იქნება , რომ null დაგვიბრუნდება. find და getReference არიან ისეთი ტიპები, რომლებიც არ ახდენენ ბაზაში ცვლილებებს,
შესაბამისად, flush იც არ იქნება გამოძახებული, მის შესრულების შემდეგაც. აქ, getReference() ვახსენე, და ბარემ განვმარტავ რა განსხვავებაა ამათ შორის.
განსხვავება იმაში მდგოამრეობს რომ თუ find() -ს ვიყენებთ, თუ ბაზაში შესაბამისი ჩანაწერი არ მოიძებნა null დაბრუნდება, getReference()-ს შემთხვევაში კი javax.persistence.EntityNotFoundException-ს ისრვრის.
როდესაც შეეხეაბაზ FlushModeType-ს, დეფაულთად AUTO აყენია. ყველაფერს თავისი გამოყენება აქვს, გააჩნია რა ამოცანა გავაქვს გადასაჭრელი, შესაბამისად შეიძლება AUTO გამოგვადგეს, შესაძლოა COMMIT. ამიტომაც გვაქვს setFlushMode(), რომლის საშუალებითაც შეგვიძლია ვაკონტროლოთ flush -ის მუშაობა. მაგალთად, თუ ბევრი აბდეიტებია გასაკეთებელი, შეგვიძლია ფერფორმენსის მიზნით აბდეიტი ერთ batch ში გავაკეთოთ, ამისთვის სწორედ COMMIT გვჭირდება. მოვიყვანოთ მაგალითიც.
ენამი გამოიყურება შემდეგნაირად:
public enum FlushModeType{ AUTO, COMMIT }
შესაბამისი მისამრთი:
################################ javax.persistence.FlushModeType ################################
იმის შემდეგ რაც persist(), merge(), remove() გამოვიყენებთ, ცვლილებები ბაზაში არ აისახება მანამ სანამ ენთითი მენეჯერი არ გააუკეთებს flush-ს. ჩვენ შეგვიძლია იძულებით მოვახდინოთ დასინქრონიზირება, თუ გამოვიყენებთ flush() მეთოდს. ზოგადად, დეფაულთად ისე არის კონფიგურირებული რომ, flush ხდება მაშინ, როდესაც ტრანზაქცია მთავრდება და ასევე მაშინაც, როდესაც რაიმე ქუერის ეგზექიუთს გავუკეთებთ - აქ დასაზუსტებელია query ში რას ვგულისხმობთ და რა გამონაკლისები არსებობს: მაგალითად, მოვახდინეთ რაიმე ობიექტის persist და შემდეგ find() ით დავაბრუნოთ შესაბამისი ობიექტი. შედეგი ის იქნება , რომ null დაგვიბრუნდება. find და getReference არიან ისეთი ტიპები, რომლებიც არ ახდენენ ბაზაში ცვლილებებს,
შესაბამისად, flush იც არ იქნება გამოძახებული, მის შესრულების შემდეგაც. აქ, getReference() ვახსენე, და ბარემ განვმარტავ რა განსხვავებაა ამათ შორის.
განსხვავება იმაში მდგოამრეობს რომ თუ find() -ს ვიყენებთ, თუ ბაზაში შესაბამისი ჩანაწერი არ მოიძებნა null დაბრუნდება, getReference()-ს შემთხვევაში კი javax.persistence.EntityNotFoundException-ს ისრვრის.
როდესაც შეეხეაბაზ FlushModeType-ს, დეფაულთად AUTO აყენია. ყველაფერს თავისი გამოყენება აქვს, გააჩნია რა ამოცანა გავაქვს გადასაჭრელი, შესაბამისად შეიძლება AUTO გამოგვადგეს, შესაძლოა COMMIT. ამიტომაც გვაქვს setFlushMode(), რომლის საშუალებითაც შეგვიძლია ვაკონტროლოთ flush -ის მუშაობა. მაგალთად, თუ ბევრი აბდეიტებია გასაკეთებელი, შეგვიძლია ფერფორმენსის მიზნით აბდეიტი ერთ batch ში გავაკეთოთ, ამისთვის სწორედ COMMIT გვჭირდება. მოვიყვანოთ მაგალითიც.
Saturday, November 9, 2013
EX $PATH Linux
წარმოვიდგინოთ სიტვაცია როდესაც პროგრამა დავაყენეთ და კლასფასში არ ჩაჯდა, მაგალითად:
და გვეუბნება:
პრობლემა ორიდან ერთია, არ პროგრამა არ მიყენია ან კლასფასში არ მიზის[ხდებახოლმე].
მოვძებნოთ სად გვიგდია ჩვენი airmon - [ან თუ არის საერთოდ]
ისე მოსაძებნად ესეც შეგვიიძლია
კარგია, ახლა კლასფასი ვნახოთ:
როგორც ჩანს ჩვენი პროგრამ არ ზის. ოკ ჩავსვათ მარტივად:
სულ ეს იყო, შევამოწმოთ ფასი:
და მივიღეთ აუთფუთი:
linux:~ # aming-ng
და გვეუბნება:
#If 'airmon-ng' is not a typo you can use command-not-found to lookup the package that contains it, like this: cnf airmon-ng
პრობლემა ორიდან ერთია, არ პროგრამა არ მიყენია ან კლასფასში არ მიზის[ხდებახოლმე].
მოვძებნოთ სად გვიგდია ჩვენი airmon - [ან თუ არის საერთოდ]
linux:~ # find / -name airmon-ng /usr/local/sbin/airmon-ng
ისე მოსაძებნად ესეც შეგვიიძლია
linux:~ # locate airmon-ng
კარგია, ახლა კლასფასი ვნახოთ:
linux:~ # echo $PATH #/home/vakhoq/bin:/usr/local/bin :/usr/bin:/sbin:/usr/sbin:/bin :/usr/bin/X11:/usr/X11R6/bin :/usr/games
როგორც ჩანს ჩვენი პროგრამ არ ზის. ოკ ჩავსვათ მარტივად:
linux:~ # export PATH=$PATH:/usr/local/sbin
სულ ეს იყო, შევამოწმოთ ფასი:
linux:~ # airmon-ng
და მივიღეთ აუთფუთი:
Interface Chipset Driver
wlan0 ath9k - [phy0]
Subscribe to:
Posts (Atom)