Gå til innhold

Blogg - kobling av MySQL og jsp


Anbefalte innlegg

Oppgave 1: Det første vi må gjøre for å lage bloggen vår er å opprette en ny database der vi kan lagre innleggene og kommentarene. Til dette trenger vi to tabeller: én som inneholder innlegg og én som inneholder kommentarene. Kommentarene trenger en fremmednøkkel som forteller hvilket innlegg de hører til. Hvilke felt dere tar med er opp til dere, men det kan være lurt å ha med et felt for dato og klokkeslett slik at innleggene og kommentarene kan vises sortert med den nyeste øverst.

 

Da gjorde jeg følgende i databasen min dagjonas_blogg:

 

CREATE TABLE innlegg(
id int AUTO_INCREMENT NOT NULL,
dato varchar(20), 
klokkeslett varchar(20),
overskrift varchar(20), 
melding varchar(200), 
PRIMARY KEY(id)
);

CREATE TABLE kommentarer(
dato varchar(20), 
klokkeslett varchar(20), 
melding varchar(200), 
innleggid int
);

 

Oppgave 2: Lag "nyttinnlegg.jsp"-siden som inneholder skjemaet som skal brukes til å legge til nye innlegg i bloggen. I tillegg til de vanlige feltene skal skjemaet også inneholde et passord-felt av typen <input type="password" />. Dette skal benyttes slik at ikke hvem som helst skal kunne legge til nye innleggg i bloggen din.

 

Lag deretter "mottak.jsp"-siden som skal motta informasjonen fra skjemaet og legge til innleggene i databasen. Her må du sjekke at passordet som ble skrevet inn stemmer overens med et passord du velger selv.

 

nyttinnlegg.jsp

<form action="mottak.jsp" method="post">
<b>Skriv et nytt innlegg</b><p>
Overskrift:<br/>
<input type="text" name="overskrift"/><br/>
Melding:<br/>
<textarea rows="5" cols="40" name="melding"></textarea><br/>
Passord:<br/>
<input type="ikke-det-nei"/><br/>
<input type="submit" value="Send"> <input type="reset" value="Tøm">
</form>

 

mottak.jsp

<%@page import="java.sql.*" %>

<%
// Laster inn databasedriver
Class.forName("org.gjt.mm.mysql.Driver").newInstance();
// Lager en forbindelse med databasen
Connection db = DriverManager.getConnection(
"jdbc:mysql://mysql.stud.ntnu.no/dagjonas_blogg","dagjonas_itgk","ikke-det-nei");
%>
// Oppretter en statement og resultatsett for spørringer	
Statement st= db.createStatement();
ResultSet rs;

//tar i mot parametere
String navn = request.getParameter("overskrift");
String karakter = request.getParameter("melding");

//oppretter spørring for å legge inn i databasen
String sporring = "INSERT INTO innlegg (overskrift, melding) VALUES ('"+overskrift+"', '"+melding+"')";

//utfører spørringen executeUpdate for å legge inn og endre informasjon
st.executeUpdate(sporring);

// Stenger databasen etter bruk
db.close();
%>

 

Dette funker ikke helt, og det skjønte jeg jo egentlig, for jeg er ikke helt stødig på dette.

Derfor lurer jeg på om noen ser hva som er galt?

Ser selv at jeg ikke har noen dato og klokkeslett, vet ikke hvordan jeg skal få til det, og så var det dette med å koble sammen de to tabellene.

Endret av dagjonas
Lenke til kommentar
Videoannonse
Annonse

Til dato og klokkeslett er det greiest å bruke dato- og klokkeslett-datatypene (og slå sammen dato og klokkeslett i én kolonne).

 

Jeg har ikke peiling på JSP, men det bør finnes en enkel funksjon som lager en dato og et klokkeslett som du kan bruke. Jeg prøvde dokumentasjonen/API'en på sun.com, men jeg fikk nesten hodepine.

 

Når du skal legge inn et innlegg trenger du kun å røre inlegg-tabellen. Ikke kommentar-tabellen. Kommentar-tabellen trenger du kun å røre når du skal skrive ut innlegg + kommentarer, og legge inn kommentarer.

 

