[ mikorkns @ 24.08.2006. 16:32 ] @
Jel moze neko da mi objasni razliku izmedju Statement i PreparedStatement klasa?

Pozz.
[ nemnesic @ 24.08.2006. 16:53 ] @
Statement:

primer: Select user_name, address, phone from tbl_customers where
user_name = 'ES_test' and pass = 'ES_PASS';

ok kao sto vidis ovde su ti user_name i pass HARD CODED. znaci ne mozes
da ih menjas dynamicly.
****************************************

Prepared statement:
primer: Select user_name, address, phone from tbl_customers where
user_name = ? and pass = ?;

e sad prepared statement ti nije hard coded. znaci 1? (prvi ?) i 2?
(drugi ?) mozes da menjas. Lepo napises funkciju koju pozoves sa
parametrima npr. ES_test za user_name i ES_pass za pass i kazes im gde
koji ide. Na kom mestu. Mesto br 1. ili Mesto br 2.

nadam se da ti je sada malo jasnije...ako nije..pitaj...ja sam tu do
4:30PM EST.

pozdrav
nn


--

-All programmers are playwrights and all computers are lousy actors.
[ djalfirevic @ 24.08.2006. 16:57 ] @
Citat:
mikorkns: Jel moze neko da mi objasni razliku izmedju Statement i PreparedStatement klasa?

Pozz.


Kao sto je nemnesic rekao...

Evo objasnjenja u Java SDK Documentation:

An object that represents a precompiled SQL statement.

A SQL statement is precompiled and stored in a PreparedStatement object. This object can then be used to efficiently execute this statement multiple times.

Note: The setter methods (setShort, setString, and so on) for setting IN parameter values must specify types that are compatible with the defined SQL type of the input parameter. For instance, if the IN parameter has SQL type INTEGER, then the method setInt should be used.

If arbitrary parameter type conversions are required, the method setObject should be used with a target SQL type.

In the following example of setting a parameter, con represents an active connection:


Code:

