上传部分文档

This commit is contained in:
jimmy committed 2025-01-18 23:55:07 +08:00
1 parent 6605a34b36
commit e2921c8347
15 files changed
+346 -17

No files matched your search

+4 -2
View File
@@ -26,9 +26,11 @@ export default function autoGenerateSidebar (
// 完整路径
const docP = path.join(roleFolderName, docPath)
console.log(docP);
console.log(docP,'=====docP=====');
let sidebarP = path.join(roleFolderName, genPath)
console.log(sidebarP);
console.log(sidebarP,'++++sidebarP++++');
// /home/runner/work/duyl328.github.io/duyl328.github.io/docs/notes
// /home/runner/work/duyl328.github.io/duyl328.github.io/docs/.vitepress
return {
name: 'autoSidebar',
+23 -3
View File
@@ -1,12 +1,32 @@
export default {
"/notes/": [
{
"text": "计算机基础知识",
"text": "JDBC",
"collapsed": true,
"items": [
{
"text": "01操作系统基础.md",
"link": "notes/计算机基础知识/01操作系统基础.md"
"text": "01JDBC介绍.md",
"link": "notes/JDBC/01JDBC介绍.md"
},
{
"text": "02JDBC体系结构.md",
"link": "notes/JDBC/02JDBC体系结构.md"
},
{
"text": "03获取连接.md",
"link": "notes/JDBC/03获取连接.md"
},
{
"text": "04查询结果集.md",
"link": "notes/JDBC/04查询结果集.md"
},
{
"text": "05PreparedStatement.md",
"link": "notes/JDBC/05PreparedStatement.md"
},
{
"text": "06事务与锁.md",
"link": "notes/JDBC/06事务与锁.md"
}
]
}
+19
View File
@@ -0,0 +1,19 @@
JDBC(Java Database Connectivity)
是一个独立于特定数据库管理系统、通用的SQL数据库存取和操作的公共接口(一组API),定义了用来访问数据库的标准Java类库,(java.sql,javax.sql)使用这些类库可以以一种标准的方法、方便地访问数据库资源。
JDBC为访问不同的数据库提供了一种统一的途径,为开发者屏蔽了一些细节问题。
JDBC的目标是使Java程序员使用JDBC可以连接任何提供了JDBC驱动程序的数据库系统,这样就使得程序员无需对特定的数据库系统的特点有过多的了解,从而大大简化和加快了开发过程。
如果没有JDBC,那么Java程序访问数据库时是这样的:
![我们认为的连接](../../public/note/JDBC/JDBC%E4%BB%8B%E7%BB%8D/img-1.png)
有了JDBC,Java程序访问数据库时是这样的:
![真实的连接](../../public/note/JDBC/JDBC%E4%BB%8B%E7%BB%8D/img-2.png)
总结如下:
![综述](../../public/note/JDBC/JDBC%E4%BB%8B%E7%BB%8D/img-3.png)
+32
View File
@@ -0,0 +1,32 @@
JDBC接口(API)包括两个层次:
面向应用的API:Java API,抽象接口,供应用程序开发人员使用(连接数据库,执行SQL语句,获得结果)。
面向数据库的API:Java Driver API,供开发商开发数据库驱动程序用。
JDBC是sun公司提供一套用于数据库操作的接口,java程序员只需要面向这套接口编程即可。
不同的数据库厂商,需要针对这套接口,提供不同实现。不同的实现的集合,即为不同数据库的驱动。 ——— 面向接口编程
JDBC程序编写步骤
![img.png](../../public/note/JDBC/JDBC%E4%BD%93%E7%B3%BB%E7%BB%93%E6%9E%84/img.png)
补充:ODBC(Open Database Connectivity,开放式数据库连接),是微软在Windows平台下推出的。使用者在程序中只需要调用ODBC API,由
ODBC 驱动程序将调用转换成为对特定的数据库的调用请求。
> [!IMPORTANT]
> 连接步骤概述
第一步:注册驱动(作用告诉Java程序,即将要连接的数据库是哪个品牌的)
第二步:获取连接(表示JVM的进程和数据库进程之间的通道打开了,这属于进程之间通信,使用之后一定要关闭)
第三步:获取数据库操作对象(专门负责执行sql语句的对象)
第四步:执行SQL语句
第五步:处理查询结果集(只有当第四步指定的是select语句时,才会有第五步的查询结果集)
第六步:释放资源(使用完资源一定要释放)
+116
View File
@@ -0,0 +1,116 @@
## 第一种方式
这种方式注册的驱动数据最原始的方式,不常用
```java
Statement stmt = null;
Connection conn = null;
try {
// 1、注册驱动
DriverManager.registerDriver(new Driver());
// 2、获取连接
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/bjpowernode", "root", "123456");
System.out.println(conn);
// 3、获取数据库操作对象
// 这个方法创建的对象,是专门用来指定 sql 语句的
stmt = conn.createStatement();
// 4、执行 sql
String sql1 = "insert into t_student(id, name, class) VALUE (9, '张三', 3)";
// 这个方法用于执行 DML 语句(insert,update,delete),并且返回值是影响数据库中记录条数
int count = stmt.executeUpdate(sql1);
System.out.println(count);
// 5、处理查询结果集
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
// 6、释放资源
// 在这里确保数据内容一定要关闭
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
```
## 获取连接的第二种方式
在JDBC的Driver中静态代码快中已经写好了实现类,使用反射进行静态代码块的调用,完成连接的获取
这种方式更加常用
```java
try {
// 使用反射机制运行这个类中的静态代码块,完成对应内容的获取
/*
Mysql的JDBC中的Driver的静态代码块
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
*/
Class.forName("com.mysql.cj.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/bjpowernode", "root", "123456");
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
```
## 获取连接的最终版
以上连接的方式都是基于代码量的减少,为了让代码更灵活,往往会将需要配置的内容放到一个配置文件中,通过读取配置文件获取对应要操作的内容
这种方式更加灵活,也更加常用
```java
// 使用 资源绑定器 获取配置文件中的内容
ResourceBundle bundle = ResourceBundle.getBundle("JDBCTest04");
String className = bundle.getString("className");
String url = bundle.getString("url");
String user = bundle.getString("user");
String password = bundle.getString("password");
String sql = bundle.getString("sql");
Connection conn = null;
Statement stmt = null;
try {
// 注册驱动
Class.forName(className);
conn = DriverManager.getConnection(url, user, password);
// 获取数据操作对象
stmt = conn.createStatement();
// 执行 sql 语句
int count = stmt.executeUpdate(sql);
System.out.println(count);
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
} finally {
// 关闭连接
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
```
+51
View File
@@ -0,0 +1,51 @@
| ResultSet | executeQuery(String sql) <br />执行给定的 SQL 语句,该语句返回单个 ResultSet 对象。 |
|-----------|-------------------------------------------------------------------|
通过这个方法可以进行结果集的查询,并且将查询结果包装成ResultSet对象进行返回
可以使用对应的方法调用
### 使用指定的列的方式将结果返回
```java
String sql = "select ENAME,SAL from emp";
// 发送静态的 select 语句
rs = stmt.executeQuery(sql);
// re.next() 返回值是一个布尔值,判断是否有下一个
while (rs.next()) {
// 使用 getString 方法获取对应下标的值,无论是什么类型都会转换为String类型
// JDBC 中所有下标从 1 开始
String ename = rs.getString(1);
// 这里的 1 和 2 代表的一行数据的第几列
String sal = rs.getString(2);
System.out.println(ename + ", " + sal);
```
### 使用返回列名的方式将结果返回
> 必须是数据库返回结果的列名,如果重命名则要写重命名后的内容
```java
while (rs.next()) {
// 这里也能写取出指定数据的名称,这种方式更加健壮
// 以列的名字获取对应的内容
// 如果查询结果经过重命名,那么必须写重命名后的内容
String ename = rs.getString("ENAME");
String sal = rs.getString("SAL");
System.out.println(ename + ", " + sal);
}
```
### 将指定结果按指定的类型返回
> 这个类型必须以创建数据库时的指定类型为准
```java
while (rs.next()) {
String ename = rs.getString("ENAME");
// 直接以数字的形式查询内容【其他方式同理】
int sal = rs.getInt("SAL");
System.out.println(ename + ", " + (sal+100));
}
```
+23
View File
@@ -0,0 +1,23 @@
## PreparedStatement的使用
- 可以通过调用 Connection 对象的 preparedStatement(String sql) 方法获取 PreparedStatement 对象
- PreparedStatement 接口是 Statement 的子接口,它表示一条预编译过的 SQL 语句
- PreparedStatement 对象所代表的 SQL 语句中的参数用问号(?)来表示,
调用 PreparedStatement 对象的 setXxx() 方法来设置这些参数. setXxx() 方法有两个参数,
第一个参数是要设置的 SQL 语句中的参数的索引(从 1 开始),
第二个是设置的 SQL 语句中的参数的值
## PreparedStatement和Statement的区别
PreparedStatement 解决了SQL注入问题
Statement 是预编译一次执行一次,PreparedStatement 是编译一次,可执行N次。PreparedStatement 效率更高。
PreparedStatement会在编译阶段进行安全检查
如果业务中需要使用SQL注入的时候会使用 Statement,使用场景:在列表升序和降序的排序中,需要将内容拼入行尾
+70
View File
@@ -0,0 +1,70 @@
## JDBC中的事务
JDBC中的默认事务是自动提交
将JDBC中的事务设置为手动提交
然后进行数据库的修改,如果没有出现异常并且数据正常,进行提交
如果出现异常,直接回滚数据
```java
Connection conn = null;
PreparedStatement pr = null;
try {
Class.forName("com.mysql.cj.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc_test", "root", "123456");
// 将自动提交禁用
conn.setAutoCommit(false);
String sql = "update t_user set realName = ? where id = ? ";
pr = conn.prepareStatement(sql);
pr.setString(1,"123");
pr.setInt(2,15);
int count = pr.executeUpdate();
pr.setString(1,"123");
pr.setInt(2,16);
count += pr.executeUpdate();
// 如果能到这里一定没有问题,将数据进行提交
conn.commit();
System.out.println(count);
} catch (ClassNotFoundException | SQLException e) {
// 如果出现异常,直接将数据库进行回滚
if (conn != null) {
try {
conn.rollback();
} catch (SQLException ex) {
ex.printStackTrace();
}
}
e.printStackTrace();
} finally {
if (pr != null) {
}
if (conn != null) {
}
}
```
## 乐观锁和悲观锁
乐观锁:支持并发,事务不需要排队,之不要需要一个版本号
多线程之间同时进行数据的修改:
第一个线程先修改数据,并将版本号从1.0更新到1.1
第二个线程更新完数据后,发现版本号是1.1和最初的版本号不同,会自动回滚
如果多个线程更新数据,更新前版本号和更新后的版本号一致,那么数据安全,会提交
悲观锁(行级锁):事务必须排队,数据被锁住了,不允许并发
在查询语句后加上 for updata 就是行级锁
```sql
select username
from t_user
where username like '%a_' for update
```
+8
View File
@@ -0,0 +1,8 @@
# JDBC
### 简介
### 目录
@@ -1 +0,0 @@
TODO
-11
View File
@@ -1,11 +0,0 @@
# 计算机基础知识
### 简介
计算机基础相关知识...
### 目录
+ [操作系统基础](./01 操作系统基础)
Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 239 KiB