• 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:维护了一条
  • 相关阅读:
    Spark面对OOM问题的解决方法及优化总结 (转载)
    spark rdd 宽窄依赖理解
    hive orc update
    hive sql 语句执行顺序及执行计划
    java 正则 贪婪匹配 匹配sql语句中的引号内容
    java 权重随机算法实现
    MySQL创建用户和加限权
    MySQL完整性约束
    MySQL基础操作与数据类型
    MySQL数据库初识
  • 原文地址:https://www.cnblogs.com/bingyimeiling/p/14746106.html
Copyright © 2020-2023  润新知