JDBC
由来与描述
- 没有JDBC前
开发者想操作数据库,必须需要了解每个数据库对应的数据库驱动程序API,由于每个数据库驱动程序的API都不同,所以当需要迁移数据库时,根本不平滑,需要大量修改与重写
- 有了JDBC后
Sum公司也知道问题之后,就提出一种约束 —— JDBC规范,让所有数据库厂商都按照这个JDBC规范来开发数据库驱动程序,以便于Java程序能用统一方式操作不同的数据库,数据库迁移变成可行
- JDBC描述
JDBC是一种Java web的规范,需要具体开发者(数据库厂商)来实现
JDBC
常用四大API
- DriverManager
作用:
1、注册驱动
Class.forName("com.jdbc.mysql.Driver");
2、获取连接
Connection conn = DriverManager.getConnection();
- Connection
作用:
1、创建执行SQL语句的对象(3种)
Statement createStatement() // 执行SQL语句
PreparedStatement prepareStatement() // 预编译SQL并执行
CallableStatement prepareCall() // 执行SQL存储过程
2、进行事务管理
setAutoCommit(boolean b)
commit()
rollback()
- Statement
作用:
1、执行SQL语句
boolean execute(String sql) // 执行SQL语句,执行select就返回true,否则返回false
ResultSet executeQuery(String sql) // 执行SQL中的select语句
int executeUpdate(String sql) // 执行SQL中的insert/update/delete语句
2、执行批量SQL语句
addBatch(String sql) // 添加到批量处理
executeBatch() // 执行批量处理
clearBatch() // 清空批量处理
- ResultSet
(select语句)查询结果的集合
作用:获取到查询的结果
next() //判断是否有下一条数据
getXXX() //根据数据类型获取查询记录的数据
getObject() //通用获取数据方法
JDBC资源释放
释放原则:
晚创建,早释放
;资源稀有,不释放很快会阻塞
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb","root","root");
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("select * from user");
rs.close();
stmt.close();
conn.close();
JDBC CURD操作
- 增加
Connection conn = null;
Statement stmt = null;
try{
// 注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 获得连接
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/myDB","root","root");
// 获取执行SQL语句对象
stmt = conn.createStatement();
// 编写SQL
String sql = "insert into user values ("xiaomin","女人",12)";
// 执行SQL语句
int i = stmt.executeUpdate(sql);
if(i > 0){
System.out.println("插入成功!");
}
}catch(Exception e){
e.printStackTrace();
}finally{
if(stmt != null){
try{
stmt .close();
}catch(SQLException e){
e.printStackTrace();
}finally{
stmt = null;
}
}
if(conn != null){
try{
conn.close();
}catch(SQLException e){
e.printStackTrace();
}finally{
conn = null;
}
}
}
- 更新
Connection conn = null;
Statement stmt = null;
try{
// 注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 获得连接
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/myDB","root","root");
// 获取执行SQL语句对象
stmt = conn.createStatement();
// 编写SQL
String sql = "update user set name = 'wt'";
// 执行SQL语句
int i = stmt.executeUpdate(sql);
if(i > 0){
System.out.println("更新成功!");
}
}catch(Exception e){
e.printStackTrace();
}finally{
if(stmt != null){
try{
stmt .close();
}catch(SQLException e){
e.printStackTrace();
}finally{
stmt = null;
}
}
if(conn != null){
try{
conn.close();
}catch(SQLException e){
e.printStackTrace();
}finally{
conn = null;
}
}
}
- 删除
Connection conn = null;
Statement stmt = null;
try{
// 注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 获得连接
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/myDB","root","root");
// 获取执行SQL语句对象
stmt = conn.createStatement();
// 编写SQL
String sql = "delete from user where id = 3";
// 执行SQL语句
int i = stmt.executeUpdate(sql);
if(i > 0){
System.out.println("删除成功!");
}
}catch(Exception e){
e.printStackTrace();
}finally{
if(stmt != null){
try{
stmt .close();
}catch(SQLException e){
e.printStackTrace();
}finally{
stmt = null;
}
}
if(conn != null){
try{
conn.close();
}catch(SQLException e){
e.printStackTrace();
}finally{
conn = null;
}
}
}
- 查询
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try{
// 注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 获得连接
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/myDB","root","root");
// 获取执行SQL语句对象
stmt = conn.createStatement();
// 编写SQL
String sql = "select * from user";
// 执行SQL语句
rs = stmt.executeQuery(sql);
if(rs.next()){
System.out.print(rs.getString("name"));
}
}catch(Exception e){
e.printStackTrace();
}finally{
if(rs != null){
try{
rs .close();
}catch(SQLException e){
e.printStackTrace();
}finally{
rs = null;
}
}
if(stmt != null){
try{
stmt .close();
}catch(SQLException e){
e.printStackTrace();
}finally{
stmt = null;
}
}
if(conn != null){
try{
conn.close();
}catch(SQLException e){
e.printStackTrace();
}finally{
conn = null;
}
}
}
JDBC SQL注入解决方案
开发时,使用
PreparedStatement对象
取代Statement对象
来执行SQL,
有效避免SQL注入
- 增加
Connection conn = null;
PreparedStatement pstmt = null;
try{
// 注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 获得连接
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/myDB","root","root");
// 编写SQL
String sql = "insert into user values (?,?,?)";
// 获取执行SQL语句对象
pstmt = conn.preparedStatement(sql);
// 设置参数
pstmt.setString(1, "qqq");
pstmt.setString(2, "bbb");
pstmt.setString(3, "ccc");
// 执行SQL语句
int i = pstmt.executeUpdate();
if(i > 0){
System.out.println("插入成功!");
}
}catch(Exception e){
e.printStackTrace();
}finally{
if(pstmt != null){
try{
pstmt.close();
}catch(SQLException e){
e.printStackTrace();
}finally{
pstmt = null;
}
}
if(conn != null){
try{
conn.close();
}catch(SQLException e){
e.printStackTrace();
}finally{
conn = null;
}
}
}
- 更新
Connection conn = null;
PreparedStatement pstmt = null;
try{
// 注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 获得连接
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/myDB","root","root");
// 编写SQL
String sql = "update user set name = ?, age = ?, pwd = ? where id = ?";
// 获取执行SQL语句对象
pstmt = conn.preparedStatement(sql);
// 设置参数
pstmt.setString(1, "wt");
pstmt.setString(2, 15);
pstmt.setString(3, "basdcx");
pstmt.setString(4, 10);
// 执行SQL语句
int i = pstmt.executeUpdate();
if(i > 0){
System.out.println("更新成功!");
}
}catch(Exception e){
e.printStackTrace();
}finally{
if(pstmt != null){
try{
pstmt.close();
}catch(SQLException e){
e.printStackTrace();
}finally{
pstmt = null;
}
}
if(conn != null){
try{
conn.close();
}catch(SQLException e){
e.printStackTrace();
}finally{
conn = null;
}
}
}
- 删除
Connection conn = null;
PreparedStatement pstmt = null;
try{
// 注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 获得连接
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/myDB","root","root");
// 编写SQL
String sql = "delete from user where id = ?";
// 获取执行SQL语句对象
pstmt = conn.preparedStatement(sql);
// 设置参数
pstmt.setString(1, 16);
// 执行SQL语句
int i = pstmt.executeUpdate();
if(i > 0){
System.out.println("删除成功!");
}
}catch(Exception e){
e.printStackTrace();
}finally{
if(pstmt != null){
try{
pstmt.close();
}catch(SQLException e){
e.printStackTrace();
}finally{
pstmt = null;
}
}
if(conn != null){
try{
conn.close();
}catch(SQLException e){
e.printStackTrace();
}finally{
conn = null;
}
}
}
- 查询
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try{
// 注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 获得连接
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/myDB","root","root");
// 编写SQL
String sql = "select * from user where sex = ?";
// 获取执行SQL语句对象
pstmt = conn.preparedStatement(sql);
// 设置参数
pstmt.setString(1, '男');
// 执行SQL语句
rs = pstmt.executeQuery();
while(rs.next()){
System.out.println(rs.getString("name"));
}
}catch(Exception e){
e.printStackTrace();
}finally{
if(rs != null){
try{
rs.close();
}catch(SQLException e){
e.printStackTrace();
}finally{
rs = null;
}
}
if(pstmt != null){
try{
pstmt.close();
}catch(SQLException e){
e.printStackTrace();
}finally{
pstmt = null;
}
}
if(conn != null){
try{
conn.close();
}catch(SQLException e){
e.printStackTrace();
}finally{
conn = null;
}
}
}
连接池(数据源)JDBC优化技术
数据库连接频繁创建与消耗,在资源使用上是一种浪费
- 常用连接池
C3P0、HikariCP、Druid、Tomcat、Dbcp
- 用法(以C3P0为例)
ComboPooledDataSource dataSource = new ComboPooledDataSource(); // 只需一个对象
// 获取连接
Connection conn = dataSource.getConnection();