上面已经看到了双向many2one/one2many关系的映射。
但是我们说,在关联关系中,还存在组合/聚合关系。
所谓聚合就是one方和many方可以独立存在;组合关系是强聚合关系,one方和many方解除关系后,就没有实际意义了。
在组合关系中,必须要处理的一个问题就是级联关系。
下面使用SaleBill和SaleBillItem对象来完成双向的many2one/one2many的组合关系。
对象设计如下:
对于组合关系,数据表的结构设计和many2one一样,都是many方一个外键引用one方的主键。在组合关系中,一般来说,明细项是不需要额外有一个Mapper文件的,所有的映射都应该放在One方的映射文件中。下面来看看映射文件:
映射文件的内容都已经注释详细。
主要注意一点的就是在设计映射文件的时候需要考虑组合关系的一般设计方式,所以在上面的配置文件中只做了SaleBill对象的映射。
这个配置文件还是很好理解的,其中所有的配置点在前面都已经介绍过。
在组合关系中,主要的问题就是一个级联保存,但是注意,在mybatis中设计组合的级联保存,删除,这个过程应该是我们自己来控制的。
下面来看看怎么测试组合关系:
具体测试代码:
Mybatis映射原理MyBatis的真正强大之处在于它的映射语句,这也是它的魔力所在。由于它的映射语句异常强大,映射器的 XML 文件就显得相对简单。
MyBatis3.0相比2.0版本的一个最大变化,就是支持使用接口来调用方法。
以前使用 SqlSession 通过命名空间调用 MyBatis 方法时,首先需要用到命名空间和方法id 组成的字符串来调用相应的方法 。当参数多于 1 个的时候,需要将所有参数放到一个 Map对象中 。 通过 Map 传递多个参数,使用起来很不方便,而且还无法避免很多重复的代码。使用接口调用方式就会方便很多, MyBatis 使用 Java 的动态代理可以直接通过接口来调用 相应 的方法,不需要提供接口的实现类,更不需要在实现类中使用 SqlSess 工∞以通过命名空 间间接调用 。另外,当有多个参数的时候,通过参数注解@ Par am 设置参数的名字省去了 手动构造 Map 参数的过程,尤其在 Spring 中使用的时候,可以配置为自动扫描所有的接口类 ,直接将接口注入需要用到的地方。mapper文件示例:
需要注意的是<mapper>根标签的 name space 属性。当 Mapper 接口和 XML 文件关联的时候,命名空间口amespace 的值就需要配置成接口的全限定名称,例如 UserMapper 接口对应的 tk. mybatis . simple .mapper . UserMapper, MyBatis 内部就是通过这个值将接口和XML 关联起来的。
mybati s-config.xml 配置文件中的 mappers 元素中配置所有的 mapper ,部分配置代码如下 。
更简单的配置方式,代码如下
这种配置方式会先查找 tk.mybatis.simple . mapper 包下所有的接口,循环对接口进行如下操作。这种配置方式会先查找 tk.mybatis.simple . mapper 包下所有的接口,循环对接口进行判断接口对应的命名 空 间是否己经存在,如果不存在就抛出异常,存在就继续进行接下来的操作。加载接口对应的却也映射文件 , 将接口全限定名转换为路径.
为什么 Mapper 接口没有实现类却能被正常调用呢?
这是因为MyBaits 在 Mapper 接口上使用了动态代理的一种非常规的用法,熟悉这动态代理的用法不仅有利于理解 MyBatis 接口和 XML 的关系,还能开阔思路 。
从代理类中可以看到,当调用 一个接口的方法时,会先通过接口的全限定名称和当前调用的方法名的组合得到一个方法 id,这个 id 的值就是映射 XML 中口arnespa ce 和具体方法 id的组合。所以可以在代理方法中使用 sqlSession 以命名空间的方式调用方法。通过这种方式可以将接口和 XML 文件中的方法关联起来。这种代理方式和常规代理的不同之处在于,这里没有对某个具体类进行代理,而是通过代理转化成了对其他代码的调用。
由于方法参数和返回值存在很多种情况,因此 MyBatis 的内部实现会比上面的逻辑复杂得多,正是因为 MyBatis 对接口动态代理的实现,我们在使用接口方式的时候才会如此容易。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持七叶笔记。