Java教程

mybatis学习笔记

本文主要是介绍mybatis学习笔记,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
第一部分:自定义持久层框架 1.1 原始JDBC编写步骤及存在问题 1.2 问题解决思路 1.3 自定义框架设计 1.4 自定义框架实现 1.5 自定义框架优化 第二部分:Mybatis相关概念 第三部分:Mybatis基本应用 3.1 开发步骤 3.2 Mybatis映射文件概述 3.3 MyBatis核心配置文件层级关系 3.4 Mybatis核心配置文件SqlSessionConfig.xml解析 3.5 mybatis 常用API介绍 3.6 Mybatis的Dao层实现方式 3.7 动态sql语句 第四部分:Mybatis复杂映射开发 第五部分:Mybatis注解开发 第六部分:Mybatis缓存 6.1 一级缓存 6.2 二级缓存 6.3 二级缓存整合redis 第七部分:Mybatis插件 7.1 插件介绍 7.2 Mybatis插件原理 7.3 自定义插件 7.4 pageHelper分页插件 7.5 通用Mappper 第八部分:Mybatis架构原理 8.1 功能架构分层 8.2 主要构件及其关系 第九部分: Mybatis源码解析 第一部分:自定义持久层框架   1.1 原始JDBC编写步骤及存在问题 编写步骤(查询): 加载数据库驱动--》通过驱动管理类获取数据库连接--》定义sql语句--》获取预编译statement--》设置参数--》向数据库发出sql执行查询,查询结果集--》遍历结果集,封装实体--》关闭资源   存在问题: 1)频繁的创建、释放数据库连接会造成系统资源的浪费,从而影响系统性能。 2)sql语句存在硬编码、使用preparedStatement向有占位符传参数存在硬编码、结果集解析的时候存在硬编码,造成代码不易维护。   1.2 问题解决思路 1)使用数据库连接池初始化连接资源 2)将sql抽取到xml文件中 3)使用反射、内省等底层技术,将数据库字段与实体属性进行自动映射。   1.3 自定义框架设计 使用端: 提供核心配置文件: SqlMapConfig.xml:存放数据源信息,引入Mapper.xml Mapper.xml:存放sql语句的配置信息   框架端:本质是对jdbc的封装 1)读取配置文件 首先以流的形式读取配置文件,然后将字节输入流存进两个javabean对象,方便后续的操作。 两个javabean如下: Configuration:存放数据库基本信息,Map<namespace+"."+id,mappedstatement> MappedStatement:id标识,sql语句,statement类型(select,insert,update,delete),输入参数java类型,输出参数java类型   2)解析配置文件 创建SqlSessionFactoryBuilder类 方法: SqlSessionFactory build() 第一:使用dom4j解析配置文件,将解析出来的内容封装到Configuration和MappedStatement中 第二:创建SqlSessionFactory的实现类DefaultSqlSessionFactory   3)创建SqlSessionFactory 方法:openSession() :获取SqlSession接口的实现类实例对象   4)创建SqlSession接口及实现类DefaultSqlSession,主要封装crud方法 方法:selectList(String stateMentId, Object param):查询所有 selectOne(String stateMentId, Object param):查询单个 ... 具体实现:封装jdbc完成对数据库的操作 5)Executor,实现类SimpleExecutor   涉及到的设计模式: Builder构建者模式,工厂模式,代理模式   1.4 自定义框架实现 动手敲一下代码。。。   1.5 自定义框架优化 上述自定义框架存在的问题: 1) dao的实现类里存在重复代码,整个操作的过程模板重复(创建sqlSession,调用sqlSession,关闭sqlSession) 2) dao实现类中存在硬编码,调用sqlSession方法时,参数statement的id硬编码   解决方案:使用代理模式来创建接口的代理对象(不管代理对象调用何方法,都会转到invoke())   代理模式注意事项:
  • Mapper.xml文件中的namespace与Mapper接口中的全限定名相同
  • Mapper.xml中定义的每个statement的id与Mapper接口的方法名相同
  • Mapper.xml中定义的每个sql的parameterType与Mapper接口的输入参数类型相同
  • Mapper.xml中定义的每个sql的resultType与Mapper接口的输出参数类型相同
  Mapper 接口的工作原理是JDK动态代理,Mybatis运行时会使用JDK动态代理为Mapper接口生成代理对象proxy,代理对象会拦截接口方法,根据类的全限定名+方法名,唯一定位到一个MapperStatement并调用执行器执行所代表的sql,然后将sql执行结果返回。   Mapper接口里的方法,是不能重载的,因为是使用 全限名+方法名 的保存和寻找策略。     第二部分:Mybatis相关概念   Mybatis是一款优秀的基于ORM(对象关系映射)的半自动化轻量级的持久层框架,SQL与JAVA编码分离。   第三部分:Mybatis基本应用   3.1 开发步骤 1) 添加Mybatis坐标 2)创建user数据库表 3)编写user实体类 4)编写映射文件UserMapper.xml 5)编写核心配置文件SqlMapConfig.xml 6)编写测试类   注:增加,更新,删除操作涉及数据库变化,要使用sqlSession对象显示的提交事务, 即sqlSesison.commit();因为sqlSessionFactory.openSession()默认开启一个事务,但不会主动提交。 如果需要它主动提交,需要调用它的有参构造方法sqlSessionFactory.openSession(true).     3.2 Mybatis映射文件概述 0 3.3 MyBatis核心配置文件层级关系   0 3.4 Mybatis核心配置文件SqlSessionConfig.xml解析 1)environments标签 数据库环境的配置,支持多配置 0 其中: 事务管理器transactionManagee有两种类型:JDBC和MANAGED 数据源datasource有三种类型:POOLED,UNPOOLED,JNDI   2)mapper标签 该标签的作用是加载映射,加载方式如下:
  • 使用相对类路径的资源引用,例如:
   
  • 使用完全限定资源定位符(url),例如:
   
  • 使用映射器接口实现类的完全限定类名,例如:
   
  • 将包内的映射器接口实现全部注册为映射器,例如
    3)properties标签 用于加载外部的properties文件,习惯上将数据源的信息单独抽取成一个properties配置文件   4)typeAliases标签 类型别名     3.5 mybatis 常用API介绍 SqlSession工厂构建器SqlSessionFactoryBuilder 常用API: SqlSessionFactory build(IputStream, inputStream) SqlSession工厂对象SqlSessionFactory 常用API:openSession()(需要手动提交事务)或openSesison(true)(自动提交事务) SqlSession会话对象 常用APi:增删改查方法。。。     3.6 Mybatis的Dao层实现方式   1)传统开发方式 需要编写dao接口及实现类(实现类有重复代码,且statementId存在硬编码问题)   2)代理开发方式 开发人员只需要编写Mapper接口(相当于dao接口),由Mybatis框架根据接口定义生成动态代理对象,代理对象的方法体同上面的dao接口实现类的方法。 Mapper接口需要遵循以下规范:
  • Mapper.xml文件中的namespace与Mapper接口中的全限定名相同
  • Mapper.xml中定义的每个statement的id与Mapper接口的方法名相同
  • Mapper.xml中定义的每个sql的parameterType与Mapper接口的输入参数类型相同
  • Mapper.xml中定义的每个sql的resultType与Mapper接口的输出参数类型相同
  3.7 动态sql语句       and id=#{id}   ...         #{id}       sql片段抽取   第四部分:Mybatis复杂映射开发 一对一配置 一对多配置 多对多配置   第五部分:Mybatis注解开发 @Insert:实现新增 @Update:实现更新 @Delete:实现删除 @Select:实现查询 @Result:实现结果集封装 @Results:可以与@Result 一起使用,封装多个结果集 @One:实现一对一结果集封装 @Many:实现一对多结果集封装   第六部分:Mybatis缓存   一级缓存和二级缓存底层的数据结构都是HashMap Mybatis默认实现的缓存类是PerpetualCahe 自定义缓存类必须实现Cache类     6.1 一级缓存 Mybatis的一级缓存是指SQLSession,一级缓存的作用域是SQlSession, Mabits默认开启一级缓存。 在同一个SqlSession中,执行相同的SQL查询时;第一次会去查询数据库,并写在缓存中,第二次会直接从缓存中取。 当执行SQL时候两次查询中间发生了增删改的操作,则SQLSession的缓存会被清空。 每次查询会先去缓存中找,如果找不到,再去数据库查询,然后把结果写到缓存中。 Mybatis的内部缓存使用一个HashMap,key(statementId+rowBounds参数+sql语句)。Value为查询出来的结果集映射成的java对象。 SqlSession执行insert、update、delete等操作commit后会清空该SQLSession缓存。 0   6.2 二级缓存 二级缓存的原理同一级缓存 但二级缓存是基于Mapper文件的namespace的,也就是说多个sqlSession可以共享一个Mapper中的二级缓存区域, 并且,如果两个Mapper的namespace相同,即使是两个mapper,那么这两个Mapper中执行sql查询的数据也将保存到相同的二级缓存区域中。   二级缓存默认是关闭的,需要手动开启!! 开启二级缓存步骤: 1)首先在全局配置文件SqlMapConfig.xml文件中加入以下代码:       2) 其次在Mapper.xml中开启缓存 < cache>   开启二级缓存后,对应的POJO类需要实现序列化接口serializable,为了将缓存数据取出来执行反序列化操作, 因为二级缓存数据存储介质多种多样,不一定只存在内存中,有可能存在硬盘中,如果我们再取这个缓存的时候,就需要反序列化了。   当一级缓存和二级缓存同时存在:先查询二级缓存再查询一级缓存,因为一级缓存的实现在BaseExecutor,而二级缓存的实现在CachingExecutor,CachingExecutor是BaseExecutor的装饰器   userCache和flushCache 在statement中设置userCahce = "false"可以禁用当前select语句的二级缓存。useCahce默认是true。 在statement中设置flushCache="true",可以刷新缓存,默认是true。在mapper的同一个namespace中,如果有其它的insert,update,delete操作数据后需要刷新缓存,如果不执行缓存会存在脏读。   二级缓存的默认实现类是PerpetualCache   6.3 二级缓存整合redis mybatis自带的二级缓存仅支持单服务器工作,无法实现分布式缓存。 分布式缓存:在几个不同的服务器之间,我们使用第三方框架,将缓存存进第三方框架中(redis,memcached,ehcache),然后无论有多少台服务器,我们都能从缓存中获取数据。   mybatis提供了一个针对cache接口的redis实现类,该类存在mybatis-redis包中 需要在mapper.xml 中加入cache的类型指向   mybais-redis在存数据的时候,是使用的hash结构,把hash的id作为这个hash的key(hash的key在mybatis中就是mapper中的namespace); 这个mapper中的查询数据作为hash的filed,需要缓存的内容直接使用serializeUtil存储,serializeUtil和其它序列化类差不多,负责对象的序列化和反序列化。     第七部分:Mybatis插件   7.1 插件介绍 Mybatis四大核心对象:Executor,StatementHandler,ParameterHandler,ResultSetHandler Mybatis支持用插件对四大核心对象进行拦截,对Mybatis来说,插件就是拦截器,用来增强核心对象的功能,增强功能本质上是借助于底层的动态代理实现的, 换句话说,Mybatis的四大对象都是代理对象。   Mybatis所允许拦截的方法如下:
  • 执行器Executor(update,query,commit,rollback等方法)
  • Sql语法构建器StatementHandler(prepare,parameterize,batch,updates,query等方法)
  • 参数处理器ParameterHandler(getParameterObject,setParameters方法)
  • 结果处理器ResultSetHandler(handleResultSets,handleOutputParameters等方法)
  7.2 Mybatis插件原理   当我们定义一个插件,并在SqlMapConfig.xml增加插件配置后,这样Mybatis在启动的时候就可以加载插件,并保存插件实例到相关对象(InterceptorChain拦截器链)中. 待准备工作完成后,Mybatis处于就绪状态。我们再执行sql的时候,需要先通过DefaultSqlSessionFactory创建SqlSession. Execoutor实例会在创建SqlSession的过程中被创建,Executor实例被创建完毕之后,Mybatis会通过JDK动态代理为实例生代理类, 这样,插件逻辑即可以在Executor相关方法调用前被调用。   7.3 自定义插件 自定义插件需要实现Interceptor接口,并重写 Object intercept(Invocation invocation)方法和 Object plugin(Object target)及void setProperties(Properties properties)方法 0   0   7.4 pageHelper分页插件   开发步骤: 1)导入通用的pageHelper坐标 2)在Mybatis核心配置文件SqlMapConfig.xml中配置pageHelper插件 3)测试分页数据获取   7.5 通用Mappper 通用mappper就是为了解决单表的增删改查,基于mybatis的插件机制,开发人员不需要写sql,不需要在dao的增加方法,需要写好实体类,就能支持增删改查方法。 具体参考老师的笔记!!   第八部分:Mybatis架构原理   8.1 功能架构分层 Mybatis的功能架构可分为三层: 1)API接口层 Mybatis与数据库交互有两种方式: a)使用传统的Mybatis提供的API b)使用Mapper的代理方式 2)数据库处理层 负责具体的sql查找,sql解析,sql执行和执行结果映射等操作。它主要的目的是根据调用的请求完成一次性数据库操作。 3)基础支撑层 负责最基础的功能支撑,包括连接管理,事务管理,配置加载和缓存处理。   8.2 主要构件及其关系
  • SqlSesison :作为Mybatis工作的主要顶层API,表示和数据库交互的会话,完成必要数据库的增删改查功能。
  • Executor:Mybatis执行器,是Mybatis调度的核心,负责SQl语句的生成和查询缓存的维护
  • StatementHandler:封装了JDBC的statement操作(设置参数,将Statement结果集转成list集合)
  • ParameterHandler:负责对用户传递的参数转成JDBC Statement所需要的参数
  • ResultSetHandler:负责将JDBC返回的ResultSet结果集转换成List类型的集合
  • TypeHandler:负责Java类型和JDBC数据类型之间的映射和转换
  • MappedStatement:维护了一条
这篇关于mybatis学习笔记的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!