SSM框架阶段 - MyBatis学习总结

概述

  • MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的ORM持久层框架
  • MyBatis 消除了几乎所有的 JDBC 代码,参数的手动设置以及结果集的检索
  • MyBatis 使用简单的 XML 或注解用于配置和原始映射,将接口和 Java 的POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录
  • ORM(Object/Ralational Mapping)即对象/关系映射。是一种数据持久化技术,它在对象模型和关系型数据库之间建立起对应关系,并且提供了一种机制,通过JavaBean对象去操作数据库表中的数据,不同的持久层框架ORM是不同的
  • 持久化:即把数据保存到可永久保存的存储设备中(如磁盘,数据库等)
  • 持久层:dao/mapper层就是持久层

核心接口和类

每个MyBatis的应用程序都以一个SqlSessionFactory对象的实例为核心

  • 首先获取SqlSessionFactorBuilder对象,可以根据XML配置文件或Configuration类的实例构建该对象
  • 然后获取SqlSessionFactory对象,该对象实例可以通过SqlSessionFactoryBuilder对象来获得
  • 最后获取SqlSession实例,SqlSession对象中完全包含以数据库为背景的所有执行SQL操作的方法,可以用该实例来直接执行已映射的SQL语句
  • SqlSessionFactoryBuilder
    • SqlSessionFactoryBuilder负责构建SqlSessionFactory,并且提供了多个build()方法的重载
    • 配置信息可以以三种形式提供给SqlSessionFactoryBuilder的build()方法,InputStream(字节流)、Reader(字符流)、Configuration(类)
      • InputStream inputStream= Resources.getResourceAsStream(“mybatis/mybatis.xml”);
    • SqlSessionFactoryBuilder的最大特点:用过即丢。一旦创SqlSessionFactory对象之后,这个类就不需要存在了,因此SqlSessionFactoryBuilder的最佳范围就是存在于方法体内,也就是局部变量而已
  • SqlSessionFactory
    • SqlSessionFactory提供的openSession()方法来获取SqlSession的实例
    • openSession()方法的参数为boolean值时,若传入为true表示关闭事务控制,自动提交;false表示开始事务控制,若不传参,默认为true
    • SqlSessionFactory对象一旦创建,就会在整个应用运行过程中始终存在,没有理由去销毁或再创建它,并且再应用运行中也不建议多次创建SqlSessionFactory。因此SqlSessionFactory的最佳作用域是Application,即随着应用的生命周期一同存在,那么这种存在于整个应用运行期间,并且同时只有一个对象实例的模式称之为单例模式
  • SqlSession
    • SqlSession是用于执行持久化操作的对象,类似于JDBC中的Connection。它提供了面向数据库执行SQL命令所需的所有方法,可以通过SqlSession实例直接运行已映射的SQL语句
    • SqlSession对应着一次数据库会话。由于数据库会话不是永久的,因此SqlSession的生命周期也不应该是永久的,相反,再每一次访问数据库都需要创建它(这里并不是说SqlSession只能执行一次SQL,SqlSession完全可以执行多次,但是若关闭了SqlSession,那么就需要重新创建它),创建SqlSession的地方只有一个,那就是SqlSessionFactory对象的openSession()方法
    • 每个线程都有自己的SqlSession实例,SqlSession实例不能被共享,也不是线程安全的。因此最佳的作用域范围是request作用域或者方法体作用域内
    • 使用方式
      • 1.通过SqlSession实例来直接执行已映射的SQL语句
      • 2.基于mapper接口方式操作数据
操作步骤
  • 读取配置文件
    • InputStream inputStream= Resources.getResourceAsStream(“mybatis/mybatis.xml”);
  • 获取一个工厂类
    • SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(inputStream);
  • 获取一个sqlSession会话
    • SqlSession session = factory.openSession();
  • 获取Mapper的接口对象
    • 接口类型 对象名 = session.getMapper(接口类.class);
  • 调用接口中的方法
    • List list = 对象名.方法();
  • 事务提交
    • session.commit();
  • 关闭会话
    • session.close();
  • 注释

<select id="selectUser" resultType="com.xl.entity.UserEntity">
		SELECT
			/* SQL中的注释:采用SQL多行注释 */
			id, name, status 
		FROM
			users 
select>

MyBatis核心(全局)配置文件(mybatis-config.xml)

