Mybatis杂记:
当数据库涉及到一对一时Mybatis的处理方法:
- 例如在bean类中定义如下两个类(Hus和Wife类),在国内还是一夫一妻制的吧,2333(逃。。。)
然后需要做的就是在Hus和Wife类中各自写上另一方的引用!
public class Hus {
private long id;
private String name;
private int age;
private Wife wife;
//Getter and Setter
//toString
//Constuctor
}
public class Wife {
private long id;
private String name;
private int age;
private Hus hus;
//Getter and Setter
//toString
//Constuctor
}
- 在
Mapper
类中定义如下方法:
List<Hus> findHus_Wife();
- 重点就落在了
XXXMapper.XML
文件的编写上:
有5种编写的方式:
- 定义
select
标签,然后写好SQL语句:
<select id="findHus_Wifes" resultMap="hus_wife_model">
select a.ID,a.NAME,a.AGE, b.id ids,b.NAME names,b.AGE ages
from HUS a,WIFE b
where a.id=b.hus_id
</select>
注意: Hus表和Wife表具有相同的列名id和name,age,如不采用别名,Mybatis会认为这里的参数为相同,故需要立别名来保证Mybatis查找到Wife表的内容!
定义ResultMap
:
注意:其中hus和wife经过别名处理,请在mybatis-config.xml中定义别名!或在type内些上bean类的全限定名尚可。
<resultMap id="hus_wife_model" type="hus">
<id property="id" column="id"></id>
<result property="name" column="name"/>
<result property="age" column="age"/>
<result property="wife.id" column="ids"/>
<result property="wife.name" column="names"/>
<result property="wife.age" column="ages"/>
</resultMap>
id
、 name
与age
都是查询到的Hus表中的三个数据,当设计到Wife表时,第一后边的column
属性要变成上方SQL语句中ids
,names
和ages
,第二property属性内要写成wife.id
形式,wife是Hus类中对Wife引用名,即第四条属性(Mybatis会自动去搜寻getWife()方法,并将其以去掉get,并取后面字段小写的方式来获取属性名),获取到对象以后,.后写的就是Wife内的属性,取属性方式同理。
- select语句同上,重写
ResultMap
:
先写一个type为Wife的ResultMap:
<resultMap id="wife_model1" type="wife">
<id property="id" column="ids"></id>
<result property="name" column="names"/>
<result property="age" column="ages"/>
</resultMap>
再写type为Hus的ResultMap:
<association>
标签就可以用来关联一对一的映射关系,property
属性指向引用变量wife,ResultMap
属性内填写的是wife的模板,也就是先为Hus类中第四个属性wife的引用书写模板,后在定义Hus的模板过程中再将刚才定义的wife的模板通过association
标签引入,这样就达到了一对一关联的目的!
<resultMap id="hus_model2" type="hus">
<id property="id" column="id"></id>
<result property="name" column="name"/>
<result property="age" column="age"/>
<association property="wife" resultMap="wife_model1"/>
</resultMap>
select
语句同上,重写ResultMap
:
<resultMap id="mod1_hus" type="hus">
<id property="id" column="id"></id>
<result property="name" column="name" />
<result property="age" column="age" />
<association property="wife" javaType="wife">
<id property="id" column="ids"/>
<result property="name" column="names" />
<result property="age" column="ages"/>
</association>
</resultMap>
这次不同的是用了同一个ResultMap
来定义模板,在association
标签中写入的是wife内的三个属性,总的来讲和2中使用的方法类似,相当于把两个模板合二为一!
select
继续不变化,再次变化resultMap
<resultMap id="mod3_hus" type="hus">
<id property="id" column="id"></id>
<result property="name" column="name"/>
<result property="age" column="age"/>
</resultMap>
<resultMap id="mod3_hus_wife" type="hus" extends="mod3_hus">
<result property="wife.id" column="ids"/>
<result property="wife.name" column="names"/>
<result property="wife.age" column="ages"/>
</resultMap>
先定义一个hus的resultMap
,然后再定义一个resultMap
继承它!extends
表示从某个模板中把属性配置继承过来,类型一致。这样mod3_hus_wife
中就有了继承的hus属性和新增的wife属性,也达到了我们所要的效果!
- 转变思想:
- 先编写一个
select
,作用是基于 hus_id 在wife表查询一行记录
<select id="selectWifeByhus_id" parameterType="Long" resultType="wife">
select id,name,AGE
from WIFE
where HUS_ID=#{id}
</select>
- 然后编写一个
resultMap
,association
中column
和select
填的是上面编写的select
和他需要传入的参数值,相当于取当前的id属性(即hus的id属性hus_id)说去上面定义的select
中通过hus_Id查询到对应的wife属性,然后将其填入<association>
的子标签中!
<resultMap id="mod2_hus" type="hus">
<id property="id" column="id"></id>
<result property="name" column="name"/>
<result property="age" column="age"/>
<!-- column 表示基于该属性去查询 -->
<association property="wife" column="id" select="selectWifeByhus_id">
<id property="id" column="id"></id>
<result property="name" column="name"/>
<result property="age" column="age"/>
</association>
</resultMap>
这样我们的主select
的作用就是从Hus中取出对应的值就好了!
<select id="findHus_Wife3" resultMap="mod2_hus">
select id,name,age
from HUS
</select>