四、缓存
1、介绍
(1)作用:就是提升查询的效率;
(2)分类:
- 一缓(本地缓存):session 级别的缓存,默认开启,session关闭则失效;
- 二缓(全局缓存):namespace级别的缓存,要手动开启;
2、一级缓存
(1)一级缓存失效的四种情况
- sqlsession 不同,不同的session 之间不能共享数据;
- 参数不同的情况;
- 两次相同的查询之间有 增删改 的操作;
- 第二次查询之前手动清空缓存;
3、二级缓存
(1)作用:可以实现不同的 session 之间的数据共享,一个 namespace(一个接口)对应一个map(二级缓存);
(2)原理:
- 一次会话中查询的数据会默认保存在一级缓存中;
- 当对应的会话关闭的时候,如果开启了二级缓存,在session关闭清空缓存数据之前会将数据存到二级缓存中;
- 需要注意的是如果 session 没有关闭,一级缓存的数据是不会自动存到二级缓存中的;
(3)使用:总开关(主配文件里的 setting)和分开关(sql映射文件里用 cache标签来开启)都要打开;
4、缓存原理和设置
(1)缓存相关设置
- 全局的 cacheEnabled 和 select 标签的 useCache 都是和二级缓存相关的设置,不会影响一级缓存;
- flashCache属性在增删改的标签里是默认开启,在 select 标签里是默认关闭的,这个属性为 true的话会清空一二级的缓存;
- session 的 clearcache 方法只会清除当前 session 的一级缓存;
- 全局 LocalcacheScope 可以用来关闭一级缓存(一般不用);
(2)原理图示
5、第三方缓存整合(ehcache)
(1)步骤:
- 导入缓存的包和整合包;
- 引入ehcache配置文件;
- 直接在mapper xml 中用 cache 标签引用;
- 另一个 mapper 可以用 cache-ref 标签来引用其他 mapper 的缓存策略;
五、整合spring(SSM整合)
1、导包
(1)核心包:spring包、springmvc包、mybatis包、spring-mybatis整合包
(2)其他包:日志包、连接池包
2、mybatis 配置
(1)主要就是配全局 settings 等;
3、springMVC 配置
(1)controller 扫描;
(2)视图解析器;
(3)注解驱动;
(4)默认servlet 处理;
4、spring 配置
(1)包扫描;
(2)数据源的配置;
(3)事务管理(基于注解的事务);
(4)sqlSessionFactory配置;
(5)配置可以批量执行的 sqlSession;
(6)配置Mapper 接口的扫描(不可少);
5、web.xml配置
(1)全局参数配置 spring配置文件的路径;
(2)配置spring 监听;
(3)配置 springmvc 的DispatcherServlet;
(4)spring框架会自动加载 web-inf 下的配置文件,classpath 路径下的配置文件需要配置路径;
(5)所有配置文件的示例;
六、逆向工程
1、概念
- 就是根据数据库表自动生成 bean、mapper 和相应的映射文件;
- 逆向工程常用的方法有:配置 eclipse 插件生成;使用java 工程来生成;
2、使用
(1)导包
(2)配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<!-- targetRuntime="MyBatis3Simple":生成简单版的CRUD
MyBatis3:豪华版 -->
<context id="DB2Tables" targetRuntime="MyBatis3">
<!-- jdbcConnection:指定如何连接到目标数据库 -->
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/mybatis?allowMultiQueries=true"
userId="root"
password="123456">
</jdbcConnection>
<!-- -->
<javaTypeResolver >
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
<!-- javaModelGenerator:指定javaBean的生成策略
targetPackage="test.model":目标包名
targetProject="\MBGTestProject\src":目标工程
-->
<javaModelGenerator targetPackage="com.atguigu.mybatis.bean"
targetProject=".\src">
<property name="enableSubPackages" value="true" />
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!-- sqlMapGenerator:sql映射生成策略: -->
<sqlMapGenerator targetPackage="com.atguigu.mybatis.dao"
targetProject=".\conf">
<property name="enableSubPackages" value="true" />
</sqlMapGenerator>
<!-- javaClientGenerator:指定mapper接口所在的位置 -->
<javaClientGenerator type="XMLMAPPER" targetPackage="com.atguigu.mybatis.dao"
targetProject=".\src">
<property name="enableSubPackages" value="true" />
</javaClientGenerator>
<!-- 指定要逆向分析哪些表:根据表要创建javaBean -->
<table tableName="tbl_dept" domainObjectName="Department"></table>
<table tableName="tbl_employee" domainObjectName="Employee"></table>
</context>
</generatorConfiguration>
(3)运行生成器 java 代码
public void testMbg() throws Exception {
List<String> warnings = new ArrayList<String>();
boolean overwrite = true;
File configFile = new File("mbg.xml");
ConfigurationParser cp = new ConfigurationParser(warnings);
Configuration config = cp.parseConfiguration(configFile);
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config,
callback, warnings);
myBatisGenerator.generate(null);
}
3、注意事项
- mybatis 的SSM集成和逆向工程的具体使用方法和示例代码 github 上官方目录都有;
- 可以生成简单查询和复杂查询的代码,复杂查询的方式类似于 hibernate 的 QBC;
- or 条件的拼接
EmployeeExample example = new EmployeeExample();
Criteria criteria = example.createCriteria();
criteria.andLastNameLike("%e%");
criteria.andGenderEqualTo("1");
Criteria criteria2 = example.createCriteria();
criteria2.andEmailLike("%e%");
example.or(criteria2);
七、运行原理
1、sqlsessionfactory 初始化
- 把配置文件所有的信息解析并保存在 configuration 中,并返回一个包含 configuration 的 defaultSqlSessionFactory 对象;
- 一个 mapperedStatement 代表一个增删改查的信息;
2、sqlsession 对象获取
- 返回一个 defaultSqlSession 对象,里面包含了 configuration 和 executor;
- executor的两次包装:二级缓存开启的话会有一次包装;拦截器链会有一次包装;
3、获取接口代理对象
- 调用 getMapper 方法实际上是从一个 mapperproxyfactory 的工厂类中获得 mapperproxy 对象,里面包含了defaultsqlsession;
4、查询实现
-
注意:在四大对象的创建过程中都会有插件的介入;
八、插件扩展
1、插件开发
(1)原理
- 四大对象的创建不是直接返回的,而是 intercepter 调用了 plugin 方法包装生成代理对象;
- 我们可以使用插件对四大对象进行包装生成代理对象,这样就可以拦截到四大对象的每一个执行;
(2)简单实现--单个插件
- 写一个类继承intercepter ,重写 intercept(拦截)、plugin(包装)、和 setProperties(属性设置)方法;
- 用 @intercepts 注解给插件签名;
- 在全局配置文件中引用插件;
(3)多个插件:拦截同一个对象同一个方法
- 包装:顺序包装;
- 执行:逆序执行;
- 特点:多个插件是对目标对象进行层层包装的;
(4)开发示例:
(5)PageHelper 插件
- 实现分页相关功能
- 使用:导包-----主配置文件注册插件------mapper查询前设置参数;
- 说明:参数设置后可以返回一个 page 对象其中包含很多分页信息;也可以用pageinfo包装查询结果;
2、扩展
(1)批量执行sql语句
- 普通使用:就是在 openSession 传入 executorType;
- 与 Spring 集成:
<!--配置一个可以进行批量执行的sqlSession -->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg name="sqlSessionFactory" ref="sqlSessionFactoryBean"></constructor-arg>
<constructor-arg name="executorType" value="BATCH"></constructor-arg>
</bean>
- mybatis 主配置文件的setting 里有一个批量执行的开关,但是不建议开启,因为会影响所有的sql执行;
(2)mybatis 调用存储过程
- 带游标的存储过程的创建(oracle分页查询):存储过程语法、游标使用;
- 调用过程:select 标签设置 statementtype参数;{call proname(args)};游标的封装用到resultMap;
(3)自定义类型处理器处理枚举类型
- 枚举类型:name(名)和 ordinal(suoyin);
- 使用 mybatis 自带的类型处理器:只能保存名字或者索引中的一个;
- 自定义:类继承typehandler;重写相应方法(实质就是调用ps和rs 的 get 和 set 方法);主配置文件中注册;
- 说明:枚举的本质就是一个类;枚举的值本质就是枚举对象;枚举当然也可以有构造方法;
- 注意:保存数据的时候可以针对具体的字段设置 typehandler;select 查询的时候也可以针对具体字段在 resultMap中指定typeHandler,但是必须保证保存和查询的typeHandler是一致的