了解JDBC
了解JDBC
urcuteimmehinge概述
sun公司为了简化开发人员(对数据库)同意操作马,提供了一个(Java操作数据)规范,俗称JDBC
前置包:
- Java.sql
- javax.sql
- 数据库驱动包 mysql-connecttor-java-版本.jar
一、JDBC中对象的解释
第一个JDBC程序
- 创建数据库
1 | # 创建数据库 |
- 导入数据库驱动
- 项目包下创建lib文件
- 右键lib
- 代码
1 | public static void main(String[] args) throws ClassNotFoundException, SQLException { |
步骤总结:
- 加载驱动
- 连接数据库 DriverManage
- 获得执行SQL的对象 Statement
- 获取返回的结果集
- 释放连接
二、对象解释
DriverManager
1 | // 1. 加载驱动 |
URL
1 | String url = "jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8"; |
Statement 执行SQL的对象 PrepareStatement 执行SQL的对象
1 | String sql = "select * from users"; // 编写SQL |
ResultSet 查询的结果集:封装了所有的查询结果
- 获得指定的数据类型
1
2
3
4
5
6
7resultSet.getObject(); // 不知道具体类型使用object
// 知道列的具体类型使用指定的
resultSet.getString();
resultSet.getInt();
resultSet.getFloat();
resultSet.getDate();
... - 遍历,指针
1
2
3
4
5resultSet.beforeFirst(); // 移动到最前面
resultSet.afterLast(); // 移动到最后面
resultSet.next(); // 移动到下一个
resultSet.previous(); // 移动到前一行
resultSet.absolute(); // 移动到指定行
释放资源
1 | // 耗资源,用完关掉 |
三、statement对象
jdbc中的statement对象用于向数据库发送SQL语句,想完成对数据的增删改查,只需要通过对象想数据库发送增删改查语句即可。
Statement对象的executeUpdate方法,用于向数据库发送增、删、改的SQL语句,executeUpdate执行完后,将返回一个整数(即增删改语句导致数据库几行数据发生了变化)。
Statement.executeQuery方法用于向数据库发送查询语句,executeQuery方法返回代表查询结果的ResultSet对象。
CRUD操作-create
使用executeUpdate(String sql)方法完成数据添加操作:
1 | Statement statement = connection.createStatement(); |
CRUD 操作-delete
使用executeUpdate(String sql)方法完成数据删除操作:
1 | Statement statement = connection.createStatement(); |
CRUD-update
使用executeUpdate(String sql)方法完成数据修改操作:
1 | Statement statement = connection.createStatement(); |
CRUD操作-read
1 | Statement statement = connection.createStatement(); |
代码实现
- 编写db.properties配置文件
1
2
3
4driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8
username=root
password=123456
- 提取工具类
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
54
55
56
57
58
59import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
public class JdbcUtils {
private static String driver = null;
private static String url = null;
private static String username = null;
private static String password = null;
static {
try {
InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties");
Properties properties = new Properties();
properties.load(in);
driver = properties.getProperty("driver");
url = properties.getProperty("url");
username = properties.getProperty("username");
password = properties.getProperty("password");
// 1.驱动只用加载一次
Class.forName(driver);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
// 获取连接
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url, username, password);
}
// 释放连接资源
public static void release(Connection conn, Statement st, ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (st != null) {
try {
st.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
} - 编写增删改的方法,
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
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92// 增
package com.jdbc.utils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class TestInsert {
public static void main(String[] args) {
Connection conn = null;
Statement st = null;
ResultSet rs = null;
try {
conn = JdbcUtils.getConnection(); // 获取连接
st = conn.createStatement(); // 获得SQL的执行对象
String sql = "insert into user(id,'name','password','email','birthday') values(4,'xxx''1234556','xxx@xxx.com','2021-12-01')";
int i = st.executeUpdate(sql);
if (i > 0) {
System.out.println("插入成功");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtils.release(conn, st, rs);
}
}
}
// 删
package com.jdbc.utils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class TestDelete {
public static void main(String[] args) {
Connection conn = null;
Statement st = null;
ResultSet rs = null;
try {
conn = JdbcUtils.getConnection(); // 获取连接
st = conn.createStatement(); // 获得SQL的执行对象
String sql = "delete from user where id=4";
int i = st.executeUpdate(sql);
if (i > 0) {
System.out.println("删除成功");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtils.release(conn, st, rs);
}
}
}
// 改
package com.jdbc.utils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class TestUpdate {
public static void main(String[] args) {
Connection conn = null;
Statement st = null;
ResultSet rs = null;
try {
conn = JdbcUtils.getConnection(); // 获取连接
st = conn.createStatement(); // 获得SQL的执行对象
String sql = "update user set 'name'='xxx','email'='xxx@xxx.com' where id=1";
int i = st.executeUpdate(sql);
if (i > 0) {
System.out.println("更新成功");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtils.release(conn, st, rs);
}
}
} - 查询
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// 查
package com.jdbc.utils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class TestSelect {
public static void main(String[] args) {
Connection conn = null;
Statement st = null;
ResultSet rs = null;
try {
conn = JdbcUtils.getConnection();
st = conn.createStatement();
// SQL
String sql = "select * from user where id=1";
rs = st.executeQuery(sql); // 查询完毕会返回一个结果集
while (rs.next()) {
System.out.println(rs.getString("name"));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtils.release(conn, st, rs);
}
}
}
SQL 注入问题
sql存在漏洞,会被攻击, SQL会被拼接 or
1 | package com.jdbc.utils; |
四、PrepareStatement对象
PrepareStatement可以防止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
40package com.jdbc.study03;
import com.jdbc.utils.JdbcUtils;
import java.sql.*;
import java.util.Date;
public class TestInsert {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement st = null;
try {
conn = JdbcUtils.getConnection();
// 区别 ?占位符代替参数
String sql = "insert into users(id,'name','password','email','birthday') values(?,?,?,?,?)";
st = conn.prepareStatement(""); // 预编译SQL,先写SQL,然后不执行
// 手动参数赋值
st.setInt(1, 4);
st.setString(2, "姓名");
st.setString(3, "123456");
st.setString(4, "xxx@xx.com");
// sql.Data 数据库
// util.Data java new Data().getTime() 获得时间戳
st.setDate(5, new java.sql.Date(new Date().getTime()));
int i = st.executeUpdate();
if (1 > 0) {
System.out.println("插入成功");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtils.release(conn, st, null);
}
}
} - 删除
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
32package com.jdbc.study03;
import com.jdbc.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class TestDelete {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement st = null;
try {
conn = JdbcUtils.getConnection();
String sql = "delete form users where id=?";
st = conn.prepareStatement(sql);
// 手动赋值
st.setInt(1, 4);
// 执行
int i = st.executeUpdate();
if (1 > 0) {
System.out.println("删除成功");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtils.release(conn, st, null);
}
}
} - 更新
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
34package com.jdbc.study03;
import com.jdbc.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class TestUpdate {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement st = null;
try {
conn = JdbcUtils.getConnection();
// String sql = "update set 'name'='xxx','password'='123456','email'='xxx@xx.com' where id=?";
String sql = "update users set 'name' = '?' where id=?;";
st = conn.prepareStatement(sql);
st.setString(1, "姓名");
st.setInt(2, 1);
int i = st.executeUpdate();
if (i != 0) {
System.out.println("修改成功");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtils.release(conn, st, null);
}
}
} - 查询
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
30package com.jdbc.study03;
import com.jdbc.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class TestSelect {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement st = null;
ResultSet rs = null;
try {
conn = JdbcUtils.getConnection();
String sql = "select * from users id=?;";
st = conn.prepareStatement(sql); // 预编译
st.setInt(1, 4); // 传递参数
rs = st.executeQuery();
while (rs.next()) {
System.out.println(rs.getString("name"));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtils.release(conn, st, rs);
}
}
} - 防止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
41package com.jdbc.study03;
import com.jdbc.utils.JdbcUtils;
import java.sql.*;
public class PreventSQLInjection {
public static void main(String[] args) {
// 正常登陆
// login("xxx","123456");
login(" 'or '1=1", " 'or '1=1'");
}
// 登陆业务
public static void login(String username, String password) {
Connection conn = null;
PreparedStatement st = null;
ResultSet rs = null;
try {
conn = JdbcUtils.getConnection();
String sql = "select * from user where 'name'=? and 'password'=?";
st = conn.prepareStatement(sql);
st.setString(1, "姓名");
st.setString(2, "123456");
rs = st.executeQuery(sql); // 查询完毕会返回一个结果集
while (rs.next()) {
System.out.println(rs.getString("name"));
System.out.println(rs.getString("password"));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtils.release(conn, st, rs);
}
}
}
五,事务
ACID原则
- 原子性:要么完成,要么不完成
- 一致性:总数不变
- 隔离性:多个进程互不干扰
- 持久性:一旦提交不可逆,持久化到数据库
隔离性的问题:
脏读:一个事务读取了另一个没有提交的事务
不可重读读:在同一个事务内,和重复读取表中的数据,表数据发生了改变
续读(幻读):在一个事务内,读取到别个插入的数据,导致前后读出来的结果不一致
评论
匿名评论隐私政策
✅ 你无需删除空行,直接评论以获取最佳展示效果