webForumDet fria alternativet

Skapa statement 1 gång

9 svar · 372 visningar · startad av tosses

tossesMedlem sedan aug. 2003190 inlägg
#1

Finns det något sätt att skapa statement 1 gång?

Varje gång jag ska ha ut nåt från DB och det kan vara flera gånger/sida så skriver jag:

Class.forName("org.gjt.mm.mysql.Driver").newInstance();
Connection visaConn = DriverManager.getConnection("jdbc:mysql:///steget?user=hmm&password=hmm");
Statement visaStmt = visaConn.createStatement();

String visaQr = "SELECT sni92.Fenkelbranch, sni92.Kod FROM sni92 GROUP BY sni92.Fenkelbranch";
ResultSet rslt = visaStmt.executeQuery(visaQr);

Fast Jag borde egentligen skriva så här:

Class.forName("org.gjt.mm.mysql.Driver").newInstance();
Connection visaConn = DriverManager.getConnection("jdbc:mysql:///steget?user=hmm&password=hmm");
Statement visaStmt = visaConn.createStatement();

och längre ner på sidan flera-->

String visaQr = "SELECT sni92.Fenkelbranch, sni92.Kod FROM sni92 GROUP BY sni92.Fenkelbranch";
ResultSet rslt = visaStmt.executeQuery(visaQr);

String visaQr = "SELECT sni92.Fenkelbranch, sni92.Kod FROM sni92 GROUP BY sni92.Fenkelbranch";
ResultSet rslt = visaStmt.executeQuery(visaQr);

String visaQr = "SELECT sni92.Fenkelbranch, sni92.Kod FROM sni92 GROUP BY sni92.Fenkelbranch";
ResultSet rslt = visaStmt.executeQuery(visaQr);

typ. (Fast olika frågor + whileloopar).

Men det fungerar inte, finns det något sätt?

andreascarlssonMedlem sedan feb. 2003202 inlägg
#2

Min första tanke när jag såg detta, var att du borde lägga in all databashantering i en egen klass.

Sedan skickar du bara med dina statements när du anropar klassen.

Detta var iochförsig inte svar på din fråga, men det torde kunna bidra till en mer lättläst applikation som är enklare att underhålla.

Det måste ju vara jobbigt att skriva hela den där härvan, bara för att öppna upp en connection till databasen? ;)

sgtpepperMedlem sedan apr. 20007 588 inlägg
#3

Om du skall använda samma statement flera gånger så SKALL du använda ett PreparedStatement som du förbereder och sedan upprepade gånger anropar.

I din kod ovan så kommer du få problem då du definerar objektet visaQr och rslt flera gånger vilket ger ett "Dublicate local variable"-kompilatorfel.

Så här skall du göra:

Class.forName("org.gjt.mm.mysql.Driver").newInstance();
Connection conn = DriverManager.getConnection("jdbc:mysql:///steget?user=hmm&password=hmm");
PreparedStatement pStmt = conn.prepareStatement("SELECT sni92.Fenkelbranch, sni92.Kod FROM sni92 GROUP BY sni92.Fenkelbranch");

ResultSet rs = null;

rs = pStmt.executeQuery();
rs = pStmt.executeQuery();
rs = pStmt.executeQuery();
...
rs = pStmt.executeQuery();

Men eftersom du i exemplet ovan kör exakt samma sats, utan några skillnader i sökvilkoret så är det bara onödigt att anropa databasen om och om igen, då är det bättre att du initialt kör frågan och sedan lagrar den i lämpligt objekt och sedan använder detta objekt när du senare i koden vill ha ut resultatet igen.

tossesMedlem sedan aug. 2003190 inlägg
#4

Tyvärr beskrev jag lite dåligt! Era svar är väldigt bra men...

Om jag vill byta ut sqlfrågan.. ex:

Class.forName("org.gjt.mm.mysql.Driver").newInstance();
Connection conn = DriverManager.getConnection("jdbc:mysql:///steget?user=hmm&password=hmm");
PreparedStatement pStmt = conn.prepareStatement("SELECT sni92.Fenkelbranch, sni92.Kod FROM sni92 GROUP BY sni92.Fenkelbranch");

ResultSet rs = null;

rs = pStmt.executeQuery(fråga 1);
rs = pStmt.executeQuery(fråga 2);
rs = pStmt.executeQuery(fråga 3);
...
rs = pStmt.executeQuery(fråga 4);

??????

Kan jag skriva så här då:

