



<html>
<head>
  <title>javabog.dk -  - Databaser (JDBC)</title>
  <link rev="stylesheet" type="text/css" href="../typografi.css">
  <meta name="description" content="Lærebog i Java. Af Jacob Nordfalk. Udkommet hos Forlaget Globe">
  <meta name="keywords" content="designmønster, programmering, OOP, objekter, klasser, objektorienteret programmering, Java, JSP, lærebog, UML, IT">
</head>
<body bgcolor="#ffffff">



<a href='http://javabog.dk/'>javabog.dk</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='kapitel7.jsp'>&lt;&lt; forrige</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='indhold.jsp'>indhold</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='kapitel9.jsp'>n&aelig;ste &gt;&gt;</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='kode/'>programeksempler</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='../index_VP.html'>om bogen</a>

<H1 CLASS="western" STYLE="">8 <a name='afsn8'></a>Databaser
(JDBC)</H1>
<DIV ID="Indholdsfortegnelse12">
  <P STYLE="margin-top: 0.3cm; margin-bottom: 0cm"><BR>
  </P>
  <P STYLE="margin-left: 0.3cm; margin-top: 0.15cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 11pt"><B>8.1
  Basisfunktioner i JDBC  130</B></FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">8.1.1
  Indl&aelig;se driveren  130</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">8.1.2
  Etablere forbindelsen  130</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">8.1.3
  Kommunikere med databasen  131</FONT></FONT></P>
  <P STYLE="margin-left: 0.3cm; margin-top: 0.15cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 11pt"><B>8.2
  Forpligtigende eller ej? (commit)  132</B></FONT></FONT></P>
  <P STYLE="margin-left: 0.3cm; margin-top: 0.15cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 11pt"><B>8.3
  Optimering  133</B></FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">8.3.1
  Bruge den rigtige databasedriver  133</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">8.3.2
  L&aelig;gge opdateringer i k&oslash; (batch-opdateringer)  133</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">8.3.3
  P&aring; forh&aring;nd forberedt SQL  134</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">8.3.4
  Kalde gemte procedurer i databasen  135</FONT></FONT></P>
  <P STYLE="margin-left: 0.3cm; margin-top: 0.15cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 11pt"><B>8.4
  Avanceret  136</B></FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">8.4.1
  Opdatering og navigering i ResultSet-objekter  136</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">8.4.2
  Metadata  136</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">8.4.3
  Metadata om databasen  136</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">8.4.4
  Metadata om svaret p&aring; en foresp&oslash;rgsel  136</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">8.4.5
  Eksempel - udskrive en vilk&aring;rlig tabel  137</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">8.4.6
  Persistering af objekter - JDO  138</FONT></FONT></P>
</DIV>
















<P CLASS="kapiteloversigt-western">Dette kapitel foruds&aelig;tter
lidt kendskab til databaser og databasesproget SQL (Structured Query
Language), og at man har en fungerende database, som man &oslash;nsker
adgang til fra Java.</P>
<H2 CLASS="western" STYLE="">8.1 <a name='afsn8.1'></a>Basisfunktioner
i JDBC</SPAN></H2>
<P CLASS="western">Et program, der bruger JDBC, skal basalt set
udf&oslash;re f&oslash;lgende handlinger: Indl&aelig;se driveren,
etablere forbindelsen og dern&aelig;st kommunikere med databasen.</P>
<H3 CLASS="western">8.1.1 <a name='afsn8.1.1'></a>Indl&aelig;se driveren</H3>
<P CLASS="western">Det g&oslash;res ved at indl&aelig;se en
driver-klasse:</P>
<PRE CLASS="kode-western">  Class.forName(&quot;sun.jdbc.odbc.JdbcOdbcDriver&quot;);</PRE><P CLASS="western">
Denne klasse s&oslash;rger for at registrere sig hos
java.sql.DriverManager. 
</P>
<P CLASS="western">Med Java under Windows f&oslash;lger en standard
JDBC-ODBC-bro med, s&aring; man kan kontakte alle datakilder,
der er defineret under ODBC.</P>

