目录
Statement 与 PreparedStatement:执行SQL
以Mysql为例,连接本地数据库
基本过程
1.在项目中导入相关的jar包或相关依赖,即mysql-connector的jar包
IDEA导入jar包的方法为:
File->Project Structure->Modules->Dependencies->点击右侧加号->1.Jars or directories
如果使用Maven创建工程则在pom.xml中导入依赖
<dependencies>
<dependency><!--导入mysql依赖-->
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.25</version>
</dependency>
</dependencies>
2.注册JDBC驱动程序,即向内存中导入JDBC
Class.forName("com.mysql.jdbc.Driver");
3.建立连接,调用DriverManager.getConnection()方法
DriverManager.getConnection()方法返回一个Connection对象,参数为数据库url地址,用户名和密码
如:
Connection coon=DriverManager.getConnection("jdbc:mysql://localhost/lsl","root","123456");
4.建立数据库操作,通过Connection对象的createStatement()方法返回一个可以操控数据对象的Statement对象
如:
Statement stmt=coon.createStatement();
当然还可以返回其它对象:
Statement:使用静态SQL语句;
CallableStatement:访问存储过程时使用
PreparedStatement:计划多次使用SQL语句时
5.执行SQL,通过上一步创建的数据操作对象调用其方法执行SQL语句,返回的结果存入ResultSet对象中
如:
ResultSet rs=stmt.executeQuery("select * from test");
6.通过调用ResultSet对象查看数据
上述创建的对象必须在使用完时调用close方法关闭
示例:
import java.sql.*;
public class Main {
public static void main(String[] args) {
try{
Class.forName("com.mysql.jdbc.Driver");//将驱动程序加载到内存
Connection coon=DriverManager.getConnection("jdbc:mysql://localhost/lsl","root","123456");//建立连接
Statement stmt=coon.createStatement();//返回数据操作对象
ResultSet rs=stmt.executeQuery("select * from test");//返回结果集
while(rs.next()){
System.out.println(rs.getInt("id"));
}
coon.close();
stmt.close();
rs.close();
}catch (ClassNotFoundException e){
e.printStackTrace();
}catch (SQLException se){
se.printStackTrace();
}
}
}
Statement 与 PreparedStatement:执行SQL
Statement:执行静态SQL
boolean execute(String SQL) | 如果 ResultSet 对象可以被检索返回布尔值 true,否则返回 false。使用这个方法来执行 SQL DDL 语句,判断SQL是否允许被执行 |
int executeUpdate(String SQL) | 用于执行 INSERT、UPDATE 或 DELETE 语句以及 SQLDDL(数据定义语言)语句。返回值是一个整数,指示受影响的行数(即更新计数) |
ResultSet executeQuery(String SQL) | 返回 ResultSet 对象。用于产生单个结果集的语句,例如 SELECT 语句 |
PreparedStatement 接口扩展了 Statement 接口,有利于高效地执行多次使用的 SQL 语句,执行动态SQL
在JDBC中所有的参数都被代表?符号,这是已知的参数标记。在执行SQL语句之前,必须提供值的每一个参数。
所有的?都有一个preparedIndex,依次为1,2,3.......而?的具体值需要通过外部绑定
例:
Connection conn = DriverManager.getConnection(DB_URL,USER,PASS);//连接对象
String sql = "UPDATE Students set age=? WHERE id=?";//这里我们要更改一个同学的年龄,参数待定
PreparedStatement stmt = conn.prepareStatement(sql);//绑定sql,获取PreparedStatement 对象
//将值绑定到参数,参数从左至右序号为1,2...
stmt.setInt(1, 22); // 绑定 age 的值,PreparedIndex为1,即第一个?绑定age的值为22
stmt.setInt(2, 1); // 绑定 ID 的值,PreparedIndex为2,即第二个?绑定id的值为1
int rows = stmt.executeUpdate();//执行sql
ResultSet:结果集
结果集通常是通过执行查询数据库的语句生成,表示数据库查询结果的数据表。
ResultSet 对象具有指向其当前数据行的光标。最初,光标被置于第一行之前。next 方法将光标移动到下一行;因为该方法在 ResultSet 对象没有下一行时返回 false,所以可以在 while 循环中使用它来迭代结果集。
光标可以方便我们对结果集进行遍历。默认的 ResultSet 对象不可更新,仅有一个向前移动的光标。因此,只能迭代它一次,并且只能按从第一行到最后一行的顺序进行。
结果集用来承接获取到的数据,可以指定通过创建数据操作对象(Statement/PreparedStatement等)时指定结果集的类型和方式
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:
类型 | 描述 |
---|---|
ResultSet.TYPE_FORWARD_ONLY | 游标只能向前移动的结果集 |
ResultSet.TYPE_SCROLL_INSENSITIVE | 游标可以向前和向后滚动,但不及时更新,就是如果数据库里的数据修改过,并不在ResultSet中反应出来 |
ResultSet.TYPE_SCROLL_SENSITIVE | 游标可以向前和向后滚动,并及时跟踪数据库的更新,以便更改ResultSet中的数据 |
并发性的ResultSet,即指定RSConcurrency,如果不指定任何并发类型,将自动获得一个为 CONCUR_READ_ONLY
并发 | 描述 |
---|---|
ResultSet.CONCUR_READ_ONLY | 创建结果集只读。这是默认的 |
ResultSet.CONCUR_UPDATABLE | 创建一个可更新的结果集 |
例:
Statement stmt = conn.createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
导航方法是用于移动光标的(光标指示元组的位置)。
方法 | 说明 |
---|---|
public void beforeFirst() throws SQLException | 将光标移动到正好位于第一行之前 |
public void afterLast() throws SQLException | 将光标移动到刚刚结束的最后一行 |
public boolean first() throws SQLException | 将光标移动到第一行 |
public void last() throws SQLException | 将光标移动到最后一行 |
public boolean absolute(int row) throws SQLException | 将光标移动到指定的行 |
public boolean relative(int row) throws SQLException | 从它目前所指向向前或向后移动光标行的给定数量 |
public boolean previous() throws SQLException | 将光标移动到上一行。上一行关闭的结果集此方法返回false |
public boolean next() throws SQLException | 将光标移动到下一行。如果没有更多的行结果集中的此方法返回false |
public int getRow() throws SQLException | 返回的行号,该光标指向的行 |
public void moveToInsertRow() throws SQLException | 将光标移动到一个特殊的行,可以用来插入新行插入到数据库中的结果集。当前光标位置被记住 |
public void moveToCurrentRow() throws SQLException | 移动光标返回到当前行,如果光标在当前插入行,否则,这个方法不执行任何操作 |
ResultSet接口中有各种get 方法来查看结果集。
可以更新结果集,也可以在更新结果集后更新数据库
方法 | 说明 |
---|---|
public void updateString(int columnIndex, String s) throws SQLException | 指定列中的字符串更改为s的值 |
public void updateString(String columnName, String s) throws SQLException | 类似于前面的方法,不同之处在于由它的名称,而不是它的索引指定的 |
public void updateRow() | 通过更新数据库中相应的行更新当前行 |
public void deleteRow() | 从数据库中删除当前行 |
public void refreshRow() | 刷新在结果集的数据,以反映最新变化在数据库中 |
public void cancelRowUpdates() | 取消所做的当前行的任何更新 |
public void insertRow() | 插入一行到数据库中。当光标指向插入行此方法只能被调用 |
数据类型/事务/批处理/异常
数据类型转换:
java中的数据类型和sql中的数据类型并不一样,转换通过映射完成,例如时期和时间类型在java.sql中都有相应的类Date/Time等
事务:
JDBC中的每条SQL语句都是自动执行提交的,要使用事务方式需要调用Connection对象的setAutoCommit()方法,传参为false即关闭自动提交
之后通过Connection对象的commit()方法和roolback()方法提交或回滚事务
批处理:
一次向数据库提交多次sql的方式
- 使用createStatement()方法创建一个Statement对象
- 设置使用自动提交为 false
- 添加任意多个SQL 语句到批量处理,使用addBatch()方法
- 使用executeBatch()方法,将返回一个整数数组,数组中的每个元素代表了各自的更新语句的更新计数
- 最后,提交使用commit()方法的所有更改
异常:
JDBC 的异常处理非常类似于Java Exception处理。JDBC 最常见的异常处理的是 java.sql.SQLException.
方法 | 描述 |
---|---|
getErrorCode() | 获取此 SQLException 对象的特定于供应商的异常代码 |
getNextException() | 通过 setNextException(SQLException ex) 获取链接到此 SQLException 对象的异常 |
getSQLState() | 获取此 SQLException 对象的 SQLState。对于 JDBC 驱动程序的错误,没有有用的信息从该方法返回。对于一个数据库错误,则返回五位 XOPEN SQLSTATE 代码。这种方法可以返回 null |
iterator() | 返回在链接的 SQLExceptions 上进行迭代的迭代器 |
setNextException(SQLException ex) | 将 SQLException 对象添加到链接的末尾 |