Class.forName("org.gjt.mm.mysql.Driver").newInstance();
Connection conn = DriverManager.getConnection("jdbc:mysql:///steget?user=hmm&password=hmm");

PreparedStatement pStmt = conn.prepareStatement("SELECT sni92.Fenkelbranch, sni92.Kod FROM sni92 GROUP BY sni92.Fenkelbranch");

ResultSet rs = null;

rs = pStmt.executeQuery();

PreparedStatement pStmt = conn.prepareStatement("SELECT något annat");

ResultSet rs = null;

rs = pStmt.executeQuery();

eller... ????

/Tomas

LimeMedlem sedan sep. 2001961 inlägg
#5

Jo... Det du gör är följande

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

pstmt.setBigDecimal(1, 153833.00)
pstmt.setInt(2, 110592)

I detta fall så ersätter du första ? med 153833.00 och det andra ? med 110592. Dessa värden kommer pstmt att ha tills du ändrar dom.

Kollade hur det görs när man använder SQLServer 2000 och där skapas en "stored procedure" när man anropar med PreparedStatement första gången. Det är annars en bra idé...

Om det är två olika frågor så kan du inte använda PreparedStatement. Eller kan och kan... Det är onödigt.

tossesMedlem sedan aug. 2003190 inlägg
#6

Det var nog inte det jag menade

utan att skapa:

Class.forName("org.gjt.mm.mysql.Driver").newInstance();
Connection visaConn = DriverManager.getConnection("jdbc:mysql:///steget?user=hmm&password=hmm");
Statement visaStmt = visaConn.createStatement();

1 gång på sidan och sedan :

String förstafrågan = "SELECT en sak";
ResultSet förstarslt = visaStmt.executeQuery(förstafrågan );

String andrafrågan = "SELECT nåt annat";
ResultSet andranyrslt = visaStmt.executeQuery(andrafrågan );

i olika delar av sidan

sgtpepperMedlem sedan apr. 20007 588 inlägg
#7

Lime skrev:

Om det är två olika frågor så kan du inte använda PreparedStatement. Eller kan och kan... Det är onödigt.

Det är i princip aldrig onödigt att använda PreparedStatement, åtminstone inte om SQL-frågan tar parametrar och/eller skall köras flera gånger.

Kollade hur det görs när man använder SQLServer 2000 och där skapas en "stored procedure" när man anropar med PreparedStatement första gången.

Det har jag mycket svårt att tänka mig. Det som görs vid skapandet av ett PreparedStatement är att SQL-frågan parsas, kompileras och optimeras så att den är färdig att exekveras mot databasen.

De tre första stegen (parse, kompilering och optimering) behöver sedan inte köras för påföljande körningar av prepared statementet vilket är fallet om man använder Statement.

Men att en stored procedure skulle skapas om man använder SQLServer för varje PreparedStatement tror jag inte på. Du blandar antagligen ihop PreparedStatement med CallableStatement.

sgtpepperMedlem sedan apr. 20007 588 inlägg
#8

tosses skrev:

Det var nog inte det jag menade

Du har ju i princip fått svar på frågan ovan, men jag kör igen:

Class.forName("org.gjt.mm.mysql.Driver").newInstance();
Connection visaConn = DriverManager.getConnection("jdbc:mysql:///steget?user=hmm&password=hmm");
PreparedStatement visaStmt = null; 

visaStmt =  visaConn.prepareStatement("SELECT en sak");
ResultSet förstarslt = visaStmt.executeQuery();

visaStmt =  visaConn.prepareStatement("SELECT en annan sak");
ResultSet andranyrslt = visaStmt.executeQuery();

Men lägg inte databaslogik i JSP-sidan, det är typ 5 lager för högt upp i strukturen. JSP-sidorna skall hantera presentationslogiken, databaslogiken skall ligga långt som fan nere i källaren.

tossesMedlem sedan aug. 2003190 inlägg
#9

ja man e vel lite trögtänkt!!

Men tack! nu fattar jag preparedstatement.

LimeMedlem sedan sep. 2001961 inlägg
#10

sgtpepper skrev:

Men att en stored procedure skulle skapas om man använder SQLServer för varje PreparedStatement tror jag inte på. Du blandar antagligen ihop PreparedStatement med CallableStatement.

Du har givetvis helt rätt sgtpepper. Jag blandar ihop dessa.

139 ms totalt · 3 externa anrop · v20260731065814-full.0e50b1ef
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
136 ms — hämta tråd, inlägg och bilagor (db)