Den spørringen du har der, skal i grunnen fungere siden du har valgt kolonner som skal skrives til, men kanskje den må være slik:

INSERT INTO innlegg (id, overskrift, melding) VALUES ('', '"+overskrift+"', '"+melding+"')

Lenke til kommentar

Hm, skal jeg da legge til en kode for dato og klokkeslett inn i tabellene jeg har opprettet i databasen eller skal jeg på en eller annen måte få det til slik at når man skriver et nytt innlegg så sendes det automatisk med dato og klokkeslett til databasen?

 

Edit: får sendt informasjonen til databasen, er det med klokkeslett og dato som jeg fortsatt ikke vet hvordan jeg skal gjøre.

Endret av dagjonas
Lenke til kommentar

Kan gjøre det på to måter. Sistnevnte kom jeg ikke på før nå, men synes egentlig at det var en genial løsning.

 

La JSP lage dato (eksempel fra PHP siden jeg ikke har snøring på JSP):

PHP
<?php

// Har koblet til og alt det der

 

$dato date('Y-m-d H:i:s'); // Lager en dato-streng som blir seende ut som: 2006-11-06 00:23:30

 

$insert_data mysql_query("INSERT INTO innlegg (id, dato, overskrift, melding) VALUES ('', '{$dato}', '{$overskrift}', '{$melding}'");

?>

Eller rett og slett la MySQL gjøre det selv:

INSERT INTO innlegg (id, dato, overskrift, melding) VALUES('', NOW(), '{variabel med overskrift}', '{variabel med innlegg}')

 

I begge eksemplene har jeg slått dato og tid sammen til én kolonne.

Lenke til kommentar

Får det ikke helt til jeg, ble nå slik, fra databasen (brukte alt. 2):

 

+----+---------------------+------------+---------+
| id | datotid             | overskrift | melding |
+----+---------------------+------------+---------+
|  1 | 2006-11-06 19:13:05 |            |         |
|  2 | NULL                | Test       | Test    |
+----+---------------------+------------+---------+

 

Ville hatt dato og tid der det står null, akkurat som id økes med én for hvert innlegg vil jeg at for hvert innlegg skal den aktuelle datoen og tiden stå i den kolonnen.

Lenke til kommentar

Det skal den gjøre også.

NOW() er en funksjon som printer tiden og datoen i det spørringen blir behandlet. Merkelig at du ikke får det til. Kanskje du har glemt å forandre: ...INTO innlegg (id, dato, overskrift, melding)... til ...INTO innlegg (id, datotid, overskrift, melding)... ?

Lenke til kommentar

Jepp, nå ble det.

Men hvordan kan jeg endre formateringen på datoen, så i stedet for 2006-11-06 vil jeg ha 06.11.2006?

 

Edit: det ovenfor er uvesentlig i forhold til det neste problemet.

 

Nå som vi lister opp blogginnleggene skal vi legge til informasjon om hvor mange kommentarer hvert innlegg har. Dette kan vi gjøre ved å utføre en spørring for hvert innlegg vi viser frem. Denne spørringen skal sjekke hvor mange kommentarer akkurat dette innlegget har.

 

Et tips her er å bruke kodeordet "COUNT(*)" som gir tilbaket antall rader som matcher spørringen (f.eks. SELECT COUNT(*) FROM person WHERE alder=32).

 

Dersom et innlegg har kun én kommentar skal det skrives i entall (1 kommentar), ellers skal det stå i flertall (x kommentarer).

 

Teksten som forteller hvor mange kommentarer et innlegg har skal også være en link til en side som viser innlegget sammen med alle kommentarene. For å få til dette skal du lage en side kalt "innlegg.jsp". Denne siden trenger informasjon om hvilket innlegg du vil vise, og det får vi til ved å legge til en parameter i linken til innlegg.jsp. Hvis du kaller parameteren som forteller dette "vis", så blir linken til innlegget med id=1:

<a href="innlegg.jsp?vis=1">x kommentarer</a>

innlegg.jsp kan så hente verdien til vis-parameteren for å finne ut hvilket innlegg som skal vises.

 

