



<html>
<head>
  <title>javabog.dk - Webprogrammering med Java Server Pages - Brug af databaser</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='kapitel4.jsp'>&lt;&lt; forrige</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='indhold.jsp'>indhold</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='kapitel6.jsp'>n&aelig;ste &gt;&gt;</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='kode/'>programeksempler</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='../index_JSP.html'>om bogen</a>

<H1 CLASS="western" STYLE="">5 <a name='afsn5'></a>Brug af
databaser</H1>
<DIV ID="Indholdsfortegnelse15">
  <P STYLE="margin-top: 0.5cm; 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>5.1
  Strategier til databaseadgang  92</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">5.1.1
  Hvilken database skal man v&aelig;lge  92</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>5.2
  I gang med databaser og MySQL  92</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">5.2.1
  SQL-kommandoer og foresp&oslash;rgsler  93</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">5.2.2
  Administrere databasen fra kommandolinjen  93</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">5.2.3
  Administrere databasen med MySQLCC  95</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">5.2.4
  Administrere fra et udviklingsv&aelig;rkt&oslash;j  95</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>5.3
  Kontakt til database fra Java  (JDBC)  97</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">5.3.1
  Kontakt gennem ODBC under Windows  97</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">5.3.2
  Kontakt til MySQL-database  97</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">5.3.3
  Kontakt til en Oracle-database  98</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>5.4
  Kommunikation med database fra Java  98</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">5.4.1
  SQL-kommandoer og foresp&oslash;rgsler fra Java  99</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">5.4.2
  P&aring; forh&aring;nd forberedt SQL  100</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>5.5
  Eksempel - g&aelig;stebog  102</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">5.5.1
  Oprette tabellen i databasen  102</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">5.5.2
  Visning af g&aelig;stebogen (gaestebog.jsp)  103</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">5.5.3
  Indskrivning (indskriv_i_gaestebog.jsp)  104</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>5.6
  Test dig selv  105</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>5.7
  Resum&eacute;  105</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>5.8
  Avanceret: Optimering  106</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">5.8.1
  Bruge den rigtige databasedriver  106</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">5.8.2
  P&aring; forh&aring;nd forberedt SQL  106</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">5.8.3
  L&aelig;gge opdateringer i k&oslash; (batch)  107</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">5.8.4
  L&aelig;gge 'stored procedures' i databasen  107</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">5.8.5
  Forbindelsespuljer (Connection pooling)  108</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">5.8.6
  Metadata  108</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">5.8.7
  Eksempel: Webgr&aelig;nseflade til database   108</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>5.9
  Avanceret: JDBC RowSet  110</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">5.9.1
  JdbcRowSet  110</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">5.9.2
  CachedRowSet  110</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">5.9.3
  FilteredRowSet og JoinRowSet  111</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">5.9.4
  WebRowSet  112</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">5.9.5
  Mere information  114</FONT></FONT></P>
</DIV>
<P CLASS="kapiteloversigt-western"><SPAN LANG="da-DK">En overordnet
forst&aring;else af databaser foruds&aelig;ttes i store dele af
resten af bogen. Kapitlet foruds&aelig;tter <a href='kapitel3.jsp'>kapitel 3</a>, Interaktive sider
og lidt kendskab til databaser.</SPAN></P>
<H2 CLASS="western" STYLE="">5.1 <a name='afsn5.1'></a>Strategier
til databaseadgang</SPAN></H2>
<P CLASS="western">I dette kapitel vil vi se p&aring;, hvordan man
kommunikerer med en database fra Java og JSP.</P>
<P CLASS="western"><SPAN LANG="da-DK">Der er rigtig mange muligheder
for, hvordan databasekommunikationen kan foreg&aring;.</SPAN> <SPAN LANG="da-DK">De
fleste muligheder involverer JDBC (Java DataBase Connectivity), som
bliver gennemg&aring;et i dette kapitel.</SPAN></P>
<P CLASS="western">Nogle af mulighederne er:</P>
<UL>
  <LI><P CLASS="western"><SPAN LANG="da-DK">At bruge JDBC direkte fra
  JSP-siderne (som beskrevet i f.eks. dette kapitel i <a href='kapitel5.jsp#afsn5.5'>afsnit 5.5</a>, Eksempel - g&aelig;stebog)</SPAN></P>
  <LI><P CLASS="western"><SPAN LANG="da-DK">At bruge JDBC fra
  Java-klasser, der s&aring; bruges fra JSP-siderne (beskrevet i det
  f&oslash;lgende, se <a href='kapitel9.jsp'>kapitel 9</a>, Javab&oslash;nner i JSP-sider,
  hvordan klasser kan bruges fra JSP-sider)</SPAN></P>
  <LI><P CLASS="western"><SPAN LANG="da-DK">At bruge JSTLs
  databasefunktioner fra JSP (se <a href='kapitel6.jsp#afsn6.3'>afsnit 6.3</a>, JSTL og databaser (&lt;sql: &gt;))</SPAN></P>
  <LI><P CLASS="western"><SPAN LANG="da-DK">At bruge JDBC RowSet (se
  <a href='kapitel5.jsp#afsn5.9'>afsnit 5.9</a>, JDBC RowSet), herunder:</SPAN></P>
  <LI><P CLASS="western">Bruge CachedRowSet direkte fra JSP-sider
  (eller Java-klasser)</P>
  <LI><P CLASS="western">Bruge WebRowSet til at producere XML, der
  derp&aring; kan transformeres</P>
  <LI><P CLASS="western">med XSL (XML Style Sheet - ikke beskrevet i
  denne bog, men se <a href='kapitel11.jsp#afsn11.1.4'>afsnit 11.1.4</a>)</P>
  <LI><P CLASS="western">med JSTLs XML-tags (se et eksempel i afsnit
  6.4.3)</P>
  <LI><P CLASS="western"><SPAN LANG="da-DK">At bruge EJB - Enterprise
  JavaBeans (se <a href='kapitel12.jsp'>kapitel 12</a>) med containerstyret persistens.</SPAN></P>
  <LI><P CLASS="western">At bruge JDO (Java Data Objects - ikke
  beskrevet i denne bog)</P>