MyBatis 的配置文件包含了影响 MyBatis 行为的设置(settings)和属性(properties)信息

  • :配置文件的根元素节点,子元素需按顺序书写
  • :配置属性文件
    • resource属性:外部指定properties属性文件
      • name属性:属性名
      • value属性:属性值
    • 使用不在一个地方配置执行顺序为
      • 在 properties 元素体内指定的属性首先被读取
      • 然后根据 properties 元素中的 resource 属性读取全类名下属性文件或根据 url 属性指定的路径读取属性文件,并覆盖已读取的同名属性
      • 最后读取作为方法参数传递的属性,并覆盖已读取的同名属性
  • :设置MyBatis运行中的全局行为
      • name:属性名
        • cacheEnabled:对在此配置文件下的所有cache二级缓存进行全局性开关设置,默认true
        • lazyLoadingEnabled:全局性设置懒加载,默认true,如果设为fasle,则所有相关联的都会被初始化加载
        • autoMappingBehavior:MyBatis对于自动映射的匹配级别为 NONE|PARTIAL|FULL
          • NUNE:禁止自动匹配
          • PARTIAL:默认。自动匹配所有属性(要求是列名和javaBean属性名一致),有内部嵌套(association,collection)的除外
          • FULL:自动匹配所有
        • aggressivelazyLoading:属性按需加载
      • value:属性值
  • :为Java类型命名别名(别名处理器)
    • alias:别名
    • type:实体类全类名
    • 也可@Alias注解为其指定一个别名
    • MyBatis已经为许多常见的 Java 类型内建了相应的类型别名。它们都是大写不敏感的,我们在起别名的时候千万不要占用已有的别名
  • :类型处理器
    • 无论是 MyBatis 在预处理语句(PreparedStatement)中设置一个参数时还是从结果集中取出一个值时, 都会用类型处理器将获取的值以合适的方式转换成 Java 类型
  • :插件
    • 插件通过动态代理机制,可以介入四大对象的任何一个方法的执行
    • Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
    • ParameterHandler (getParameterObject, setParameters)
    • ResultSetHandler (handleResultSets, handleOutputParameters)
    • StatementHandler (prepare, parameterize, batch, update, query)
  • :配置MyBatis的多套运行环境,将SQL映射到多个不同的数据库上,该元素节点下可以配置多个environment子元素节点,但是必须指定其中一个默认运行环境(通过default指定)
    • :配置MyBatis的一套运行环境,
      • id:指定当前环境的唯一标识
      • :事务管理
        • type:MyBatis有两种事物管理类型,即JDBC、MANAGED
          • 设置其属性为JDBC,直接使用JDBC的提交和回滚功能,依赖于从数据源获得来连接来管理事务的生命周期
          • MANAGED:不提交或回滚一个连接、让容器来管理事务的整个生命周期
          • 可自定义事物管理类型:实现TransactionFactory接口,type=全名/别名
      • :数据源(库)配置
        • type:有三种数据源类型(UNPOOLED、POOLED、JNDI)
          • UNPOOLED:不使用连接池
          • POOLED:使用连接池
          • JNDI: 在EJB 或应用服务器这类容器中查找指定的数据源
          • 自定义:实现DataSourceFactory接口,定义数据源的获取方式
          • name属性:属性名
          • value属性:属性值
  • :根据不同的数据库厂商执行不同的语句
    • type:DB_VENDOR //使用MyBatis提供的VendorDatabaseIdProvider解析数据库厂商标识。也可以实现DatabaseIdProvider接口来自定义
      • 会通过 DatabaseMetaData#getDatabaseProductName() 返回的字符串进行设置。由于通常情况下这个字符串都非常长而且相同产品的不同版本会返回不同的值,所以最好通过设置属性别名来使其变短
    • Property-name:数据库厂商标识
    • Property-value:为标识起一个别名,方便SQL语句使用databaseId属性引用
    • 匹配规则
      • 如果没有配置databaseIdProvider标签,那么databaseId=null
      • 如果配置了databaseIdProvider标签,使用标签配置的name去匹配数据库信息,匹配上设置databaseId=配置指定的值,否则依旧为null
      • 如果databaseId不为null,他只会找到配置databaseId的sql语句
      • MyBatis 会加载不带 databaseId 属性和带有匹配当前数据库databaseId 属性的所有语句。如果同时找到带有 databaseId 和不带databaseId 的相同语句,则后者会被舍弃
  • :映射器作用是告诉MyBatis去哪里找到SQL映射文件(该文件内容是开发者定义的映射SQL语句),整个项目可以有一个或多个SQL映射文件
    • :获取SQL映射文件
      • resource:使用类资源路径获取资源
      • class:使用全类名获取,要求接口和映射文件同包同名
      • url:使用URL获取资源
    • :批量获取映射文件
      • name:文件所在包名 //要求接口和映射文件同包同名

