知识点
- Statement、PreparedStatement和CallableStatement都是接口(interface)。
- Statement继承自Wrapper、PreparedStatement继承自Statement、CallableStatement继承自PreparedStatement。
- Statement接口提供了执行语句和获取结果的基本方法;
PreparedStatement接口添加了处理 IN 参数的方法;
CallableStatement接口添加了处理 OUT 参数的方法
a.Statement:
普通的不带参的查询SQL;支持批量更新,批量删除;
b.PreparedStatement:
可变参数的SQL,编译一次,执行多次,效率高;
安全性好,有效防止Sql注入等问题;
支持批量更新,批量删除;
c.CallableStatement:
继承自PreparedStatement,支持带参数的SQL操作;
支持调用存储过程,提供了对输出和输入/输出参数(INOUT)的支持;
Statement每次执行sql语句,数据库都要执行sql语句的编译 ,
最好用于仅执行一次查询并返回结果的情形,效率高于PreparedStatement。
PreparedStatement是预编译的,使用PreparedStatement有几个好处
- 在执行可变参数的一条SQL时,PreparedStatement比Statement的效率高,因为DBMS预编译一条SQL当然会比多次编译一条SQL的效率要高。
- 安全性好,有效防止Sql注入等问题。
- 对于多次重复执行的语句,使用PreparedStament效率会更高一点,并且在这种情况下也比较适合使用batch;
- 代码的可读性和可维护性。
Jdbc工具类
public class JdbcUtil {
static {
try {
// 驱动防二次注册
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
// Class.forName("com.mysql.jdbc.Driver");
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取connection
*
* @return
*
* @throws SQLException
*/
public static Connection getConnection() throws SQLException {
String url = "jdbc:mysql://localhost:3306/test";
String user = "root";
String password = "123456";
// 4.获取结果
return DriverManager.getConnection(url, user, password);
}
/**
* 释放资源
*
* @param connection
* @param statement
* @param resultSet
*/
public static void release(Connection connection, Statement statement, ResultSet resultSet) {
closeResultSet(resultSet);
closeStatement(statement);
closeConnection(connection);
}
/**
* 释放结果集资源
*
* @param resultSet
*/
private static void closeResultSet(ResultSet resultSet) {
try {
if (resultSet != null) {
resultSet.close();
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
resultSet = null;
}
}
/**
* 释放statement资源
*
* @param statement
*/
private static void closeStatement(Statement statement) {
try {
if (statement != null) {
statement.close();
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
statement = null;
}
}
/**
* 释放数据库连接资源
*
* @param connection
*/
private static void closeConnection(Connection connection) {
try {
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
connection = null;
}
}
}
测试
public class JdbcDemo {
@Test
public void test01() {
// Statement执行 ,其实是拼接sql语句的,然后在一起执行
Connection connection = null;
Statement statement = null;
try {
connection = JdbcUtil.getConnection();
statement = connection.createStatement();
int count = statement.executeUpdate("select id, name from t_test");
System.err.println("select=" + count);
count = statement.executeUpdate("insert t_test values(123, '名字')");
System.err.println("insert=" + count);
count = statement.executeUpdate("delete from t_test where id = '123' ");
System.err.println("delete=" + count);
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtil.release(connection, statement, null);
}
}
@Test
public void test02() {
// PreparedStatement
Connection connection = null;
PreparedStatement ps = null;
ResultSet resultSet = null;
try {
// 先定义sql语句
String sql = "select * from t_user where username=? and password=?";
connection = JdbcUtil.getConnection();
ps = connection.prepareStatement(sql);
// 占位符 从 1 开始
ps.setString(1, "zhaowu");
ps.setString(2, "123");
// ps.setInt();
resultSet = ps.executeQuery();
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtil.release(connection, ps, resultSet);
}
}
@Test
public void test03() {
// CallableStatement
// create procedure getNameById
// (in in_id int, out return_name varchar(2))
// select name from t_user where id=in_id
Connection connection = null;
CallableStatement cstmt = null;
try {
connection = JdbcUtil.getConnection();
cstmt = connection.prepareCall("{call getNameById(?,?)}");
// 给第一个问号赋值 123
cstmt.setInt(1, 123);
// 给第二个问号变量注册,输出为Char类型
cstmt.registerOutParameter(2, Types.CHAR);
cstmt.execute();
String name = cstmt.getString(1);
System.out.println("name:" + name);
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtil.release(connection, cstmt, null);
}
}
}