====== Processing DB Connection =====
----
* [[https://mariadb.com/downloads/connectors/connectors-data-access/java8-connector/|JDBC Connector]] <- Download
* JDBC står for Java Database Connectivity
* Det er Java’s “bro” mellem din Java-kode og en database (fx MySQL, MariaDB, SQLite)
* JAR-filen indeholder alle klasser og metoder, som gør det muligt at:
* Oprette forbindelse til databasen
* Udføre SQL-queries
* Læse/Gemme resultater i et ''ResultSet''
- Opret en tom sketch.
- Opret en mappe ''code'' i samme folder som din sketch.
- Hent .jar-filen (fx mariadb-java-client-3.5.7.jar).
- Læg jar fil i ''code'' mappe.
- Download nedestående ''Database.java'' og gem denne i samme folder som din sketch.
- **!! OBS !!** -// Du skal nu rette Database.java således at det passer med din database. (USER, PASSWORD etc.)//
- Du bør nu kunne bruge MariaDB gennem JDBC Connection i din Sketch.
- Hent Simpel Bogdatabase (zip fil)
- Pak zip fil ud, og åben i notepad.
- Kør SQL i mariaDB client for at oprette database
* [[https://www.sojamo.de/libraries/controlP5/reference/index.html|ControlP5 reference]]
* [[https://sojamo.de/libraries/controlP5/#examples|ControlP5 examples]]
* [[https://www.w3schools.com/sql/default.asp|SQL reference]] (w3schools)
* {{ :docs:books_simple.zip |Simpel Bogdatabase}} Database SQL: ''library'', 1 table. 20 records.
----
==== Øvelse ====
* Få forbindelse til MariaDB data fra Processing
* Fyld et ControlP5 TextArea op med de bøger (title og author) fra ''library'' test databasen
* Opret to Input felter (title, author), samt en knap.
* Ved tryk på knap skal der oprettes en ny bog i database. TextArea skal efterfølgende opdateres (genbrug kode fra ovenstående, gennem en funktion)
* Input felter renses.
* Tilføj et søgefelt (textfield), samt en søge knap (button)
* Ved tryk på søge knap skal der søges i både **titel** og **author** ud fra keyword som er indtastet i søgefelt. (hint brug:**LIKE** og **OR**) (der håndteres pt. kun ét keyword)
* Søge resultatet vises i TextArea.
----
Test kode
=== Opret forbindelse ===
import java.sql.Connection;
import controlP5.*;
Database db;
Connection conn;
void setup() {
db = Database.getInstance();
conn = db.getConnection();
// ..andet kode fx. control P5 m.m.
}
Du kan nu efterfølgende tilgå databasen gennem **conn**.
----
==== Indsæt record ====
Her indsættes en record i `Books`-tabellen:
try {
String sql = "INSERT INTO Books (title, author) VALUES(?, ?)";
PreparedStatement stmt = conn.prepareStatement(sql);
stmt.setString(1, title);
stmt.setString(2, author);
int rows = stmt.executeUpdate();
stmt.close();
println("Inserted artist: " + title+ " (" + author+ ") - " + rows + " row(s) affected");
} catch(SQLException e) {
e.printStackTrace();
}
**Forklaring på try/catch:**
Vi bruger try/catch for at **håndtere fejl**, som kan opstå når vi arbejder med databaser, fx hvis:
* forbindelsen er forkert
* tabellen ikke findes
* der indsættes ugyldige værdier
Hvis en fejl opstår, stopper programmet ikke brat – i stedet kan fange fejlen (Catch) og vise hvad som skete (`e.printStackTrace()`).
----
==== Læs data (query) ====
Her hentes bøger fra 'Books' table.
try {
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT title, author FROM Books");
while(rs.next()) {
String title = rs.getString("title");
String author = rs.getString("author");
println(title + ": " + author);
}
rs.close();
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
**try/catch:**
Samme princip gælder her: databasen kan fejle, fx hvis forespørgslen er forkert eller forbindelsen mistes. try/catch sørger for, at programmet kan håndtere fejlen pænt og ikke crasher.
----
==== Tips ====
* Luk altid ResultSet, Statement og Connection, når du er færdig.
* PreparedStatement beskytter mod SQL-injektion og gør det nemt at indsætte variabler.
* PreparedStatement er praktisk til at indsætte flere records, fordi du kan genbruge statement og blot ændre værdien.
* Starte med at håndtere Database/SQL i main, du vil senere senere flytte den fukntionalitet/logik til egne klasser.
----
import java.sql.*;
public class Database {
// Singleton-instans
private static Database instance;
// JDBC-forbindelsen
private Connection connection;
// === RET DISSE ===
private static final String HOST = "localhost";
private static final String DATABASE = "skole_db";
private static final String USER = "root";
private static final String PASSWORD = "";
private static final String URL =
"jdbc:mariadb://" + HOST + ":3306/" + DATABASE + "?useSSL=false";
// Privat constructor (singleton)
private Database() {
try {
connection = DriverManager.getConnection(URL, USER, PASSWORD);
System.out.println("Database connected");
} catch (SQLException e) {
System.out.println("Database connection failed");
e.printStackTrace();
}
}
// Få singleton-instansen
public static Database getInstance() {
if (instance == null) {
instance = new Database();
}
return instance;
}
// Giv adgang til forbindelsen
public Connection getConnection() {
return connection;
}
public void close() {
try {
if (connection != null && !connection.isClosed()) {
connection.close();
System.out.println("Database closed");
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}