</UL>
<P CLASS="western"><SPAN LANG="da-DK">Hvilken l&oslash;sning der er
bedst afh&aelig;nger af, hvor omfattende ens webapplikation er og
hvor meget man forventer den senere skal vedligeholdes. Dette vil
blive diskuteret n&aelig;rmere i <a href='kapitel10.jsp#afsn10.2'>afsnit 10.2</a>, Model 1 og model 2-arkitekturer.</SPAN></P>
<P CLASS="western">Er du begynder og skal til at lave din f&oslash;rste
webapplikation, anbefales det, at du bruger en af de to f&oslash;rste
muligheder (JDBC enten fra JSP eller Java-klasser). Du kan s&aring;
kigge p&aring; de andre muligheder p&aring; et senere tidspunkt.</P>
<H3 CLASS="western">5.1.1 <a name='afsn5.1.1'></a>Hvilken database skal man v&aelig;lge</H3>
<P CLASS="western">Det f&oslash;rste skridt for at komme i gang med
databaser er naturligvis, at installere en database, man kan
kommunikere med.</P>
<P CLASS="western">Bruger du Windows og har du Microsoft
Office-pakken installeret, kan du v&aelig;lge at bruge Microsoft
Access-databasen. Den er dog ikke s&aelig;rlig velegnet til st&oslash;rre
projekter. Har du adgang til en anden kommerciel database, s&aring;som
Oracle, kan du med fordel bruge den. 
</P>
<P CLASS="western"><SPAN LANG="da-DK">Her i bogen vil vi bruge MySQL,
som er en meget popul&aelig;r database med &Aring;ben Kildekode
(eng.: Open Source), der er gratis tilg&aelig;ngelig fra
</SPAN><A CLASS="western" HREF="http://mysql.com/"><SPAN LANG="da-DK">http://mysql.com</SPAN></A><SPAN LANG="da-DK">.</SPAN></P>
<P CLASS="western">Under Linux er den h&oslash;jst sandsynligt med i
din distribution, s&aring; du skal blot aktivere den i
kontrolpanelet, s&aring; vil den automatisk blive installeret. 
</P>
<P CLASS="western"><SPAN LANG="da-DK">Bruger du et andet styresystem
(f.eks. Windows eller Mac) m&aring; du selv hente den ned fra
</SPAN><A CLASS="western" HREF="http://mysql.com/"><SPAN LANG="da-DK">http://mysql.com</SPAN></A><SPAN LANG="da-DK">
og installere den.</SPAN></P>

<H2 CLASS="western">5.2 <a name='afsn5.2'></a>I gang med databaser og MySQL</SPAN></H2>
<P CLASS="western"><SPAN LANG="da-DK">N&aring;r man kommunikerer med
en database, bruger man som regel sproget SQL (Structured Query
Language). </SPAN>
</P>
<H3 CLASS="western">5.2.1 <a name='afsn5.2.1'></a>SQL-kommandoer og foresp&oslash;rgsler</H3>
<P CLASS="western">Det f&oslash;lgende viser nogle eksempler p&aring;
SQL-sproget. 
</P>
<P CLASS="western">For at oprette en tabel kaldet kunder med to
kolonner, et navn som er en tekst og en kredit som er et tal, skriver
man:</P>
<PRE CLASS="kode-western">CREATE TABLE kunder (navn varchar(32), kredit float);</PRE><P CLASS="western">
Tabellen er tom til at starte med. For at tilf&oslash;je to kunder
skriver man:</P>
<PRE CLASS="kode-western">INSERT INTO kunder VALUES('Jacob', -1799);
<SPAN LANG="da-DK">INSERT INTO kunder(navn,kredit) VALUES('Brian', 0);</SPAN></PRE><P CLASS="western">
Nu er der to r&aelig;kker (poster) i tabellen. Da vi tilf&oslash;jede
'Brian' skrev vi ogs&aring; kolonnenavnene (hvis man ikke kender
r&aelig;kkef&oslash;lgen eller der m&aring;ske er flere kolonner er
det en god id&eacute;).</P>
<P CLASS="western">Nu ville tabellen se ud som f&oslash;lger:</P>
<TABLE BORDER=1 BORDERCOLOR="#000000" CELLPADDING=4 CELLSPACING=0>
  <COL>
  <COL>
  <THEAD>
    <TR VALIGN=TOP>
      <TH>
        <P CLASS="western"> navn  
        </P>
      </TH>
      <TH>
        <P CLASS="western"> kredit 
        </P>
      </TH>
    </TR>
  </THEAD>
  <TBODY>
    <TR>
      <TD VALIGN=TOP>
        <P CLASS="western"> Jacob 
        </P>
      </TD>
      <TD VALIGN=BOTTOM SDVAL="-1799" SDNUM="1030;">
        <P CLASS="western">-1799</P>
      </TD>
    </TR>
    <TR>
      <TD VALIGN=TOP>
        <P CLASS="western"> Brian 
        </P>
      </TD>
      <TD VALIGN=BOTTOM SDVAL="0" SDNUM="1030;">
        <P CLASS="western">0</P>
      </TD>
    </TR>
  </TBODY>
</TABLE>
<P CLASS="western" ALIGN=LEFT><SPAN LANG="da-DK">Hele tabellen kunne
udskrives med </SPAN>SQL-foresp&oslash;rgslen</P>
<PRE CLASS="kode-western"><SPAN LANG="da-DK">SELECT * FR</SPAN>OM kunder;</PRE><P CLASS="western">
Denne foresp&oslash;rgsel kunne forfines, f.eks. til at frems&oslash;ge
navne, hvor kreditten er negativ:</P>
<PRE CLASS="kode-western"><SPAN LANG="da-DK">SELECT navn FR</SPAN>OM kunder WHERE<SPAN LANG="da-DK"> kredit &gt; 0</SPAN>;</PRE><P CLASS="western">
Der som svar blot giver 'Jacob'.</P>
<P CLASS="western">Man kan naturligvis ogs&aring; opdatere tabellen.
Lad os rette i Brians kredit:</P>
<PRE CLASS="kode-western">UPDATE kunder SET kredit=10 WHERE navn='Brian';</PRE><P CLASS="western">
Man kan slette. Her sletter f.eks. vi r&aelig;kken (eller r&aelig;kkerne)
hvor navnet er Jacob: 
</P>
<PRE CLASS="kode-western">DELETE FROM kunder WHERE navn='Jacob';</PRE><P CLASS="western">
Vi kunne ogs&aring; slette hele tabellen med:</P>
<PRE CLASS="kode-western">DROP TABLE kunder;</PRE>
<P CLASS="western">Her er alle kommandoerne samlet:</P>
<PRE CLASS="kode-western"><I>-- Filnavn: sqleksempler.sql</I>
<SPAN LANG="da-DK"><I>-- Kan bruges fra kommandolinjen med: mysql test &lt; sqleksempler.sql</I></SPAN>

<SPAN LANG="da-DK">CREATE TABLE kunder (navn varchar(32), kredit float); <I>-- opret tabel</I></SPAN>
<SPAN LANG="da-DK">INSERT INTO kunder VALUES('Jacob', -1799);          <I>-- inds&aelig;t r&aelig;kke</I></SPAN>
<SPAN LANG="da-DK">INSERT INTO kunder(navn,kredit) VALUES('Brian', 0); <I>-- do, med navngivne kolonner</I></SPAN>
<SPAN LANG="da-DK">UPDATE kunder SET kredit=10 WHERE navn='Brian';     <I>-- s&aelig;t Brians kredit til 10 kr</I></SPAN>
<SPAN LANG="da-DK">DELETE FROM kunder WHERE navn='Jacob';              <I>-- slet r&aelig;kke om Jacob</I></SPAN>
<SPAN LANG="da-DK">SELECT * FR</SPAN>OM kunder;                               <I>-- vis hele tabellen</I>
<SPAN LANG="da-DK">DROP TABLE kunder;                                  <I>-- slet tabellen igen</I></SPAN></PRE>