Det vil si at det mine blogg-innlegg vises, må det også under hver blogg være muligheten til å trykke på "kommenter" dersom ingen har kommentert bloggen, "1 kommentar" eller "flere kommentarer" for å kommentere blogginnlegget mitt. Dermed blir man sendt videre til siden innlegg.jsp.

 

Først må blogg.jsp få den nødvendige linkingen, noe slikt (har tullekodet litt inni der):

 

while(rs.next()){
String overskrift = rs.getString("overskrift");
String melding = rs.getString("melding");
String dato = rs.getString("datotid");


out.println("<b>" + overskrift + "</b>" + "<i> - " + dato + "</i>" + "<br/>" + melding + "<br/>");
out.println("<a href="innlegg.jsp?vis=1">x kommentarer</a>"); 
out.println("<p	/>");
}

 

Jeg må få knyttet vis parameteren opp til innleggsiden og en løkke for "x kommentarer".

 

Ble mye dette, men det er litt morsomt også.

Endret av dagjonas
Lenke til kommentar
Men hvordan kan jeg endre formateringen på datoen, så i stedet for 2006-11-06 vil jeg ha 06.11.2006?
SELECT DATE_FORMAT(datotid, '%d.%m.%Y %H:%i:%s') AS datotid FROM tabell

 

Dette kan vi gjøre ved å utføre en spørring for hvert innlegg vi viser frem.

7232911[/snapback]

Det virker jo lite ytelsesmessig gjennomtenkt, når man kan løse alt veldig lett med én spørring med en JOIN (sammen COUNT()). Endret av endrebjorsvik
Lenke til kommentar

Det er godt mulig, men JOIN har jeg foreløpig ikke lært noe om.

 

Knoter med å få med en "kommentarer" link i where-løkka nå.

 

while(rs.next()){
//henter ut data fra resultatsettet
String overskrift = rs.getString("overskrift");
String melding = rs.getString("melding");
String dato = rs.getString("datotid");
String id = rs.getString("id");

out.println("<b>" + overskrift + "</b>" + "<i> - " + dato + "</i>" + "<br/>" + melding + "<br/>");
out.println("<a href=\"innlegg.jsp?vis=1\">kommentarer</a>");
out.println("<p/>");
}

 

Først så tullet jeg veldig med å få out.println til å ville lage en link når det ble flere gåseøyne inni der, men det ble. Nå er det det å få koblet selve linken til innlegget som den out.println ovenfor skriver ut som jeg ikke får til.

 

EDIT: kanskje den linken som skrives ut i tillegg må være en slags <form> slik at innlegg.jsp kan hente den infoen, for jeg ser ikke helt hvordan innlegg.jsp skulle klare det ellers.

Endret av dagjonas
Lenke til kommentar

Nå er jeg ikke helt sikker på hvordan dette fungerer men kan du ikke lage 2 ResultSet objekter? altså ResultSet rs, og ResultSet rs2. Og så kan du inni while-løkka di( den som kjører gjennom ResultSet rs) skrive sql spørringen: rs2.executeQuery("SELECT COUNT(*) FROM kommentar WHERE innleggid=id (Dette går bare om du gjør om id Stringen din til: int id = rs.getInt("id") )

 

Etter dette flytter du pekeren ned ett hakk i rs2-settet:

 

rs2.next();

 

Så oppretter du en ny int som sier hvor mange kommentarer innlegget har:

 

int ant_kommentar = rs2.getInt("COUNT(*)");

 

da har du en int verdi som vet hvor mange kommentarer akkurat dette innlegget har.

 

PS. Husk at alt dette skal være i while-løkka.

 

Noen som ser noe feil? er ikke helt stødig på mySQL spørringer.

Eller er det kanskje en uting å bruke 2 ResultSet objekter og å kjøre 2 spørringer "samtidig" slik det her blir gjort i while-løkka?

Lenke til kommentar

Når det gjelder den vis-verdien som skal sendes til innlegg.jsp, så må den først opprettes:

 

int vis;

 

så, når du skriver hyperlinken så gjør du slik:

 

out.println("<a href=\"innlegg.jsp?vis="+id+"\">kommentarer</a>");

 

Der vis-verdien blir id'en til innlegget. Dette tar du da inn i innlegg.jsp siden med samme request som ved vanlig form:

 

String id = request.getParameter("vis");

 

Så må du vel parse denne til en int for å bruke den i en eventuell sql spørring:

 

int id_verdi = Integer.parseInt(id);

 

Dette skal funke er jeg ganske sikker på :)

