java JDBC
数据库URL
JDBC URL的一般语法为: jdbc:subprotocol:other stufff
其中,suprotocol 用于选择连接到数据库的具体驱动程序, other stuff 参数的格式随所使用的subprotocol的不同而不同
例如:
jdbc:derby://localhost:1527//COREJAVA;ctreate=true
jdbc:postgresql:COREJAVA // postgresql 和derby是数据库
驱动程序JAR文件:
驱动文件可以在数据库的官网下载;例如mysql的驱动程序下载地址
也可以创建MAVEN项目
在:https://dev.mysql.com/downloads/connector/ 选择对应压缩包下载
命令行连接:https://www.cnblogs.com/jiangfeilong/p/10587376.html
maven JDBC连接实例
package org.feilong.mysql; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; //import com.mysql.cj.jdbc.*; public class Url { public static final String URL = "jdbc:mysql://192.168.1.104:3306/gc"; public static final String USER = "root"; public static final String PASSWORD = "1"; public static void main(String[] args) { try { Class.forName("com.mysql.cj.jdbc.Driver"); System.out.println("register success"); } catch (ClassNotFoundException e1) { System.out.println("register fail"); e1.printStackTrace(); }//注册驱动 try(Connection conn = DriverManager.getConnection(URL, USER, PASSWORD)){//连接 Statement stmt = conn.createStatement(); //执行者 ResultSet rs = stmt.executeQuery("SELECT * FROM books"); //结果集, // while (rs.next()) { System.out.println(rs.getString("author") + " "+rs.getString(2)); } conn.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
public ResultSet executeQuery()执行select语句 返回结果在result里
public int executeUpdate()
public long executelargeUpdate()
执行Insert/update/delete/create table/drop table等 返回修改的行数
public boolean execute() 执行任何语句
ReultSet使用注意事项:
得到数据库信息
try(Connection conn = DriverManager.getConnection(URL, USER, PASSWORD)){//连接 Statement stmt = conn.createStatement(); //执行者 //Integer rs = stmt.executeUpdate("DROP DATABASE IF EXISTS mysql_test1"); DatabaseMetaData meta = conn.getMetaData(); ResultSet rs1 = meta.getCatalogs(); while(rs1.next()) System.out.println(rs1.getString(1)); conn.close();
事务处理
JDBC 事务步骤
关闭自动提交,实现多语句同一事务
connection.setAutoCommit(false);
connection.commit();提交事务
connection.rollback();回滚事务
保存点机制
connection.setSavepoint()
connection.rollback(savepoint)
public static void execute(Connection conn,String sql){ try { Statement stmt = conn.createStatement(); boolean rs = stmt.execute(sql); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void main(String[] args) { try { Class.forName("com.mysql.cj.jdbc.Driver"); System.out.println("register success"); } catch (ClassNotFoundException e1) { System.out.println("register fail"); e1.printStackTrace(); }//注册驱动 try(Connection conn = DriverManager.getConnection(URL, USER, PASSWORD)){//连接 conn.setAutoCommit(false); //关闭自动提交 execute(conn,"USE mysql_test"); // PreparedStatement pstmt = conn.prepareStatement(sql); //pstmt.setString(1,"cust_id INT NOT NULL AUTO_INCREMENT,"); String sql = "CREATE TABLE customers ( ?,?,?,?,?,?)"; execute(conn,"CREATE TABLE customers" + "(" + "cust_id INT NOT NULL AUTO_INCREMENT, " + //#INCREMENT 可以为表中的数据类型为整形的列设置自增型 "cust_name CHAR(50) NOT NULL, " + //#不允许null值的列 "cust_set CHAR(1) NOT NULL DEFAULT 0, " + //不允许null值的列且默认值是0 "cust_address CHAR(50) NULL," + "cust_contact CHAR(50) NULL," + "PRIMARY KEY(cust_id) " + //设置cust_id 为主键 ")"); Savepoint phase1 = conn.setSavepoint(); //设置一个保存点 execute(conn,"SHOW TABLES"); conn.rollback(phase1); //回到保存点 即上面2行无效 conn.commit(); //执行操作 System.out.println("success"); //DatabaseMetaData meta = conn.getMetaData(); //ResultSet rs1 = meta.getCatalogs(); //while(rs.next()) //System.out.println(rs.getString(1)); conn.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); }
安全的字符串拼接PreparedStatement
普通的字符串拼接可能会被人加入恶意代码,使用PreparedStatement可以避免
PreparedStatement采用待定系数法,使用示例
String sql = "INSERT INTO customers VALUES( ?,?,?,?,?)"; PreparedStatement pstmt = conn.prepareStatement(sql); pstmt.setInt(1,1); //替换sql里的?号 pstmt.setString(2, "feilong"); pstmt.setString(3, "1"); pstmt.setString(4, "www.feilong.com"); pstmt.setString(5, "china"); int rs = pstmt.executeUpdate(); Savepoint phase1 = conn.setSavepoint(); //设置一个保存点 execute(conn,"SHOW TABLES"); conn.rollback(phase1); //回到保存点 即上面2行无效 conn.commit(); //执行操作 System.out.println("success");
PreparedStatement有一个 Batch方法可以批量提交
try(Connection conn = DriverManager.getConnection(URL, USER, PASSWORD)){//连接 conn.setAutoCommit(false); //关闭自动提交 execute(conn,"USE mysql_test"); //pstmt.setString(1,"cust_id INT NOT NULL AUTO_INCREMENT,"); String sql = "INSERT INTO customers VALUES( ?,?,?,?,?)"; PreparedStatement pstmt = conn.prepareStatement(sql); for(int i = 2; i < 100; i++){ pstmt.setInt(1,i); //替换sql里的?号 pstmt.setString(2, "feilong"); pstmt.setString(3, "1"); pstmt.setString(4, "www.feilong.com"); pstmt.setString(5, "china"); pstmt.addBatch(); //添加到batch列表 } // int rs = pstmt.executeUpdate(); pstmt.executeBatch(); //全部提交 //pstmt.close(); Savepoint phase1 = conn.setSavepoint(); //设置一个保存点 execute(conn,"SHOW TABLES"); conn.rollback(phase1); //回到保存点 即上面2行无效 conn.commit(); //执行操作 System.out.println("success");
ResultSetMetaData
ResultSet可以用来承载所有的select语句返回的结果集
ResultSetmetaData用来获取ResultSet返回的属性(如,没一行的名字类型等)
示例:
try (Connection conn = DriverManager.getConnection(URL, USER, PASSWORD)) {// 连接 conn.setAutoCommit(false); // 关闭自动提交 execute(conn, "USE mysql_test"); Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT * FROM customers"); ResultSetMetaData meta = rs.getMetaData(); //得到元数据 int cols = meta.getColumnCount(); //得到列的数量 for(int i = 1; i <= cols; i++){ System.out.println(meta.getColumnName(i) + "," + meta.getColumnTypeName(i));; } // pstmt.close(); Savepoint phase1 = conn.setSavepoint(); // 设置一个保存点 execute(conn, "SHOW TABLES"); conn.rollback(phase1); // 回到保存点 即上面2行无效 conn.commit(); // 执行操作 System.out.println("success"); // DatabaseMetaData meta = conn.getMetaData(); // ResultSet rs1 = meta.getCatalogs(); // while(rs.next()) // System.out.println(rs.getString(1)); conn.close();
数据库连接池
享元模式
C3P0连接池
//C3p0连接池
package org.feilong.mysql; import java.sql.Connection; import com.mchange.v2.c3p0.ComboPooledDataSource; public class C3p0Factory1 { private static ComboPooledDataSource dataSource = null; public static void init() throws Exception{ dataSource = new ComboPooledDataSource(); dataSource.setDriverClass("com.mysql.cj.jdbc.Driver"); //加载驱动 dataSource.setJdbcUrl("jdbc:mysql://192.168.1.104:3306/mysql_test"); //数据库URL dataSource.setUser("root"); //设置帐号 dataSource.setPassword("1"); //设置密码 dataSource.setMinPoolSize(5); //设置初始连接数量 dataSource.setAcquireIncrement(5); //设置每次增加的数量 dataSource.setMaxPoolSize(20); //设置最大连接数量 } public static Connection getConnection() throws Exception{ if(dataSource == null){ init(); } return dataSource.getConnection(); //连接数据库 } }
Druid和加载properies连接示例
package org.feilong.mysql; import com.alibaba.druid.pool.DruidDataSourceFactory; import java.io.InputStream; import java.sql.Connection; import java.util.Properties; import com.alibaba.druid.pool.DruidDataSource; public class DruidFactory1 { private static DruidDataSource dataSource = null; public static void init() throws Exception { Properties properties = new Properties(); //Properties 配置参数文件 InputStream in = DruidFactory1.class.getClassLoader().getResourceAsStream("druid.properties"); properties.load(in); dataSource = (DruidDataSource)DruidDataSourceFactory.createDataSource(properties); in.close(); } public static Connection getConnection() throws Exception{ if( dataSource == null) { init(); } return dataSource.getConnection(); } }
package org.feilong.mysql; import java.sql.*; import javax.sql.rowset.CachedRowSet; import javax.sql.rowset.RowSetFactory; import javax.sql.rowset.RowSetProvider; public class SelectTest { public static void main(String[] args) { Connection conn = null; try { conn = DruidFactory1.getConnection(); Statement stmt = conn.createStatement(); System.out.println("create success"); ResultSet rs = stmt.executeQuery("SELECT * FROM mysql_test.customer ORDER BY cust_address"); while (rs.next()) { System.out.println(rs.getRow()+", " +rs.getString(1) + ", " + rs.getString(2)); } } catch (Exception e) { e.printStackTrace(); } finally { try { if (conn != null) conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
properties配置文件
driverClassName=com.mysql.jdbc.Driver url=jdbc:mysql://127.0.0.1:3306/test username=root password=123456 filters=stat initialSize=2 maxActive=300 maxWait=60000 timeBetweenEvictionRunsMillis=60000 minEvictableIdleTimeMillis=300000 validationQuery=SELECT 1 testWhileIdle=true testOnBorrow=false testOnReturn=false poolPreparedStatements=false maxPoolPreparedStatementPerConnectionSize=200