<H3 CLASS="western">5.2.2 <a name='afsn5.2.2'></a>Administrere databasen fra kommandolinjen</H3>
<P CLASS="western">Efter at MySQL er blevet installeret, skal den
startes op. Det kan enten g&oslash;res ved at installere den som en
tjeneste, der startes automatisk, n&aring;r computeres starter op
eller ved at starte programmet 'mysqld' manuelt (som superbruger).</P>
<P CLASS="western"><SPAN LANG="da-DK">N&aring;r MySQL installeres,
opretter den som standard en tom database med navnet 'test', der kan
tilg&aring;s af alle brugere</SPAN>.</P>
<P CLASS="western">Somme tider kan det v&aelig;re n&oslash;dvendigt
at arbejde med databasen fra kommandolinjen, m&aring;ske fordi man
ikke har adgang til en grafisk brugergr&aelig;nseflade. 
</P>
<P CLASS="western">Man kan logge p&aring; test-databasen med
kommandoen</P>
<PRE CLASS="western">  mysql test</PRE><P CLASS="western">
Her er et fuldt eksempel p&aring;, hvordan kommunikation med MySQL
fra kommandolinjen kunne se ud. Det brugeren skriver er i fed:</P>
<PRE CLASS="data-western"><SPAN STYLE="font-weight: medium">$&gt; </SPAN><B>mysql test</B>
<SPAN LANG="da-DK">Reading table information for completion of table and column names</SPAN>
<SPAN LANG="da-DK">You can turn off this feature to get a quicker startup with -A</SPAN>

<SPAN LANG="da-DK">Welcome to the MySQL monitor.  Commands end with ; or \g.</SPAN>
<SPAN LANG="da-DK">Your MySQL connection id is 7 to server version: 4.0.15</SPAN>

<SPAN LANG="da-DK">Type 'help;' or '\h' for help. Type '\c' to clear the buffer.</SPAN>

<SPAN LANG="da-DK">mysql&gt; <B>CREATE TABLE kunder (navn varchar(32), kredit float);</B></SPAN>
<SPAN LANG="da-DK">Query OK, 0 rows affected (0.32 sec)</SPAN>

<SPAN LANG="da-DK">mysql&gt; <B>INSERT INTO kunder VALUES('Jacob', -1799);</B></SPAN>
<SPAN LANG="da-DK">Query OK, 1 row affected (0.00 sec)</SPAN>

<SPAN LANG="da-DK">mysql&gt; <B>INSERT INTO kunder(navn,kredit) VALUES('Brian', 0);</B></SPAN>
<SPAN LANG="da-DK">Query OK, 1 row affected (0.00 sec)</SPAN>

<SPAN LANG="da-DK">mysql&gt; <B>UPDATE kunder SET kredit=10 WHERE navn='Brian';</B></SPAN>
<SPAN LANG="da-DK">Query OK, 1 row affected (0.00 sec)</SPAN>
<SPAN LANG="da-DK">Rows matched: 1  Changed: 1  Warnings: 0</SPAN>

<SPAN LANG="da-DK">mysql&gt; <B>SELECT * FROM kunder;</B></SPAN>
<SPAN LANG="da-DK">+-------+--------+</SPAN>
<SPAN LANG="da-DK">| navn  | kredit |</SPAN>
<SPAN LANG="da-DK">+-------+--------+</SPAN>
<SPAN LANG="da-DK">| Jacob |  -1799 |</SPAN>
<SPAN LANG="da-DK">| Brian |     10 |</SPAN>
<SPAN LANG="da-DK">+-------+--------+</SPAN>
<SPAN LANG="da-DK">2 rows in set (0.00 sec)</SPAN>

<SPAN LANG="da-DK">mysql&gt; <B>show tables;</B></SPAN>
<SPAN LANG="da-DK">+-----------------+</SPAN>
<SPAN LANG="da-DK">| Tables_in_test  |</SPAN>
<SPAN LANG="da-DK">+-----------------+</SPAN>
<SPAN LANG="da-DK">| kunder          |</SPAN>
<SPAN LANG="da-DK">+-----------------+</SPAN>
<SPAN LANG="da-DK">1 rows in set (0.00 sec)</SPAN>

<SPAN LANG="da-DK">mysql&gt; <B>exit</B></SPAN>
<SPAN LANG="da-DK">Bye</SPAN></PRE><P CLASS="western">
Sammenlign med <a href='kapitel5.jsp#afsn5.2.1'>afsnit 5.2.1</a>, SQL-kommandoer og foresp&oslash;rgsler.
Se ogs&aring; MySQL-manualen (<A CLASS="western" HREF="http://mysql.com/doc/"><SPAN LANG="da-DK">http://mysql.com/doc/</SPAN></A><SPAN LANG="da-DK">
under ' Tutorial') for en introduktion til SQL og MySQL.</SPAN></P>

<H4 CLASS="western">Brugere i databasen</H4>
<P CLASS="western">Som udgangspunkt findes databasebrugeren '' (intet
brugernavn) og brugeren 'root' i MySQL. Begge brugere kan kun logge
p&aring; fra den lokale maskine uden adgangskode.</P>
<P CLASS="western">Ovenfor har vi brugt brugeren med et tomt
brugernavn, der kun kan se databasen 'test' og ikke kan oprette nye
databaser.</P>
<P CLASS="western">&Oslash;nsker man at bruge en anden databasebruger
og/eller adgangskode skriver man:</P>
<PRE CLASS="western">  mysql -u brugernavn -p</PRE><P CLASS="western">
og indtaster adgangskoden (-p angiver at adgangskoden skal l&aelig;ses
fra tastaturet). For en bruger uden adgangskode, f.eks. bruger 'root'
skriver man:</P>
<PRE CLASS="western">  mysql -u root</PRE><H4 CLASS="western">
Oprette en database</H4>
<P CLASS="western">&Oslash;nsker man at oprette en anden database kan
det g&oslash;res fra kommandolinjen med:</P>
<PRE CLASS="western">  mysqladmin -u root create jspdb</PRE><P CLASS="western">
Nu er databasen 'jspdb' oprettet. Derefter kan man g&aring; ind i den
med:</P>
<PRE CLASS="western">  mysql -u root jspdb</PRE><H3 CLASS="western">
5.2.3 <a name='afsn5.2.3'></a>Administrere databasen med MySQLCC</H3>
<P CLASS="western">Fra MySQL.com kan man ogs&aring; hente MySQL
Control Center (MySQLCC), som kan hj&aelig;lpe med at administrere
ens database, herunder oprette og &aelig;ndre i databaser og tabeller
samt selvf&oslash;lgelig inds&aelig;tte, slette og s&oslash;ge i
tabellerne:</P>
<P CLASS="western" ALIGN=CENTER><IMG SRC="bog6_html_m30d1718e.png" NAME="Grafik28" ALIGN=BOTTOM BORDER=0></P>
<P CLASS="western">MySQLCC findes til Linux og Windows. Herover er
det vist under Linux.</P>
<P CLASS="western">V&aelig;rkt&oslash;jet er meget p&aelig;dagogisk,
idet man kan v&aelig;lge at f&aring; vist pr&aelig;cist hvilke
SQL-kommandoer, der udf&oslash;res (nederst p&aring; billedet). Dette
kan man s&aring; bruge til selv at l&aelig;re SQL.</P>