Lenke til kommentar

Setter det med hva som skal stå akkurat i linken (1 kommentar, 2 kommentarer) litt på vent, lar det bare stå "kommentér" i første omgang.

 

Koblingen mellom blogg.jsp og innlegg.jsp gir meg mer hodebry. :dontgetit:

 

-sakset fra blogg.jsp:

//oppretter variablen vis
int vis;

//går gjennom hele resultatsettet
while(rs.next()){
//henter ut data fra resultatsettet
String overskrift = rs.getString("overskrift");
String melding = rs.getString("melding");
String dato = rs.getString("datotid");
String id = rs.getString("id");

out.println("<b>" + overskrift + "</b>" + "<i> - " + dato + "</i>" + "<br/>" + melding + "<br/>");
out.println("<a href=\"innlegg.jsp?vis="+id+"\">Kommentér</a>");
out.println("<p	/>");
}

 

Det fungerer fint, for kommentarer på blogg-innlegg 1 linkes det til innlegg.jsp?vis=1, og for nummer to innlegg.jsp?vis=2. Så var det å få innlegg.jsp?vis=1 til å vise innlegg 1 og ingen andre.

 

-sakset fra innlegg.jsp

laster inn databasedriver, oppretter statement og resultatsett for spørringer som vanlig

//tar imot vis, lagrer det i en streng før den gjøres om til int
String id = request.getParameter("vis");
int id_verdi = Integer.parseInt(id);

//lager en spørring som henter ut fra tabellene.
String sporring = "SELECT id, overskrift, melding, datotid FROM innlegg WHERE id=\"id_verdi\"";

//utfører denne spørringen executeQuery for å hente ut informasjon
rs = st.executeQuery(sporring);

//henter ut data fra resultatsettet
String overskrift = rs.getString("overskrift");
String melding = rs.getString("melding");
String dato = rs.getString("datotid");

out.println("<b>" + overskrift + "</b>" + "<i> - " + dato + "</i>" + "<br/>" + melding + "<br/>");

db.close();
%>

 

Jeg antar det er noe galt i spørringen min der jeg spør etter id=\"id_verdi\". Jeg har prøvd flere varianter der, men ingen har så langt fungert.

 

Feilmelding:

java.lang.NumberFormatException: null

at java.lang.Integer.parseInt(Integer.java:436)

at java.lang.Integer.parseInt(Integer.java:518)

osv.

 

Tusen takk for hjelpen så langt, flott at noen tar seg bryet. :thumbup:

Lenke til kommentar

id er en integer-kolonne. Derfor trenger du ikke gåseøyne rundt id_verdi.

Og er Java så smart at det vet at det er variabelen id_verdi, og ikke strengen 'id_verdi' som skal sendes til databasen? Jeg kan ikke se noen måte variabel-navnet skiller seg ut fra resten av strengen. Isåfall ville vel også verdien av variabelen id blitt puttet istedetfor 'id' i første del av spørringen.

 

Har du prøvd å printe spørringen, for å se hva den virkelig sender?

out.println(sporring);

 

Edit: Hvis jeg ikke er helt på jordet, skulle jeg tro spørringen burde være noe sånt som dette:

String sporring = "SELECT id, overskrift, melding, datotid FROM innlegg WHERE id="+id_verdi;

Endret av endrebjorsvik
Lenke til kommentar

Fungerer ikke.

Dersom jeg bare setter id=1, sender den det, men det er noe med formateringen på id=osv..

Har prøvd med flere ulike varianter, men neida.

 

// Oppretter en statement og resultatsett for spørringer	
Statement st= db.createStatement();
ResultSet rs;