SQL映射文件(mapper.xml)

  • 映射文件指导着MyBatis如何进行数据库增删改查
  • //映射文件的根元素节点,只有一个属性namespace
    • namespace:用于区分不同的mapper,全局唯一,绑定DAO接口,即面向接口编程。当namespace绑定某一接口之后(一个接口对应一个映射文件),可以不用写该接口的实现类,MyBatis会通过接口的完整限定名查找到对应的mapper配置来执行SQL语句,因此namespace的属性值必须要和接口同名
  • //映射插入语句 //映射更新语句 //映射删除语句
    • id:命名空间的唯一识别符,可以被用来引用这条语句,与接口中的方法名一致
    • parameterType:参数类型,可不传MyBatis会根据TypeHandler自动推断
    • flushCache:有语句被调用,会导致本地缓存和二级缓存被清空,默认为true
    • timeout:在抛出异常前,驱动程序等待数据库返回请求结果的秒数,默认为unset
    • statementType:默认为PREPARED映射类型,也可设置为STATEMENT映射类型,CALLABLE映射类型
    • useGeneratedKeys:MyBatis 使用 JDBC 中的 getGeneratedKeys 方法来取出由数据库内部生成的主键(MySQL),默认为false,delete中无效
    • keyProperty:指定能够唯一识别对象的属性,MyBatis通过getGeneratedKeys方法的返回值或insert语句的selectKey子元素设置它的键值,默认为unset,delete中无效
    • keyColumn:通过生成的键值设置表中列名,当主键列不是表中的第一列时需设置,在某些数据库(PostgreSQL)是必须的,delete中无效
    • databaseId:与的value值对应,若配置了databaseIdProvider,MyBatis会加载所有不带databaseId或匹配当前databaseId的语句,如果带或者不带都有,则不带的会被忽略
    • //为语句传参
      • KeyProperty:selectKey语句结果应该被设置的目标属性
      • KeyColumn:匹配属性的返回结果集中的列名称
      • resultType:结果的类型
      • order:设置为BEFORE,表示先执行selectKey中的语句,设置为AFTER,表示先执行外层语句
      • statementType:默认为PREPARED映射类型,也可设置为STATEMENT映射类型,CALLABLE映射类型
    • #{key}:获取参数的值,预编译到SQL中,安全,类似JDBC的PreparedStatement可防止SQL注入,返回字符串带引号 ‘’
    • ${key}:获取参数的值,拼接到SQL中,有SQL注入问题
  • 中resultMap的id名称
  • type:需要映射到的类对象
  • 如果设置这个属性,MyBatis 将会为本结果映射开启或者关闭自动映射。 这个属性会覆盖全局的属性 autoMappingBehavior。默认值:未设置(unset)
  • //将查询结果作为参数注入到实例的构造方法中
    • //标记结果作为 ID
    • //标记结果作为普通参数
  • //设置主键(可多个)
    • column:数据表的列,使用{key1=column1,key2=column2…}的形式传递多列数据
    • property:将column属性指定的列结果映射到对象的哪个属性
    • javaType:实体类中字段类型
    • jdbcType:表中字段类型
  • //配置映射关系
    • column:数据表的列
    • property:将column属性指定的列结果映射到对象的哪个属性
    • javaType:实体类中字段类型
    • jdbcType:表中字段类型
  • //处理查询结果中关联其他对象的情况,映射JavaBean的某个复杂类型的属性
    • fetchType:eager立即加载/lazy延迟加载
    • columnPrefix:祛除查询结果内列名的指定前缀
    • javaType:完整的Java类名或者别名,若映射带一个JavaBean,则MyBatis通常会自行检测到其他类型,若映射到一个HashMap,则应该明确指定javaType
    • 嵌套查询方式(分段查询) //指的是通过执行另外一个 SQL 映射语句来返回所关联的对象类型
      • column:指定数据表的列
      • property:将column属性指定的列结果映射到对象的哪个属性
      • select:调用