<H3 CLASS="western">5.2.4 <a name='afsn5.2.4'></a>Administrere fra et udviklingsv&aelig;rkt&oslash;j</H3>
<P CLASS="western">De fleste udviklingsv&aelig;rkt&oslash;jer har
mere eller mindre sofistikerede SQL-v&aelig;rkt&oslash;jer. 
</P>
<P CLASS="western">En af de mest raffinerede er Oracle JDeveloper,
der lader en designe tabellerne visuelt:</P>
<P CLASS="western"><IMG SRC="bog6_html_m574e3049.png" NAME="Grafik55" ALIGN=BOTTOM BORDER=0></P>
<P CLASS="western"><SPAN LANG="da-DK">... og senere hen vise (og,
hvis det er en Oracle-database, ogs&aring; redigere) tabel</SPAN>len:</P>
<P CLASS="western"><IMG SRC="bog6_html_724783d0.png" NAME="Grafik56" BORDER=0></P>
<H2 CLASS="western" STYLE="">5.3 <a name='afsn5.3'></a>Kontakt til
database fra Java  (JDBC)</SPAN></H2>
<P CLASS="western"><SPAN LANG="da-DK">Adgang til en database fra Java
sker gennem et s&aelig;t klasser, der under et kaldes JDBC (Java
DataBase Connectivity). Disse klasser ligger i pakken java.sql. </SPAN>
</P>
<P CLASS="western">JSP-sider, der arbejder med databaser skal derfor
importere denne pakke i starten:</P>
<PRE CLASS="kode-western">&lt;%@ page language=&quot;java&quot; import=&quot;java.sql.*&quot; %&gt;</PRE><P CLASS="western">
Tilsvarende skal der i starten af Java-filer, der arbejder med
databaser, st&aring;: 
</P>
<PRE CLASS="kode-western">import java.sql.*;</PRE>
<P CLASS="western">At f&aring; kontakt til en database fra Java
kr&aelig;ver to skridt:</P>
<OL>
  <LI><P CLASS="western">Indl&aelig;se databasedriveren</P>
  <LI><P CLASS="western">Etablere forbindelsen</P>
