MyBatis读书学习笔记(二)——映射器

来源:互联网 发布:淘宝e客服怎么设置 编辑:程序博客网 时间:2024/06/04 18:07

映射器是MyBatis最复杂且最重要的组件。它由一个接口加上XML文件(或者注解)组成。在映射器中可以配置参数、各类的sql语句、存储过程、缓存、级联等复杂的内容,并且通过简易的映射规则映射到指定的POJO或者其他对象上,映射器能有效消除JDBC底层代码。


2.1 概述

主要元素有8个:insert, select, update, delete, sql, resultMap, cache, cache-ref。


2.2 select——查询语句

主要元素有:id, parameterType, resultType, resultMap。

2.2.1 简单应用


<?xml verison = "1.0" encoding = "UTF-8"?><select id = "countUserByFirstName" parameterType = "string" resultType = "int">select count(*) total from t_userwhere user_name like concat(#{firstName},'%') </select>

id与Mapper的全限定名联合成为一个唯一的标识,用于标识这条SQL。

parameterType表示这条SQL返回接受的参数类型,可以是MyBatis系统定义或自定义的别名,也可以是类的全限定名。

resultType表示这条SQL返回的结果类型。

#{firstName}是通过Mapper接口传入的参数。

则可以知道,只有这条SQL还不够,我们需要提供一个接口,给类似Service类进行调用访问,比如此接口方法可定义为:

public Integer countUserByFirstName(String firstName);

2.2.2 自动映射和驼峰映射

MyBatis提供自动映射功能,在默认情况下自动映射是开启的,使用它的好处在于能有效减少大量的映射配置,从而减少工作量。

在setting元素中有两个可以配置的选项autoMappingBehavior和mapUnderscoreToCamelCase,它们是控制自动映射和驼峰映射的开关。

如果系统都严格按照驼峰命名法(比如,数据库字段为role_name,则POJO属性名为roleName),那么只要在配置项把mapUnderscoreToCamelCase设置为true即可。

MyBatis会严格按照驼峰命名的方式做自动映射,只是这样会要求数据字段和POJO的属性名严格对应,降低了灵活性,这也是实际工作中需要考虑的问题。

2.2.3 传递多个参数

1.使用map接口传递参数

例如,可以把接口方法定义为:

public List<Role> findRolesByMap(Map<String,Object> parameterMap);

map几乎适合所有场景,但用的不多。原因有二:首先,map是一个键值对应的集合,使用者要通过阅读它的键,才能明了作用;其次,使用map不能限定其传递的数据类型,因此业务性质不强,可读性差,使用者要读懂代码才能知道需要传递什么参数。

2.使用注解

可以通过@Param(org.apache.ibatis.annotation.Param),可以通过它去定义映射器的参数名称,使用它可以得到更好的可读性,例如,可以把接口方法定义为:

public List<Role> findRoleByAnnotation(@Param("roleName") String roleName, @Param("note") String note);

3.通过Java Bean

例如,可以把接口方法定义为:

public List<Role> findRolesByBean(RoleParams roleParam);

此形式较为推荐。

2.2.4 使用resultMap映射结果集

2.2.5 分页参数RowBounds


2.3 insert元素——插入语句

2.3.1 主键回填

JDBC中的Statement对象在执行插入SQL后,可以通过getGeneratedKeys方法获得数据库生成的主键(需要数据库驱动主持),这样便能达到获取主键的功能。在insert语句中有一个开关属性useGeneratedKeys,用来控制是否打开这个功能,它的默认值是false。当打开了这个开关,还要配置其属性keyProperty或keyColumn,告诉系统把主键放入哪个主键中,如果存在多个主键,就要用逗号把他们隔开。

useGeneratedKeys代表采用JDBC的Statement对象的getGeneratedKeys返回主键,而keyProperty则代表将用哪个POJO的属性去匹配这个主键,说明它会用数据库生成主键去赋值给这个POJO,测试主键回填的结果。


2.4 update元素和delete元素

与上雷同


2.5 resultMap元素

resultMap的作用是定义映射规则、级联的更新、定制类型转化器等。resultMap定义的主要是一个结果集的映射关系,也就是SQL到Java Bean的映射关系定义,它也支持级联等特性。只是MyBatis现有版本只支持resultMap查询,不支持更新或保存,更不支持级联的更新、删除和修改。

2.5.1 resultMap元素构成

resultMap元素的子元素如下:

<resultMap><constructor><idArg/><arg/></constructor><id/><result/><association/><collection/><discriminator><case/></discriminator></resultMap>

constructor元素用于配置构造方法。一个POJO可能不存在没有参数的构造方法,可以使用constructor进行配置。id元素表示哪个列是主键,允许多个主键,多个主键则称为联合主键。result是配置POJO到SQL列名的映射关系。

2.5.2 使用POJO存储结果集

使用map方式就意味着可读性的丢失,POJO是最常用的方式。一方面可以使用自动映射,正如使用resultType属性一样,但是有时候需要更为复杂的映射或级联,这个时候还可以使用select语句的resultMap属性配置映射集合,只是使用前要配置类似的resultMap。示例如下:


<resultMap id = "roleResultMap" type = "com.leearn.chapter4.pojo.Role"><id property = "id" column = "id"/><result property = "roleName" column = "role_name"/><result property = "note" column = "note"/></resultMap>


resultMap元素的属性id代表这个resultMap的标识,type代表这需要映射的POJO,这里可以使用MyBatis定义好的类的别名,也可以使用自定义的类的全限定名。

在映射关系中,id元素表示这个对象的主键,property代表着POJO的属性名称,column表示数据库sql的列名。


2.6 级联

级联是一个数据库实体概念。比如角色就需要存在用户与之对应,这样就有角色用户表,一个角色可能有多个用户,这就是一对多级联;还有一对一的级联,比如身份证和公民是一对一的关系。在MyBatis中还有一种鉴别器的级联,它是一种可以选择具体实现类的级联,比如要查找雇员及其体检表的信息,但是雇员有性别之分,而根据性别不同,其体检表的项目也会不一样。

级联不是必须的,级联的好处是获取关键数据是否便捷,但级联过多会增加系统的复杂度,同时降低系统的性能,所以当级联的层数超过3层时,就不要使用级联了,因为这样会造成多个对象关联,导致系统的耦合、复杂和难以维护。

2.6.1 延迟加载

MyBatis支持延迟加载,我们希望一次性把常用的级联数据提供SQL直接查询出来,而对于那些不常用的级联数据不要取出,等待用时才取出,对这些数据可采用延时加载的功能。

MyBatis的settings配置中存在两个元素可以配置级联。

lazyLoadingEnabled是一个开关,决定开不开启延迟加载,默认值为false,则不开启延迟加载。

而aggressiveLazyLoading的默认值,在3.4.2版本之后变为false,之前是true。


2.7 缓存

在MyBatis中允许使用缓存,缓存一般放在可高速读写的存储器上。比如服务器的内存,它能能够有效提高系统的性能,因为数据库在大部分场景下是把存储在磁盘上的数据索引出来。索引磁盘是一个较为缓慢的过程,读取内存或者高速缓存处理器的速度要比读取磁盘快得多,但是它们空间有限,所以一般只会把那些常用且命中率高的数据缓存起来,以便将来使用。

2.7.1 一级缓存和二级缓存

一级缓存是在SqlSession上的缓存,二级缓存只在SqlSessionFactory上的缓存。默认也就是没有任何配置的情况下,MyBatis会开启一级缓存,这个缓存不需要POJO对象可序列化(实现java.io.Serializable接口)。




原创粉丝点击