JDBC 介紹

JDBC 是 Java 语言连接数据库,本质是 sun 公司制定的一个接口


1
2
3
为什么SUN需要制定一套JDBC接口?
因为每一个数据库的底层实现原理都不一样。Oracle数据库有自己的原理,MySQL数据库也有自己的原理,MS SqlServer数据库也有自己的原理…
每一个数据库产品都有自己独特的实现原理,如果没有这套接口就需要写多套java程序。

alt text

使用

  • 第一步:注册驱动 作用:告诉 Java 程序,即将要连接的是哪个品牌的数据库
  • 第二步:获取连接 表示 JVM 的进程和数据库进程之间的通道打开了,这属于进程之间的通信使用完之后一定要关闭通道
  • 第三步:获取数据库操作对象 专门执行 sql 语句的对象
  • 第四步:执行 SQL 语句 DQL DML…
  • 第五步:处理查询结果集 只有当第四步执行的是 select 语句的时候,才有这第五步处理查询结果集
  • 第六步:释放资源 使用完资源之后一定要关闭资源。Java 和数据库属于进程间的通信,开启之后一定要关闭

重要的接口和类

DriverManager 类(驱动管理类)

全是静态方法,我们用它来注册驱动

  • registerDriver(Driver driver):向 DriverManager 注册驱动程序
  • getConnection(String url, String user, String password):建立到给定数据库 URL 的连接

Statement(执行 sql)

用于执行静态 SQL 语句并返回它所生成结果的对象

  • executeUpdate(String sql):执行更新语句,该语句可能为 INSERT、UPDATE 或 DELETE 语句,返回值是“影响数据库中的记录条数”
  • executeQuery(String sql):执行 SQL 查询语句,该语句返回单个 ResultSet 对象

ResultSet 接口(查询结果集)

sql 查询语句后可以将结果封装到 ResultSet 中

  • next():将光标从当前位置向前移一行。ResultSet 光标最初位于第一行之前;第一次调用 next 方法使第一行成为当前行;第二次调用使第二行成为当前行,依此类推(用来查询结果)
  • getString(int columnIndex):不管数据库中的数据类型是什么,都以 String 的形式取出(columnIndex 是指取列数,第一列,第二列…)
  • getString(String columnLabel):不管数据库中的数据类型是什么,都以 String 的形式取出( columnLabel 指查询语句中的列名)

完整示例:

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
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class DbUtil {

public static final String URL = "jdbc:mysql://localhost:3306/imooc";
public static final String USER = "liulx";
public static final String PASSWORD = "123456";

public static void main(String[] args) throws Exception {
//1.加载驱动程序
Class.forName("com.mysql.jdbc.Driver");
//2. 获得数据库连接
Connection conn = DriverManager.getConnection(URL, USER, PASSWORD);
//3.操作数据库,实现增删改查
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT user_name, age FROM imooc_goddess");
//如果有数据,rs.next()返回true
while(rs.next()){
System.out.println(rs.getString("user_name")+" 年龄:"+rs.getInt("age"));
}
}
}

反射机制注册驱动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static void main(String[] args) {
try {
//1、注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2、获取连接
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?useSSL=false","root","root");
System.out.println(conn);

} catch (SQLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
————————————————

JDBC 事务

封装事务工具类

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import java.sql.*;

/*
JDBC工具类,简化JDBC编程
*/
public class DBUtil {

/**
* 工具类中的构造方法是私有的
* 因为工具类中的方法都是静态的,直接通过类名去调即可。
*/
private DBUtil(){}

/**
* 静态代码块,类加载的时候执行
* 把注册驱动程序的代码放在静态代码块中,避免多次获取连接对象时重复调用
*/
static {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}

public static Connection getConnection() throws SQLException {
return DriverManager.getConnection("jdbc:mysql://localhost:3306/mydatabase?useSSL=false","root","root");
}

public static void close(Connection conn, Statement ps, ResultSet rs){
if (rs != null) {
try {
rs.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (ps != null) {
try {
ps.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}

在 java 中执行 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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package ustc.java.jdbc;
import ustc.java.jdbc.DBUtil.DBUtil;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/*
行级锁/悲观锁
*/
public class JDBCTest14 {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;

try {
conn = DBUtil.getConnection();
// 开启事务
conn.setAutoCommit(false);

ps = conn.prepareStatement("select ename,job,sal from emp where job = ? for update ");
ps.setString(1,"MANAGER");

rs = ps.executeQuery();

while(rs.next()) {
System.out.println(rs.getString("ename") + "," + rs.getString("job") + "," + rs.getString("sal"));
}
// 提交事务(事务结束)
conn.commit();
} catch (SQLException throwables) {
// 回滚事务(事务结束)
try {
conn.rollback();
} catch (SQLException e) {
e.printStackTrace();
}
throwables.printStackTrace();
} finally {
DBUtil.close(conn,ps,rs);
}
}
}