顶哥说官网:www.dintalk.cn 同时更新!
MyBatis概述
开发环境,流程及生命周期
映射器
动态sql和高级查询
嵌套查询和延迟加载
事务控制及数据源
MyBatis的缓存
附录:常用配置
一:MyBatis概述
MyBatis的前身是Apache的一个开源项目iBatis,2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis。2013年11月迁移到GitHub,因此目前MyBatis是由GitHub维护的。
同样作为持久层框架的Hibernate在前些年非常的火,它在配置了映射文件和数据库连接文件后就可以通过Session操作,它甚至提供了HQL去操作POJO进而操作数据库的数据,几乎可以使编程人员脱离sql语言。可是为什么MyBatis却越来越受欢迎呢?我们稍稍总结如下:
Hibernate: 1.不方便的全表映射,比如更新时需要发送所有的字段;
2.无法根据不同的条件组装不同sql;
3.对多表关联和复制sql查询支持较差;
4.有HQL但性能较差,做不到sql优化;
5.不能有效支持存储过程;
在当今的大型互联网中,灵活、sql优化,减少数据的传递是最基本的优化方法,但是Hibernate却无法满足我们的需求,而MyBatis提供了更灵活、更方便的方法。在MyBatis里,我们需要自己编写sql,虽然比Hibernate配置要多,但是是MyBatis可以配置动态sql,也可以优化sql,且支持存储过程,MyBatis几乎能做到 JDBC 所能做到的所有事情!凭借其高度灵活、可优化、易维护等特点,成为目前大型移动互联网项目的首选框架。
二:开发环境、流程及生命周期
1.开发环境
1.1 导入依赖jar包
导入mybatis的jar包,如果采用Maven进行部署,只需导入mybatis坐标。
导入数据库驱动jar包或坐标。
代码调试阶段可导入日志工具jar包或坐标,如log4j。
导入Junit单元测试坐标。
1.2 创建mybatis的主配置文件
在resources目录下建立一个名字为mybatis-config.xml(名称随意)配置文件,编写所需配置信息。
1.3 准备实体类和表结构
遵循开发规范:
类属性命名尽量和表字段保持一致。
实体类实现序列化接口。
实体类属性使用包装类型定义,如Integer。
Tips: 有时可以考虑通过定义时初始化来避免可能的空指针异常!
如:private List list = new ArrayList<>() ;
1.4 创建Mapper接口(Dao接口)建立接口方法和sql映射文件
创建Mapper接口,在内定义CRUD方法。
**Tips:** 方法名唯一,需要在对应的mapper.xml文件中配置id。
在resources下创建sql映射文件。
**Tips:** 同对应的Mapper接口保持包结构及命名一致。
如:Mapper接口:cn.dintalk.dao.UserMapper
对应配置文件:cn.dintalk.dao.UserMapper.xml
1.5 将映射文件加入到mybatis主配置文件中
将映射文件通过引入的方式加入到mybatis的主配置文件中。
**Tips:** 所有映射文件会随主配置文件在程序运行时加入内存,任一映射文件出错都会导致整个环境报错!(初学者经常搞混resultType和resultMap)。
1.6 编写代码进行CRUD操作
在映射文件中编写sql进行crud操作,在单元测试中,或service层中调用方法!
2.开发流程
环境搭建好后开发基本流程为:
接口定义方法 。
Mapper.xml文件中编写sql。
单元测试或service调用。
Tips: 接口中方法名称和Mapper.xml文件中sql语句的id保持一致!
3.生命周期
MyBatis的核心组件:
SqlSessionFactoryBuilder(构造器):根据配置信息或代码生成SqlSessionFactory
SqlSessionFactory(工厂接口):依靠工厂来生成SqlSession(会话)。
SqlSession(会话): 既可以发生sql去执行并返回结果,也可以获取Mapper的接口
SQL Mapper:它是MyBatis新设计的组件,它是由一个java接口和xml文件(或注解)构成的,需要给出对应的sql和映射规则。它负责发送sql去执行,并返回结果。
正确理解并掌握上述核心组件的生命周期可以让我们写出高效的程序,还可避免带来严重的并发问题。
3.1 SqlSessionFactoryBuilder
其作用就是利用xml或java编码获得资源来构建SqlSessionFactory对象,构建成功就失去了存在的意义,将其回收。所以它的生命周期只存在于方法的局部。
3.2 SqlSessionFactory
SqlSessionFactory的作用是创建SqlSession,而SqlSession就是一个会话,相当于JDBC中的Connection对象,每次访问数据库都需要通过SqlSessionFactory创建SqlSession,所以SqlSessionFactory应该在MyBatis应用的整个生命周期中。我们使每一个数据库只对应一个SqlSessionFactory(单例模式)。
3.3 SqlSession
SqlSession是一个会话,相当于JDBC的一个Connection对象,它的生命周期应该是在请求数据库处理事务的过程中。是一个线程不安全的对象,涉及多线程时格外当心。此外,每次创建的SqlSession都必须及时关闭它。
3.4 Mapper
Mapper是一个接口,没有任何实现类,其作用是发送sql,返回我们需要的结果,或者执行sql修改数据库数据,因此它也因该在一个SqlSession事务方法之内,是一个方法级别的东西。就如同 JDBC中的一条sql语句的执行,它的最大范围和SqlSession是相同的。
Tips: 根据核心组件封装工具、形成SqlSession使用模板
public class MyBatisUtil {
private static SqlSessionFactory build =null; static {
try { //使用MyBatis的Resources加载资源获得输入流,构建工厂 InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml"); build = new SqlSessionFactoryBuilder().build(inputStream); } catch (IOException e) {
throw new RuntimeException("资源文件加载失败!"); } } //使用工厂生产sqlSession public static SqlSession openSession(){
return build.openSession(); }}
SqlSession使用方法
//1.定义sqlSessionSqlSession sqlSession = null;try {
sqlSession = openSession(); //2.获取映射器 UserMapper mapper = sqlSession.getMapper(UserMapper.class); //3.some code like 'User u = mapper.findById(id);' //4.sqlSession不提交默认回滚&#