1、简介
-
什么是Mybatis?
- MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。
- MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。
- MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
- 历史
- MyBatis 本是apache的一个开源项目iBatis,
- 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。
- 2013年11月迁移到Github。
- iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAOs)
-
持久化
- 数据持久化
- 持久化就是将程序的数据在持久状态和瞬时状态转化的过程
- 瞬时状态
- 内存 断电即失
- 数据持久化
- 数据库(jdbc)、
io文件持久化(太占用资源,所以慢慢废弃)
- 数据库(jdbc)、
- 数据持久化
-
持久层
- Dao层、Service层、Controller层
- 完成持久化工作的代码块
- 层之间的界限十分明显
- Dao层、Service层、Controller层
-
使用Mybatis原因
- 传统的JDBC代码太复杂了。简化。框架。自动化
- 帮助程序员将数据存入数据库中
- 不使用Mybatis也可以写代码,只是更容易上手。
- 优点
- 简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。
- 灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。 sql写在xml里,便于统一管理和优化。通过sql语句可以满足操作数据库的所有需求。
- 解除sql与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。
- 提供映射标签,支持对象与数据库的orm字段关系映射
- 提供对象关系映射标签,支持对象关系组建维护
- 提供xml标签,支持编写动态sql
- 使用的人多!市场活跃度高
2、编写Mybatis程序的注意事项
- 注意mybatis-config.xml中配置Mapper接口与xxxMapper.xml的映射
- SqlSessionFactorybuilder
- 一旦创建了SqlSessionFactory就不再需要了
- 最佳作用域是方法作用域(局部方法变量),不要让其一直存在,保证xml解析资源卡伊被释放给更重要的事情 工具类
- SqlSessionFactory
- 一旦被创建就应该在应用的运行期间一直存在,不要重复创建多次
- 最佳作用域是应用作用域(单例模式/静态单例模式)
- SqlSession
- 每个线程都应该有它自己的SqlSession实例.
- SqlSession不是线程安全的,因此不能被共享
- 最佳作用域是请求或方法作用域,绝不能将SqlSession实例的引用放在一个类的静态域或者任何类型的托管作用域中
- 换句话说,每次收到Http请求就可以打开一个SqlSession,返回一个响应就关闭它,应该放到finlly中
- 增删改需要提交事务
- 假设我们的实体类或者数据库中的表,字段或者参数过多,我们应当考虑使用Map
- Map传递参数,直接在Sql中取出key即可
- 对象传递参数,直接在sql中取对象的属性即可
- 只有一个基本类型的情况下,可以直接在sql中取到
- 多个参数用Map
3、日志工厂
-
标准日志输出
<settings> <!--标准日志输出--> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings
-
Log4j
-
什么是Log4j?
- Log4j是Apache的一个开源项目,通过Log4j,我们可以控制日志信息疏松的目的地是控制台、文件、GUI组件
- 我们也可以控制每一条日志的输出格式
- 通过定义每一条日志信息的级别,我们能更加细致的控制日志的生成过程
- 通过一个配置文件来灵活配置,而不需要修改应用代码
-
使用
-
导入Log4j包
<dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency>
-
log4j.properties
略(网上好多)
-
配置
<settings> <setting name="logImpl" value="LOG4J"/> </settings>
-
-
简单使用
-
在要使用Log4j的类中,导入包
import org.apache.log4j.Logger;
-
创建日志对象,参数为当前类的class
static Logger logger = Logger.getLogger(Demo01.class);
-
日志等级
- 由低到高:debug<info<warn<Error<Fatal;
-
区别:
-
debug 级别最低,可以随意的使用于任何觉得有利于在调试时更详细的了解系统运行状态的东东;
-
info 重要,输出信息:用来反馈系统的当前状态给最终用户的;
后三个,警告、错误、严重错误,这三者应该都在系统运行时检测到了一个不正常的状态。
-
warn, 可修复,系统可继续运行下去;
-
Error, 可修复性,但无法确定系统会正常的工作下去;
-
Fatal, 相当严重,可以肯定这种错误已经无法修复,并且如果系统继续运行下去的话后果严重。
-
-
使用场景
- 什么时候使用 info, warn , error ?
- info 用于打印程序应该出现的正常状态信息, 便于追踪定位;
- warn 表明系统出现轻微的不合理但不影响运行和使用;
- error 表明出现了系统错误和异常,无法正常完成目标操作。
- 什么时候使用 info, warn , error ?
-
-
4、Mybatis执行流程
-
Resource获取加载全局配置文件
-
实例化SqlSessionFactoryBuilder
-
使用XMLConfigbuilder解析配置文件流,通过他的parse()方法解析mybatis配置文件
-
parse()解析完成后,他返回了一个configuration对象,用来存放mybatis核心配置文件解析完成后的结果
-
返回了一个build方法,把刚才的返回值configuration作为参数传入这个方法中,并返回了一个DefaultSqlSessionFactory对象,这是SqlSessionFactory的实现类,用来生产defaultSqlSession对象。
-
调用openSession()方法
-
Transaction,创建事务,sql执行时都要涉及到事务操作的,提交或回滚。而这个transaction产生需要environment(xml中配置的),environment是从configuration中获得的,通过这些参数transactionFactory就产生了transaction。
-
Executor,利用Trabsaction调用newExecutor创建执行器(SimpleExecutor简单执行器),他是mybatis的核心执行器,相当于jdbc中的statement,发送sql语句并执行。
-
通过得到Transaction和Executor创建出sqlSession
-
通过DefaultSqlSession的getMapper()来生成mapper接口的代理对象,(利用jdk动态代理)
-
通过返回的代理对象的getUser方法调用getMapper方法最终执行的方法
5、缓存
5.1、简介
- 什么是缓存?
- 存在内存中的临时数据
- 将用户经常查询的数据放在缓存(内存)中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)查询,从缓存中查询,从而提高查询效率,解决了高并发系统的性能问题
- 为什么使用缓存?
- 减少和数据库的交互次数,减少系统开销,提高系统效率
- 什么样的数据能使用缓存?
- 经常查询并且不经常改变的数据
5.2、Mybatis缓存
- Mybatis包含一个非常强大的查询缓存特性,它可以非常方便的定制和配置缓存.缓存可以极大的提升查询效率
- Mybatis系统默认定义了两级缓存: 一级缓存和二级缓存
- 默认情况下,只有一级缓存开启. (SqlSession级别的缓存,也成为本地缓存)
- 二级缓存需要手动开启和配置,是基于namespace级别的缓存
- 为了提高扩展性,Mybatis定义了缓存接口Cache.我们可以通过实现Cache接口来定义二级缓存
5.3、一级缓存
-
一级缓存也叫本地缓存: SqlSession
- 与数据库同一次会话期间查询到的数据会放到本地缓存中
- 以后如果需要获取相同的数据,直接从缓存中拿,没必要再去查询数据库
-
缓存失效的情况
- 查询不同的东西
- 增删改操作可能会改变原来的数据,所以必定会刷新缓存
- 查询不同的Mapper.xml
- 手动清理缓存
sqlsession.clearCache();
-
小结
- 一级缓存默认是开启的,只在一次SqlSession中有效,也就是拿到连接到关闭连接取键内有效
- 一级缓存就是一个Map
5.4、二级缓存
-
二级缓存也叫全局缓存,一级缓存作用域太低了,所以诞生了二级缓存
-
基于namespace级别的缓存,一个名称空间对应一个二级缓存
-
工作机制
- 一个会话查询一条数据,这个数据就会被放在当前会话的一级缓存中
- 如果当前会话关闭了,这个会话对应的一级缓存就没了;但是,会话关闭了,一级缓存中的数据被保存到二级缓存中.
- 心得会话查询信息,就可以从二级缓存中获取内容
- 不同的mapper查出的数据会放在自己对应的缓存(map)中
- 二级缓存是事务性的.这意味着,当SqlSession完成提交时,或是完成并回滚,但没有执行flushCache=true 的增删改语句时,缓存会获得更新
-
开启二级缓存
-
在mybatis-config.xml文件中配置setting开启全局缓存(不显式的调用也行,默认就为true)
<setting name="cacheEnabled" value="true" />
-
在xxxMapper.xml中配置cache开启缓存
<cache/>
-
也可以自定义参数
<cache eviction="FIFO" 使用FIFO输出策略 flushInterval="60000" 每过60秒进行一次刷新 size="512" 最多只能存512个缓存 readOnly="true" 只允许读 />
-
-
注意
-
在没有定义输出策略时,需要将实体类序列化,否则会报错
implements Seriailizable
-
-
小结
- 只要开启了二级缓存,在同一个Mapper下就有效
- 所有数据都会先放在一级缓存中
- 只有当会话提交,或者关闭的时候,才会提交到二级缓存中
5.5、缓存原理
- 缓存顺序
- 先看二级缓存中有没有
- 再看一级缓存中有没有
- 查询数据库
5.6、自定义缓存
-
Ehcache
- Encache是一种广泛使用的开源Java分布式缓存.主要面向通用缓存,JavaEE和轻量级容器
-
使用
-
导包
<dependency> <groupId>org.mybatis.caches</groupId> <artifactId>mybatis-ehcache</artifactId> <version>1.2.1</version> </dependency>
-
在
<cache/>
中添加type属性<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>
-
创建文件ehcache.xml文件配置
-