Using MySQL with Java Q2 2014 David Bennett QA Engineer April 15th, 2015 Who are you? ● Java Experts, Intermediate, Beginners ● MySQL Experts, Intermediate, Beginners ● Developers, DBAs, System Admins ● Just interested 2 www.percona.com Me QA Engineer at Percona ● Designer/Developer/Consultant ● 20+ years in technology ● 15+ years working with MySQL ● 15+ years working with Java ● Focused on web apps ● Linux devotee ● I love MySQL, I like Java ● 3 Dave Bennett www.percona.com Basic Topology Java Application (Web, Service, Desktop) Java Runtime Engine (JRE) JDBC Interface JDBC Driver (Connector/J) MySQL 4 www.percona.com What is JDBC? ● A standardized interface between Java and SQL ● JDBC is to Java what ODBC is to Windows ● Virtually all Java/SQL applications use JDBC ● Like ODBC, JDBC is used more and more on Servers, Desktop use waning. 5 www.percona.com What is Connector/J? 6 ● Most widely used JDBC Driver for MySQL today ● Started life in 1998 as MM.MySQL (M. Matthews) ● Acquired by MySQL AB in 2002 ● Owned by Oracle today, available under GPLv2 ● JDBC Type 4 – 100% Java – No Middleware www.percona.com import java.sql.*; public class MysqlVersion { public static void main(String[] args) throws SQLException,ClassNotFoundException { Class.forName( "com.mysql.jdbc.Driver" ); Connection con = DriverManager.getConnection( "jdbc:mysql://localhost/test","user","pwd" ); Statement st = con.createStatement(); ResultSet rs = st.executeQuery( "SELECT concat('Hello from mysql ',version()) AS msg" ); if (rs.next()) { System.out.println(rs.getString("msg")); } rs.close(); st.close(); con.close(); } } 7 www.percona.com import java.sql.*; public class MysqlVersion { public static void main(String[] args) throws SQLException,ClassNotFoundException { Class.forName( "com.mysql.jdbc.Driver" ); Connection con = DriverManager.getConnection( "jdbc:mysql://localhost/test","user","pwd" ); Statement st = con.createStatement(); ResultSet rs = st.executeQuery( "SELECT concat('Hello from mysql ',version()) AS msg" ); if (rs.next()) { System.out.println(rs.getString("msg")); } rs.close(); st.close(); con.close(); } } 8 www.percona.com import java.sql.*; public class MysqlVersion { public static void main(String[] args) throws SQLException,ClassNotFoundException { Class.forName( "com.mysql.jdbc.Driver" ); Connection con = DriverManager.getConnection( "jdbc:mysql://localhost/test","user","pwd" ); Statement st = con.createStatement(); ResultSet rs = st.executeQuery( "SELECT concat('Hello from mysql ',version()) AS msg" ); if (rs.next()) { System.out.println(rs.getString("msg")); } rs.close(); st.close(); con.close(); } } 9 www.percona.com import java.sql.*; public class MysqlVersion { public static void main(String[] args) throws SQLException,ClassNotFoundException { Class.forName( "com.mysql.jdbc.Driver" ); Connection con = DriverManager.getConnection( "jdbc:mysql://localhost/test","user","pwd" ); Statement st = con.createStatement(); ResultSet rs = st.executeQuery( "SELECT concat('Hello from mysql ',version()) AS msg" ); if (rs.next()) { System.out.println(rs.getString("msg")); } rs.close(); st.close(); con.close(); } } 10 www.percona.com import java.sql.*; public class MysqlVersion { public static void main(String[] args) throws SQLException,ClassNotFoundException { Class.forName( "com.mysql.jdbc.Driver" ); Connection con = DriverManager.getConnection( "jdbc:mysql://localhost/test","user","pwd" ); Statement st = con.createStatement(); ResultSet rs = st.executeQuery( "SELECT concat('Hello from mysql ',version()) AS msg" ); if (rs.next()) { System.out.println(rs.getString("msg")); } rs.close(); st.close(); con.close(); } } 11 www.percona.com import java.sql.*; public class MysqlVersion { public static void main(String[] args) throws SQLException,ClassNotFoundException { Class.forName( "com.mysql.jdbc.Driver" ); Connection con = DriverManager.getConnection( "jdbc:mysql://localhost/test","user","pwd" ); Statement st = con.createStatement(); ResultSet rs = st.executeQuery( "SELECT concat('Hello from mysql ',version()) AS msg" ); if (rs.next()) { System.out.println(rs.getString("msg")); } rs.close(); st.close(); con.close(); } } 12 www.percona.com import java.sql.*; public class MysqlVersion { public static void main(String[] args) throws SQLException,ClassNotFoundException { Class.forName( "com.mysql.jdbc.Driver" ); Connection con = DriverManager.getConnection( "jdbc:mysql://localhost/test","user","pwd" ); Statement st = con.createStatement(); ResultSet rs = st.executeQuery( "SELECT concat('Hello from mysql ',version()) AS msg" ); if (rs.next()) { System.out.println(rs.getString("msg")); } rs.close(); st.close(); con.close(); } } 13 www.percona.com import java.sql.*; public class MysqlVersion { public static void main(String[] args) throws SQLException,ClassNotFoundException { Class.forName( "com.mysql.jdbc.Driver" ); Connection con = DriverManager.getConnection( "jdbc:mysql://localhost/test","user","pwd" ); Statement st = con.createStatement(); ResultSet rs = st.executeQuery( "SELECT concat('Hello from mysql ',version()) AS msg" ); if (rs.next()) { System.out.println(rs.getString("msg")); } rs.close(); st.close(); con.close(); } } 14 www.percona.com import java.sql.*; public class MysqlVersion { public static void main(String[] args) throws SQLException,ClassNotFoundException { Class.forName( "com.mysql.jdbc.Driver" ); Connection con = DriverManager.getConnection( "jdbc:mysql://localhost/test","user","pwd" ); Statement st = con.createStatement(); ResultSet rs = st.executeQuery( "SELECT concat('Hello from mysql ',version()) AS msg" ); if (rs.next()) { System.out.println(rs.getString("msg")); } rs.close(); st.close(); con.close(); } } 15 www.percona.com 16 www.percona.com 17 www.percona.com 18 www.percona.com 19 www.percona.com 20 www.percona.com 21 www.percona.com Connector/J Basic* URL jdbc:mysql://[host][:port]/[database][?prop=val[&prop=val]] Where: is: host TCP/IP host (defaults to IPV4 127.0.0.1) port TCP/IP port (defaults to 3306) database Database name (defaults to none) prop A configuration property val The configuration property's value * There are more advanced options for other protocols (IPV6, Named Pipes), replication, failover, load balancing, etc... 22 www.percona.com Connector/J URL Examples jdbc:mysql:// Connect the MySQL server at 127.0.0.1 on port 3306 without specifying a database. You must use Connection.setCatalog("{database}") or database.table reference in queries. jdbc:mysql://dbserver Connect the MySQL server dbserver on port 3306 without specifying a database. You must use Connection.setCatalog("{database}") or database.table reference in queries. jdbc:mysql://dbserver/mydb Connect the MySQL server dbserver on port 3306 using database mydb. jdbc:mysql://dbserver:3307/mydb Connect the MySQL server dbserver on port 3307 using database mydb. 23 www.percona.com Connector/J URL Examples jdbc:mysql:// Connect the MySQL server at 127.0.0.1 on port 3306 without specifying a database. You must use Connection.setCatalog("{database}") or database.table reference in queries. jdbc:mysql://dbserver Connect the MySQL server dbserver on port 3306 without specifying a database. You must use Connection.setCatalog("{database}") or database.table reference in queries. jdbc:mysql://dbserver/mydb Connect the MySQL server dbserver on port 3306 using database mydb. jdbc:mysql://dbserver:3307/mydb Connect the MySQL server dbserver on port 3307 using database mydb. 24 www.percona.com Connector/J URL Examples jdbc:mysql:// Connect the MySQL server at 127.0.0.1 on port 3306 without specifying a database. You must use Connection.setCatalog("{database}") or database.table reference in queries. jdbc:mysql://dbserver Connect the MySQL server dbserver on port 3306 without specifying a database. You must use Connection.setCatalog("{database}") or database.table reference in queries. jdbc:mysql://dbserver/mydb Connect the MySQL server dbserver on port 3306 using database mydb. jdbc:mysql://dbserver:3307/mydb Connect the MySQL server dbserver on port 3307 using database mydb. 25 www.percona.com Connector/J URL Examples jdbc:mysql:// Connect the MySQL server at 127.0.0.1 on port 3306 without specifying a database. You must use Connection.setCatalog("{database}") or database.table reference in queries. jdbc:mysql://dbserver Connect the MySQL server dbserver on port 3306 without specifying a database. You must use Connection.setCatalog("{database}") or database.table reference in queries. jdbc:mysql://dbserver/mydb Connect the MySQL server dbserver on port 3306 using database mydb. jdbc:mysql://dbserver:3307/mydb Connect the MySQL server dbserver on port 3307 using database mydb. 26 www.percona.com Connector/J URL Examples jdbc:mysql:// Connect the MySQL server at 127.0.0.1 on port 3306 without specifying a database. You must use Connection.setCatalog("{database}") or database.table reference in queries. jdbc:mysql://dbserver Connect the MySQL server dbserver on port 3306 without specifying a database. You must use Connection.setCatalog("{database}") or database.table reference in queries. jdbc:mysql://dbserver/mydb Connect the MySQL server dbserver on port 3306 using database mydb. jdbc:mysql://dbserver:3307/mydb Connect the MySQL server dbserver on port 3307 using database mydb. 27 www.percona.com Connector/J parameters Passing in JDBC URL: Connection con = DriverManager.getConnection( "jdbc:mysql://host/db?autoReconnect=true&useConfigs=maxPerformance" ); Passing in a Properties file: dbProperties.load(MyClass.class.getClassLoader() .getResourceAsStream("db.properties")); Connection con = DriverManager.getConnection("jdbc:mysql://", dbProperties); Passing from MysqlDataSource set*() methods: MysqlDataSource mds=new MysqlDataSource(); mds.setUrl("jdbc:mysql://"); mds.setUser("user"); mds.setPassword("pwd"); mds.setAutoReconnect(true); mds.setUseConfigs("maxPerformance"); Connection con=mds.getConnection(); 28 www.percona.com Connector/J parameters Passing in JDBC URL: Connection con = DriverManager.getConnection( "jdbc:mysql://host/db?autoReconnect=true&useConfigs=maxPerformance" ); Passing in a Properties file: dbProperties.load(MyClass.class.getClassLoader() .getResourceAsStream("db.properties")); Connection con = DriverManager.getConnection("jdbc:mysql://", dbProperties); Passing from MysqlDataSource set*() methods: MysqlDataSource mds=new MysqlDataSource(); mds.setUrl("jdbc:mysql://"); mds.setUser("user"); mds.setPassword("pwd"); mds.setAutoReconnect(true); mds.setUseConfigs("maxPerformance"); Connection con=mds.getConnection(); 29 www.percona.com Connector/J parameters Passing in JDBC URL: Connection con = DriverManager.getConnection( "jdbc:mysql://host/db?autoReconnect=true&useConfigs=maxPerformance" ); Passing in a Properties file: dbProperties.load(MyClass.class.getClassLoader() .getResourceAsStream("db.properties")); Connection con = DriverManager.getConnection("jdbc:mysql://", dbProperties); Passing from MysqlDataSource set*() methods: MysqlDataSource mds=new MysqlDataSource(); mds.setUrl("jdbc:mysql://"); mds.setUser("user"); mds.setPassword("pwd"); mds.setAutoReconnect(true); mds.setUseConfigs("maxPerformance"); Connection con=mds.getConnection(); 30 www.percona.com Connector/J parameters Passing in JDBC URL: Connection con = DriverManager.getConnection( "jdbc:mysql://host/db?autoReconnect=true&useConfigs=maxPerformance" ); Passing in a Properties file: dbProperties.load(MyClass.class.getClassLoader() .getResourceAsStream("db.properties")); Connection con = DriverManager.getConnection("jdbc:mysql://", dbProperties); Passing from MysqlDataSource set*() methods: MysqlDataSource mds=new MysqlDataSource(); mds.setUrl("jdbc:mysql://"); mds.setUser("user"); mds.setPassword("pwd"); mds.setAutoReconnect(true); mds.setUseConfigs("maxPerformance"); Connection con=mds.getConnection(); 31 www.percona.com Generic JDBC App Example import java.io.IOException; import java.sql.*; import java.util.Properties; public class DBHello { public static void main(String[] args) throws SQLException,ClassNotFoundException,IOException { Properties dbp = new Properties(); dbp.load(DBHello.class.getClassLoader() .getResourceAsStream("db.properties")); Class.forName(dbp.getProperty("class")); Connection con = DriverManager.getConnection(dbp.getProperty("url"), dbp); Statement st = con.createStatement(); ResultSet rs = st.executeQuery(dbp.getProperty("versionQuery")); if (rs.next()) { System.out.printf("Hello from %s\n",rs.getString("version")); } rs.close(); st.close(); con.close(); } } 32 www.percona.com Generic JDBC App Example import java.io.IOException; import java.sql.*; import java.util.Properties; public class DBHello { public static void main(String[] args) throws SQLException,ClassNotFoundException,IOException { Properties dbp = new Properties(); dbp.load(DBHello.class.getClassLoader() .getResourceAsStream("db.properties")); Class.forName(dbp.getProperty("class")); Connection con = DriverManager.getConnection(dbp.getProperty("url"), dbp); Statement st = con.createStatement(); ResultSet rs = st.executeQuery(dbp.getProperty("versionQuery")); if (rs.next()) { System.out.printf("Hello from %s\n",rs.getString("version")); } rs.close(); st.close(); con.close(); } } 33 www.percona.com Generic JDBC App Example import java.io.IOException; import java.sql.*; import java.util.Properties; public class DBHello { public static void main(String[] args) throws SQLException,ClassNotFoundException,IOException { Properties dbp = new Properties(); dbp.load(DBHello.class.getClassLoader() .getResourceAsStream("db.properties")); Class.forName(dbp.getProperty("class")); Connection con = DriverManager.getConnection(dbp.getProperty("url"), dbp); Statement st = con.createStatement(); ResultSet rs = st.executeQuery(dbp.getProperty("versionQuery")); if (rs.next()) { System.out.printf("Hello from %s\n",rs.getString("version")); } rs.close(); st.close(); con.close(); } } 34 www.percona.com Generic JDBC App Example db.properties configured for MySQL: # driver class=com.mysql.jdbc.Driver # connection url url=jdbc:mysql://localhost user=user password=pwd # parameters autoReconnect=true useConfigs=maxPerformance # version query versionQuery=SELECT CONCAT_WS(' ',@@version_comment,@@version,\ @@version_compile_os,@@version_compile_machine) AS `version` Returns: Hello from MySQL Community Server (GPL) 5.6.23-log Linux x86_64 35 www.percona.com Prepared Statements ● ● Security – Better protection from SQL injection attacks, parameters are sent separately, escaping unnecessary Performance – Prepared Statements are re-usable. Interpretation and Optimization happens only once. ● More Performance – Combined with Pooling/Caching. ● Use them whenever you can. 36 www.percona.com Let's do something useful DiskFreeChecker.java github.com/dbpercona/DiskFreeChecker 37 ● Runs as a service, records storage capacity to a table ● Runs as a report, outputs capacity growth over time ● Load JDBC configuration from a Java properties file ● PreparedStatement Query with ResultSet ● Use and Reuse of PreparedStatement ● Batch inserts using addBatch/executeBatch ● Dynamic DDL creation www.percona.com Prepared Statement Query pst=con.prepareStatement( "SELECT * FROM diskfree WHERE `hostname` = ? AND `when` = ?"); pst.setString(1, hostname); pst.setTimestamp(2, ts); rs=pst.executeQuery(); while (rs.next()) { DiskFreeEntry dfe=new DiskFreeEntry(); dfe.id = rs.getLong("id"); dfe.hostname = rs.getString("hostname"); dfe.fileSystemName = rs.getString("file_system_name"); dfe.totalSpace = rs.getLong("total_space"); dfe.spaceUsed = rs.getLong("space_used"); dfe.spaceFree = rs.getLong("space_free"); dfe.percentageUsed = rs.getBigDecimal("percentage_used"); dfe.fileSystemRoot = rs.getString("file_system_root"); dfe.when = rs.getTimestamp("file_system_root"); diskFreeEntries.put(dfe.fileSystemRoot,dfe); } rs.close(); pst.close(); 38 www.percona.com Prepared Statement Query pst=con.prepareStatement( "SELECT * FROM diskfree WHERE `hostname` = ? AND `when` = ?"); pst.setString(1, hostname); pst.setTimestamp(2, ts); rs=pst.executeQuery(); while (rs.next()) { DiskFreeEntry dfe=new DiskFreeEntry(); dfe.id = rs.getLong("id"); dfe.hostname = rs.getString("hostname"); dfe.fileSystemName = rs.getString("file_system_name"); dfe.totalSpace = rs.getLong("total_space"); dfe.spaceUsed = rs.getLong("space_used"); dfe.spaceFree = rs.getLong("space_free"); dfe.percentageUsed = rs.getBigDecimal("percentage_used"); dfe.fileSystemRoot = rs.getString("file_system_root"); dfe.when = rs.getTimestamp("file_system_root"); diskFreeEntries.put(dfe.fileSystemRoot,dfe); } rs.close(); pst.close(); 39 www.percona.com Prepared Statement Query pst=con.prepareStatement( "SELECT * FROM diskfree WHERE `hostname` = ? AND `when` = ?"); pst.setString(1, hostname); pst.setTimestamp(2, ts); rs=pst.executeQuery(); while (rs.next()) { DiskFreeEntry dfe=new DiskFreeEntry(); dfe.id = rs.getLong("id"); dfe.hostname = rs.getString("hostname"); dfe.fileSystemName = rs.getString("file_system_name"); dfe.totalSpace = rs.getLong("total_space"); dfe.spaceUsed = rs.getLong("space_used"); dfe.spaceFree = rs.getLong("space_free"); dfe.percentageUsed = rs.getBigDecimal("percentage_used"); dfe.fileSystemRoot = rs.getString("file_system_root"); dfe.when = rs.getTimestamp("file_system_root"); diskFreeEntries.put(dfe.fileSystemRoot,dfe); } rs.close(); pst.close(); 40 www.percona.com Prepared Statement Query pst=con.prepareStatement( "SELECT * FROM diskfree WHERE `hostname` = ? AND `when` = ?"); pst.setString(1, hostname); pst.setTimestamp(2, ts); rs=pst.executeQuery(); while (rs.next()) { DiskFreeEntry dfe=new DiskFreeEntry(); dfe.id = rs.getLong("id"); dfe.hostname = rs.getString("hostname"); dfe.fileSystemName = rs.getString("file_system_name"); dfe.totalSpace = rs.getLong("total_space"); dfe.spaceUsed = rs.getLong("space_used"); dfe.spaceFree = rs.getLong("space_free"); dfe.percentageUsed = rs.getBigDecimal("percentage_used"); dfe.fileSystemRoot = rs.getString("file_system_root"); dfe.when = rs.getTimestamp("file_system_root"); diskFreeEntries.put(dfe.fileSystemRoot,dfe); } rs.close(); pst.close(); 41 www.percona.com Prepared Statement Query pst=con.prepareStatement( "SELECT * FROM diskfree WHERE `hostname` = ? AND `when` = ?"); pst.setString(1, hostname); pst.setTimestamp(2, ts); rs=pst.executeQuery(); while (rs.next()) { DiskFreeEntry dfe=new DiskFreeEntry(); dfe.id = rs.getLong("id"); dfe.hostname = rs.getString("hostname"); dfe.fileSystemName = rs.getString("file_system_name"); dfe.totalSpace = rs.getLong("total_space"); dfe.spaceUsed = rs.getLong("space_used"); dfe.spaceFree = rs.getLong("space_free"); dfe.percentageUsed = rs.getBigDecimal("percentage_used"); dfe.fileSystemRoot = rs.getString("file_system_root"); dfe.when = rs.getTimestamp("file_system_root"); diskFreeEntries.put(dfe.fileSystemRoot,dfe); } rs.close(); pst.close(); 42 www.percona.com Prepared Statement Query pst=con.prepareStatement( "SELECT * FROM diskfree WHERE `hostname` = ? AND `when` = ?"); pst.setString(1, hostname); pst.setTimestamp(2, ts); rs=pst.executeQuery(); while (rs.next()) { DiskFreeEntry dfe=new DiskFreeEntry(); dfe.id = rs.getLong("id"); dfe.hostname = rs.getString("hostname"); dfe.fileSystemName = rs.getString("file_system_name"); dfe.totalSpace = rs.getLong("total_space"); dfe.spaceUsed = rs.getLong("space_used"); dfe.spaceFree = rs.getLong("space_free"); dfe.percentageUsed = rs.getBigDecimal("percentage_used"); dfe.fileSystemRoot = rs.getString("file_system_root"); dfe.when = rs.getTimestamp("file_system_root"); diskFreeEntries.put(dfe.fileSystemRoot,dfe); } rs.close(); pst.close(); 43 www.percona.com Prepared Statement Query pst=con.prepareStatement( "SELECT * FROM diskfree WHERE `hostname` = ? AND `when` = ?"); pst.setString(1, hostname); pst.setTimestamp(2, ts); rs=pst.executeQuery(); while (rs.next()) { DiskFreeEntry dfe=new DiskFreeEntry(); dfe.id = rs.getLong("id"); dfe.hostname = rs.getString("hostname"); dfe.fileSystemName = rs.getString("file_system_name"); dfe.totalSpace = rs.getLong("total_space"); dfe.spaceUsed = rs.getLong("space_used"); dfe.spaceFree = rs.getLong("space_free"); dfe.percentageUsed = rs.getBigDecimal("percentage_used"); dfe.fileSystemRoot = rs.getString("file_system_root"); dfe.when = rs.getTimestamp("file_system_root"); diskFreeEntries.put(dfe.fileSystemRoot,dfe); } rs.close(); pst.close(); 44 www.percona.com Prepared Statement Reuse pst = con.prepareStatement("SELECT MAX(`when`) FROM diskfree " + "WHERE `when` < ( NOW() - INTERVAL ? SECOND ) " + "AND `hostname` = ?"); // then pst.setBigDecimal(1, secondsBack); pst.setString(2, hostname); rs = pst.executeQuery(); if (rs.next()) { then = rs.getTimestamp(1); } rs.close(); // now pst.setInt(1, 0); rs = pst.executeQuery(); if (rs.next()) { now = rs.getTimestamp(1); } rs.close(); pst.close(); 45 www.percona.com Prepared Statement Reuse pst = con.prepareStatement("SELECT MAX(`when`) FROM diskfree " + "WHERE `when` < ( NOW() - INTERVAL ? SECOND ) " + "AND `hostname` = ?"); // then pst.setBigDecimal(1, secondsBack); pst.setString(2, hostname); rs = pst.executeQuery(); if (rs.next()) { then = rs.getTimestamp(1); } rs.close(); // now pst.setInt(1, 0); rs = pst.executeQuery(); if (rs.next()) { now = rs.getTimestamp(1); } rs.close(); pst.close(); 46 www.percona.com Prepared Statement Reuse pst = con.prepareStatement("SELECT MAX(`when`) FROM diskfree " + "WHERE `when` < ( NOW() - INTERVAL ? SECOND ) " + "AND `hostname` = ?"); // then pst.setBigDecimal(1, secondsBack); pst.setString(2, hostname); rs = pst.executeQuery(); if (rs.next()) { then = rs.getTimestamp(1); } rs.close(); // now pst.setInt(1, 0); rs = pst.executeQuery(); if (rs.next()) { now = rs.getTimestamp(1); } rs.close(); pst.close(); 47 www.percona.com Prepared Statement Reuse pst = con.prepareStatement("SELECT MAX(`when`) FROM diskfree " + "WHERE `when` < ( NOW() - INTERVAL ? SECOND ) " + "AND `hostname` = ?"); // then pst.setBigDecimal(1, secondsBack); pst.setString(2, hostname); rs = pst.executeQuery(); if (rs.next()) { then = rs.getTimestamp(1); } rs.close(); // now pst.setInt(1, 0); rs = pst.executeQuery(); if (rs.next()) { now = rs.getTimestamp(1); } rs.close(); pst.close(); 48 www.percona.com Prepared Statement Reuse pst = con.prepareStatement("SELECT MAX(`when`) FROM diskfree " + "WHERE `when` < ( NOW() - INTERVAL ? SECOND ) " + "AND `hostname` = ?"); // then pst.setBigDecimal(1, secondsBack); pst.setString(2, hostname); rs = pst.executeQuery(); if (rs.next()) { then = rs.getTimestamp(1); } rs.close(); // now pst.setInt(1, 0); rs = pst.executeQuery(); if (rs.next()) { now = rs.getTimestamp(1); } rs.close(); pst.close(); 49 www.percona.com Prepared Statement Reuse pst = con.prepareStatement("SELECT MAX(`when`) FROM diskfree " + "WHERE `when` < ( NOW() - INTERVAL ? SECOND ) " + "AND `hostname` = ?"); // then pst.setBigDecimal(1, secondsBack); pst.setString(2, hostname); rs = pst.executeQuery(); if (rs.next()) { then = rs.getTimestamp(1); } rs.close(); // now pst.setInt(1, 0); rs = pst.executeQuery(); if (rs.next()) { now = rs.getTimestamp(1); } rs.close(); pst.close(); 50 www.percona.com Prepared Statement Batches pst=con.prepareStatement( // prepare insert "INSERT INTO diskfree (`hostname`,`file_system_name`,"+ "`total_space`,`space_used`,`space_free`,`percentage_used`,"+ "`file_system_root`,`when`) VALUES (?,?,?,?,?,?,?,?)"); for (DiskFreeEntry diskFreeEntry : getDiskFreeEntries()) pst.setString ( 1, diskFreeEntry.hostname ); pst.setString ( 2, diskFreeEntry.fileSystemName ); pst.setLong ( 3, diskFreeEntry.totalSpace ); pst.setLong ( 4, diskFreeEntry.spaceUsed ); pst.setLong ( 5, diskFreeEntry.spaceFree ); pst.setBigDecimal( 6, diskFreeEntry.percentageUsed ); pst.setString ( 7, diskFreeEntry.fileSystemRoot ); pst.setTimestamp ( 8, when ); pst.addBatch(); // } int[] inserts=pst.executeBatch(); // int totalInserts=0; for (int i : inserts) totalInserts += i; // 51 { add to batch execute batch compute total www.percona.com Prepared Statement Batches pst=con.prepareStatement( // prepare insert "INSERT INTO diskfree (`hostname`,`file_system_name`,"+ "`total_space`,`space_used`,`space_free`,`percentage_used`,"+ "`file_system_root`,`when`) VALUES (?,?,?,?,?,?,?,?)"); for (DiskFreeEntry diskFreeEntry : getDiskFreeEntries()) pst.setString ( 1, diskFreeEntry.hostname ); pst.setString ( 2, diskFreeEntry.fileSystemName ); pst.setLong ( 3, diskFreeEntry.totalSpace ); pst.setLong ( 4, diskFreeEntry.spaceUsed ); pst.setLong ( 5, diskFreeEntry.spaceFree ); pst.setBigDecimal( 6, diskFreeEntry.percentageUsed ); pst.setString ( 7, diskFreeEntry.fileSystemRoot ); pst.setTimestamp ( 8, when ); pst.addBatch(); // } int[] inserts=pst.executeBatch(); // int totalInserts=0; for (int i : inserts) totalInserts += i; // 52 { add to batch execute batch compute total www.percona.com Prepared Statement Batches pst=con.prepareStatement( // prepare insert "INSERT INTO diskfree (`hostname`,`file_system_name`,"+ "`total_space`,`space_used`,`space_free`,`percentage_used`,"+ "`file_system_root`,`when`) VALUES (?,?,?,?,?,?,?,?)"); for (DiskFreeEntry diskFreeEntry : getDiskFreeEntries()) pst.setString ( 1, diskFreeEntry.hostname ); pst.setString ( 2, diskFreeEntry.fileSystemName ); pst.setLong ( 3, diskFreeEntry.totalSpace ); pst.setLong ( 4, diskFreeEntry.spaceUsed ); pst.setLong ( 5, diskFreeEntry.spaceFree ); pst.setBigDecimal( 6, diskFreeEntry.percentageUsed ); pst.setString ( 7, diskFreeEntry.fileSystemRoot ); pst.setTimestamp ( 8, when ); pst.addBatch(); // } int[] inserts=pst.executeBatch(); // int totalInserts=0; for (int i : inserts) totalInserts += i; // 53 { add to batch execute batch compute total www.percona.com Prepared Statement Batches pst=con.prepareStatement( // prepare insert "INSERT INTO diskfree (`hostname`,`file_system_name`,"+ "`total_space`,`space_used`,`space_free`,`percentage_used`,"+ "`file_system_root`,`when`) VALUES (?,?,?,?,?,?,?,?)"); for (DiskFreeEntry diskFreeEntry : getDiskFreeEntries()) pst.setString ( 1, diskFreeEntry.hostname ); pst.setString ( 2, diskFreeEntry.fileSystemName ); pst.setLong ( 3, diskFreeEntry.totalSpace ); pst.setLong ( 4, diskFreeEntry.spaceUsed ); pst.setLong ( 5, diskFreeEntry.spaceFree ); pst.setBigDecimal( 6, diskFreeEntry.percentageUsed ); pst.setString ( 7, diskFreeEntry.fileSystemRoot ); pst.setTimestamp ( 8, when ); pst.addBatch(); // } int[] inserts=pst.executeBatch(); // int totalInserts=0; for (int i : inserts) totalInserts += i; // 54 { add to batch execute batch compute total www.percona.com Prepared Statement Batches pst=con.prepareStatement( // prepare insert "INSERT INTO diskfree (`hostname`,`file_system_name`,"+ "`total_space`,`space_used`,`space_free`,`percentage_used`,"+ "`file_system_root`,`when`) VALUES (?,?,?,?,?,?,?,?)"); for (DiskFreeEntry diskFreeEntry : getDiskFreeEntries()) pst.setString ( 1, diskFreeEntry.hostname ); pst.setString ( 2, diskFreeEntry.fileSystemName ); pst.setLong ( 3, diskFreeEntry.totalSpace ); pst.setLong ( 4, diskFreeEntry.spaceUsed ); pst.setLong ( 5, diskFreeEntry.spaceFree ); pst.setBigDecimal( 6, diskFreeEntry.percentageUsed ); pst.setString ( 7, diskFreeEntry.fileSystemRoot ); pst.setTimestamp ( 8, when ); pst.addBatch(); // } int[] inserts=pst.executeBatch(); // int totalInserts=0; for (int i : inserts) totalInserts += i; // 55 { add to batch execute batch compute total www.percona.com Prepared Statement Batches pst=con.prepareStatement( // prepare insert "INSERT INTO diskfree (`hostname`,`file_system_name`,"+ "`total_space`,`space_used`,`space_free`,`percentage_used`,"+ "`file_system_root`,`when`) VALUES (?,?,?,?,?,?,?,?)"); for (DiskFreeEntry diskFreeEntry : getDiskFreeEntries()) pst.setString ( 1, diskFreeEntry.hostname ); pst.setString ( 2, diskFreeEntry.fileSystemName ); pst.setLong ( 3, diskFreeEntry.totalSpace ); pst.setLong ( 4, diskFreeEntry.spaceUsed ); pst.setLong ( 5, diskFreeEntry.spaceFree ); pst.setBigDecimal( 6, diskFreeEntry.percentageUsed ); pst.setString ( 7, diskFreeEntry.fileSystemRoot ); pst.setTimestamp ( 8, when ); pst.addBatch(); // } int[] inserts=pst.executeBatch(); // int totalInserts=0; for (int i : inserts) totalInserts += i; // 56 { add to batch execute batch compute total www.percona.com Prepared Statement Batches pst=con.prepareStatement( // prepare insert "INSERT INTO diskfree (`hostname`,`file_system_name`,"+ "`total_space`,`space_used`,`space_free`,`percentage_used`,"+ "`file_system_root`,`when`) VALUES (?,?,?,?,?,?,?,?)"); for (DiskFreeEntry diskFreeEntry : getDiskFreeEntries()) pst.setString ( 1, diskFreeEntry.hostname ); pst.setString ( 2, diskFreeEntry.fileSystemName ); pst.setLong ( 3, diskFreeEntry.totalSpace ); pst.setLong ( 4, diskFreeEntry.spaceUsed ); pst.setLong ( 5, diskFreeEntry.spaceFree ); pst.setBigDecimal( 6, diskFreeEntry.percentageUsed ); pst.setString ( 7, diskFreeEntry.fileSystemRoot ); pst.setTimestamp ( 8, when ); pst.addBatch(); // } int[] inserts=pst.executeBatch(); // int totalInserts=0; for (int i : inserts) totalInserts += i; // 57 { add to batch execute batch compute total www.percona.com Prepared Statement Writes int keepDays=30; String strKeepDays=dbp.getProperty("keep.days"); if (strKeepDays != null) keepDays = new Integer(strKeepDays).intValue(); pst = con.prepareStatement( "DELETE FROM diskfree WHERE `when` < ( NOW() - INTERVAL ? DAY)"); pst.setInt(1, keepDays); pst.execute(); int updateCount=pst.getUpdateCount(); if (updateCount > 0) System.out.println("Cleaned up "+updateCount+" old entries."); else System.out.println("No old entries to clean up."); pst.close(); 58 www.percona.com Prepared Statement Writes int keepDays=30; String strKeepDays=dbp.getProperty("keep.days"); if (strKeepDays != null) keepDays = new Integer(strKeepDays).intValue(); pst = con.prepareStatement( "DELETE FROM diskfree WHERE `when` < ( NOW() - INTERVAL ? DAY)"); pst.setInt(1, keepDays); pst.execute(); int updateCount=pst.getUpdateCount(); if (updateCount > 0) System.out.println("Cleaned up "+updateCount+" old entries."); else System.out.println("No old entries to clean up."); pst.close(); 59 www.percona.com Prepared Statement Writes int keepDays=30; String strKeepDays=dbp.getProperty("keep.days"); if (strKeepDays != null) keepDays = new Integer(strKeepDays).intValue(); pst = con.prepareStatement( "DELETE FROM diskfree WHERE `when` < ( NOW() - INTERVAL ? DAY)"); pst.setInt(1, keepDays); pst.execute(); int updateCount=pst.getUpdateCount(); if (updateCount > 0) System.out.println("Cleaned up "+updateCount+" old entries."); else System.out.println("No old entries to clean up."); pst.close(); 60 www.percona.com Prepared Statement Writes int keepDays=30; String strKeepDays=dbp.getProperty("keep.days"); if (strKeepDays != null) keepDays = new Integer(strKeepDays).intValue(); pst = con.prepareStatement( "DELETE FROM diskfree WHERE `when` < ( NOW() - INTERVAL ? DAY)"); pst.setInt(1, keepDays); pst.execute(); int updateCount=pst.getUpdateCount(); if (updateCount > 0) System.out.println("Cleaned up "+updateCount+" old entries."); else System.out.println("No old entries to clean up."); pst.close(); 61 www.percona.com Prepared Statement Writes int keepDays=30; String strKeepDays=dbp.getProperty("keep.days"); if (strKeepDays != null) keepDays = new Integer(strKeepDays).intValue(); pst = con.prepareStatement( "DELETE FROM diskfree WHERE `when` < ( NOW() - INTERVAL ? DAY)"); pst.setInt(1, keepDays); pst.execute(); int updateCount=pst.getUpdateCount(); if (updateCount > 0) System.out.println("Cleaned up "+updateCount+" old entries."); else System.out.println("No old entries to clean up."); pst.close(); 62 www.percona.com Performance parameters Parameter What it does cachePrepStmts=true If true, cache prepared statements on client side cacheCallableStmts=true If true, cache prepared stored procedure calls CacheServerConfiguration= If true, reduces connect queries by caching server configuration variables. true useLocalSessionState=true If true, reduces setup queries by using the local session state elideSetAutoCommits=true If true, only set autocommit if the server doesn't match the client autocommit setting. AlwaysSendSetIsolation= false If false, doesn't set the transaction isolation level on connect. Uses server default isolation level enableQueryTimeouts=false If false, disables query timeouts 63 www.percona.com Performance parameters useConfigs=maxPerformance 64 Parameter What it does cachePrepStmts=true If true, cache prepared statements on client side cacheCallableStmts=true If true, cache prepared stored procedure calls CacheServerConfiguration= true If true, reduces connect queries by caching server configuration variables. useLocalSessionState=true If true, reduces setup queries by using the local session state elideSetAutoCommits=true If true, only set autocommit if the server doesn't match the client autocommit setting. AlwaysSendSetIsolation= false If false, doesn't set the transaction isolation level on connect. Uses server default isolation level enableQueryTimeouts=false If false, disables query timeouts www.percona.com Debugging parameters Parameter What it does profileSQL=true If true, log query execution times to the configured logger. gatherPerfMetrics=true If true, collect performance metrics to the configured logger. useUsageAdvisor=true If true, inefficient use of JDBC and MySQL will logged to the configured logger as warnings. logSlowQueries=true If true, 'slow' queries will be logged to the configured logger (slowQueryThresholdMillis) explainSlowQueries=true If true, an 'EXPLAIN' statement for slow queries will be logged to the configured logger. 65 www.percona.com Debugging parameters useConfigs=fullDebug 66 Parameter What it does profileSQL=true If true, log query execution times to the configured logger. gatherPerfMetrics=true If true, collect performance metrics to the configured logger. useUsageAdvisor=true If true, inefficient use of JDBC and MySQL will logged to the configured logger as warnings. logSlowQueries=true If true, 'slow' queries will be logged to the configured logger (slowQueryThresholdMillis) explainSlowQueries=true If true, an 'EXPLAIN' statement for slow queries will be logged to the configured logger. www.percona.com Other Handy Parameters 67 ● autoReconnect ● characterEncoding ● useInformationSchema ● maxRows www.percona.com Alternative JDBC Driver ● 68 MariaDB Java Client Maintained-ed by MariaDB team Fork from Drizzle JDBC Stable release 1.1.8 Compatible with: ✔ MySQL ✔ Percona Server / PXC ✔ MariaDB www.percona.com Alternative JDBC Driver Pros Maybe be faster in some cases It is under active development Cons Not as feature rich Not as mature ● 69 www.percona.com What to learn about next ● Connection Pooling ● ● JNDI / Container Managed ● ● DataSource, Spring Object Relational Mapping ● 70 DBCP, C3P0, BoneCP JPA, Hibernate, Spring www.percona.com THANK YOU 71 www.percona.com www.percona.com