一级缓存是statement缓存
建造者模式:SqlSessionFactoryBulider,XMLConfgBulider,XMLMapperBuilder
工厂模式:SqlSessionFactory、MapperProxyFactory
单例模式:ErrorContext
代理模式:JDK动态代理MapperProxy
模版方法模式:BaseExecution和simpleExecution
适配器模式:对其他的日志框架实现适配
装饰者模式:二级缓存就是使用装饰者模式实现的
(1)首先通过Resource类的方法去通过mybatis的xml文件获取InputStreamReader IO流
(2)SqlSessionFactoryBulider调用buile方法,Build方法内部创建了XMLConfigBuilder对象去解析mybatis.xml文件转换成Configuration对象,用XMLMapperBuilder去解析配置文件。把mapper.xml所在的位置存放到hashset中,把接口的class文件注册到mapperRegister中,然后使用Configuration对象创建了DefaultSqlSessionFactory
(3)通过SqlSessionFactory.openSession()获取到sqlsession对象,openSession方法中通过Configuration对象和执行器(BatchExecutor 批处理,SimpleExecutor 简单)去创建DefaultSqlSession,在创建执行器的时候会去判断创建哪种类型的执行器,批处理或者简单类型的,最后会去判断是否创建二级缓存执行器,默认是开启的,通过简单或者批处理执行器去创建
(4)通过sqlsession.getMapper方法去获取到Mapper对象,底层是使用JDK动态代理模式获取的对象,getMapper就是从mapperRegister中找的
(1)sql语句与代码分离,存放于xml配置文件中,降低耦合度,便于维护管理
(2)Mybatis是一个持久层框架(写入硬盘)
(3)提供XML标签,支持动态sql(例如if else)
(4)提供映射标签,支持对象和数据库的ORM字段关系映射(property column)
(5)封装了JDBC,与传统的JDBC相比,减少了50%以上的代码量
(1)SQL语句的编写工作量大
(2)SQL语句依赖数据库,移植性差
Mybatis是一个半ORM(对象关系映射)的持久层框架,简单封装了JDBC
注解:适合单表简单操作
XML:适合复制操作
(1)性能要求高
(2)需求变动大,SQL语句可以灵活改动
#{}是预编译处理,${}是字符串替换。
适用#{}可以有效的防止注入攻击
(1)字段取别名
(2)resultMap
(1)加载驱动
(2)获取连接
(3)创建statement对象
(4)执行sql
(5)关闭资源
public void test_insert()
{
String driver="oracle.jdbc.driver.OracleDriver";
String url="jdbc:oracle:thin:@127.0.0.1:1521:orcl";//orcl为sid
String user="briup";
String password="briup";
Connection conn=null;
Statement stat=null;
try {
//1、注册驱动
Class.forName(driver);
//2、获取连接
conn= DriverManager.getConnection(url, user, password);
//System.out.println(conn);
//3、创建statement对象
stat=conn.createStatement();
//4、执行sql语句
String sql="insert into lover values(5,'suxingxing',to_date('21-9-2016','dd-mm-yyyy'))";
stat.execute(sql);
//System.out.println(stat.execute(sql));
//5、处理结果集,如果有的话就处理,没有就不用处理,当然insert语句就不用处理了
} catch (Exception e) {
e.printStackTrace();
}
finally{
//6、关闭资源
try {
if(stat!=null)stat.close();
} catch (SQLException e) {
e.printStackTrace();
}
try {
if(conn!=null)conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
(1)like #{value} 传值时加入%
(2)like “%”#{value}"%"
(3)like concat("%",#{value},"%")
(1)Mapper接口中的方法不能重载,因为xml中id是根据方法名识别的
(2)每一个、、、标签,都会被解析为一个MapperStatement对象。
(3)Mapper 接口的工作原理是JDK动态代理
(1)Mybatis使用RowBounds对象进行分页,它是针对ResultSet结果集执行的内存分页,而非物理分页。
(2)分页插件的基本原理是使用Mybatis提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的sql,然后重写sql
(1)通过反射创建对象
(2)使用标签,一一对应
(3)使用别名对应 as
先循环插入且不提交,全部插入后一次性提交
(1)直接传入,用#{0},#{1}表示第几个参数
(2)@param(“name”) String name,用#{name}获取
(3)传入对象,用#{name}获取
(1)动态编写sql语句
(2)根据表达式,完成逻辑判断,动态拼接sql
(3)九种标签:trim | where | set | foreach | if | choose | when | otherwise | bind
(1)、、、、,加上动态sql的9个标签,其中为sql片段标签,通过标签引入sql片段,为不支持自增的主键生成策略标签。
(1)namespace+id作为key,只要namespace不同,id相同也行
(1)Hibernate属于全自动ORM映射工具,使用Hibernate查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取,所以它是全自动的。
(2)Mybatis在查询关联对象或关联集合对象时,需要手动编写sql来完成,所以,称之为半自动ORM映射工具。
一对一:association
一对多:collection
(1)association和collection可以配置lazyLoadingEnabled=true|false
(2)使用CGLIB动态代理,在真正调用的时候才去查询指定sql
<association property="customer" javaType="cn.com.mybatis.po.Customer" select="findCustomerById" column="cus_id">
</association>
<select id="findCustomerById" parameterType="int" resultType="cn.com.mybatis.po.Customer">
select * from customer where cus_id=#{id}
</select>
<settings>
<!-- 打开延迟加载的开关 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 将积极加载改为消极加载(即按需加载) -->
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
1)一级缓存: 基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 Session,当 Session flush 或 close 之后,该 Session 中的所有 Cache 就将清空,默认打开一级缓存。
2)二级缓存与一级缓存其机制相同,默认也是采用 PerpetualCache,HashMap 存储,不同在于其存储作用域为 Mapper(Namespace),并且可自定义存储源,如 Ehcache。默认不打开二级缓存,要开启二级缓存,使用二级缓存属性类需要实现Serializable序列化接口(可用来保存对象的状态),可在它的映射文件中配置 ;
3)对于缓存数据更新机制,当某一个作用域(一级缓存 Session/二级缓存Namespaces)的进行了C/U/D 操作后,默认该作用域下所有 select 中的缓存将被 clear 掉并重新更新,如果开启了二级缓存,则只根据配置判断是否刷新。
(1)接口实现类继承SqlSessionDaoSupport
(2)xml中配置映射
(3)使用mapper扫描器
先找二级缓存,二级缓存没有配置的话,再去找一级缓存
一级缓存:sqlsession缓存
二级缓存:sqlsessionFactory缓存,存到第三方缓存
一级缓存底层是使用map集合去存放的,查询的时候会缓存到map集合中,在增删改数据的时候会去清除全部的缓存,在集群的条件下,一台节点缓存了数据之后,另一台节点去修改,此时会导致第一台出现脏读。
(1)开启二级缓存
(2)查询的时候增加随机数,但是这样map集合很快就满了
(3)在增删改的时候执行器会调用update方法会去清除缓存,我们可以调用这个clear方法清除缓存
Mybatis默认最多查询Integer最大值2^32-1
BaseExecutor:继承了Executor,实现了部分方法,是个抽象类,使用模版方法设计模式,实现他的子类有简单执行器、批处理执行器、还有重复使用执行器,默认情况下是使用简单执行器的
SimpleExecutor:简单的执行类,并不会做一些处理就执行sql
BacthExecutor:批处理执行器,toUpdate、toQuery、toFlushStatements三个方抽象法
ReuseExecutor:重复使用执行器,其中定义个一个Map
Statement:用于执行不带参数的简单SQL语句
PreparedStatement:预编译,默认采用
SqlSessionFactoryBulider:根据InputStreamReader转换流去创建SqlSessionFactory
SqlSessionFactory:根据执行器创建SqlSession
SqlSession:存放sql会话信息,属性有执行器和configuration,getMapper方法就是从configuration中的MapperRegistry中的MapperProxyFactory获取到代理类
XMLConfgBulider:用来解析mybatis配置文件,返回configuration对象
XMLMapperBuilder:主要是用于解析mybatis中的标签里边的内容
RoutingStatementHandler,这是一个封装类,它不提供具体的实现,只是根据Executor的类型,创建不同的类型StatementHandler。
SimpleStatementHandler,这个类对应于JDBC的Statement对象,用于没有预编译参数的SQL的运行。
PreparedStatementHandler 这个用于预编译参数SQL的运行。
localCache:hashmap存放一级缓存
DefaultResoultSetHandler:返回结果集给客户端