JDBC总结:理解Java数据库连接的核心概念与基本操作

前言


关于JDBC的学习

JDBC

JDBC步骤

步骤总结 (6步)

  1. 注册驱动
  2. 获取连接
  3. 创建statement
  4. 发送SQL语句,并获取结果
  5. 结果集解析
  6. 关闭资源
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
/**
* @Author Valyn
* Description: 利用jdbc技术,完成用户数据查询工作
*
* TODO: 步骤总结 (6步)
* 1. 注册驱动
* 2. 获取连接
* 3. 创建statement
* 4. 发送SQL语句,并获取结果
* 5. 结果集解析
* 6. 关闭资源
*/
public class JdbcStatementQueryPart {

public static void main(String[] args) throws SQLException {

//1.注册驱动
/**
* TODO: 注意
* Driver -> com.mysql.cj.jdbc.Driver
*/
DriverManager.registerDriver(new Driver());

//2.获取连接
/**
* TODO: 注意
* 面向接口编程
* java.sql 接口 = 实现类
* connection 使用java.sql.Connection接口接收
*/
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/atguigu",
"root",
"root");

//3.创建小车
Statement statement = connection.createStatement();

//4.发送SQL语句
String sql = "select id,account,password,nickname from t_user ;";
ResultSet resultSet = statement.executeQuery(sql);

//5.结果集解析
while (resultSet.next()){
int id = resultSet.getInt("id");
String account = resultSet.getString("account");
String password = resultSet.getString("password");
String nickname = resultSet.getString("nickname");
System.out.println(id+"::"+account+"::"+password+"::"+nickname);
}

//6.关闭资源 【先开后关】
resultSet.close();
statement.close();
connection.close();

}

}
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
public class JdbcStatementLoginPart {

public static void main(String[] args) throws ClassNotFoundException, SQLException {

//1.输入账号和密码
Scanner scanner = new Scanner(System.in);
String account = scanner.nextLine();
String password = scanner.nextLine();
scanner.close();

//2.jdbc的查询使用
/**
* 类加载: java文件 -> 编译 -> 【 class字节码文件 --> 类加载 --> jvm虚拟中 --> Class对象】
* 类加载具体步骤: 加载 【class文件转成对象加载到虚拟机中】->
* 连接 【验证(检查类文件) -> 准备 (静态变量赋默认值) -> 解析 (调用静态代码块) 】 ->
* 初始化 -> (赋真实值)
* 以下7种方式会触发类加载:
* 1. new关键字
* 2. 调用静态属性
* 3. 调用静态方法
* 4. 接口 包含1.8 新特性 default关键字
* 5. 反射 【Class.forName() 类名.class】
* 6. 子类调用会触发父类的静态代码块
* 7. 触发类的入口方法main
*/
//注册一次驱动
Class.forName("com.mysql.cj.jdbc.Driver");



/**
* 重写: 为了子类扩展父类的方法!父类也间接的规范了子类方法的参数和返回!
* 重载: 重载一般应用在第三方的工具类上,为了方便用户多种方式传递参数形式!简化形式!
*/
/**
* 三个参数:
* String URL: 连接数据库地址
* String user: 连接数据库用户名
* String password: 连接数据库用户对应的密码
* 数据库URL语法:
* JDBC:
* ip port
* jdbc:mysql | jdbc:oracle :// 127.0.0.1 | localhost : 3306 / 数据库名
* jdbc:mysql://localhost:3306/day01
* 192.168.33.45
* jdbc:mysql://192.168.33.45/3306/day01
* 当前电脑的省略写法! 注意:本机和端口3306
* jdbc:mysql://localhost:3306/day01 = jdbc:mysql:///day01
*
* 两个参数:
* String URL : 写法还是jdbc的路径写法!
* Properties : 就是一个参数封装容器!至少要包含 user / password key!存储连接账号信息!
*
* 一个参数:
* String URL: URl可以携带目标地址,可以通过?分割,在后面key=value&key=value形式传递参数
* jdbc:mysql:///day01?user=root&password=123456
* 扩展路径参数(了解):
* serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=true
*
*/
//获取连接
Connection connection = DriverManager.getConnection("jdbc:mysql:///atguigu", "root", "root");

//固定方法固定剂
//创建statement
Statement statement = connection.createStatement();

//执行SQL语句 [动态SQL语句,需要字符串拼接]
String sql = "select * from t_user where account = '"+account+"' and password = '"+password+"' ;";


/**
* ResultSet 结果集对象 = executeQuery(DQL语句)
* int 响应行数 = executeUpdate(非DQL语句)
*/
ResultSet resultSet = statement.executeQuery(sql);


//ResultSet == 小海豚 你必须有面向对象的思维:Java是面向对象编程的语言 OOP!
/**
*
* TODO:1.需要理解ResultSet的数据结构和小海豚查询出来的是一样,需要在脑子里构建结果表!
* TODO:2.有一个光标指向的操作数据行,默认指向第一行的上边!我们需要移动光标,指向行,在获取列即可!
* boolean = next()
* false: 没有数据,也不移动了!
* true: 有更多行,并且移动到下一行!
* 推荐:推荐使用if 或者 while循环,嵌套next方法,循环和判断体内获取数据!
* if(next()){获取列的数据!} || while(next()){获取列的数据!}
*
*TODO:3.获取当前行列的数据!
* get类型(int columnIndex | String columnLabel)
* 列名获取 //lable 如果没有别名,等于列名, 有别名label就是别名,他就是查询结果的标识!
* 列的角标 //从左到右 从1开始! 数据库全是从1开始!
*/

//进行结果集对象解析
if (resultSet.next()){
//只要向下移动,就是有数据 就是登录成功!
System.out.println("登录成功!");
}else{
System.out.println("登录失败!");
}

//关闭资源
resultSet.close();
statement.close();
connection.close();
}

}
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
/**
* @Author Valyn
* Description: 再次加强curd练习
*/
public class JdbcPreparedStatementCrudPart {


/**
* 插入一条用户数据!
* 账号: test
* 密码: test
* 昵称: 测试
*/
@Test
public void testInsert() throws Exception{

//注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");

//获取连接
Connection connection = DriverManager.getConnection("jdbc:mysql:///atguigu", "root", "root");

//TODO: 切记, ? 只能代替 值!!!!! 不能代替关键字 特殊符号 容器名
String sql = "insert into t_user(account,password,nickname) values (?,?,?);";
PreparedStatement preparedStatement = connection.prepareStatement(sql);

//占位符赋值
preparedStatement.setString(1, "test");
preparedStatement.setString(2, "test");
preparedStatement.setString(3, "测试");

//发送SQL语句
int rows = preparedStatement.executeUpdate();

//输出结果
System.out.println(rows);

//关闭资源close
preparedStatement.close();
connection.close();
}



/**
* 修改一条用户数据!
* 修改账号: test的用户,将nickname改为tomcat
*/
@Test
public void testUpdate() throws Exception{

//注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");

//获取连接
Connection connection = DriverManager.getConnection("jdbc:mysql:///atguigu", "root", "root");

//TODO: 切记, ? 只能代替 值!!!!! 不能代替关键字 特殊符号 容器名
String sql = "update t_user set nickname = ? where account = ? ;";
PreparedStatement preparedStatement = connection.prepareStatement(sql);

//占位符赋值
preparedStatement.setString(1, "tomcat");
preparedStatement.setString(2, "test");

//发送SQL语句
int rows = preparedStatement.executeUpdate();

//输出结果
System.out.println(rows);

//关闭资源close
preparedStatement.close();
connection.close();
}


/**
* 删除一条用户数据!
* 根据账号: test
*/
@Test
public void testDelete() throws Exception{

//注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");

//获取连接
Connection connection = DriverManager.getConnection("jdbc:mysql:///atguigu", "root", "root");

//TODO: 切记, ? 只能代替 值!!!!! 不能代替关键字 特殊符号 容器名
String sql = "delete from t_user where account = ? ;";
PreparedStatement preparedStatement = connection.prepareStatement(sql);

//占位符赋值
preparedStatement.setString(1, "test");

//发送SQL语句
int rows = preparedStatement.executeUpdate();

//输出结果
System.out.println(rows);

//关闭资源close
preparedStatement.close();
connection.close();
}



/**
* 查询全部数据!
* 将数据存到List<Map>中
* map -> 对应一行数据
* map key -> 数据库列名或者别名
* map value -> 数据库列的值
* TODO: 思路分析
* 1.先创建一个List<Map>集合
* 2.遍历resultSet对象的行数据
* 3.将每一行数据存储到一个map对象中!
* 4.将对象存到List<Map>中
* 5.最终返回
*
* TODO:
* 初体验,结果存储!
* 学习获取结果表头信息(列名和数量等信息)
*/
@Test
public void testQueryMap() throws Exception{

//注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");

//获取连接
Connection connection = DriverManager.getConnection("jdbc:mysql:///atguigu", "root", "root");

//TODO: 切记, ? 只能代替 值!!!!! 不能代替关键字 特殊符号 容器名
String sql = "select id,account,password,nickname from t_user ;";
PreparedStatement preparedStatement = connection.prepareStatement(sql);

//占位符赋值 本次没有占位符,省略

//发送查询语句
ResultSet resultSet = preparedStatement.executeQuery();

//创建一个集合
List<Map> mapList = new ArrayList<>();

//获取列信息对象
ResultSetMetaData metaData = resultSet.getMetaData();
int columnCount = metaData.getColumnCount();
while (resultSet.next()) {
Map map = new HashMap();
for (int i = 1; i <= columnCount; i++) {
map.put(metaData.getColumnLabel(i), resultSet.getObject(i));
}
mapList.add(map);
}

System.out.println(mapList);

//关闭资源close
preparedStatement.close();
connection.close();
resultSet.close();
}
}
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
/**
* @Author Valyn
* Description: 使用预编译Statement解决注入攻击问题
*/
public class JdbcPreparedStatementLoginPart {


public static void main(String[] args) throws ClassNotFoundException, SQLException {

//1.输入账号和密码
Scanner scanner = new Scanner(System.in);
String account = scanner.nextLine();
String password = scanner.nextLine();
scanner.close();

//2.jdbc的查询使用
//注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");

//获取连接
Connection connection = DriverManager.getConnection("jdbc:mysql:///atguigu", "root", "root");

//创建preparedStatement
//connection.createStatement();
//TODO 需要传入SQL语句结构
//TODO 要的是SQL语句结构,动态值的部分使用 ? , 占位符!
//TODO ? 不能加 '?' ? 只能替代值,不能替代关键字和容器名
String sql = "select * from t_user where account = ? and password = ? ;";
PreparedStatement preparedStatement = connection.prepareStatement(sql);

//占位符赋值
//给占位符赋值! 从左到右,从1开始!
/**
* int 占位符的下角标
* object 占位符的值
*/
preparedStatement.setObject(2,password);
preparedStatement.setObject(1,account);

//这哥们内部完成SQL语句拼接!
//执行SQL语句即可
ResultSet resultSet = preparedStatement.executeQuery();
//preparedStatement.executeUpdate()

//进行结果集对象解析
if (resultSet.next()){
//只要向下移动,就是有数据 就是登录成功!
System.out.println("登录成功!");
}else{
System.out.println("登录失败!");
}

//关闭资源
resultSet.close();
preparedStatement.close();
connection.close();
}

}

后记