PreparedStatement pstmt = con.prepareStatement("UPDATE EMPLOYEES
                                     SET SALARY = ? WHERE ID = ?");
pstmt.setBigDecimal(1, 153833.00)
pstmt.setInt(2, 110592)
 


Nadam se da ti je ovo takodje pomoglo...

[ _owl_ @ 24.08.2006. 23:47 ] @
Citat:

Statement:

primer: Select user_name, address, phone from tbl_customers where
user_name = 'ES_test' and pass = 'ES_PASS';

ok kao sto vidis ovde su ti user_name i pass HARD CODED. znaci ne mozes
da ih menjas dynamicly.

Konkatenacija stringova ti je sigurno potpuno nepoznat pojam. Na svu srecu bas sam raspolozen da dam dodatno objasnjenje.
Code:

Statement stm ...
String upit="Select user_name, address, phone from tbl_customers where user_name='" + getUsername() + "' and pass='" + getPassword() + "'";
ResultSet rs=stm.executeQuery(upit)

Gle cuda nista nije hard kodovano. Ipak jedna od bitnijih razlika je sto se kod PreparedStatement objekta automatski vrsi eskejpovanje svih prosledjenih parametara (tako da je sql injection nemoguc) dok kod Statement objekta to nije slucaj.
[ mikorkns @ 25.08.2006. 08:06 ] @
Hvala svima, jasno je.
Pozz.
[ Au197/79 @ 25.08.2006. 09:10 ] @
Citat:
_owl_: Konkatenacija stringova ti je sigurno potpuno nepoznat pojam.


I od boljeg ima bolje (ova verzija samo u 1.5+):
Code:

String obrazac = "Select user_name, address, phone from tbl_customers where user_name = '%s' and pass = '%s'";
String upit = String.format(obrazac, getUsername(), getPassword() );
. . .


Živela Pythonizacija Jave!!!
[ hyle @ 25.08.2006. 09:12 ] @
Citat:
_owl_: Konkatenacija stringova ti je sigurno potpuno nepoznat pojam. Na svu srecu bas sam raspolozen da dam dodatno objasnjenje.

Ti si neki vidovit dečko i znaš šta je kome poznato, a šta nije? Takve ispade zadrži za svoj parapsihološki forum a ovde se drži Jave.


Nego, da se vratimo na temu.
Ako imaš potrebu da izvršavaš isti upit više puta ali sa različitim parametrima onda koristiš PreparedStatement. Razlika je u načinu na koji će sama baza da tretira tvoj upit.

Code:

PreparedStatement pstmt = con.prepareStatement("UPDATE EMPLOYEES SET SALARY = ? WHERE ID = ?");

Svaki put kada pozoveš ovaj upit, bez obzira što daješ različite parametre (recimo prvi put proslediš parametre 0 i 32, a drugi put 1000 i 21), baza će znati da se radi o istom upitu i iskoritiće svoj keš upita i brže će ga izvršiti.

Ukoliko svaki put kreiraš statement i direktno u SQL ubacuješ parametre onda će baza te upite videti kao različite i moraće svaki put da radi prekompajliranje upita i neće moći da iskoristi interni keš. Upite iz prethodnog primera baza bi videla kao "UPDATE EMPLOYEES SET SALARY = 0 WHERE ID = 32" i "UPDATE EMPLOYEES SET SALARY = 1000 WHERE ID = 21"

Dobre baze podataka, kao što je recimo Oracle, su dovoljno pametne da prepoznaju da se radi o istom upitu čak i ako koristiš Statement sa parametrima ubačenim u SQL ali ne preporučujem da se oslanjaš na to. Kod Oracle-a tu opciju moraš "ručno" da uključiš (Cursor sharing), tj. po defaultu nije uključena. Pretpostavljam da besplatne baze podataka nisu toliko "pametne" ali možda i grešim.

Ne preporučujem da se uzdaš u "pamet" baze podataka već lepo koristiš PreparedStatement kada je to potrebno i ne boli te glava.
[ dejankr @ 25.08.2006. 09:18 ] @
U gotovo 90% (a možda i 100%) slučajeva treba koristiti PreparedStatement umesto Statement. Ovo se pogotovo odnosi na slučajeve kada vrednost query parametara unosi korisinik (a to je uglavnom slučaj) jer PreparedStatement vrši escape parametara i lišava te problema oko slučajnih ili namernih grešaka od strane korisnika, raznih expolita (SQL injection) itd. Takođe, većina baza će ti dati bolje performanse kada se koristi PreparedStatement ukoliko se isti upit koristi često.
[ hyle @ 25.08.2006. 10:31 ] @
Citat:
dejankr: U gotovo 90% (a možda i 100%) slučajeva treba koristiti PreparedStatement umesto Statement.


Ja sam naišao do sada na jedan slučaj kada mi je bolje rezultate davao Statement od PreparedStatement-a.

Evo kakva situacija je bila u pitanju. Imao sam tabelu, neka se zove "Tabela", koja je imala kolonu "Polje" na kojoj je postojao indeks. Radio sam upit:
Code:
SELECT * FROM Tabela WHERE polje = 0

U navedenoj tabeli 5% redova ima vrednost polja 0, a 95% redova ima vrednost polja 1. Kada sam koristio Statement Oracle se ispravno ponašao i koristio je indeks nad navedenim poljem, a u situaciji kada sam koristio PreparedStatement Oracle nije koristio indeks i upit je radio jako sporo.

Problem sa nekorišćenjem indeksa je nastao iz sledećeg razloga. Oracle pre izvršenja upita određuje strategiju koju će koristiti za izvršenje upita. U situaciji kada sam koristio PreparedStatement onda je Oracle razmatrao upit "SELECT * FROM Tabela WHERE polje = ?" i za takav upit je zaključio da je bolje da ne koristi indeks jer nije znao da koju vrednost parametra će korisnik proslediti, a kada sam koristio Statement Oracle je znao da se od njega zahteva samo 5% redova iz tabele i zaključio je da će u toj situaciju upit brže raditi sa indeksom.
[ djalfirevic @ 25.08.2006. 12:02 ] @
Citat:
mikorkns: Hvala svima, jasno je.
Pozz.


Ljudi bre covek je rekao da je jasno...