jdbc、数据库连接池和数据库底层原理
- 1.客户端和服务器端来回传输数据,用的都是Statement对象嘛???
- 2.直接创建数据库驱动driver,占用内存空间
- 3.工作中如何写sql代码:
- 4.什么是上下文?
- 5.接口由组长编写么?
- 6.jdbc简介:
- 7.研究一下数据库索引和慢查询等问题???
- 8.防止sql注入的方式:
- 9.数据库的行和列索引是从几开始的???
- 10.如何开启mysql数据库日志?
- 11.释放资源顺序:一般先开的后关
- 12.释放资源不要放在一个try...catch里:
- 13.有没有释放资源的工具类,或者注解啥的
- 14.回滚出现异常的话,事务也会回滚 。
- 15.我不回滚也不提交,我直接关闭资源会咋样
- 16.关闭事务会导致什么???
- 17.为什么要使用连接池:java创建连接访问数据库服务器,需要先进行三次握手,所以非常耗时。
- 18.连接池好处:提高连接复用性,减轻服务器压力
- 20.jdbc连接池原理:
- 21.普通项目jar包放在模块根目录lib下面,web项目放在web-inf 的lib下面。
- 22.研究一下var提示字段的时候,那个才是我想要的???
- 23.数据库底层:详解一条 SQL 的执行过程
- 24.MySQL的数据存在磁盘上到底长什么样
- 25.数据库索引:
- 26.为什么 MySQL索引要用 B+tree
- 27.数据库查询优化:
1.客户端和服务器端来回传输数据,用的都是Statement对象嘛???
应该是
2.直接创建数据库驱动driver,占用内存空间
反射就不需要创建对象了。
自动加载驱动
Java.sql.DriverManager 的内部实现机制决定了这样代码的出现。只有先通过 Class.forName 找到特定驱动的 class 文件,DriverManager.getConnection 方法才能顺利地获得 Java 应用和数据库的连接。这样的代码为编写程序增加了不必要的负担,JDK 的开发者也意识到了这一点。从 Java 6 开始,应用程序不再需要显式地加载驱动程序了,DriverManager 开始能够自动地承担这项任务.
3.工作中如何写sql代码:
先在datagrip写好sql语句,再粘贴到java代码中。
4.什么是上下文?
通俗的理解,上下文,也就是执行任务所需要的相关信息。这个任务可以是一段代码,一个线程,一个进程,一个函数。当这个“任务”,相关信息需要保存下来,就可以使用Context来记录了。
一旦真正理解了上下文的概念,就像解读三描述的一样,只要想有个object来保存相关信息,就可以叫context了。这个看似高大上的名字,真的会给不理解context一词的人,造成一种距离感,难以直观的理解代码表述的含义,还以为有什么高深的用法。
原文链接:https://blog.csdn.net/caizir913/article/details/108826764
5.接口由组长编写么?
先定义接口规范,按规范开发。
先写接口再写实现类。
一般由:框架、项目经理、自己来写
6.jdbc简介:
JDBC 4.2:随 JDK 1.8 一起发布。
(JDBC API被划分为两部分:核心API(java.sql包)和扩展API(javax.sql包)。)
JDBC 是一种规范,它提供的接口,一套完整的,可移植的访问底层数据库的程序。
JDBC API中重要的接口和类:
DriverManager:这个类管理数据库驱动程序的列表。
Connection : 此接口表示通信上下文,即与数据库中的所有的通信都是通过此连接对象。
Statement : 【不太合理】可以使用这个接口创建的对象的SQL语句提交到数据库。一些派生的接口接受除执行存储过程的参数。
ResultSet:【不太合理】 这些对象保存从数据库后,执行使用Statement对象的SQL查询中检索数据。它作为一个迭代器,可以通过移动它来检索下一个数据。
SQLException:这个类用于处理发生在数据库应用程序中的任何错误。
原文链接:https://blog.csdn.net/fanxiaobin577328725/article/details/81986035
7.研究一下数据库索引和慢查询等问题???
23以后
8.防止sql注入的方式:
一、正则表达式
既然攻击是通过参数对关键字进行修改的,那么我们就可以用一个正则表达式对传入的参数进行限制,如果参数
中含有能对SQL语句造成影响的特殊符号或关键字,就退出程序,返回输入不合法的提示。
二、PreparedStatement
PreparedStatement语句是预编译的语句对象,他可以先将语句中的参数用占位符 ?代替,形成一个语句骨架发送
到服务器上,让服务器编译确定下来,这样,后面传进来的参数即使有特殊符号和关键字,也不会再对SQL产生影响了。
原文链接:https://blog.csdn.net/a9876rtyui/article/details/103002294
9.数据库的行和列索引是从几开始的???
列索引是从1开始,行索引是从0开始的
10.如何开启mysql数据库日志?
SHOW VARIABLES LIKE '%general_log%'
SET GLOBAL general_log=ON;
SET GLOBAL general_log=OFF;
11.释放资源顺序:一般先开的后关
12.释放资源不要放在一个try…catch里:
一个有异常,后面语句不会执行.close了.
13.有没有释放资源的工具类,或者注解啥的
14.回滚出现异常的话,事务也会回滚 。
15.我不回滚也不提交,我直接关闭资源会咋样
事务会也会被关闭,缓存中的数据没同步到硬盘
提交和回滚相当于io流的刷新。
16.关闭事务会导致什么???
conn.setAutoCommit(false);
pst1 = conn.prepareStatement("update user set balance = balance-1 where id = 1;");
pst2 = conn.prepareStatement("update user set balance = balance+1 where id = 2;");
conn.setAutoCommit(true);
int row1 = pst1.executeUpdate();
int row2 = pst2.executeUpdate();
if (row1 > 0 && row2 > 0) {
conn.commit();
}
会报错
17.为什么要使用连接池:java创建连接访问数据库服务器,需要先进行三次握手,所以非常耗时。
18.连接池好处:提高连接复用性,减轻服务器压力
连接池在创建成功后会在第一时间连接到数据库服务器
有连接三次握手>高速公路
19.连接对象归还连接到连接池中
(底层使用动态代理增强close方法,不是关闭连接,是把连接归还到连接池)
连接池中的conn.close();是返还连接给连接池中,不是销毁。
20.jdbc连接池原理:
21.普通项目jar包放在模块根目录lib下面,web项目放在web-inf 的lib下面。
22.研究一下var提示字段的时候,那个才是我想要的???
好像是只有一个提示的时候,回车是提示。
如果是多个提示的时候,回车就是自己写的东西。
23.数据库底层:详解一条 SQL 的执行过程
1. Buffer Pool 是 MySQL 的一个非常重要的组件,因为针对数据库的增删改操作都是在 Buffer Pool 中完成的
2. Undo log 记录的是数据操作前的样子
3. redo log 记录的是数据被操作后的样子(redo log 是 Innodb 存储引擎特有)
4. bin log 记录的是整个操作记录(这个对于主从复制具有非常重要的意义)
从准备更新一条数据到事务的提交的流程描述
1. 首先执行器根据 MySQL 的执行计划来查询数据,先是从缓存池中查询数据,如果没有就会去数据库中查询,如果查询到了就将其放到缓存池中
2. 在数据被缓存到缓存池的同时,会写入 undo log 日志文件
3. 更新的动作是在 BufferPool 中完成的,同时会将更新后的数据添加到 redo log buffer 中
4. 完成以后就可以提交事务,在提交的同时会做以下三件事
5. (第一件事)将redo log buffer中的数据刷入到 redo log 文件中
6. (第二件事)将本次操作记录写入到 bin log文件中
7. (第三件事)将 bin log 文件名字和更新内容在 bin log 中的位置记录到redo log中,同时在 redo log 最后添加 commit 标记
24.MySQL的数据存在磁盘上到底长什么样
表逻辑上相邻的记录行数据在磁盘上并不一定是物理相邻的。
25.数据库索引:
1)联合索引
INDEX idx_test(col_a,col_b)`。这种包含多个字段的索引就被称为**“联合索引”**
类似新华字典,偏旁首部查字:
我们按顺序使用了**“两个目录”,一个叫做“部首目录”,一个叫做“检字表”。并且我们可以看到上图中检字表的内容都是按部首分门别类组织的。这两个部分合在一起就是我们在本节讨论的主题——联合索引。即通过第一个字段的值(部首)在第一级索引中找到对应的第二级索引**位置(检字表页码),然后在第二级索引中根据第二个字段的值(笔画)找到符合条件的数据所在的位置(险字的真正页码)。
1.1)最左前缀匹配
从前面使用部首目录的例子中可以看出,如果我们不知道一个字的部首是什么的话,那基本是没办法使用这个目录的。这说明仅仅通过笔画数(第二个字段)是没办法使用部首目录的。
这就引申出了联合索引的一个规则:联合索引中的字段,只有某个字段(笔画)左边的所有字段(部首)都被使用了,才能使用该字段上的索引。例如,有索引 INDEX idx_i1(col_a,col_b)
,如果查询条件为 wherecol_b=1
,则无法使用索引 idx_i1
。
如果我们知道部首但是不知道笔画数,比如不知道“横折竖弯勾”是算一笔还是两笔,那我们仍然可以使用“部首目录”部分的内容,只是要把“检字表”对应部首里的所有字都看一遍就能找到我们要找的字了。
这就引申出了联合索引的另一个规则:联合索引中的字段,即使某个字段(部首)右边的其他字段(笔画)没有被使用,该字段之前(含)的所有字段仍然可以正常使用索引。例如,有索引 INDEX idx_i2(col_a,col_b,col_c)
,则查询条件 wherecol_a=1andcol_b=2
在字段 col_a
和 col_b
上仍然可以走索引。
2)聚集索引
新华字典的侧面可以看到一个V字形的一个个黑色小方块,有很多人都会在侧面写上 A
, B
, C
, D
这样对应的拼音字母。因为字典中所有的字都是按照拼音顺序排列的,有时候直接使用首字母翻开对应的部分查也很快。
拼音目录这样的索引,数据会根据索引中的顺序进行排列和组织的,这样的索引就被称为聚集索引,而非聚集索引就是其他的一般索引。因为数据只能按照一种规则排序,所以一张表至多有一个聚集索引,但可以有多个非聚集索引。
一张表至多有一个聚集索引,但可以有多个非聚集索引。
(https://mp.weixin.qq.com/s/WMuxdG3ymNMWWDk1XhLwZQ)
26.为什么 MySQL索引要用 B+tree
1)二叉树:
二叉树对于这种依次递增的数据列其实是不适合作为索引的数据结构。
2)Hash表:
Hash 表:一个快速搜索的数据结构,搜索的时间复杂度 O(1)
Hash 函数:将一个任意类型的 key,可以转换成一个 int 类型的下标
MySQL
的索引依然不采用能够精准定位的Hash 表。因为它不适用于范围查询。
3)红黑树:
但 MySQL
的索引依然不采用能够精确定位和范围查询都优秀的红黑树。
因为当 MySQL
数据量很大的时候,索引的体积也会很大,可能内存放不下,所以需要从磁盘上进行相关读写,如果树的层级太高,则读写磁盘的次数(I/O交互)就会越多,性能就会越差。
4)b-树:
删除的时候,可能会删除到节点或者叶子,会导致连锁反应(多米诺骨牌)
5)b+树:
单个节点存储越多的元素,自然在整个过程中的磁盘💽I/O交互就越少;
相对 B-tree 来说,所有的查询最终都会找到叶子节点,这也是 B+tree 性能稳定的一个体现;
所有叶子节点通过双向链表相连,范围查询非常方便,这也是 B+tree 最明显的优势。
27.数据库查询优化:
基本思路,使用索引的语句也有可能是慢查询。
我们的查询优化的过程,往往就是减少扫描行数的过程。
慢查询归纳起来大概有这么几种情况:
-
全表扫描(没有条件相当有没有使用索引)
-
全索引扫描(用索引也可能时全索引扫描)
-
索引过滤性不好(会导致回表)
-
频繁回表的开销(建立联合索引)
终极解决方案,建立虚拟列+联合索引,虚拟列在更新的时候也不能主动修改,它的值会根据定义自动生成。