<P CLASS="western">Er det en anden database, skal man have en jar-fil
(et Java-ARkiv, en samling klasser pakket i zip-formatet) med en
driver fra producenten, og man skal indl&aelig;se en anden
driver-klasse fra jar-filen (der skal ligge i  CLASSPATH).</P>
<P CLASS="western"><SPAN LANG="da-DK">De nyeste drivere kan findes p&aring;
</SPAN><SPAN STYLE="font-weight: medium"><A CLASS="western" HREF="http://java.sun.com/jdbc"><SPAN LANG="da-DK">http://java.sun.com/jdbc</SPAN></A></SPAN><SPAN LANG="da-DK">,
men f&oslash;lger ofte med n&aring;r man anskaffer sig en database.</SPAN></P>

<P CLASS="western">For at f&aring; indl&aelig;st en driver til en
Oracle-database skriver man:</P>
<PRE CLASS="kode-western">  Class.forName(&quot;oracle.jdbc.driver.OracleDriver&quot;);</PRE><P CLASS="western">
Driver-filen, der f&oslash;lger med Oracles produkter, hedder typisk
classes12.zip.</P>

<P CLASS="western">For at f&aring; indl&aelig;st en driver til en
MySQL-database skriver man:</P>
<PRE CLASS="kode-western">  Class.forName(&quot;com.mysql.jdbc.Driver&quot;)</PRE><P CLASS="western">
<SPAN LANG="da-DK">Driver-filen til MySQL (kaldet Connector/J) kan
hentes p&aring; </SPAN><SPAN STYLE="font-weight: medium"><A CLASS="western" HREF="http://mysql.com/"><SPAN LANG="da-DK">http://mysql.com</SPAN></A></SPAN><SPAN LANG="da-DK">.</SPAN></P>

<H3 CLASS="western">8.1.2 <a name='afsn8.1.2'></a>Etablere forbindelsen</H3>
<P CLASS="western">Herefter kan man oprette forbindelsen med (for en
ODBC-driver):</P>
<PRE CLASS="kode-western">  Connection forb = DriverManager.getConnection(&quot;jdbc:odbc:datakilde1&quot;);</PRE><P CLASS="western">
Parameteren er en URL til databasen, som driver-klassen genkender.
Husk, at datakildens navn (her &quot;datakilde1&quot;) f&oslash;rst
skal v&aelig;re defineret i Windows' Kontrolpanel under ODBC.</P>

<P CLASS="western">Er det en Oracle-database, kunne man skrive:</P>
<PRE CLASS="kode-western">  Connection forb = DriverManager.getConnection(
<SPAN LANG="da-DK">               &quot;jdbc:oracle:thin:@ora.javabog.dk:1521:student&quot;,&quot;jacob&quot;,&quot;jacob&quot;);</SPAN></PRE><P CLASS="western">
Hvorefter man skulle have oprettet forbindelsen til databasen
'student' p&aring; maskinen   'ora.javabog.dk' port 1521 med
brugernavn 'jacob' og adgangskode 'jacob'.</P>

