====== 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(); } } }