JDBC

JDBC本质

  • 官方(sun公司)定义的一套操作所有关系型数据库的规则,即接口
  • 各个数据库厂商去实现这套接口,提供数据库驱动jar包
  • 我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类

JDBC使用

六个步骤

  • 注册驱动(可省略)
  • 获取连接
  • 获取操作对象
  • 执行sql
  • 处理查询操作集
  • 关闭资源

详细例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class JDBC {
public static void main(String[] args) throws Exception {
// 1.注册驱动
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
// 2.获取连接
Connection conn = DriverManager.getConnection("jdbc:mysql:///jdbc", "root", "88888888");
// 3.获取操作对象
Statement stat = conn.createStatement();
// 4.执行sql
String sql = "select * from tb_user";
ResultSet re = stat.executeQuery(sql);
// 5.处理查询集
while(re.next()){
Integer id = re.getInt(1);
String name = re.getString(2);
System.out.println(id + ":" + name);
}
// 6.释放资源
re.close();
stat.close();
conn.close();
}
}

详解

1 注册驱动

注册驱动主要有两种方式

  • 方法1
1
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
  • 方法2

通过反射进行注册,这也是现在常用的方式

1
Class.forName("com.mysql.jdbc.Driver");

2 获取连接

1
Connection conn = DriverManager.getConnection("jdbc:mysql:///jdbc", "root", "88888888");

调用DriverManager的getConnection方法,其参数为:

  • url:数据库链接
  • username:数据库用户名
  • password:数据库密码

3 获取操作对象

Statement不能防止sql注入,所以很少使用。

1
Statement stat = conn.createStatement();

4 执行sql语句

1
2
String sql = "select * from tb_user";
ResultSet re = stat.executeQuery(sql);

Statement下有两个方法:

  • int executeUpdate(String sql):

    该方法用于执行DML语句,即增删改。返回的值为被影响的行数。

  • ResultSet executeQuery(String sql):

    该方法用于执行DQL语句,即查询语句。返回了ResultSet。

5 处理查询集

当我们执行的语句是DQL语句时,就会返回一个ResultSet。在这其中就包含了我们查询的数据。

从ResultSet中获取数据

1
2
3
4
5
6
ResultSet re = stat.executeQuery(sql);
while(re.next()){
Integer id = re.getInt(1);
String name = re.getString(2);
System.out.println(id + ":" + name);
}
  • boolean next()方法:

    返回下一存储位置是否有数据。有就返回true,没有就返回false。

  • int getInt(String str),int getInt (int i):

    返回对应数据库中表对应列或字段的数据。str就是字段名。i就是字段顺序,从1开始。

    如果获取的是String数据类型。则为String getString(String str),String getString(int i)。以此类推。

6 释放资源

如果执行了DQL语句,那么就要释放ResultSet。

1
2
3
re.close;
statm.close;
conn.close;

PreparedStatement

通过Statement对象执行sql语句时,可能会存在sql注入问题,会存在一定的安全隐患。所以后来产生了PreparedStatement对象,可以有效的解决sql注入问题。

1 获取方式

与Statement一样,但是在获取时,就得写入sql语句。并且使用占位符” ? “。

1
2
String sql = "select * from tb_user where id = ? and name = ?";
PreparedStatement preparedStatement = connection.prepareStatement(sql);

2 注入数据

sql语句是不完整的,需要用数据去替换掉对应的” ? “。

PreparedStatement提供了相应的方法:

void setInt(int i,int x):

  • i是第几个占位符。
  • x是注入的数据。

如果需注入String类型数据,则为void setString(int i,String str)。以此类推。

3 执行sql

  • DML语句

    1
    void executeUpdate();
  • DQL语句

    1
    ResoultSet executeQuery();

以上两个方法都不需要任何参数。

4 与Statement对比

  1. Statement存在Sql注入问题,preparedStatement解决了Sql注入问题
  2. Statement是编译一次执行一次,preparedStatement是编译一次,可以执行多次。preparedStatement执行效率更高
  3. preparedStatement会在编译阶段做类型的安全检查

事务管理

事务对应的方法全在Connection中。

  1. 开启事务。

    在JDBC中,事务是默认开启的,但是是自动提交。我们可以通过

    1
    void setAutoCommit(Boolean b)

    关闭其自动提交。

    • ture:开启自动提交(默认)
    • false:关闭自动提交
  2. 提交事务

    1
    void commit()
  3. 回滚事务

    1
    viod rollbac()

下面是一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import com.mysql.jdbc.Driver;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

public class JDBC {
public static void main(String[] args) throws SQLException {
DriverManager.registerDriver(new Driver());
Connection conn = null;
Statement state = null;
try {
conn = DriverManager.getConnection("jdbc:mysql:///jdbc", "root", "88888888");
// 关闭自动提交
conn.setAutoCommit(false);
state = conn.createStatement();
String sql1 = "update tb_user set money = 1000 where id = 1";
String sql2 = "update tb_user set money = 1000 where id = 2";
state.executeUpdate(sql1);
state.executeUpdate(sql2);
// 一切正常,提交事务
conn.commit();
} catch (Exception e) {
// 出现异常,回滚事务
conn.rollback();
e.printStackTrace();
} finally {
// 无论提交与否,最后都需要是释放资源
state.close();
conn.close();
}
}
}

如果有什么,可以通过下面的邮箱和我联系!!!

img