[[oktatas:programozás:java:java adatbázis:mysql|< MySQL]] ====== Java MySQL - JDBC illesztő ====== * **Szerző:** Sallai András * Copyright (c) 2011, Sallai András * Szerkesztve: 2011, 2014, 2015, 2018, 2022 * Licenc: [[https://creativecommons.org/licenses/by-sa/4.0/|CC BY-SA 4.0]] * Web: https://szit.hu ===== JDBC használata a Java nyelvben ===== A JDBC használata során célszerű írni néhány metódust: * kapcsolatteremtés * kapcsolat lezárása * lekérdezés Az alábbiakban erre látunk példát, majd azok felhasználására a main() metódusban. Nagyobb programok esetén természetesen külön osztályt szokás létrehozni. import java.sql.*; class Mysql { String host = "localhost"; String port = "3306"; String db = "sargazrt"; String user = "sargazrt"; String pass = "titok"; public Connection connect() { Connection conn = null; try { conn = tryConnect(); }catch(SQLException ex) { System.err.println("Hiba az adatbázishoz kapcsolódás során!"); } return conn; } public Connection tryConnect() throws SQLException { Connection conn = null; String url = "jdbc:mysql://" + host + ":" + port + "/"+ db; conn = DriverManager.getConnection(url, user, pass); return conn; } public void close(Connection conn) { try { tryClose(conn); }catch(SQLException ex) { System.err.println("Hiba az adatbázis bezárása során!"); } } public void tryClose(Connection conn) throws SQLException { conn.close(); } public ResultSet query(Connection conn, String sql) { ResultSet rs = null; try { rs = tryQuery(conn, sql); }catch(SQLException ex) { System.err.println("Hiba a lekérdezés során"); } return rs; } public ResultSet tryQuery(Connection conn, String sql) throws SQLException { ResultSet rs = null; Statement stmt = conn.createStatement(); return stmt.executeQuery(sql); } } class Program01 { public static void main(String[] args) { System.out.println("MySQL kapcsolódás..."); Mysql mysql = new Mysql(); Connection conn = mysql.connect(); String sql = "select * from Dolgozok"; ResultSet rs = mysql.query(conn, sql); try { while(rs.next()) { System.out.printf("%s %s\n", rs.getString("nev"), rs.getString("telepules") ); } }catch(SQLException ex) { System.err.println("Hiba az adatok kinyerése során!"); } mysql.close(conn); } } A Makefile segít megérteni, milyen parancssori parancsokkal fordíthatjuk, futtathatjuk a JDBC-t használó programunk. SOURCES=Program01.java all: javac $(SOURCES) runl: xterm -e "java -cp .:/usr/share/java/mysql.jar Program01 & read" runw: cmd /c "java -cp .:c:\javalibs\mysql-connector-java-verzioszam.jar Program01 && pause" A következő példák futtató batch-fájl és futtató-script írását szemlélteti: java -classpath ".;mysql-connector-java-5.1.24-bin.jar" Program01 java -classpath ".:mysql-connector-java-5.1.24-bin.jar" Program01 Vegyük észre, a -classpath paraméterében (;) pontosvesszőt használtam. Linux esetén ezt le kell cserélni (:) kettőspontra. A verziószámot ki kell cserélni az aktuálisra. Megadhatunk abszolút útvonalat is, mint azt a Makefile-ban tettük. ===== Beállításfájl használata ===== Az adatbázis jellemzőinek leírására, használhatunk beállításfájlokat is. Ez biztosítja a program hordozhatóságát adatbázisok között. Ha nem használunk beállításfájlokat, az adatbázis jellemzők be vannak építve a programba, fixen. A beállítófájl egy .properties kiterjesztésű állomány lehet, amelyekben a tulajdonság, értékpárok az ini fájlokban használt mintát követi. A következőkben egy ilyen állományt látunk: host=localhost port=3306 database=sargazrt user=sargazrt pass=titok A program, amelyben felhasználjuk a beállításállományt: import java.sql.*; import java.util.ResourceBundle; class Mysql { String host; String port; String database; String user; String pass; Mysql() { ResourceBundle rb = ResourceBundle.getBundle("Program01"); this.host = rb.getString("host"); this.port = rb.getString("port"); this.database = rb.getString("database"); this.user = rb.getString("user"); this.pass = rb.getString("pass"); } public Connection connect() { Connection conn = null; try { conn = tryConnect(); }catch(SQLException ex) { System.err.println("Hiba az adatbázishoz kapcsolódás során!"); } return conn; } public Connection tryConnect() throws SQLException { Connection conn = null; String url = "jdbc:mysql://" + host + ":" + port + "/"+ database; conn = DriverManager.getConnection(url, user, pass); return conn; } public void close(Connection conn) { try { tryClose(conn); }catch(SQLException ex) { System.err.println("Hiba az adatbázis bezárása során!"); } } public void tryClose(Connection conn) throws SQLException { conn.close(); } public ResultSet query(Connection conn, String sql) { ResultSet rs = null; try { rs = tryQuery(conn, sql); }catch(SQLException ex) { System.err.println("Hiba a lekérdezés során"); } return rs; } public ResultSet tryQuery(Connection conn, String sql) throws SQLException { ResultSet rs = null; Statement stmt = conn.createStatement(); return stmt.executeQuery(sql); } } class Program01 { public static void main(String[] args) { System.out.println("MySQL kapcsolódás..."); Mysql mysql = new Mysql(); Connection conn = mysql.connect(); String sql = "select * from Dolgozok"; ResultSet rs = mysql.query(conn, sql); try { while(rs.next()) { System.out.printf("%s %s\n", rs.getString("nev"), rs.getString("telepules")); } }catch(SQLException ex) { System.err.println("Hiba az adatok kinyerése során!"); } mysql.close(conn); } } Segédállományok a fordításhoz: SOURCES=Program01.java all: javac $(SOURCES) runl: xterm -e "java -cp .:/usr/share/java/mysql.jar Program01 & read" runw: cmd /c "java -cp .:c:\javalibs\mysql-connector-java-verzioszam.jar Program01 && pause" ===== PreparedStatement SQL utasítása ===== PreparedStatement használata esetén, ha naplózni szeretnénk a használt SQL utasítást, akkor gondba kerülhetünk. A PreparedStatement lényege, pont az, hogy megváltoztatjuk az SQL lekérdező karaktersorozatot. Ez után visszanyerni PreparedStatement objektumból a használt SQL parancsot a toString() metódussal ilyen formán lehetséges: public void beszur(Connection con, String sql) { try { tryBeszur(con, sql); }catch(SQLException ex) { System.err.println("Hiba az SQL lekérdezés során!"); } } public void tryBeszur(Connection con, String sql) throws SQLException { PreparedStatement ps = con.prepareStatement(sql); ps.setString(1, "Bereg József"); ps.setString(2, "Szolnok"); System.out.println(ps.toString()); ps.executeUpdate(); } Ha meghívjuk a metódust, az eredmény ehhez hasonló lesz: com.mysql.jdbc.JDBC4PreparedStatement@143d2a58: insert into szemelyek (nev, telepules) values ('Bereg József', 'Szolnok') ===== Meghajtó ellenőrzése ===== Célszerű programból ellenőrizni a JDBC meghajtó használhatóságát. Ezt egy erre a célra létrehozott checkMysqlDriver() metódus mutat példát: public void checkMysqlDriver() { try { tryCheckMysqlDriver(); }catch(ClassNotFoundException ex) { System.err.println("Az osztály nem található!"); }catch(InstantiationException ex) { System.err.println("Hiba a példányosítás során!"); }catch(IllegalAccessException ex) { System.err.println("Hozáférésre nem jogosult!"); } } public void tryCheckMysqlDriver() throws ClassNotFoundException, InstantiationException, IllegalAccessException { Class.forName("org.gjt.mm.mysql.Driver").newInstance(); } ===== GUI ===== ==== Táblázatmodellé alakítás ==== A Java Swing GUI felületei egyik táblázatok adatait használni képes osztálya a TableModel. A példában a visszakapott eredményt egy TableModel objektumban helyezzük el: public TableModel resultSetToTableModel(ResultSet rs) { TableModel model = null; try { model = tryResultSetToTableModel(rs); }catch(SQLException ex) { System.err.println("Hiba a metadadatok lekérése során!"); } return model; } public TableModel tryResultSetToTableModel(ResultSet rs) throws SQLException { ResultSetMetaData metaData = rs.getMetaData(); int numberOfColumns = metaData.getColumnCount(); ArrayList columnNames = new ArrayList(); for(int i=0; i< numberOfColumns; i++) { columnNames.add(metaData.getColumnLabel(i+1)); } ArrayList rows = new ArrayList(); while(rs.next()) { ArrayList row = new ArrayList(); for(int i=1; i<= numberOfColumns; i++) { row.add(rs.getObject(i)); } rows.add(row); } Object[] columnNamesArray = columnNames.toArray(); Object[][] tableContent = new Object[rows.size()][numberOfColumns]; for(int i=0; i)rows.get(i)).toArray(); } return new DefaultTableModel(tableContent, columnNamesArray); } ===== Függelék ===== ==== Mysql.java ==== package adatbazis; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties; public class Mysql { String host; String port; String database; String user; String pass; Mysql() { initProperties(); } public void initProperties() { try { tryInitProperties(); } catch (FileNotFoundException ex) { System.err.println("A fájl nem található!"); } catch (IOException ex) { System.err.println("Hiba az olvasás során!"); } } public void tryInitProperties() throws FileNotFoundException, IOException { Properties pro = new Properties(); InputStream fis = new FileInputStream("adatbazisswing.properties"); pro.load(fis); this.host = pro.getProperty("host"); this.port = pro.getProperty("port"); this.database = pro.getProperty("database"); this.user = pro.getProperty("user"); this.pass = pro.getProperty("pass"); } public void checkMysqlDriver() { try { tryCheckMysqlDriver(); }catch(ClassNotFoundException ex) { System.err.println("Az osztály nem található!"); }catch(InstantiationException ex) { System.err.println("Hiba a példányosítás során!"); }catch(IllegalAccessException ex) { System.err.println("Hozáférésre nem jogosult!"); } } public void tryCheckMysqlDriver() throws ClassNotFoundException, InstantiationException, IllegalAccessException { Class.forName("org.gjt.mm.mysql.Driver").newInstance(); } public Connection connect() { Connection conn = null; try { conn = tryConnect(); } catch (SQLException ex) { System.err.println("Hiba az adatbázishoz kapcsolódás során!"); } return conn; } public Connection tryConnect() throws SQLException { checkMysqlDriver(); String url = "jdbc:mysql://" + host + ":" + port + "/" + database; System.out.println(url + " " + user + " " + pass); Connection conn = DriverManager.getConnection(url, user, pass); //DriverManager.setLogWriter(new PrintWriter(System.err)); return conn; } public void close(Connection conn) { try { tryClose(conn); } catch (SQLException ex) { System.err.println("Hiba az adatbázis bezárása során!"); } } public void tryClose(Connection conn) throws SQLException { conn.close(); } public ResultSet query(Connection conn, String sql) { ResultSet rs = null; try { rs = tryQuery(conn, sql); } catch (SQLException ex) { System.err.println("Hiba a lekérdezés során"); } return rs; } public ResultSet tryQuery(Connection conn, String sql) throws SQLException { Statement stmt = conn.createStatement(); return stmt.executeQuery(sql); } public void beszur(Connection con, String sql) { try { tryBeszur(con, sql); } catch (SQLException ex) { System.err.println("Hiba az SQL végrehajtása során!"); } } public void tryBeszur(Connection con, String sql) throws SQLException { PreparedStatement ps = con.prepareStatement(sql); ps.setString(1, "Bereg József"); ps.setString(2, "Szolnok"); System.out.println(ps.toString()); ps.executeUpdate(); } } ===== Irodalom, források ===== ==== Könyv ==== * George Reese, Randy Jay Yarger, Tim King: * A MySQL kezelése és használata * O'REILLY ==== MySQL ==== * http://docs.oracle.com/javase/tutorial/jdbc/ (2018) * http://www.wbluhm.com/MySQLTut.html (2018) * http://www.kitebird.com/articles/jdbc.html (2018) * http://dev.mysql.com/doc/refman/5.0/en/connector-j-reference-using-ssl.html (Kapcsolódás SSL-en keresztül) (2018) * http://zetcode.com/db/mysqljava/ (2018) * http://mrbool.com/how-to-connect-with-mysql-database-using-java/25440 (2018) * http://www.vogella.com/tutorials/MySQLJava/article.html (2018) * https://community.oracle.com/thread/1293816?start=0&tstart=0 (2018) * http://www.codejava.net/java-se/jdbc/connect-to-mysql-database-via-jdbc (2018) * http://tutorials.jenkov.com/jdbc/ (2018) ==== MariaDB ==== * https://docs.jelastic.com/connection-to-mariadb (2018) * https://github.com/MariaDB/mariadb-connector-j (2018) * https://mariadb.com/kb/en/library/about-mariadb-connector-j/ (2018) ==== SQLite ==== * http://www.sqlitetutorial.net/sqlite-java/sqlite-jdbc-driver/ (2018) * http://www.sqlitetutorial.net/sqlite-java/ * https://github.com/xerial/sqlite-jdbc ==== MSSQL ==== * https://docs.microsoft.com/en-us/sql/connect/jdbc/microsoft-jdbc-driver-for-sql-server?view=sql-server-2017