0%

JDBC基本操作

JDBC基本操作

1
2
3
4
create table user(
id int primary key auto_increment,
name varchar(50)
) ENGINE = InnoDB DEFAULT CHARSET = utf8;

JDBC概念

JDBC是一个独立于特定数据库管理系统、通用的SQL数据库存取和操作的公共接口,定义了用来访问数据库的标准的Java类库

连接步骤

  • 加载驱动

  • 进行数据库连接

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
// 驱动
private static final String DRIVER = "com.mysql.jdbc.Driver";
// 地址
private static final String URL = "jdbc:mysql://localhost:3306/test";
//用户名
private static final String USER_NAME = "root";
// 密码
private static final String PSW = "123456";

/**
* 获取连接
*/
public static Connection getConnection(){
Connection conn = null;
try {
// 加载驱动
Class.forName(DRIVER);
// 数据库连接
conn = DriverManager.getConnection(URL,USER_NAME,PSW);

} catch (ClassNotFoundException e) {
System.out.println("加载驱动失败,请检查是否引入Jar包或者驱动名称是否正确");
throw new RuntimeException("加载驱动失败,请检查是否引入Jar包或者驱动名称是否正确",e);
} catch (SQLException throwables) {
System.out.println("连接数据库失败,请检查数据库地址,用户名,密码是否正确");
throw new RuntimeException("连接数据库失败,请检查数据库地址,用户名,密码是否正确",throwables);
}
return conn;
}

/**
* 关闭连接
* @param conn
*/
public static void close(Connection conn){
if(conn != null){
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}

注意:为什么需要使用Class.forName()来加载数据库驱动

是因为在每个Driver中都包含有一个静态代码块,实际调用的是DriverManager.registerDriver(new Driver());方法

1
2
3
4
5
6
7
8
9
10
11
12
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
public Driver() throws SQLException {
}

static {
try {
DriverManager.registerDriver(new Driver());
} catch (SQLException var1) {
throw new RuntimeException("Can't register driver!");
}
}
}

DriverManager

该类进行数据库驱动的管理,可以注册多个数据库驱动,根据url来动态的选择不同的数据库连接。

操作数据库

Statement接口

使用Statement接口来操作静态的SQL语句

executeUpdate方法
添加
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
/**
* 插入操作
* @param sql
*/
public static void doInsert(String sql){
Connection conn = getConnection();
Statement statement = null;

try {
statement = conn.createStatement();
int result = statement.executeUpdate(sql);
System.out.println(sql+"执行成功,插入"+result+"条数据");
} catch (SQLException e) {
throw new RuntimeException("执行失败",e);
} finally {
if(statement != null){
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
close(conn);
}
}
修改
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
/**
* 修改操作
* @param sql
*/
public static void doUpdate(String sql){
Connection conn = getConnection();
Statement statement = null;

try {
statement = conn.createStatement();
int result = statement.executeUpdate(sql);
System.out.println(sql+"执行成功,修改"+result+"条数据");
} catch (SQLException e) {
throw new RuntimeException("执行失败",e);
} finally {
if(statement != null){
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
close(conn);
}
}
删除
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
/**
* 删除操作
* @param sql
*/
public static void doDelete(String sql){
Connection conn = getConnection();
Statement statement = null;

try {
statement = conn.createStatement();
int result = statement.executeUpdate(sql);
System.out.println(sql+"执行成功,删除"+result+"条数据");
} catch (SQLException e) {
throw new RuntimeException("执行失败",e);
} finally {
if(statement != null){
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
close(conn);
}

}

PreparedStatement接口

该接口为Statement的子接口,属于预处理操作,可以传入带有占位符的SQL,然后再进行补充占位符,索引值从1开始。

可以有效地禁止SQL注入

executeUpdate方法
插入
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public static void doPreparedInsert(String name){
Connection conn = getConnection();
PreparedStatement statement = null;

try {
String sql = "insert into user (name) values (?)";
statement = conn.prepareStatement(sql);
statement.setString(1,name);
int result = statement.executeUpdate();
System.out.println(sql+"执行成功,插入"+result+"条数据");
} catch (SQLException e) {
throw new RuntimeException("执行失败",e);
} finally {
if(statement != null){
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
close(conn);
}
}

在创建preparedStatement对象时,有一个重载方法

1
2
3
4
// 第二个参数表示一个是否返回自增主键的一个biaoshi
// Statement.RETURN_GENERATED_KEYS
// Statement.NO_GENERATED_KEYS
PreparedStatement prepareStatement(String sql, int autoGeneratedKeys)

在使用该PreparedStatement执行插入操作时,可以使用statement.getGeneratedKeys()来返回一个新生成主键的ResultSet对象,结果集中只有一列GENERATED_KEY,存放的新生成的主键值

更新

与插入类似

删除

与插入类似

结果集

在查询数据时,返回的是一个二维的结果集,使用ResultSet来遍历结果集

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
public static void doQuery(){
String sql = "select * from user";
Connection conn = getConnection();
PreparedStatement statement = null;
ResultSet resultSet = null;
try {
statement = conn.prepareStatement(sql);
resultSet = statement.executeQuery();
// resultSet.next 方法 将光标向前移动一行,最初为第一行之前,第一次调用使得第一行为当前行
while (resultSet.next()){
int id = resultSet.getInt("id");
String name = resultSet.getString("name");
System.out.println("查询到id为"+id+",name为"+name+"的记录");
}

} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
if(resultSet != null){
try {
resultSet.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
close(conn,statement);
}
}

批量操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public static void doBatchInsert(String sql){
Connection conn = getConnection();
PreparedStatement statement = null;
try {
statement = conn.prepareStatement(sql);
for(int i = 0;i<1000;i++){
statement.setString(1,"张三"+i);
// 积攒sql
statement.addBatch();
}
// 执行sql
statement.executeBatch();
// 清除积攒的sql
statement.clearBatch();
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
close(conn,statement);
}

}