映射器是MyBatis最强大的工具,也是我们使用MyBatis时用得最多的工具,因此熟练掌握它十分必要。MyBatis是针对映射器构造的SQL构建的轻量级框架,并且通过配置生成对应的JavaBean返回给调用者,而这些配置主要便是映射器,在MyBatis中你可以根据情况定义动态SQL来满足不同场景的需要,它比其他框架灵活得多。MyBatis还支持自动绑定JavaBean,我们只要让SQL返回的字段名和JavaBean的属性名保持一致即可(获赠采用驼峰式命名),便可以省掉这些繁琐的映射配置。
今天主要围绕这么几个方面来讲?
1.映射器的主要元素;
2.select元素
3.insert元素
4.update元素和delete元素
5.参数
6.sql元素
7.resultMap结果映射
8.缓存cache
一、映射器的主要元素
关于映射器的主要元素,我用两张图概况。
图一:
图一除了parameterMap之外基本上就不用,其他的都用。
图二:
resultMap是我用的比较多的,至于cache或者cache-ref用的着实不是很多。一般我们在spring和ehcache整合就可以达到缓存目的。当然了,有的时候觉得每次都通过ehcache在对应的方法上配置缓存注解显得麻烦,就可以通过cache的形式。
二、select元素
select元素是我们最常用也是功能最强大的SQL语言。select元素帮助我们从数据库中读出数据,组装数据给业务人员。执行select语句前,我们需要定义参数,它可以是一个简单的参数类型,例如int、float、String,同时也可以是一个复杂参数类型,例如Map或者JavaBean等,这些都是MyBatis接受的参数类型。执行SQL后,MyBatis也提供了强大的映射规则,甚至是自动映射来帮助我们把返回的结果绑定到JavaBean中。
关于select元素的配置,我用如下的图来表示:
图一:
图二:
图三:
关于select细节的东西,我不想说太多,对于初学者而言,说的太多,显得重点不突出,对于有基础的朋友们,说的太多,显得繁琐。
以下说这个常见问题?
1.关于resultType和resultMap
resultType是针对当数据表的字段名与JavaBean中属性名一致时,我们可以使用resultType。如果不一致的话,我们就使用resultMap。因为如果在数据表的字段名与JavaBean的属性不一致的前提下你还使用resultType,那么你查询的数据应该是为Null。
2.关于多个参数传递问题
如果你的数据访问层方法中的参数大于四个以上,建议使用对象来传输数据。
如果是参数列表中的参数与xml中的sql查询条件的字段不一致,可以使用@Parm注解自定义。
例如:
三、insert元素
insert元素,相对于select元素而言要简单许多。MyBatis会在执行插入之后返回一个整数,以表示你进行操作后插入的记录数。
insert元素配置详解
用一张图来表示,如下图所示:
insert 需要注意的是参数列表中的参数与插入的数据的列名要对上,同时还有就是数据表定义的主键非空或自增及其其他字段一些特殊的定义,因为同update一样,往往因为数据表的定义导致出现小问题。
关于批量添加可以参考我的这篇文章:SSM框架之批量增加示例(同步请求jsp视图解析)
四、update和delete
这两个元素很简单,所以一般情况,我们会放在一起讨论。和insert元素一样,MyBatis执行完update元素和delete元素后会返回一个整数,标出执行后影响的记录条数。
批量修改可以参考我的这篇文章:mybatis的批量更新实例
至于批量删除,你知道了批量更新就相当于知道了这个。
五、参数
虽然在MyBatis中参数大部分是像上面所描述的那样简单,但是我们还是有必要讨论一下参数的使用。我们可以通过制定参数的类型去让对应的typeHandler处理它们。
这里需要强调的是关于特殊字符串的替换和处理(#和$)
在MyBatis中,我们常常传递字符串,我们设置的参数#(name)在大部分的情况下MyBatis会用创建预编译的语句,然后MyBatis为它设值,而有时候我们需要的是传递SQL语句的本身,而不是SQL所需要的参数。例如,在一些动态表格(有时候经常遇到根据不同的条件产生不同的动态列)中,我们要传递SQL的列名,根据某些列进行排序,或者传递列名给SQL都是比较常见的场景,当然MyBatis也对这样的场景进行了支持,这些都是Hibernate难以做到的。
六、sql元素
sql元素的意义,在于我们可以定义一串SQL语句的组成部分,其他的语句可以通过引用来使用它们。例如,你有一条SQL需要select几十个字段映射到JavaBean中去,我的第二条数据也是这几十个字段映射到JavaBean中去,显然写两遍是不合适的。那么我们就可以通过sql元素来完成。
例如,下面的这个示例,大家可以做个简单参考。
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
user_id, login_code, user_name, password, sex, identity_card, create_time, create_by, update_time, update_by, status
</sql>
<select id="selectOne" resultMap="BaseResultMap">
select <include refid="Base_Column_List"/>
from `user` where user_id=#{userId}
</select>
七、resultMap
resultMap是MyBatis里面最复杂的元素。它的作用是定义映射规则、级联的更新、定制类型转化器等。
前面我们只是仅仅提到了它和resultType的对比。
resultMap定义的主要是一个结果集的映射关系。MyBatis现有的版本只支持resultMap查询,不支持更新或者新增,更不要说说批量的删除和修改了。
1.resultMap元素的构成
其中constructor元素用于配置构造方法。一个POJO可能不存在没有参数的构造方法,这个时候我们就可以使用constructor进行配置。
id元素是表示哪个列是主键,允许多个主键,多个主键则称为联合主键。result是配置POJO到SQL列名的映射关注。这里的result和Id元素,如下图所示:
至于级联,例如一对一,一对多,多对多,我们可以分别使用association、collection等。
后面我会专门有代码示例讲解的。
不过有一点需要注意的是,通常一对一或者一对多,多对多这种的,特别损耗性能,因此对于sql,最好是优化。
关于sql优化的方法,大家可以参考我的这篇博客:造成MySQL全表扫描的原因
这篇文章不会直接告诉你这么做,但是你看了这篇文章,你就会明白为什么要这么做。
在我看来,提出问题比解决问题更重要(当然了,事物都是相对的)。
八、缓存
缓存是互联网系统常常用到的,其特定是将数据保存在内存中。目前流行的缓存服务器有MongoDB、Redis、Ehcache等。缓存是在计算机内存上保存的数据,在读取的时候无需再从磁盘读入,因此具备快速读取和使用的特点,如果缓存命中率高,那么可以极大地提高系统的性能。如果缓存命中率低,那么缓存就不存在使用的意义,所以使用缓存的关键在于存储内容访问的命中率。
关于SSM框架整合Ehcache实战,可以参考我的这篇文章:SSM框架实战之整合EhCache
这篇文章的重点不是缓存,关于redis和memcached及其与ssm框架整合实战及其应用场景,后面会专门有文章详细讲解。
小结:
本文主要参考《深入浅出MyBatis原理与实战》和自身在实战中的总结和归纳。希望能给大家有所帮助。