<P CLASS="western">Er det en MySQL-database, kunne man skrive:</P>
<PRE CLASS="kode-western">  Connection c = DriverManager.getConnection(&quot;jdbc:mysql:///jacob&quot;,&quot;root&quot;,&quot;xyz&quot;);</PRE><P CLASS="western">
Hvorefter man skulle have oprettet forbindelsen til databasen 'jacob'
p&aring; den lokale maskine med brugernavn 'root' og adgangskode
'xyz'.</P>
<H3 CLASS="western" STYLE="">8.1.3 <a name='afsn8.1.3'></a>Kommunikere
med databasen</H3>
<P CLASS="western">N&aring;r man har oprettet en forbindelse, kan man
oprette et Statement-objekt, som man kan sende kommandoer og
foresp&oslash;rgsler til databasen med (svarer til en
SQL-kommandolinje):</P>
<PRE CLASS="kode-western">  Statement stmt = forb.createStatement();</PRE>
<P CLASS="western">Her opretter vi f.eks. tabellen KUNDER og
inds&aelig;tter et par r&aelig;kker:</P>
<PRE CLASS="kode-western">import java.sql.*;
<SPAN LANG="da-DK">public class Databasekommunikation</SPAN>
<SPAN LANG="da-DK">{</SPAN>
<SPAN LANG="da-DK">  public static void main(String[] arg) throws Exception</SPAN>
<SPAN LANG="da-DK">  {</SPAN>
<SPAN LANG="da-DK">    Class.forName(&quot;oracle.jdbc.driver.OracleDriver&quot;);</SPAN>
<SPAN LANG="da-DK">    System.out.println(&quot;Driver indl&aelig;st&quot;);</SPAN>

<SPAN LANG="da-DK">    Connection forb = DriverManager.getConnection(</SPAN>
<SPAN LANG="da-DK">               &quot;jdbc:oracle:thin:@ora.javabog.dk:1521:student&quot;,&quot;jacob&quot;,&quot;jacob&quot;);</SPAN>
<SPAN LANG="da-DK">    System.out.println(&quot;Forbindelse oprettet&quot;);</SPAN>

<SPAN LANG="da-DK">    Statement stmt = forb.createStatement();</SPAN>

<SPAN LANG="da-DK"><I>    // fors&oslash;g at slette tabel - hvis den ikke findes opst&aring;r en fejl som fanges</I></SPAN>
<SPAN LANG="da-DK">    try { stmt.executeUpdate(&quot;drop table KUNDER&quot;); } catch (Exception e) {}</SPAN>

<SPAN LANG="da-DK"><I>    // opret tabel</I></SPAN>
<SPAN LANG="da-DK">    stmt.executeUpdate(&quot;create table KUNDER (NAVN varchar(32), KREDIT number)&quot;);</SPAN>
<SPAN LANG="da-DK">    System.out.println(&quot;Tabel oprettet&quot;);</SPAN>

<SPAN LANG="da-DK"><I>    // tilf&oslash;j data</I></SPAN>
<SPAN LANG="da-DK">    stmt.executeUpdate(&quot;insert into KUNDER values('Jacob', -1799)&quot;);</SPAN>

<SPAN LANG="da-DK"><I>    // brug helst navngivne kolonner. Hvis man senere skulle finde p&aring; at</I></SPAN>
<SPAN LANG="da-DK"><I>    // udvide tabellen med flere kolonner, vil SQL-kommandoen stadig virke!</I></SPAN>
<SPAN LANG="da-DK">    stmt.executeUpdate(&quot;insert into KUNDER(NAVN,KREDIT) values('Brian', 0)&quot;);</SPAN>

<SPAN LANG="da-DK"><I>    // inds&aelig;t data fra variabler</I></SPAN>
<SPAN LANG="da-DK">    String navn = &quot;Hans&quot;;</SPAN>
<SPAN LANG="da-DK">    double kredit = 500;</SPAN>
<SPAN LANG="da-DK">    stmt.executeUpdate(</SPAN>
<SPAN LANG="da-DK">               &quot;insert into KUNDER(NAVN,KREDIT) values('&quot;+navn+&quot;', &quot;+kredit+&quot;)&quot;);</SPAN>

<SPAN LANG="da-DK"><I>    // foresp&oslash;rgsler</I></SPAN>
<SPAN LANG="da-DK">    ResultSet rs = stmt.executeQuery(&quot;select NAVN, KREDIT from KUNDER&quot;);</SPAN>
<SPAN LANG="da-DK">    while (rs.next())</SPAN>
<SPAN LANG="da-DK">    {</SPAN>
<SPAN LANG="da-DK">      navn = rs.getString(&quot;NAVN&quot;);</SPAN>
<SPAN LANG="da-DK">      kredit = rs.getDouble(&quot;KREDIT&quot;);</SPAN>
<SPAN LANG="da-DK">      System.out.println(navn+&quot; &quot;+kredit);</SPAN>
<SPAN LANG="da-DK">    }</SPAN>
<SPAN LANG="da-DK">  }</SPAN>
<SPAN LANG="da-DK">}</SPAN></PRE>
<HR>
<PRE CLASS="kode-western">Driver indl&aelig;st
<SPAN LANG="da-DK">Forbindelse oprettet</SPAN>
<SPAN LANG="da-DK">Tabel oprettet</SPAN>
<SPAN LANG="da-DK">Jacob -1799.0</SPAN>
<SPAN LANG="da-DK">Brian 0.0</SPAN>
<SPAN LANG="da-DK">Hans 500.0</SPAN></PRE>
<P CLASS="western">Se ogs&aring; <a href='kapitel12.jsp#afsn12.8'>afsnit 12.8</a> for en beskrivelse af
alle klasserne, der er til r&aring;dighed til kommunikation med en
database.</P>
<H2 CLASS="western" STYLE="">8.2 <a name='afsn8.2'></a>Forpligtigende
eller ej? (commit)</SPAN></H2>
<P CLASS="western">Normalt er alle SQL-kommandoer gennem JDBC
<I>automatisk forpligtigende</I> (eng. auto-committing), dvs. de kan
ikke annulleres, hvis en senere SQL-kommando g&aring;r galt.</P>
<P CLASS="western">Vil man sl&aring; automatisk forpligtigelse fra,
kan det g&oslash;res ved at kalde setAutoCommit() p&aring;
forbindelsen. Derefter vil transaktioner (SQL-kommandoer) ikke v&aelig;re
forpligtigende, og de kan annulleres ved at kalde rollback() p&aring;
forbindelsen. N&aring;r man &oslash;nsker, at transaktionerne skal
tr&aelig;de i kraft, kalder man commit(), og f&oslash;rst herefter er
transaktionerne endeligt udf&oslash;rt p&aring; databasen og dermed
forpligtigende.</P>
<P CLASS="western">Oftest anvendes denne facilitet i forbindelse med
flere transaktioner, der enten alle skal gennemf&oslash;res eller
alle annulleres, f.eks.:</P>
<PRE CLASS="kode-western">import java.sql.*;
<SPAN LANG="da-DK">public class UdenAutocommit</SPAN>
<SPAN LANG="da-DK">{</SPAN>
<SPAN LANG="da-DK">  public static void main(String[] arg) throws Exception</SPAN>
<SPAN LANG="da-DK">  {</SPAN>
<SPAN LANG="da-DK">    Class.forName(&quot;oracle.jdbc.driver.OracleDriver&quot;);</SPAN>
<SPAN LANG="da-DK">    Connection forb = DriverManager.getConnection(</SPAN>
<SPAN LANG="da-DK">               &quot;jdbc:oracle:thin:@ora.javabog.dk:1521:student&quot;,&quot;jacob&quot;,&quot;jacob&quot;);</SPAN>

<SPAN LANG="da-DK">    try {</SPAN>
<SPAN LANG="da-DK"><B>      forb.setAutoCommit(false);</B></SPAN>
<SPAN LANG="da-DK">      Statement stmt = forb.createStatement();</SPAN>

<SPAN LANG="da-DK">      stmt.executeUpdate(&quot;insert into KUNDER(NAVN,KREDIT) values('Jacob',-17)&quot;);</SPAN>
<SPAN LANG="da-DK">      stmt.executeUpdate(&quot;insert into KUNDER(NAVN,KREDIT) values('Brian', 0)&quot;);</SPAN>

<SPAN LANG="da-DK"><I>      // flere transaktioner ...</I></SPAN>
<SPAN LANG="da-DK">      System.err.println(&quot;Alt gik godt, g&oslash;r &aelig;ndringerne forpligtigende&quot;);</SPAN>
<SPAN LANG="da-DK"><B>      forb.commit();</B></SPAN>
<SPAN LANG="da-DK">    } </SPAN>
<SPAN LANG="da-DK">    catch (Exception e) </SPAN>
<SPAN LANG="da-DK">    {</SPAN>
<SPAN LANG="da-DK">      e.printStackTrace();</SPAN>
<SPAN LANG="da-DK">      System.err.println(&quot;Noget gik galt! Annullerer &aelig;ndringerne...&quot;);</SPAN>
<SPAN LANG="da-DK"><B>      forb.rollback();</B></SPAN>
<SPAN LANG="da-DK">    } </SPAN>
<SPAN LANG="da-DK">    finally </SPAN>
<SPAN LANG="da-DK">    {</SPAN>
<SPAN LANG="da-DK"><I>      // Husk at s&aelig;tte auto-commit tilbage, af hensyn til andre transaktioner</I></SPAN>
<SPAN LANG="da-DK"><B>      forb.setAutoCommit(true);</B></SPAN>
<SPAN LANG="da-DK">    }</SPAN>
<SPAN LANG="da-DK">  }</SPAN>
<SPAN LANG="da-DK">}</SPAN></PRE>
<HR>
<PRE CLASS="kode-western">Alt gik godt, g&oslash;r &aelig;ndringerne forpligtigende</PRE>
<H2 CLASS="western" STYLE="">8.3 <a name='afsn8.3'></a>Optimering</SPAN></H2>
<P CLASS="western">&Oslash;nsker man hurtigere kommunikation med
databasen, er der en r&aelig;kke ting, man kan g&oslash;re.</P>

<H3 CLASS="western">8.3.1 <a name='afsn8.3.1'></a>Bruge den rigtige databasedriver</H3>
<P CLASS="western">JDBC-drivere findes i fire typer:</P>
<UL>
  <LI><P CLASS="western" ALIGN=LEFT>Type 1: JDBC-ODBC-broen. Dette er
  den langsomste, da den k&oslash;rer gennem ODBC, og den er dermed
  platformsspecifik (hovedsageligt til Windows).</P>
  <LI><P CLASS="western" ALIGN=LEFT>Type 2: Drivere, hvor JDBC-laget
  kalder funktioner skrevet til i f.eks. maskinkode, C eller C++ til
  den specifikke platform (normalt den hurtigste).</P>
  <LI><P CLASS="western" ALIGN=LEFT>Type 3: Platformsuafh&aelig;ngig
  (ren Java-) driver, der benytter en databaseuafh&aelig;ngig 
  kommunikationsprotokol til at kommunikere med en server, som s&aring;
  kommunikerer videre med den specifikke database. Denne type driver
  giver stor fleksibilitet.</P>
  <LI><P CLASS="western" ALIGN=LEFT>Type 4: Platformsuafh&aelig;ngig
  (ren Java-) driver, der er skrevet til at kommunikere via en
  kommunikationsprotokol med en specifik database. 
  </P>
</UL>
<P CLASS="western"><SPAN LANG="da-DK">De hurtigste drivere er type 2,
men ofte kan en type 4 driver blive n&aelig;sten lige s&aring;
hurtig. En liste med over hundrede tilg&aelig;ngelige drivere kan
findes p&aring; </SPAN><SPAN STYLE="font-weight: medium"><A CLASS="western" HREF="http://java.sun.com/jdbc"><SPAN LANG="da-DK">http://java.sun.com/jdbc</SPAN></A></SPAN><SPAN LANG="da-DK">.</SPAN></P>

<H3 CLASS="western">8.3.2 <a name='afsn8.3.2'></a>L&aelig;gge opdateringer i k&oslash;
(batch-opdateringer)</H3>
<P CLASS="western">Skal man lave mange opdateringer, kan det v&aelig;re
en fordel at sende dem af sted som &eacute;n samlet enhed (eng.:
batch) i stedet for som normalt at vente p&aring;, at hver opdatering
skal gennemf&oslash;res, f&oslash;r den n&aelig;ste kan sendes.</P>
<PRE CLASS="kode-western">import java.sql.*;
<SPAN LANG="da-DK">public class Batchopdateringer</SPAN>
<SPAN LANG="da-DK">{</SPAN>
<SPAN LANG="da-DK">  public static void main(String[] arg) throws Exception</SPAN>
<SPAN LANG="da-DK">  {</SPAN>
<SPAN LANG="da-DK">    Class.forName(&quot;oracle.jdbc.driver.OracleDriver&quot;);</SPAN>
<SPAN LANG="da-DK">    Connection forb = DriverManager.getConnection(</SPAN>
<SPAN LANG="da-DK">               &quot;jdbc:oracle:thin:@ora.javabog.dk:1521:student&quot;,&quot;jacob&quot;,&quot;jacob&quot;);</SPAN>

<SPAN LANG="da-DK">    Statement stmt = forb.createStatement();</SPAN>
<SPAN LANG="da-DK">    stmt.addBatch(&quot;insert into KUNDER(NAVN,KREDIT) values('Jacob', -1799)&quot;);</SPAN>
<SPAN LANG="da-DK">    stmt.addBatch(&quot;insert into KUNDER(NAVN,KREDIT) values('Brian', 0)&quot;);</SPAN>

<SPAN LANG="da-DK">    <I>// send f&oslash;rst nu &aelig;ndringer til databasen</I></SPAN>
<SPAN LANG="da-DK">    stmt.executeBatch();</SPAN>
<SPAN LANG="da-DK">  }</SPAN>
<SPAN LANG="da-DK">}</SPAN></PRE>


<H3 CLASS="western">8.3.3 <a name='afsn8.3.3'></a>P&aring; forh&aring;nd forberedt SQL</H3>
<P CLASS="western">Det er klart, at der i koden vist ovenfor bruges
noget tid p&aring; at fortolke SQL-kommandoen hver gang kaldet
foretages.</P>
<P CLASS="western">I stedet for at oprette en SQL-kommandolinje med
createStatement(), kan man bruge metoden prepareStatement(), hvor man
angiver SQL-kommandoen &eacute;n gang under opstart af programmet, og
derefter kan udf&oslash;re kommandoen flere gange. 
</P>
<PRE CLASS="kode-western">import java.sql.*;
<SPAN LANG="da-DK">public class ForberedtSQL</SPAN>
<SPAN LANG="da-DK">{</SPAN>
<SPAN LANG="da-DK">  public static void main(String[] arg) throws Exception</SPAN>
<SPAN LANG="da-DK">  {</SPAN>
<SPAN LANG="da-DK">    Class.forName(&quot;oracle.jdbc.driver.OracleDriver&quot;);</SPAN>
<SPAN LANG="da-DK">    Connection forb = DriverManager.getConnection(</SPAN>
<SPAN LANG="da-DK">               &quot;jdbc:oracle:thin:@ora.javabog.dk:1521:student&quot;,&quot;jacob&quot;,&quot;jacob&quot;);</SPAN>

<SPAN LANG="da-DK">    // Forbered kommandoerne til databasen i starten af programmet:</SPAN>

<SPAN LANG="da-DK">    PreparedStatement <B>inds&aelig;t = forb.prepareStatement</B>(</SPAN>
<SPAN LANG="da-DK">                                &quot;insert into KUNDER(NAVN,KREDIT) values(?, ?)&quot;);</SPAN>

<SPAN LANG="da-DK">    PreparedStatement <B>hent = forb.prepareStatement</B>(</SPAN>
<SPAN LANG="da-DK">                                             &quot;select NAVN, KREDIT from KUNDER&quot;);</SPAN>

<SPAN LANG="da-DK"><I>    // under programudf&oslash;relsen kan forberedte kommandoer udf&oslash;res mange gange:</I></SPAN>
<SPAN LANG="da-DK"><B>    inds&aelig;t.setString(1, &quot;Jacob&quot;);</B></SPAN>
<SPAN LANG="da-DK"><B>    inds&aelig;t.setInt(2, -1799);</B></SPAN>
<SPAN LANG="da-DK"><B>    inds&aelig;t.execute();</B></SPAN>

<SPAN LANG="da-DK"><B>    inds&aelig;t.setString(1, &quot;Brian&quot;);</B></SPAN>
<SPAN LANG="da-DK"><B>    inds&aelig;t.setInt(2, 0);</B></SPAN>
<SPAN LANG="da-DK"><B>    inds&aelig;t.execute();</B></SPAN>

<SPAN LANG="da-DK">    // som f&oslash;r kan opdateringerne ogs&aring; l&aelig;gges i k&oslash;:</SPAN>
<SPAN LANG="da-DK">    inds&aelig;t.setString(1, &quot;Hans&quot;);</SPAN>
<SPAN LANG="da-DK">    inds&aelig;t.setInt(2, 142);</SPAN>
<SPAN LANG="da-DK"><B>    inds&aelig;t.addBatch();</B></SPAN>

<SPAN LANG="da-DK">    inds&aelig;t.setString(1, &quot;Grethe&quot;);</SPAN>
<SPAN LANG="da-DK">    inds&aelig;t.setInt(2, 242);</SPAN>
<SPAN LANG="da-DK"><B>    inds&aelig;t.addBatch();</B></SPAN>

<SPAN LANG="da-DK">    <I>// send &aelig;ndringer til databasen</I></SPAN>
<SPAN LANG="da-DK"><B>    inds&aelig;t.executeBatch();</B></SPAN>

<SPAN LANG="da-DK">    ResultSet rs = <B>hent.executeQuery();</B></SPAN>
<SPAN LANG="da-DK"><I>    // man l&oslash;ber igennem svaret som man plejer</I></SPAN>
<SPAN LANG="da-DK">    while (rs.next())</SPAN>
<SPAN LANG="da-DK">    {</SPAN>
<SPAN LANG="da-DK">      String navn = rs.getString(1);</SPAN>
<SPAN LANG="da-DK">      double kredit = rs.getDouble(2);</SPAN>
<SPAN LANG="da-DK">      System.out.println(navn+&quot; &quot;+kredit);</SPAN>
<SPAN LANG="da-DK">    }</SPAN>
<SPAN LANG="da-DK">  }</SPAN>
<SPAN LANG="da-DK">}</SPAN></PRE>
<HR>
<PRE CLASS="kode-western">Jacob -1799.0
<SPAN LANG="da-DK">Brian 0.0</SPAN>
<SPAN LANG="da-DK">Hans 142.0</SPAN>
<SPAN LANG="da-DK">Grethe 242.0</SPAN></PRE>

<H3 CLASS="western">8.3.4 <a name='afsn8.3.4'></a>Kalde gemte procedurer i databasen</H3>
<P CLASS="western">St&oslash;rre databaser underst&oslash;tter
'stored procedures' - procedurer gemt i databasen. Disse procedurer
kan udf&oslash;res hurtigere, da databasen p&aring; forh&aring;nd kan
optimere, hvordan SQL-kaldene skal foreg&aring;.</P>
<P CLASS="western">En gemt procedure kan kaldes med et
CallableStatement (her forestiller vi os, at der p&aring; forh&aring;nd
er oprettet procedurerne <B>indsaetkunde</B> og <B>hentkunder</B> i
databasen):</P>
<PRE CLASS="kode-western">  CallableStatement inds&aelig;tP =  forb.prepareCall(&quot;call indsaetkunde(?, ?)&quot;);
<SPAN LANG="da-DK">  CallableStatement hentP =  forb.prepareStatement(&quot;?= hentkunder&quot;);</SPAN></PRE><P CLASS="western">
Resten af arbejdet foreg&aring;r som med PreparedStatement:</P>
<PRE CLASS="kode-western">  inds&aelig;tP.setString(1, &quot;Jacob&quot;);
<SPAN LANG="da-DK">  inds&aelig;tP.setInt(2, -1799);</SPAN>
<SPAN LANG="da-DK">  inds&aelig;tP.execute();</SPAN>
<SPAN LANG="da-DK">  inds&aelig;tP.setString(1, &quot;Brian&quot;);</SPAN>
<SPAN LANG="da-DK">  inds&aelig;tP.setInt(2, 0);</SPAN>
<SPAN LANG="da-DK">  inds&aelig;tP.execute();</SPAN>

<SPAN LANG="da-DK">  ResultSet rs = hentP.executeQuery();</SPAN>
<SPAN LANG="da-DK">  ...</SPAN></PRE>
<H2 CLASS="western" STYLE="">8.4 <a name='afsn8.4'></a>Avanceret</SPAN></H2>

	    Dette afsnit er ikke omfattet af Åben Dokumentslicens.<br>
	    Du skal <a href="/index_VP.html#bestil">købe</a> bogen for at
	    måtte læse dette afsnit.

  <form action="http://javabog.dk/VP/kapitel8.jsp#afsn8.4">
  <input type='checkbox' name='vis' value='8.4'>Jeg erklærer, at jeg allerede har købt bogen<br />
  <input type='checkbox' name='vis' value='8.4'>Jeg lover at anskaffe den i nær fremtid.<br />
  <input type='submit' value='Vis mig dette afsnit'>
  </form>

	  <H3 CLASS="western">8.4.1 <a name='afsn8.4.1'></a>Opdatering og navigering i
ResultSet-objekter</H3>

	    Dette afsnit er ikke omfattet af Åben Dokumentslicens.<br>
	    Du skal <a href="/index_VP.html#bestil">købe</a> bogen for at
	    måtte læse dette afsnit.

  <form action="http://javabog.dk/VP/kapitel8.jsp#afsn8.4.1">
  <input type='checkbox' name='vis' value='8.4.1'>Jeg erklærer, at jeg allerede har købt bogen<br />
  <input type='checkbox' name='vis' value='8.4.1'>Jeg lover at anskaffe den i nær fremtid.<br />
  <input type='submit' value='Vis mig dette afsnit'>
  </form>

	  <H3 CLASS="western">8.4.2 <a name='afsn8.4.2'></a>Metadata</H3>

	    Dette afsnit er ikke omfattet af Åben Dokumentslicens.<br>
	    Du skal <a href="/index_VP.html#bestil">købe</a> bogen for at
	    måtte læse dette afsnit.

  <form action="http://javabog.dk/VP/kapitel8.jsp#afsn8.4.2">
  <input type='checkbox' name='vis' value='8.4.2'>Jeg erklærer, at jeg allerede har købt bogen<br />
  <input type='checkbox' name='vis' value='8.4.2'>Jeg lover at anskaffe den i nær fremtid.<br />
  <input type='submit' value='Vis mig dette afsnit'>
  </form>

	  <H3 CLASS="western">8.4.3 <a name='afsn8.4.3'></a>Metadata om databasen</H3>

	    Dette afsnit er ikke omfattet af Åben Dokumentslicens.<br>
	    Du skal <a href="/index_VP.html#bestil">købe</a> bogen for at
	    måtte læse dette afsnit.

  <form action="http://javabog.dk/VP/kapitel8.jsp#afsn8.4.3">
  <input type='checkbox' name='vis' value='8.4.3'>Jeg erklærer, at jeg allerede har købt bogen<br />
  <input type='checkbox' name='vis' value='8.4.3'>Jeg lover at anskaffe den i nær fremtid.<br />
  <input type='submit' value='Vis mig dette afsnit'>
  </form>

	  <H3 CLASS="western">8.4.4 <a name='afsn8.4.4'></a>Metadata om svaret p&aring; en foresp&oslash;rgsel</H3>

	    Dette afsnit er ikke omfattet af Åben Dokumentslicens.<br>
	    Du skal <a href="/index_VP.html#bestil">købe</a> bogen for at
	    måtte læse dette afsnit.

  <form action="http://javabog.dk/VP/kapitel8.jsp#afsn8.4.4">
  <input type='checkbox' name='vis' value='8.4.4'>Jeg erklærer, at jeg allerede har købt bogen<br />
  <input type='checkbox' name='vis' value='8.4.4'>Jeg lover at anskaffe den i nær fremtid.<br />
  <input type='submit' value='Vis mig dette afsnit'>
  </form>

	  <H3 CLASS="western" STYLE="">8.4.5 <a name='afsn8.4.5'></a>Eksempel
- udskrive en vilk&aring;rlig tabel</H3>

	    Dette afsnit er ikke omfattet af Åben Dokumentslicens.<br>
	    Du skal <a href="/index_VP.html#bestil">købe</a> bogen for at
	    måtte læse dette afsnit.

  <form action="http://javabog.dk/VP/kapitel8.jsp#afsn8.4.5">
  <input type='checkbox' name='vis' value='8.4.5'>Jeg erklærer, at jeg allerede har købt bogen<br />
  <input type='checkbox' name='vis' value='8.4.5'>Jeg lover at anskaffe den i nær fremtid.<br />
  <input type='submit' value='Vis mig dette afsnit'>
  </form>

	  <H3 CLASS="western" STYLE="">
8.4.6 <a name='afsn8.4.6'></a>Persistering af objekter - JDO</H3>

	    Dette afsnit er ikke omfattet af Åben Dokumentslicens.<br>
	    Du skal <a href="/index_VP.html#bestil">købe</a> bogen for at
	    måtte læse dette afsnit.

  <form action="http://javabog.dk/VP/kapitel8.jsp#afsn8.4.6">
  <input type='checkbox' name='vis' value='8.4.6'>Jeg erklærer, at jeg allerede har købt bogen<br />
  <input type='checkbox' name='vis' value='8.4.6'>Jeg lover at anskaffe den i nær fremtid.<br />
  <input type='submit' value='Vis mig dette afsnit'>
  </form>

	  

<a href='http://javabog.dk/'>javabog.dk</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='kapitel7.jsp'>&lt;&lt; forrige</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='indhold.jsp'>indhold</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='kapitel9.jsp'>n&aelig;ste &gt;&gt;</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='kode/'>programeksempler</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='../index_VP.html'>om bogen</a>
<hr>
<font size=-2>http://javabog.dk/ - <b></b> af Jacob Nordfalk.
<br>
  Licens og kopiering under <a href='http://www.linuxbog.dk/licens.html'>&Aring;ben Dokumentlicens</a> (&Aring;DL)
  hvor intet andet er nævnt (71% af værket).
</font>
<br>
Ønsker du at se de sidste 29% af dette værk (362838 tegn)
skal du købe bogen. Så får du pæne figurer og layout, stikordsregister og en trykt bog med i købet.
<!-- netlæser: Wget/1.10, autoHent: true  -->
     

</body>
</html>