</OL>
<P CLASS="western">Indl&aelig;sning af driveren sker, ved at bede
systemet indl&aelig;se den p&aring;g&aelig;ldende klasse, der
derefter registrerer sig selv i JDBC-systemets driver-manager.</P>
<P CLASS="western"><SPAN LANG="da-DK">Ofte skal man have en JAR-fil
(et Java-ARkiv, en samling klasser pakket i ZIP-formatet) med en
driver fra producenten. P&aring; </SPAN><A CLASS="western" HREF="http://java.sun.com/jdbc"><SPAN LANG="da-DK">http://java.sun.com/jdbc</SPAN></A><SPAN LANG="da-DK">
kan man finde over 200 drivere til forskellige databaser.</SPAN></P>
<H3 CLASS="western">5.3.1 <a name='afsn5.3.1'></a>Kontakt gennem ODBC under Windows</H3>
<P CLASS="western">Med Java under Windows f&oslash;lger en standard
JDBC-ODBC-bro med, s&aring; man kan kontakte alle datakilder
defineret under ODBC. Denne driver indl&aelig;ses med:</P>
<PRE CLASS="kode-western">  Class.forName(&quot;sun.jdbc.odbc.JdbcOdbcDriver&quot;);</PRE><P CLASS="western">
N&aring;r forbindelsen oprettes, angiver man den &oslash;nskede
datakildes navn.</P>
<PRE CLASS="kode-western">  Connection con = DriverManager.getConnection(&quot;jdbc:odbc:datakilde1&quot;);</PRE><P CLASS="western">
Husk, at datakildens navn (her &quot;datakilde1&quot;) f&oslash;rst
skal v&aelig;re defineret i Windows' Kontrolpanel under ODBC.
Datakilden kan v&aelig;re en fil, f.eks. en Microsoft Access-fil
(.mdb) eller en rigtig database. 
</P>
<P CLASS="western">Bem&aelig;rk, at ODBC er en ret langsom protokol,
der ikke underst&oslash;tter ret mange af de mere avancerede ting.
Har du brug for bedre ydelse b&oslash;r du finde en driver, der
kommunikerer direkte med databasen/filen, i stedet for at bruge
JDBC-ODBC.</P>
<H3 CLASS="western">5.3.2 <a name='afsn5.3.2'></a>Kontakt til MySQL-database</H3>
<P CLASS="western"><SPAN LANG="da-DK">P&aring; </SPAN><A CLASS="western" HREF="http://mysql.com/"><SPAN LANG="da-DK">http://mysql.com</SPAN></A><SPAN LANG="da-DK">
kan hentes en JDBC-driver til MySQL (kaldet Connector/J). </SPAN>
</P>
<P CLASS="western">Driver-filen hedder typisk noget a la
mysql-connector-java-3.0.9-bin.jar. Den skal ligge i CLASSPATH eller
kopieres over i mappen java/jre/lib/ext/ s&aring; Java kender til
driveren<A CLASS="sdfootnoteanc" NAME="sdfootnote1anc" HREF="#sdfootnote1sym"><SUP>1</SUP></A>.</P>
<P CLASS="western">I kildeteksten skriver man:</P>
<PRE CLASS="kode-western"><SPAN LANG="da-DK">Class.forName(&quot;com.mysql.jdbc.Driver&quot;)</SPAN>;
<SPAN LANG="da-DK">Connection con = DriverManager.getConnection(&quot;jdbc:mysql:///test&quot;);</SPAN></PRE><P CLASS="western">
hvorefter man skulle have kontakt til databasen 'test' p&aring; den
lokale maskine (f&oslash;lger som standard med i MySQL), som anonym
bruger.</P>

<P CLASS="western" STYLE="">&Oslash;nsker
man at bruge en anden database, som en anden bruger, skriver man
f.eks.:</P>
<PRE CLASS="kode-western">Connection con = DriverManager.getConnection(&quot;jdbc:mysql:///jspdb&quot;,&quot;j&quot;,&quot;hemli&quot;);</PRE><P CLASS="western">
hvorefter man skulle have oprettet forbindelsen til databasen 'jspdb'
p&aring; den lokale maskine med brugernavn 'j' og adgangskode
'hemli'.</P>

<H3 CLASS="western">5.3.3 <a name='afsn5.3.3'></a>Kontakt til en Oracle-database</H3>
<P CLASS="western">&Oslash;nsker man kontakt 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 hedder classes12.zip og passer til en bestemt udgave af
Oracle-databasen. Den skal ligge i CLASSPATH eller kopieres over i
mappen java/jre/lib/ext/ s&aring; Java kender driveren.</P>
<P CLASS="western">Herefter kan man oprette forbindelsen med f.eks.:</P>
<PRE CLASS="kode-western">  Connection con = DriverManager.getConnection(
<SPAN LANG="da-DK">    &quot;jdbc:oracle:thin:@ora.javabog.dk:1521:student&quot;,&quot;j&quot;,&quot;hemli&quot;);</SPAN></PRE><P CLASS="western">
F&oslash;rste parameter er en URL til databasen. Den best&aring;r af
en protokol (jdbc), underprotokol (oracle) og noget mere, der
afh&aelig;nger af underprotokollen. I dette tilf&aelig;lde angiver
det, at databasen ligger p&aring; maskinen ora.javabog.dk port 1521
og hedder student. Anden og tredje parameter er brugernavn og
adgangskode.</P>

<H2 CLASS="western">5.4 <a name='afsn5.4'></a>Kommunikation med database fra Java</SPAN></H2>
<P CLASS="western">N&aring;r vi har en forbindelse, kan vi oprette et
&quot;statement&quot;-objekt, som vi kan sende kommandoer og
foresp&oslash;rgsler til databasen med:</P>
<PRE CLASS="kode-western">  Statement stmt = con.createStatement();</PRE><P CLASS="western">
<SPAN LANG="da-DK">Der kan opst&aring; forskellige undtagelser af
typen SQLException, der skal h&aring;ndteres.</SPAN></P>
<P CLASS="western">For at opn&aring; 'hul igennem' er det ofte en god
id&eacute; at tage &eacute;t skridt ad gangen. Eksemplerne i det
f&oslash;lgende er derfor skrevet som almindelige Java-klasser med en
main()-metode, s&aring;dan at man kan pr&oslash;ve dem fra
kommandolinjen eller i et udviklingsv&aelig;rkt&oslash;j, uden for
webserveren. 
</P>
<P CLASS="western"><SPAN LANG="da-DK">P&aring;
</SPAN><A CLASS="western" HREF="http://java.sun.com/docs/books/tutorial/jdbc/"><SPAN LANG="da-DK">http://java.sun.com/docs/books/tutorial/jdbc/</SPAN></A><SPAN LANG="da-DK">
kan du f&aring; yderligere information om JDBC og
databasekommunikation fra Java.</SPAN></P>
<H3 CLASS="western" STYLE="">5.4.1 <a name='afsn5.4.1'></a>SQL-kommandoer
og foresp&oslash;rgsler fra Java</H3>
<P CLASS="western">SQL-kommandoer, der ikke giver et svar tilbage i
form af data, s&aring;som INSERT, UPDATE, DELETE, CREATE TABLE og
DROP TABLE, sendes med executeUpdate()-metoden.</P>
<P CLASS="western">Her opretter vi f.eks. tabellen &quot;kunder&quot;
og inds&aelig;tter et par r&aelig;kker med en database defineret som
'datakilde1' i Windows' ODBC-kontrolpanel.</P>
<PRE CLASS="kode-western">import java.sql.*;
<SPAN LANG="da-DK">public class TestDatabaseforbindelseODBC</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"><B>    Class.forName(&quot;sun.jdbc.odbc.JdbcOdbcDriver&quot;);</B></SPAN>
<SPAN LANG="da-DK"><B>    Connection con = DriverManager.getConnection(&quot;jdbc:odbc:datakilde1&quot;);</B></SPAN>
<SPAN LANG="da-DK">    Statement stmt = con.createStatement();</SPAN>

<SPAN LANG="da-DK">    stmt.executeUpdate(&quot;CREATE TABLE kunder (navn varchar(32), kredit float)&quot; );</SPAN>
<SPAN LANG="da-DK">    stmt.executeUpdate(&quot;INSERT INTO kunder VALUES('Jacob', -1799)&quot;);</SPAN>
<SPAN LANG="da-DK">    stmt.executeUpdate(&quot;INSERT INTO kunder (navn,kredit) VALUES('Brian', 0)&quot;);</SPAN>
<SPAN LANG="da-DK">  }</SPAN>
<SPAN LANG="da-DK">}</SPAN></PRE>
<P CLASS="western">Tilsvarende med en MySQL-database:</P>
<PRE CLASS="kode-western">import java.sql.*;
<SPAN LANG="da-DK">public class TestDatabaseforbindelseMySQL</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"><B>    Class.forName(&quot;com.mysql.jdbc.Driver&quot;);</B></SPAN>
<SPAN LANG="da-DK"><B>    Connection con = DriverManager.getConnection(&quot;jdbc:mysql:///test&quot;);</B></SPAN>
<SPAN LANG="da-DK">    Statement stmt = con.createStatement();</SPAN>

<SPAN LANG="da-DK">    stmt.executeUpdate(&quot;CREATE TABLE kunder (navn varchar(32), kredit float)&quot; );</SPAN>
<SPAN LANG="da-DK">    stmt.executeUpdate(&quot;INSERT INTO kunder VALUES('Jacob', -1799)&quot;);</SPAN>
<SPAN LANG="da-DK">    stmt.executeUpdate(&quot;INSERT INTO kunder(navn,kredit) VALUES('Brian', 0)&quot;);</SPAN>
<SPAN LANG="da-DK">  }</SPAN>
<SPAN LANG="da-DK">}</SPAN></PRE>
<H4 CLASS="western">Foresp&oslash;rgsler</H4>
<P CLASS="western">SQL-foresp&oslash;rgslen SELECT udf&oslash;res med
metoden executeQuery():</P>
<PRE CLASS="kode-western">  ResultSet rs;
<SPAN LANG="da-DK">  rs = stmt.executeQuery(&quot;SELECT navn, kredit FROM kunder WHERE navn='Jacob'&quot;);</SPAN></PRE><P CLASS="western">
Den giver et ResultSet-objekt, der repr&aelig;senterer svaret p&aring;
foresp&oslash;rgslen (for at f&aring; alle kolonner kunne vi ogs&aring;
skrive &quot;SELECT * FROM kunder&quot;). 
</P>
<P CLASS="western">Data hentes fra ResultSet-objektet s&aring;ledes:</P>
<PRE CLASS="kode-western">  while (<B>rs.next()</B>)
<SPAN LANG="da-DK">  {</SPAN>
<SPAN LANG="da-DK">    String navn = <B>rs.getString(&quot;navn&quot;)</B>;</SPAN>
<SPAN LANG="da-DK">    double kredit = <B>rs.getDouble(&quot;kredit&quot;)</B>;</SPAN>
<SPAN LANG="da-DK">    System.out.println(navn+&quot; &quot;+kredit);</SPAN>
<SPAN LANG="da-DK">  }</SPAN></PRE><P CLASS="western">
Man kalder alts&aring; next() for at f&aring; n&aelig;ste r&aelig;kke
i svaret, l&aelig;ser de enkelte celler ud fra kolonnenavnene (eller
kolonnenumrene, regnet fra 1 af), hvorefter man g&aring;r videre til
n&aelig;ste r&aelig;kke med next() osv. N&aring;r next() returnerer
false, er der ikke flere r&aelig;kker at l&aelig;se.</P>
<H4 CLASS="western">SQL med data fra variabler</H4>
<P CLASS="western">Ofte er data gemt i variabler og kommer fra
brugeren f.eks. fra request-objektet:</P>
<PRE CLASS="kode-western">    String navn = request.getParameter(&quot;navn&quot;);</PRE><P CLASS="western">
S&aring; m&aring; man s&aelig;tte en streng sammen, der giver den
&oslash;nskede SQL-kommando:</P>
<PRE CLASS="kode-western">    int kredit = 500;

