3. PooledDataSource
PooledDataSourcePooledDataSource 内部实现了连接池功能,用于复用数据库连接。因此,从效率上来说,PooledDataSource 要高于UnpooledDataSource。PooledDataSource需要借助一些辅助类帮助它完成连接池的功能,所以接下来,我们先来认识一下相关的辅助类。
辅助类介绍PooledDataSource 需要借助两个辅助类帮其完成功能,这两个辅助类分别是:
PoolState
用于记录连接池运行时的状态,比如连接获取次数,无效连接数量等
内部定义了两个 PooledConnection 集合,用于存储空闲连接和活跃连接
PooledConnection
内部定义了一个 Connection 类型的变量,用于指向真实的数据库连接
内部还定义了一个 Connection 的代理类,用于对部分方法调用进行拦截
PooledConnection1234567891011121314151617181920212223242526272829303132333435363738class PooledConnec ...
3. 获取 BoundSql
在执行 SQL 之前,需要将 SQL 语句完整的解析出来。我们都知道 SQL 是配置在映射文件中的,但由于映射文件中的 SQL 可能会包含占位符#{},以及动态 SQL 标签,比如、等。
因此,我们并不能直接使用映射文件中配置的 SQL。MyBatis 会将映射文件中的 SQL解析成一组 SQL 片段。如果某个片段中也包含动态SQL相关的标签,那么,MyBatis会对该片段再次进行分片。最终,一个 SQL 配置将会被解析成一个 SQL 片段树。
需要对片段树进行解析,以便从每个片段对象中获取相应的内容。然后将这些内容组合起来即可得到一个完成的 SQL 语句,这个完整的 SQL 以及其他的一些信息最终会存储在 BoundSql 对象中。
成员变量信息12345private final String sql;private final List<ParameterMapping> parameterMappings;private final Object parameterObject;private final Map<String, Object> a ...
3. 解析cache节点
MyBatis 提供了一、二级缓存,其中一级缓存是 SqlSession 级别的,默认为开启状态。二级缓存配置在映射文件中,使用者需要显示配置才能开启。如果无特殊要求,二级缓存的配置很简单。如下
1<cache/>
修改缓存的一些属性,可以像下面这样配置
12345<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>
根据上面的配置创建出的缓存有以下特点:
按先进先出的策略淘汰缓存项
缓存的容量为 512 个对象引用
缓存每隔 60 秒刷新一次
缓存返回的对象是写安全的,即在外部��改对象不会影响到缓存内部存储对象
除了上面两种配置方式,我们还可以给 MyBatis 配置第三方缓存或者自己实现的缓存等。比如,我们将 Ehcache 缓存整合到 MyBatis 中,可以这样配置。
1234567<cache type="org.mybatis ...
3. 解析settings节点
相关配置是 MyBatis 中非常重要的配置,这些配置用于调整 MyBatis 运行时的行为。settings 配置繁多,在对这些配置不熟悉的情况下,保持默认配置即可。
比较简单的配置,如下:
12345<settings> <setting name="cacheEnabled" value="true"/> <setting name="lazyLoadingEnabled" value="true"/> <setting name="autoMappingBehavior" value="PARTIAL"/></settings>
分析相关源码
1234567891011121314151617// -☆- XMLConfigBuilderprivate Properties settingsAsProperties(XNode context) { if (co ...
3. 顺序一致性
顺序一致性内存模型是一个理论参考模型,在设计的时候,处理器的内存模型和编程语言的内存模型都会以顺序一致性内存模型作为参照。
数据竞争与顺序一致性当程序未正确同步时,就可能会存在数据竞争。Java内存模型规范对数据竞争的定义如下:
在一个线程中写一个变量
在另一个线程读同一个变量
而且写和读没有通过同步来排序
当代码中包含数据竞争时,程序的执行往往产生违反直觉的结果(前一章的示例正是如此)。如果一个多线程程序能正确同步,这个程序将是一个没有数据竞争的程序。
JMM对正确同步的多线程程序的内存一致性做了如下保证。
如果程序是正确同步的,程序的执行将具有顺序一致性(SequentiallyConsistent)——即程序的执行结果与该程序在顺序一致性内存模型中的执行结果相同。马上我们就会看到,这对于程序员来说是一个极强的保证。这里的同步是指广义上的同步,包括对常用同步原语(synchronized、volatile和final)的正确使用
顺序一致性内存模型顺序一致性内存模型是一个被计算机科学家理想化了的理论参考模型,它为程序员提供了极强的内存可见性保证。顺序一致性内存模型有两大 ...
3. HTTP 报文
HTTP 报文大致可分为:
报文首部
报文主体
两者由最初出现的 空行(CR+LF)来划分。通常,并不一定要有报文主体。
请求报文及响应报文的结构
请求报文(上)和响应报文(下)的结构
请求报文(上)和响应报文(下)的实例
请求报文和响应报文的首部内容数据组成
请求行
包含用于请求的方法,请求 URI 和 HTTP 版本
状态行
包含表明响应结果的状态码,原因短语和 HTTP 版本。
首部字段
包含表示请求和响应的各种条件和属性的各类首部。
分类:
通用首部
请求首部
响应首部
实体首部
其他
可能包含 HTTP 的 RFC 里未定义的首部(Cookie 等)
编码提升传输速率HTTP 在传输数据时可以按照数据原貌直接传输,但也可以在传输过程中通过编码提升传输速率。通过在传输时编码,能有效地处理大量的访问请求。但是,编码的操作需要计算机来完成,因此会消耗更多的CPU等资源
报文主体和实体主体的差异
报文(message)
是HTTP通信中的基本单位,由8位组字节流(octet sequence, 其中 octet 为 8 个比特)组成,通过 HT ...
3. Redis事务
Redis 通过 MULTI、EXEC、DISCARD、WATCH 、UNWATCH 来实现事务功能,Redis 事务具备如下几个特性
Redis 会将事务中的多个命令一次性、按顺序一次执行,在执行期间可以保证不会中断事务去执行其他命令
Redis 的事务机制是不能保证原子性的,它只保证隔离性和一致性。
Redis 事务详解Redis 的事务形式如下:
12345678910multi command1()command2()...commandn()exec/discard
MULTI
标志着事务的开始,可以将执行该命令的客户端从非事务态切换的事务态
在 multi 之后的命令都不会执行��全部进入事务队列中
123MULTI OK // 总是返回OK
EXEC
按照顺序执行先前放入事务对立中的命令,然后将客户端恢复到非事务状态。
该命令返回的是一个数组,数组中的每个元素都是每个命令的返回值。该命令不会中断命令的执行,除非遇到如下几个错误:
服务宕机
入队列的命令是错误的,比如使用不存在的命令或者命令格式错误
使用了 WATCH,有其他客户端修改了当前事 ...
3. nginx 分割日志
生产环境中的服务器,由于访问日志文件增长速度非常快,日志太大会严重影响服务器效率。同时,为了方便对日志进行分析计算,须要对日志文件进行定时切割。定时切割的方式有按月切割、按天切割、按小时切割等。最常用的是按天切割。
1234567891011121314151617181920## 保存脚本到sbin路径,命名为:cut_nginx_log.shcd /usr/local/nginx/sbinvim cut_nginx_log.sh# 输入以下内容#!/bin/bash# 这个脚本每天00:00运行# Nginx日志文件的存放路径logs_path = "/usr/local/nginx/logs/"# 创建日志存放目录mkdir -p ${logs_path}$(date -d "yesterday" + "%Y")/$(date -d "yesterday" + "%^m")/# 复制日志为新的名称mv ${logs_path}/acces ...
3. B树
B树也称B-树,它是一颗多路平衡查找树。B树的定义:
每个节点最多有m-1个关键字(可以存有的键值对)
根节点最少可以只有1个关键字
非根节点至少有m/2个关键字
每个节点中的关键字都按照从小到大的顺序排列,每个关键字的左子树中的所有关键字都小于它,而右子树中的所有关键字都大于它。
所有叶子节点都位于同一层,或者说根节点到每个叶子节点的长度都相同
每个节点都存有索引和数据,也就是对应的key和value。
描述一颗B树时需要指定它的阶数,阶数表示了一个节点最多有多少个孩子节点,一般用字母m表示阶数。根节点的关键字数量范围:1 <= k <= m-1,非根节点的关键字数量范围:m/2 <= k <= m-1。比如这里有一个5阶的B树,根节点数量范围:1 <= k <= 4,非根节点数量范围:2 <= k <= 4。
插入插入18,70,50,40插入22,发现这个节点的关键字已经大于4了,所以需要进行分裂接着插入23,25,39分裂
...
4. 容器的初始化(四)之 Spring Boot 集成
Spring Boot 对于 servlet 的处理才是重头戏:
其一,是因为 Spring Boot 使用范围很广,很少有人用 spring 而不用 Spring Boot 了
其二,是因为它没有完全遵守 Servlet3.0 的规范!
注册方式一:Servlet 3.0 注解 + @ServletComponentScan Spring Boot 依旧兼容 Servlet 3.0 一系列以 @Web* 开头的注解:@WebServlet,@WebFilter,@WebListener
1234@WebServlet("/hello")public class HelloWorldServlet extends HttpServlet{}@WebFilter("/hello/*")public class HelloWorldFilter implements Filter {}
不要忘记让启动类去扫描到这些注解
12345678@SpringBootApplication@ServletC ...