最近有幸读到《企业架构模式》这本书,需要写作于2003年,已经是十年前,但仔细读过,有些东西现在只知道是这样用,但并不知道为什么要这样做。在看过此书之后,很多东西都能够有一条线进行贯穿,在使用到一些框架时,也知道背后的原因了。
这里面有一篇讲到对象-关系元数据映射的,实际上就是指在一个数据库中一个数据表与一个java中的domain对象之间的映射,在文中提到几种操作,也提到了为什么要这样做。其中,重要的当然是为什么要这样做了,但本篇主要讲期间在mybatis中笔者之前做的一个简单的映射,最终的效果与文中的结果基本上是一致的(因此在进行code时,还是没看过此书,结果发现自己又发明了一个新轮子)。
由于使用到mybatis,所以对模型之间的关系这里并没有涉及,只简单对应于一个数据表一个模型的概念。
通常情况下,我们在数据表中一个数据表user,有2个字段分别为user_name和password.那么在java中,我们会有一个对应的domain文件,如下代码所示:
public class User { private String userName; private String password; }
这里只是一个简单的对应,同时字段user_name对应于userName,这里并不是完全相同的字符串.因此,在mybatis相对应的xml中,我们需要显示的对待mapping操作.如下xml所示:
<insert> insert into user(user_name,password) values(#{userName},#{password}); </insert> <select columnMap=tMap> <!-- tMap中需要定义mapping关系 > select user_name,password from user </select>
这里涉及到一个东西,就是我们需要手动地编写相应的mapping语句,而且涉及到多个地方.比如在insert脚本中,需要编写user_name和userName不同的语句;在select中,还需要手动进行columnMap工作.对于一般的开发人员,使用copy&paste时,这里就会出错.而且一旦涉及到模型属性的变更,比如增加一个属性,表中加一个字段,这里的修改量就较大了,而且一旦涉及到代码还不集中,那就更麻烦了.
本篇即是引入一种特殊的columnMapping对象,并通过自动生成+动态SQL构建,来完成这种操作.参考如下一个insert语句:
<insert> insert into ${table.schema()}.${table.name()}( <foreach collection="columnMappingList" separator="," item="cm"> ${cm.jdbcField} </foreach> ) values( <foreach collection="columnMappingList" separator="," item="cm"> #{e.${cm.javaProperty},jdbcType=${cm.jdbcType}} </foreach> ) </insert>