<SPAN LANG="da-DK"><I>    // inds&aelig;t data fra variablerne navn og kredit</I></SPAN>
<SPAN LANG="da-DK">    stmt.executeUpdate(&quot;INSERT INTO kunder VALUES('&quot;<B>+navn+</B>&quot;', &quot;<B>+kredit+</B>&quot;)&quot;);</SPAN></PRE><P CLASS="western">
Her ville den resulterende streng blive (hvis variablen navn
indeholdt v&aelig;rdien &quot;Hans&quot;) &quot;INSERT INTO kunder
VALUES('Hans', 500)&quot; og databasen ville inds&aelig;tte denne
r&aelig;kke.</P>
<P CLASS="western">P&aring; fuldst&aelig;ndig samme m&aring;de som
med SQL-kommandoer, kan SQL-foresp&oslash;rgsler laves, ved at s&aelig;tte
en passende SQL-streng sammen ud fra en variabel:</P>
<PRE CLASS="kode-western">  rs = stmt.executeQuery(&quot;SELECT navn, kredit FROM kunder WHERE navn='<B>&quot;+navn+&quot;</B>'&quot;);</PRE><P CLASS="western">
V&aelig;r dog opm&aelig;rksom p&aring; ikke, at introducere nogle
sikkerhedsproblemer. I l&aelig;ngden er det bedre at bruge p&aring;
forh&aring;nd forberedt SQL, i stedet for at stykke en streng sammen
med SQL-kommandoen.</P>
<H3 CLASS="western">5.4.2 <a name='afsn5.4.2'></a>P&aring; forh&aring;nd forberedt SQL</H3>
<P CLASS="western">I koden vist ovenfor er der nogle problemer:</P>
<OL>
  <LI><P CLASS="western">Ved hvert kald bruges noget tid p&aring; at
  s&aelig;tte en SQL-streng sammen, som databasen derefter skal
  fortolke for at udf&oslash;re SQL-kommandoen.</P>
  <LI><P CLASS="western"><SPAN LANG="da-DK">Hvis navnet indeholder et
  ' g&aring;r SQL-kommandoen galt. F.eks. hvis navn havde v&aelig;rdien
  &quot;Hans' venner&quot; ville SQL-strengen blive:<BR></SPAN><CODE CLASS="western"><SPAN LANG="da-DK">&quot;INSERT
  INTO kunder VALUES('Hans' venner', 500)&quot; </SPAN></CODE><SPAN LANG="da-DK"><BR>som
  er ugyldig fordi den indeholder tre '-er.</SPAN></P>
  <LI><P CLASS="western"><SPAN LANG="da-DK">Endnu v&aelig;rre er det
  med sikkerheden. Det er nemlig muligt at <I>injicere SQL</I> (eng.:
  SQL injection): Hvis brugeren er s&aring; smart, at han angiver et
  meget specielt navn, f.eks. navn=&quot;Hans', 1000000) --&quot;. Da
  vil SQL-strengen blive: <BR></SPAN><CODE CLASS="western"><SPAN LANG="da-DK">&quot;INSERT
  INTO kunder VALUES('Hans', 1000000) --', 500)&quot; </SPAN></CODE><SPAN LANG="da-DK"><BR>som
  er gyldigt SQL (-- angiver at resten af linjen er en kommentar). P&aring;
  den m&aring;de kunne brugeren oprette sig selv i databasen med
  vilk&aring;rligt store summer i kredit!<BR>Se <a href='kapitel8.jsp#afsn8.5'>afsnit 8.5</a> for en
  generel diskussion af sikkerhed.</SPAN></P>
</OL>

<P CLASS="western">I stedet for at oprette en SQL-kommandolinje med
createStatement(), b&oslash;r man derfor bruge metoden
prepareStatement(), hvor man angiver SQL-kommandoen &eacute;n gang og
derefter kan udf&oslash;re kommandoen med forskellige data mange
gange.</P>

<P CLASS="western" STYLE="">I SQL-kommandoen
skrives s&aring; et ?-tegn for hver stump data, der kan variere. F&oslash;r
hvert kald s&aelig;ttes data med en set-metode og nummeret p&aring;
stumpen (regnet fra og med 1):</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;com.mysql.jdbc.Driver&quot;);</SPAN>
<SPAN LANG="da-DK">    Connection con = DriverManager.getConnection(&quot;jdbc:mysql:///test&quot;);</SPAN>

<SPAN LANG="da-DK"><I>    // Forbered kommandoerne til databasen, f.eks. i starten af programmet:</I></SPAN>

<SPAN LANG="da-DK">    PreparedStatement inds&aelig;tPstm = con.prepareStatement(</SPAN>
<SPAN LANG="da-DK">                                &quot;INSERT INTO kunder (navn,kredit) VALUES(?, ?)&quot;);</SPAN>

<SPAN LANG="da-DK">    PreparedStatement hentPstm = con.prepareStatement(</SPAN>
<SPAN LANG="da-DK">                                &quot;SELECT navn, kredit FROM kunder WHERE navn=?&quot;);</SPAN>

<SPAN LANG="da-DK"><I>    // under programudf&oslash;relsen kan de forberedte kommandoer udf&oslash;res mange gange:</I></SPAN>
<SPAN LANG="da-DK">    for (int i=0; i&lt;100; i++) </SPAN>
<SPAN LANG="da-DK">    {</SPAN>
<SPAN LANG="da-DK"><B>      inds&aelig;tPstm.setString(1, &quot;Brian&quot;);</B></SPAN>
<SPAN LANG="da-DK"><B>      inds&aelig;tPstm.setInt(2, i);</B></SPAN>
<SPAN LANG="da-DK"><B>      inds&aelig;tPstm.execute();</B></SPAN>

<SPAN LANG="da-DK"><B>      inds&aelig;tPstm.setString(1, &quot;Hans' venner&quot;);  <I>// bem&aelig;rk ' i strengen</I></B></SPAN>
<SPAN LANG="da-DK"><B>      inds&aelig;tPstm.setInt(2, 1042+i);</B></SPAN>
<SPAN LANG="da-DK"><B>      inds&aelig;tPstm.execute();</B></SPAN>


<SPAN LANG="da-DK"><B>      hentPstm.setString(1, &quot;Hans' venner&quot;);</B>  <B>  <I>// bem&aelig;rk ' i SQL-foresp&oslash;rgslen</I></B></SPAN>
<SPAN LANG="da-DK">      ResultSet rs = <B>hentPstm.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>
<SPAN LANG="da-DK">}</SPAN></PRE><H4 CLASS="western">
&Oslash;velse</H4>
<P CLASS="western">Skriv ovenst&aring;ende program om, til at bruge
et almindeligt statement-objekt. Hvor stor er forskellen i
udf&oslash;relseshastighed (fjern kaldet til System.out.println() for
at f&aring; en klar m&aring;ling)?</P>
<H4 CLASS="western">Om optimering</H4>
<P CLASS="western"><SPAN LANG="da-DK">Ovenst&aring;ende forbedrer
ganske vist ydelsen en del (afh&aelig;ngig af JDBC-driveren), men det
vigtigste er, at ' i </SPAN><SPAN LANG="cs-CZ">strengene</SPAN><SPAN LANG="da-DK">
h&aring;ndteres, den &oslash;gede sikkerhed og (efter forfatterens
smag) den &oslash;gede overskuelighed.</SPAN></P>
<P CLASS="western">L&aelig;s mere om optimering i <a href='kapitel5.jsp#afsn5.8'>afsnit 5.8</a>.</P>

<H2 CLASS="western" STYLE="">5.5 <a name='afsn5.5'></a>Eksempel -
g&aelig;stebog</SPAN></H2>
<P CLASS="western">Et eksempel p&aring; databasekommunikation kunne
v&aelig;re en g&aelig;stebog, hvor brugerne kan se alle andre brugere
og hvad de har skrevet ind.</P>
<H3 CLASS="western">5.5.1 <a name='afsn5.5.1'></a>Oprette tabellen i databasen</H3>
<P CLASS="western">F&oslash;rst skal tabellen i databasen oprettes.
Hver r&aelig;kke har en unik id, navnet p&aring; brugeren, beskedens
tekst og datoen hvor beskeden blev oprettet. IP-adressen bliver af
sikkerhedshensyn ogs&aring; noteret. Her er SQL-koden til at oprette
tabellen:</P>
<PRE CLASS="kode-western"><I>-- Filnavn: gaestebogsoprettelse.sql</I>
<SPAN LANG="da-DK"><I>-- Kan bruges fra kommandolinjen med: mysql test &lt; gaestebogsoprettelse.sql</I></SPAN>

<SPAN LANG="da-DK">CREATE TABLE gaestebog (</SPAN>
<SPAN LANG="da-DK">  id      int  not null  primary key  auto_increment,</SPAN>
<SPAN LANG="da-DK">  navn    varchar(20),</SPAN>
<SPAN LANG="da-DK">  besked  varchar(255),</SPAN>
<SPAN LANG="da-DK">  dato    datetime,</SPAN>
<SPAN LANG="da-DK">  ip      varchar(16)</SPAN>
<SPAN LANG="da-DK">);</SPAN></PRE><P CLASS="western">
Denne SQL kan udf&oslash;res som beskrevet i <a href='kapitel5.jsp#afsn5.2.2'>afsnit 5.2.2</a>, Administrere databasen fra kommandolinjen,
eller man kan lave et lille program, der opretter tabellen:</P>
<PRE CLASS="kode-western">import java.sql.*;
<SPAN LANG="da-DK">public class Gaestebogsoprettelse</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;com.mysql.jdbc.Driver&quot;);</SPAN>
<SPAN LANG="da-DK">    Connection con = DriverManager.getConnection(&quot;jdbc:mysql:///test&quot;);</SPAN>

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

<SPAN LANG="da-DK">    stmt.executeUpdate(</SPAN>
<SPAN LANG="da-DK">      &quot;CREATE TABLE gaestebog (&quot;</SPAN>
<SPAN LANG="da-DK">      +&quot;id      int  not null  primary key  auto_increment,&quot;</SPAN>
<SPAN LANG="da-DK">      +&quot;navn    varchar(20),&quot;</SPAN>
<SPAN LANG="da-DK">      +&quot;besked  varchar(255),&quot;</SPAN>
<SPAN LANG="da-DK">      +&quot;dato    datetime),&quot;</SPAN>
<SPAN LANG="da-DK">      +&quot;ip      varchar(16)&quot;);</SPAN>
<SPAN LANG="da-DK">  }</SPAN>
<SPAN LANG="da-DK">}</SPAN></PRE>
<H3 CLASS="western" STYLE="">5.5.2 <a name='afsn5.5.2'></a>Visning
af g&aelig;stebogen (gaestebog.jsp)</H3>
<P CLASS="western">Her er siden, der viser g&aelig;stebogen:</P>
<P CLASS="western" ALIGN=CENTER><IMG SRC="bog6_html_4d2544cb.png" NAME="Grafik16" ALIGN=BOTTOM BORDER=0></P>
<P ALIGN=CENTER STYLE="margin-top: 0.11cm; margin-bottom: 0.11cm"><FONT SIZE=2 STYLE="font-size: 9pt"><I>gaestebog.jsp</I></FONT></P>
<PRE CLASS="kode-western">&lt;%@ page language=&quot;java&quot; import=&quot;java.sql.*&quot; %&gt;
<SPAN LANG="da-DK">&lt;html&gt;</SPAN>
<SPAN LANG="da-DK">&lt;head&gt;&lt;title&gt;G&aelig;stebog&lt;/title&gt;&lt;/head&gt;</SPAN>
<SPAN LANG="da-DK">&lt;body&gt;</SPAN>

<SPAN LANG="da-DK">&lt;h1&gt;G&aelig;stebog&lt;/h1&gt;</SPAN>
<SPAN LANG="da-DK">Velkommen til min lille g&aelig;stebog.&lt;br&gt;</SPAN>
<SPAN LANG="da-DK">Du kan skrive dig ind &lt;a href=&quot;indskriv_i_gaestebog.jsp&quot;&gt;her&lt;/a&gt;.</SPAN>

<SPAN LANG="da-DK">&lt;%</SPAN>
<SPAN LANG="da-DK">  <I>// Udskriv g&aelig;stebogen</I></SPAN>
<SPAN LANG="da-DK">  Class.forName(&quot;com.mysql.jdbc.Driver&quot;);</SPAN>
<SPAN LANG="da-DK">  Connection con = DriverManager.getConnection(&quot;jdbc:mysql:///test&quot;);</SPAN>
<SPAN LANG="da-DK">  Statement stmt = con.createStatement();</SPAN>
<SPAN LANG="da-DK">  ResultSet rs = stmt.executeQuery(&quot;SELECT navn, besked, dato FROM gaestebog&quot;);</SPAN>

<SPAN LANG="da-DK">  while(rs.next()) {</SPAN>
<SPAN LANG="da-DK">    %&gt;</SPAN>
<SPAN LANG="da-DK">    &lt;hr&gt;</SPAN>
<SPAN LANG="da-DK">      &lt;%= rs.getString(&quot;navn&quot;) %&gt; skrev den &lt;%= rs.getDate(&quot;dato&quot;) %&gt; </SPAN>
<SPAN LANG="da-DK">      det f&oslash;lgende indl&aelig;g:&lt;br&gt;</SPAN>
<SPAN LANG="da-DK">      &lt;%= rs.getString(&quot;besked&quot;) %&gt;</SPAN>
<SPAN LANG="da-DK">    &lt;p&gt;</SPAN>
<SPAN LANG="da-DK">    &lt;%</SPAN>
<SPAN LANG="da-DK">  } <I>// slut p&aring; while-l&oslash;kke</I></SPAN>

<SPAN LANG="da-DK">  <I>// oprydning</I></SPAN>
<SPAN LANG="da-DK">  rs.close();</SPAN>
<SPAN LANG="da-DK">  stmt.close();</SPAN>
<SPAN LANG="da-DK">  con.close();</SPAN>
<SPAN LANG="da-DK">%&gt;</SPAN>
<SPAN LANG="da-DK">&lt;/body&gt;</SPAN>
<SPAN LANG="da-DK">&lt;/html&gt;</SPAN></PRE><H3 CLASS="western">
5.5.3 <a name='afsn5.5.3'></a>Indskrivning (indskriv_i_gaestebog.jsp)</H3>
<P CLASS="western">V&aelig;lger brugeren at indskrive sig, kommer han
til f&oslash;lgende side:</P>
<P ALIGN=CENTER STYLE="margin-top: 0.11cm; margin-bottom: 0.11cm"><FONT SIZE=2 STYLE="font-size: 9pt"><I>indskriv_i_gaestebog.jsp</I></FONT></P>
<PRE CLASS="kode-western">&lt;%@ page language=&quot;java&quot; import=&quot;java.sql.*&quot; %&gt;
<SPAN LANG="da-DK">&lt;html&gt;</SPAN>
<SPAN LANG="da-DK">&lt;head&gt;&lt;title&gt;Indskriv i g&aelig;stebog&lt;/title&gt;&lt;/head&gt;</SPAN>
<SPAN LANG="da-DK">&lt;body&gt;</SPAN>

<SPAN LANG="da-DK">&lt;h1&gt;Skriv dig ind i min g&aelig;stebog&lt;/h1&gt;</SPAN>

&lt;form&gt;           &lt;img src=&quot;../kapitel_02/billede_med_avatar.jsp&quot; align=&quot;right&quot;&gt;
Navn: &lt;br&gt;
<SPAN LANG="da-DK">&lt;input type=&quot;text&quot; name=&quot;navn&quot; size=20&gt;&lt;br&gt;</SPAN>
<SPAN LANG="da-DK">Besked: &lt;br&gt;</SPAN>
<SPAN LANG="da-DK">&lt;textarea name=&quot;besked&quot; width=&quot;50&quot; height=&quot;10&quot;&gt;&lt;/textarea&gt;&lt;br&gt;</SPAN>
<SPAN LANG="da-DK">&lt;input type=&quot;submit&quot; value=&quot;OK&quot;&gt;</SPAN>
<SPAN LANG="da-DK">&lt;/form&gt;</SPAN>

<SPAN LANG="da-DK">&lt;%</SPAN>
<SPAN LANG="da-DK"><I>  // Se om der kommer nogen data fra formularen</I></SPAN>
<SPAN LANG="da-DK">  String navn = request.getParameter(&quot;navn&quot;);</SPAN>
<SPAN LANG="da-DK">  String besked = request.getParameter(&quot;besked&quot;);</SPAN>

<SPAN LANG="da-DK">  if (navn != null &amp;&amp; besked != null)</SPAN>
<SPAN LANG="da-DK">  {</SPAN>
<SPAN LANG="da-DK">    <I>// OK, vi har f&aring;et en indtastning. Tjek om brugeren reelt har tastet noget.</I></SPAN>
<SPAN LANG="da-DK">    if (navn.length() &lt; 3 || besked.length() &lt; 3)</SPAN>
<SPAN LANG="da-DK">    {</SPAN>
<SPAN LANG="da-DK">      out.write(&quot;Indtast venligst dit fulde navn og en besked.&quot;);</SPAN>
<SPAN LANG="da-DK">    } </SPAN>
<SPAN LANG="da-DK">    else </SPAN>
<SPAN LANG="da-DK">    {</SPAN>
<SPAN LANG="da-DK">      <I>// OK, beskedden er gyldig. Inds&aelig;t den i databasen</I></SPAN>
<SPAN LANG="da-DK">      Class.forName(&quot;com.mysql.jdbc.Driver&quot;);</SPAN>
<SPAN LANG="da-DK">      Connection con = DriverManager.getConnection(&quot;jdbc:mysql:///test&quot;);</SPAN>

<SPAN LANG="da-DK">      PreparedStatement pstmt = con.prepareStatement(</SPAN>
<SPAN LANG="da-DK">        &quot;INSERT INTO gaestebog (navn, besked, dato, ip) VALUES(?,?,?,?)&quot;);</SPAN>
<SPAN LANG="da-DK">      pstmt.setString(1, navn);</SPAN>
<SPAN LANG="da-DK">      pstmt.setString(2, besked);</SPAN>
<SPAN LANG="da-DK">      pstmt.setDate(3, new java.sql.Date(System.currentTimeMillis()));</SPAN>
<SPAN LANG="da-DK">      pstmt.setString(4, <SPAN STYLE="font-weight: medium">request.getRemoteAddr()</SPAN>);</SPAN>
<SPAN LANG="da-DK">      pstmt.executeUpdate();  </SPAN>
<SPAN LANG="da-DK">      pstmt.close();</SPAN>
<SPAN LANG="da-DK">      con.close();</SPAN>

<SPAN LANG="da-DK">      <I>// alt gik godt. Send brugeren tilbage til g&aelig;stebogen</I></SPAN>
<SPAN LANG="da-DK">      response.sendRedirect(&quot;gaestebog.jsp&quot;);</SPAN>
<SPAN LANG="da-DK">    }</SPAN>
<SPAN LANG="da-DK">  }</SPAN>
<SPAN LANG="da-DK">%&gt;</SPAN>
<SPAN LANG="da-DK">&lt;/body&gt;</SPAN>
<SPAN LANG="da-DK">&lt;/html&gt;</SPAN></PRE>

<P CLASS="western" ALIGN=CENTER><IMG SRC="bog6_html_615d3bcf.png" NAME="Grafik17" ALIGN=BOTTOM BORDER=0></P>

<H2 CLASS="western">5.6 <a name='afsn5.6'></a>Test dig selv</SPAN></H2>

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

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

	  <H2 CLASS="western">5.7 <a name='afsn5.7'></a>Resum&eacute;</SPAN></H2>

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

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

	  <H2 CLASS="western" STYLE="">5.8 <a name='afsn5.8'></a>Avanceret:
Optimering</SPAN></H2>

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

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

	  <H3 CLASS="western">5.8.1 <a name='afsn5.8.1'></a>Bruge den rigtige databasedriver</H3>

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

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

	  <H3 CLASS="western">5.8.2 <a name='afsn5.8.2'></a>P&aring; forh&aring;nd forberedt SQL</H3>

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

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

	  <H3 CLASS="western">5.8.3 <a name='afsn5.8.3'></a>L&aelig;gge opdateringer i k&oslash;
(batch)</H3>

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

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

	  <H3 CLASS="western">5.8.4 <a name='afsn5.8.4'></a>L&aelig;gge 'stored procedures' i databasen</H3>

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

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

	  <H3 CLASS="western">5.8.5 <a name='afsn5.8.5'></a>Forbindelsespuljer (Connection pooling)</H3>

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

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

	  <H3 CLASS="western">5.8.6 <a name='afsn5.8.6'></a>Metadata</H3>

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

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

	  <H3 CLASS="western">5.8.7 <a name='afsn5.8.7'></a>Eksempel: Webgr&aelig;nseflade til database
</H3>

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

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

	  
<H2 CLASS="western" STYLE="">5.9 <a name='afsn5.9'></a>Avanceret:
JDBC RowSet</SPAN></H2>

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

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

	  <H3 CLASS="western">5.9.1 <a name='afsn5.9.1'></a>JdbcRowSet</H3>

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

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

	  <H3 CLASS="western">5.9.2 <a name='afsn5.9.2'></a>CachedRowSet</H3>

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

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

	  <H3 CLASS="western">5.9.3 <a name='afsn5.9.3'></a>FilteredRowSet og JoinRowSet</H3>

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

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

	  <H3 CLASS="western">5.9.4 <a name='afsn5.9.4'></a>WebRowSet</H3>

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

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

	  <H3 CLASS="western">5.9.5 <a name='afsn5.9.5'></a>Mere information</H3>

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

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

	  
<DIV ID="sdfootnote1">
  <P CLASS="sdfootnote-western"><A CLASS="sdfootnotesym" NAME="sdfootnote1sym" HREF="#sdfootnote1anc">1</A>Se
  <a href='kapitel4.jsp#afsn4.9.6'>afsnit 4.9.6</a> hvis du har problemer med at f&aring; webserveren til
  at finde JAR-filerne.</P>
</DIV>

<a href='http://javabog.dk/'>javabog.dk</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='kapitel4.jsp'>&lt;&lt; forrige</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='indhold.jsp'>indhold</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='kapitel6.jsp'>n&aelig;ste &gt;&gt;</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='kode/'>programeksempler</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='../index_JSP.html'>om bogen</a>
<hr>
<font size=-2>http://javabog.dk/ - <b>Webprogrammering med Java Server Pages</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 (72% af værket).
</font>
<br>
Ønsker du at se de sidste 28% af dette værk (275315 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>