//tar imot vis, lagrer det i en streng før den gjøres om til int
String id = request.getParameter("vis");
int id_verdi = Integer.parseInt(id);

//lager en spørring som henter ut fra tabellene.
String sporring = "SELECT id, overskrift, melding, datotid FROM innlegg WHERE id="+id_verdi;

//utfører denne spørringen executeQuery for å hente ut informasjon
rs = st.executeQuery(sporring);

out.println(sporring); 


db.close();
%>

Lenke til kommentar

Dette fungerer, den skriver ut 1, 2 osv. akkurat som den skal i følge linken som ble laget.

 

//tar imot vis, lagrer det i en streng før den gjøres om til int
String id = request.getParameter("vis");
int id_verdi = Integer.parseInt(id);

out.println(id_verdi);

db.close();
%>

 

Men når spørringen skal utføres "klikker" det.

 

//lager en spørring som henter ut fra tabellene.
String sporring = "SELECT id, overskrift, melding, datotid FROM innlegg WHERE id=id_verdi";

//utfører denne spørringen executeQuery for å hente ut informasjon
rs = st.executeQuery(sporring);

 

java.sql.SQLException: Column not found: Unknown column 'id_verdi' in 'where

clause'

 

Men dersom id_verdi byttes ut med 1, 2 osv i spørringen fungerer det selvsagt.

Lenke til kommentar

Du indikerer ikke at det er variabelen id_verdi som skal stå der. Java tror at det skal stå id=id_verdi og sender det som en streng til databasen.

I PHP må man f.eks gjøre det slik:

$sporring = "SELECT * FROM table WHERE id = $id_verdi";
eller
$sporring = "SELECT * FROM table WHERE id = " . $id_verdi;

 

Feilmeldingen kommer av at MySQL prøver å finne rekker der kolonnen id er lik kolonnen id_verdi.

Jeg vet ikke om Java har noen hurtigformatering for å indikere at det skal stå en variabel der, men jeg kan tenke meg at dette kanskje kan gå:

String sporring = "SELECT id, overskrift, melding, datotid FROM innlegg WHERE id = "+id_verdi+"";

Endret av endrebjorsvik
Lenke til kommentar

Jeg har nå støtt på et nytt problem, lest i forelesningsfoiler og annet, men jeg ser ikke helt hvordan jeg skal gjøre dette.

 

Nå man vil kommentere et blogg-innlegg blir man sendt til en side hvor blogg-innlegget står øverst, deretter et skjema for å kommentere og de andre kommentarene under.

 

Kommentaren sendes til kommentarer.jsp hvor navn og kommentar blir blir sendt til databasen, ved følgende spørring:

 

String sporring = "INSERT INTO kommentarer (innleggid, datotid, navn, kommentar) VALUES ('', NOW(), '"+navn+"', '"+kommentar+"')";

 

Da kan det se ut slik i databasen:

 

mysql> SELECT * FROM kommentarer;    
+---------------------+-----------+-----------------------------------------------------+-----------+
| datotid             | navn      | kommentar                                           | innleggid |
+---------------------+-----------+-----------------------------------------------------+-----------+
| 2006-11-11 18:10:12 | Tester    | Nå kommenterer jeg innlegg nummer 2.                |         0 |
+---------------------+-----------+-----------------------------------------------------+-----------+

 

Men når jeg nå som jeg nevnte ovenfor skal vise kommentarene som det gitte blogg-innlegget har fått, må jeg ha en sammenheng mellom innlegg.id og kommentarer.id.

Som man ser ovenfor sender jeg bare 0 som ID inn til kommentarer, dette må endres på slik at id-en til det aktuelle blogg-innlegget som kommenteres blir sendt til databasen.

 

Koblingen mellom tabellene:

 

CREATE TABLE innlegg(
id int AUTO_INCREMENT NOT NULL,
datotid varchar(30),
overskrift varchar(30), 
melding varchar(200), 
PRIMARY KEY(id)
);

CREATE TABLE kommentarer(
datotid varchar(30),
navn varchar(20), 
kommentar varchar(200), 
innleggid int
);

 

Så hvordan skal jeg få sendt med rett ID?

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...