接口java |
应用场景mysql |
Statementsql |
当在运行时使用静态 SQL 语句时(Statement接口不能接受的参数)数据库 |
PrepareStatement | 当计划屡次使用 SQL 语句时(PreparedStatement 接口接收在运行时输入参数)数组 |
CallableStatement并发 |
当要访问数据库中的存储过程时(CallableStatement对象的接口还能够接受运行时输入参数)分布式 |
一、boolean execute(String SQL) 性能
若是 ResultSet 对象能够被检索返回布尔值 true,不然返回 false。使用这个方法来执行 SQL DDL 语句,或当须要使用真正的动态 SQLcode
二、int executeUpdate(String SQL) 对象
用于执行 INSERT、UPDATE 或 DELETE 语句以及 SQLDDL(数据定义语言)语句。返回值是一个整数,指示受影响的行数(即更新计数)
三、ResultSet executeQuery(String SQL)
返回 ResultSet 对象。用于产生单个结果集的语句,例如 SELECT 语句
PreparedStatement 接口扩展了 Statement 接口,有利于高效地执行屡次使用的 SQL 语句
import java.sql.*; public class JdbcTest { // JDBC 驱动器的名称和数据库地址 static final String JDBC_DRIVER = "com.mysql.jdbc.Driver"; static final String DB_URL = "jdbc:mysql://localhost/EXAMPLE"; static final String USER = "root"; static final String PASS = ""; public static void main(String[] args) { Connection conn = null; PreparedStatement stmt = null; try{ //注册 JDBC 驱动器 Class.forName("com.mysql.jdbc.Driver"); //打开链接 System.out.println("Connecting to database..."); conn = DriverManager.getConnection(DB_URL,USER,PASS); //执行查询 System.out.println("Creating statement..."); //这里咱们要更改一个同窗的年龄,参数待定 String sql = "UPDATE Students set age=? WHERE id=?"; stmt = conn.prepareStatement(sql); //将值绑定到参数,参数从左至右序号为1,2... stmt.setInt(1, 22); // 绑定 age 的值(序号为1) stmt.setInt(2, 1); // 绑定 ID 的值 // 更新 ID 为1的同窗的年龄 int rows = stmt.executeUpdate(); System.out.println("被影响的行数 : " + rows ); // 查询全部记录,并显示. sql = "SELECT id, name, age FROM Students"; ResultSet rs = stmt.executeQuery(sql); //处理结果集 while(rs.next()){ //检索 int id = rs.getInt("id"); int age = rs.getInt("age"); String name = rs.getString("name"); //显示 System.out.print("ID: " + id); System.out.print(", Age: " + age); System.out.print(", Name: " + name); System.out.println(); } //清理 rs.close(); stmt.close(); conn.close(); }catch(SQLException se){ se.printStackTrace(); }catch(Exception e){ e.printStackTrace(); }finally{ try{ if(stmt!=null) stmt.close(); }catch(SQLException se2){ } try{ if(conn!=null) conn.close(); }catch(SQLException se){ se.printStackTrace(); } } System.out.println("Goodbye!"); } }
CallableStatement 对象为全部的 DBMS 提供了一种以标准形式调用存储过程的方法。存储过程储存在数据库中。对储存过程的调用是 CallableStatement 对象所含的内容。三种类型的参数有:IN,OUT和INOUT。
CallableStatement cstmt = null; try { String SQL = "{call getEXAMPLEName (?, ?)}"; cstmt = conn.prepareCall (SQL); . . . } catch (SQLException e) { . . . } finally { cstmt.close(); }
结果集一般是经过执行查询数据库的语句生成,表示数据库查询结果的数据表。ResultSet 对象具备指向其当前数据行的光标。最初,光标被置于第一行以前。next 方法将光标移动到下一行;由于该方法在 ResultSet 对象没有下一行时返回 false,因此能够在 while 循环中使用它来迭代结果集。光标能够方便咱们对结果集进行遍历。默认的 ResultSet 对象不可更新,仅有一个向前移动的光标。所以,只能迭代它一次,而且只能按从第一行到最后一行的顺序进行。
ResultSet接口的方法可分为三类:
一、导航方法:用于移动光标
二、获取方法:用于查看当前行的光标所指向的列中的数据
三、更新方法:用于更新当前行的列中的数据
JDBC 提供下列链接方法来建立所需的ResultSet语句:
createStatement(int RSType, int RSConcurrency); prepareStatement(String SQL, int RSType, int RSConcurrency); prepareCall(String sql, int RSType, int RSConcurrency);
RSType 表示 ResultSet 对象的类型,RSConcurrency 是 ResultSet 常量,用于指定一个结果集是否为只读或可更新。
ResultSet 的类型,若是不指定 ResultSet 类型,将自动得到一个是 TYPE_FORWARD_ONLY。
类型(RSType) |
描述 |
ResultSet.TYPE_FORWARD_ONLY |
游标只能向前移动的结果集 |
ResultSet.TYPE_SCROLL_INSENTITIVE | 游标能够向前和向后滚动,但不及时更新,就是若是数据库里的数据修改过, 并不在ResultSet中反应出来 |
ResultSet.TYPE_SCROLL_SENTITIVE |
游标能够向前和向后滚动,并及时跟踪数据库的更新,以便更改ResultSet中的数据 |
并发(RSConcurrency) |
描述 |
ResultSet.CONCUR_READ_ONLY |
建立结果集只读。默认 |
ResultSet.CONCUR_READ_UPDATABLE |
建立一个可更新的结果集 |
好比初始化一个 Statement 对象来建立一个双向、可更新的ResultSet对象:
try { Statement stmt = conn.createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE); } catch(Exception ex) { .... } finally { .... }
ResultSet接口中如下方法涉及游标的移动:
实例代码:
import java.sql.*; public class JdbcTest { // JDBC 驱动器名称 和数据库地址 static final String JDBC_DRIVER = "com.mysql.jdbc.Driver"; //数据库的名称为 EXAMPLE static final String DB_URL = "jdbc:mysql://localhost/EXAMPLE"; // 数据库用户和密码 static final String USER = "root"; static final String PASS = ""; public static void main(String[] args) { Connection conn = null; Statement stmt = null; try{ //注册JDBC 驱动程序 Class.forName("com.mysql.jdbc.Driver"); //打开链接 System.out.println("Connecting to database..."); conn = DriverManager.getConnection(DB_URL,USER,PASS); System.out.println("Creating statement..."); //建立所需的ResultSet,双向,只读 stmt = conn.createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); String sql; sql = "SELECT id, name, age FROM Students"; ResultSet rs = stmt.executeQuery(sql); // 将光标移到最后一行 System.out.println("Moving cursor to the last..."); rs.last(); //处理结果集 System.out.println("Displaying record..."); int id = rs.getInt("id"); int age = rs.getInt("age"); String name = rs.getString("name"); //显示 System.out.print("ID: " + id); System.out.print(", Age: " + age); System.out.print(", Name: " + name); System.out.println(); // 将光标移到第一行 System.out.println("Moving cursor to the first row..."); rs.first(); System.out.println("Displaying record..."); id = rs.getInt("id"); age = rs.getInt("age"); name = rs.getString("name"); //显示 System.out.print("ID: " + id); System.out.print(", Age: " + age); System.out.print(", Name: " + name); //将光标移至下一行 System.out.println("Moving cursor to the next row..."); rs.next(); System.out.println("Displaying record..."); id = rs.getInt("id"); age = rs.getInt("age"); name = rs.getString("name"); // 显示 System.out.print("ID: " + id); System.out.print(", Age: " + age); System.out.print(", Name: " + name); rs.close(); stmt.close(); conn.close(); }catch(SQLException se){ se.printStackTrace(); }catch(Exception e){ e.printStackTrace(); }finally{ try{ if(stmt!=null) stmt.close(); }catch(SQLException se2){ } try{ if(conn!=null) conn.close(); }catch(SQLException se){ se.printStackTrace(); } } System.out.println("Goodbye!"); } }
方法 |
说明 |
public int getInt(String columnName) throws SQLException |
获取当前行中名为 ColumnName 列的值 |
public int getInt(int columnIndex) throws SQLException |
获取当前行中指定列的索引的值。列索引从1开始, 意味着一个行的第一列是1,行的第二列是2。 |
getString等方式相似。
一、更新结果集
方法 |
说明 |
public void updateString(String columnName,String s) throws SQLException |
修改当前行中名为 ColumnName 列的值为s |
public void updateString (int columnIndex,String s)) throws SQLException |
修改当前行中指定列中索引的值为s |
updateDouble()等方式相似。
二、更新数据库(在更新结果集以后)
方法 |
说明 |
public void updateRow() |
将当前行记录更新到数据库 |
public void deleteRow() |
从数据库删除当前行 |
public void refreshRow() |
用数据库中的最近值刷新当前行 |
public void cancelRowUpdates() |
取消对 ResultSet 对象中的当前行所做的更新。此方法在调用更新方法以后,但在调用 updateRow 方法以前调用才能够回滚对行所做的更新。若是没有进行任何更新或者已经调用 updateRow 方法,则此方法无效 |
public void insertRow() |
将当前行记录插入到数据库 |
代码示例:
Statement stmt = conn.createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE); String sql = "SELECT id, name, age FROM Students"; ResultSet rs = stmt.executeQuery(sql); //将光标移动到一个特殊的行,能够用来插入新行到结果集。当前光标位置被记住 rs.moveToInsertRow(); //结果集中插入新行 rs.updateInt("id",5); rs.updateString("name","John"); rs.updateInt("age",21); //将插入结果集的新行插入到数据库中 rs.insertRow(); //将光标返回到当前行(返回到moveToInsertRow() 方法中被记住的光标位置) rs.moveToCurrentRow();
默认状况下,JDBC链接是自动提交模式的,每条SQL语句执行完后自动提交到数据库。
事务是一条或者多条SQL语句做为一个逻辑单元,而且若是事务中任何语句执行失败,则整个事务失败。
本身管理和控制事务能够:
一、提升程序的运行性能
二、保持业务流程的完整性
三、采用分布式事务管理方式
事务的四大特性:(ACID)
一、原子性(Atomicity)
二、一致性(Consistency)
三、隔离性(Isolation)
四、持久性(Durability)
开启JDBC事务须要关闭自动提交:
Connection conn = null; conn = DriverManager.getConnection(URL); //关闭自动提交 conn.setAutoCommit(false); 事务的提交: conn.commit(); 事务的回滚: conn.rollBack();
代码示例:
import java.sql.*; public class JdbcTest { // JDBC 驱动器名称 和数据库地址 static final String JDBC_DRIVER = "com.mysql.jdbc.Driver"; //数据库的名称为 EXAMPLE static final String DB_URL = "jdbc:mysql://localhost/EXAMPLE"; // 数据库用户和密码 static final String USER = "root"; static final String PASS = ""; public static void main(String[] args) { Connection conn = null; Statement stmt = null; try{ //注册JDBC 驱动程序 Class.forName("com.mysql.jdbc.Driver"); //打开链接 System.out.println("Connecting to database..."); conn = DriverManager.getConnection(DB_URL,USER,PASS); conn.setAutoCommit(false); //执行查询 System.out.println("Creating statement..."); stmt = conn.createStatement(); //插入 String sql = "INSERT INTO Students " + "VALUES (5, 20, 'Rose')"; stmt.executeUpdate(sql); //查找 sql = "SELECT id, name, age FROM Students"; ResultSet rs = stmt.executeQuery(sql); //提交事务 conn.commit(); //获得和处理结果集 while(rs.next()){ //检索 int id = rs.getInt("id"); int age = rs.getInt("age"); String name = rs.getString("name"); //显示 System.out.print("ID: " + id); System.out.print(", Age: " + age); System.out.print(", Name: " + name); System.out.println(); } //清理环境 rs.close(); stmt.close(); conn.close(); }catch(SQLException se){ // JDBC 操做错误 se.printStackTrace(); // conn.rollback(); try{ if(conn!=null) conn.rollback(); }catch(SQLException se2){ se2.printStackTrace(); } }catch(Exception e){ // Class.forName 错误 e.printStackTrace(); }finally{ //这里通常用来关闭资源的 try{ if(stmt!=null) stmt.close(); }catch(SQLException se2){ } try{ if(conn!=null) conn.close(); }catch(SQLException se){ se.printStackTrace(); } } System.out.println("Goodbye!"); } }
批量处理容许将相关的SQL语句分组到批处理中,并经过对数据库的一次调用来提交它们,一次执行完成与数据库之间的交互。
不须要JDBC驱动程序来支持此功能。应该使用DatabaseMetaData.supportsBatchUpdates()方法来肯定目标数据库是否支持批量更新处理。若是JDBC驱动程序支持此功能,该方法将返回true。
一、使用createStatement()方法建立一个Statement对象
二、设置使用自动提交为 false
三、添加任意多个SQL 语句到批量处理,使用addBatch()方法
四、使用executeBatch()方法,将返回一个整数数组,数组中的每一个元素表明了各自的更新语句的更新计数
五、最后,提交使用commit()方法的全部更改
//建立 statement 对象 Statement stmt = conn.createStatement(); //关闭自动提交 conn.setAutoCommit(false); //建立 SQL 语句 String SQL = "INSERT INTO Students (id, name, age) VALUES(6,'Mike', 21)"; //将 SQL 语句添加到批处理中 stmt.addBatch(SQL); //建立更多的 SQL 语句 String SQL = "INSERT INTO Students (id, name, age) VALUES(7, 'Angle', 23)"; //将 SQL 语句添加到 批处理中 stmt.addBatch(SQL); //建立整数数组记录更新状况 int[] count = stmt.executeBatch(); //提交更改 conn.commit()
String SQL = "INSERT INTO Employees (id, name, age) VALUES(?, ?, ?)"; //建立 PrepareStatement 对象 PreparedStatemen pstmt = conn.prepareStatement(SQL); //关闭自动链接 conn.setAutoCommit(false); //绑定参数 pstmt.setInt( 1, 8 ); pstmt.setString( 2, "Cindy" ); pstmt.setInt( 3, 17 ); //添入批处理 pstmt.addBatch(); //绑定参数 pstmt.setInt( 1, 9 ); pstmt.setString( 2, "Jeff" ); pstmt.setInt( 3, 22 ); //添入批处理 pstmt.addBatch(); //建立数组记录更改 int[] count = pstmt.executeBatch(); //提交更改 conn.commit();