源码
BaseJdbcLogger
打印日志的抽象类。
PreparedStatementLogger
PreparedStatement
的日志。
ResultSetLogger
ResultSet
的日志。
打印debug的日志
1 | protected void debug(String text, boolean input) { |
字符串前缀
1 | private String prefix(boolean isInput) { |
打印日志的抽象类。
PreparedStatement
的日志。
ResultSet
的日志。
1 | protected void debug(String text, boolean input) { |
1 | private String prefix(boolean isInput) { |
Kryo是一个快速有效的对象图序列化Java库。它的目标是快速、高效、易使用。该项目适用于对象持久化到文件或数据库中或通过网络传输。Kryo还可以自动实现深浅的拷贝/克隆。 就是直接复制一个对象对象到另一个对象,而不是对象转换为字节然后转化为对象。
Kryo如果设置References=true
,序列化的时候会从缓存中获取之前序列化过的对象,从而提高效率。
reference=true
。默认会生成和对象相对应的id值。但第2次、第N次加载类时,会根据id值去缓存中查找相对应的对象。1 | Kryo kryo = new Kryo(); |
1 | package org.denger.mapper; |
1 | <?xml version="1.0" encoding="UTF-8"?> |
1 | package org.denger.mapper; |
对于以上极其简单代码看上去并无特殊之处,主要亮点在于 UserMapper
居然不用实现类,而且在调用 getUser
的时候,也是使用直接调用了UserMapper
实现类,那么Mybatis是如何去实现 UserMapper
的接口的呢?
可能你马上能想到的实现机制就是通过动态代理方式,看看MyBatis整个的代理过程吧。
首先在Spring的配置文件中看到下面的Bean。1
2
3
4<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
<property name="basePackage" value="org.denger.mapper"></property>
</bean>
1 | /** |
以上的MapperScannerConfigurer
的注释中描述道。
从base包中搜索所有下面所有interface
,并将其注册到Spring Bean容器中,其注册的class bean是MapperFactoryBean
。
看看它的注册过程,从MapperScannerConfigurer#Scanner
类中抽取,在初始化以上application-content.xml
文件时就会进行调用。
主要用于是搜索base packages
下的所有mapper.class
,并将其注册至spring的benfinitionHolder
中。
八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上(反斜线),问有多少种摆法。 高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。计算机发明后,有多种计算机语言可以解决此问题。
八皇后问题是一个以国际象棋为背景的问题:如何能够在 8×8 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。八皇后问题可以推广为更一般的n皇后摆放问题:这时棋盘的大小变为n × n
,而皇后个数也变成n。当且仅当n = 1
或n ≥ 4
时问题有解。
一级缓存,又叫本地缓存,是PerpetualCache
类型的永久缓存,保存在执行器中(BaseExecutor
),而执行器又在SqlSession
(DefaultSqlSession
)中,所以一级缓存的生命周期与SqlSession
是相同的。
MyBatis的一级缓存指的是在一个Session
域内,Session
为关闭的时候执行的查询会根据SQL为key
被缓存,单独使用MyBatis而不继承Spring,使用原生的MyBatis的SqlSessionFactory
来构造sqlSession
查询,是可以使用以及缓存的。
当参数不变的时候只进行一次查询,参数变更以后,则需要重新进行查询,而清空缓存以后,参数相同的查询过的SQL也需要重新查询,当执行SQL时两次查询中间发生增删改操作,则SqlSession
的缓存清空。
如果集成Spring是没有使用一级缓存。原因是一个sqlSession,但是实际上因为我们的dao继承SqlSessionDaoSupport
,而SqlSessionDaoSupport
内部sqlSession
的实现是使用用动态代理实现的,这个动态代理sqlSessionProxy
使用一个模板方法封装select()
等操作,每一次select()
查询都会自动先执行openSession()
,执行完后调用close()
方法,相当于生成一个新的session
实例,所以我们无需手动的去关闭这个session()
,当然也无法使用MyBatis的一级缓存,也就是说MyBatis的一级缓存在Spring中是没有作用的。
MyBatis SqlSession provides you with specific methods to handle transactions programmatically. But when using MyBatis-Spring your beans will be injected with a Spring managed SqlSession or a Spring managed mapper. That means that Spring will always handle your transactions.
You cannot call SqlSession.commit(), SqlSession.rollback() or SqlSession.close() over a Spring managed SqlSession. If you try to do so, a UnsupportedOperationException exception will be thrown. Note these methods are not exposed in injected mapper classes.
二级缓存,又叫自定义缓存,实现Cache
接口的类都可以作为二级缓存,所以可配置如encache等的第三方缓存。二级缓存以namespace
名称空间为其唯一标识,被保存在Configuration
核心配置对象中。1
2
3
4
5public class Configuration {
// ...
protected final Map<String, Cache> caches = new StrictMap<Cache>("Caches collection");
// ...
}
每次构建SqlSessionFactory
对象时都会创建新的Configuration
对象,因此,二级缓存的生命周期与SqlSessionFactory
是相同的。在创建每个MapperedStatement
对象时,都会根据其所属的namespace
名称空间,给其分配Cache
缓存对象。
二级缓存同样执行增删查改操作,会清空缓存。
二级缓存就是global caching
,它超出session
范围之外,可以被所有sqlSession
共享,它的实现机制和MySQL的缓存一样,开启它只需要在MyBatis的配置文件开启settings
里。
寻找问题的解的一种可靠的方法是首先列出所有候选解,然后依次检查每一个,在检查完所有或部分候选解后,即可找到所需要的解。理论上,当候选解数量有限并且通过检查所有或部分候选解能够得到所需解时,上述方法是可行的。
不过,在实际应用中,很少使用这种方法,因为候选解的数量通常都非常大(比如指数级,甚至是大数阶乘),即便采用最快的计算机也只能解决规模很小的问题。
对候选解进行系统检查的方法有多种,其中回溯和分枝定界法是比较常用的两种方法。按照这两种方法对候选解进行系统检查通常会使问题的求解时间大大减少(无论对于最坏情形还是对于一般情形)。事实上,这些方法可以使我们避免对很大的候选解集合进行检查,同时能够保证算法运行结束时可以找到所需要的解。因此,这些方法通常能够用来求解规模很大的问题。
回溯算法也叫试探法,它是一种系统地搜索问题的解的方法(一种选优搜索法,按选优条件向前搜索,以达到目标)。当搜索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术称为:回溯法,而满足回溯条件的某个状态的点称为:“回溯点”。
回溯法实际是穷举算法,按问题某种变化趋势穷举下去,如某状态的变化用完还没有得到最优解,则返回上一种状态继续穷举。
许多复杂的,规模较大的问题都可以使用回溯法,回溯算法有“通用解题方法”的美称,其采用了一种“走不通就掉头”思想作为其控制结构,用它可以求出问题的所有解和任意解。
它的应用很广泛,很多算法都用到回溯法,例如,迷宫,八皇后问题,图的m着色总是等都用到回溯法,当然其中还使用了其他策略。
原子性就是说一个操作不可以被中途CPU暂停然后调度,即不能被中断,要不就执行完,要不就不执行。
是不能被线程调度机制中断的操作,一旦操作开始,那么它一定可以在可能发生中断之前执行完毕。
一个不正确的知识:“原子操作不需要进行同步控制”。
原子性可以应用于基本数据类型(64位的long
和double
不是原子性),对于写入和读取,可以把它们当作原子操作来操作内存。但是,JVM可以将64(long
和double
)的读取和写入当作两个分离的32位操作来执行,这个就产生在读取和写入操作中间发生上下文切换问题,导致不同的任务可以看到不正确结果。
Update your browser to view this website correctly. Update my browser now