mybatis中的级联关系中的鉴别器(discriminator、case、result)

     

      鉴别器:有时一个单独的数据库查询也许返回很多不同(但是希望有些关联)数据类型的结果集。鉴别器元素就是被设计来处理这个情况的,还有包括类的继承层次结构。

      说白一点就是有时候我们想把相同类型的东西放在同一个表中进行查询,比如我们想把狗和猫放在同一个表中,但是猫和狗有不同的特点,但是我们就想把他们放在一个表中,因为他们都属于宠物。为了从表中查出来时对它们进行区分,也就是说,我在做查询时我不会说在一个表中我去写多个查询方法手动的去指定我想要的那些属性作为返回,而是将属性都进行查询,让它自动去区分,向狗的对象或猫的对象进行属性值的填装,向我们返回狗的对象还是猫的对象。这种条件下就会用到鉴别器来鉴别到底是狗还是猫,同时要引入继承的概念,猫和狗都属于宠物,所以我们在做查询时,只是去查询这个宠物,具体查出来是什么我不管,让鉴别器去做决定,到底是狗还是猫。

 

下面我们就以猫和狗的例子进行说明

 

父类(宠物类)

首先猫和狗都属于宠物,所以我们需要一个宠物类

private Integer id;
private String petName;

可以看到宠物有两个属性,这是猫和狗都具有的相同属性,也就是id和名字

 

子类(猫类,继承宠物类)

private int fish;

可以看到猫类除了继承自宠物类的属性外,还有一个fish属性,这表示的是猫拥有鱼的数量,猫喜欢吃鱼嘛。

 

子类(狗类,继承宠物类)

private Integer bone;

可以看到狗类除了继承自宠物类的属性外,还有一个bone属性,这表示的是狗拥有骨头的数量,狗喜欢骨头嘛。

 

宠物表(t_pet)创建

从上面的类中我们就可以看到猫和狗都拥有不同的属性,如何在一个表中进行查询呢,那么我们来看下表(t_pet)的结构:

<!-- pet_type:0代表狗,1代表猫 -->
id,pet_name,pet_type,bone,fish

首先我们建立的是一个宠物表,因为这个表就包含了它的子类也就是猫和狗的所有属性。可以看到其中有一个pet_type的字段,这个字段就是用来区分到底是狗还是猫的,鉴别器就是通过这个类型字段来进行装配的。

 

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

首先我们来写一个新增狗的方法吧,让大家了解怎样在插入数据的时候区分:

void addDogBean(@Param("d") DogBean dog);
<insert id="addDogBean" useGeneratedKeys="true" keyProperty="d.id">
	insert into t_pet (pet_name,pet_type,bone) values(#{d.petName},'0',#{d.bone})
</insert>

可以看到我们在做插入狗数据的时候,用狗对象将值传下来,在底层将pet_type进行了赋值,这样在表中做查询时就可以通过这个来进行猫和狗的区分了。

 

如果我们要查询狗对象呢,怎么办呢,很简单,因为我们已经知道了要查询狗对象,所以不需要鉴别器啊,根据pet_type就能够找出来狗啊,所以这样写:

List<DogBean> findAllDogBean();
<select id="findAllDogBean" resultType="DogBean">
	select id,pet_name as petName,bone from t_pet where pet_type = '0';	
</select>

从这里看出,在我们知道具体要查询什么的时候,我们可以直接用类型pet_type字段就可以区分查询出我们想要的数据。

但是有一种情况,我们就不能这样了,我想要把狗和猫一起查询出来呢,你就不可能用一个对象去把不同对象的数据接收了吧,比如你不能用狗对象去接收猫对象,所以这时候鉴别器就出来了。

 

鉴别器的使用(<discriminator>---<case>标签)

在我们没做指定查询具体对象的时候,想把不同类型的数据都查出来的时候,这时候我们就要用到鉴别器来进行不同对象的装配了。因为单一对象不能接收其他对象的数据。

下面假设我们把狗和猫都查询出来:

List<PetBean> findAllPetBean();
<resultMap type="PetBean" id="petMap">
	<!-- 公共的 -->
	<id property="id" column="id" javaType="int"/>
	<result property="petName" column="pet_name" javaType="string"/>
		
	<!-- 通过鉴别器,识别(狗|猫)数据 -->
	<discriminator column="pet_type" javaType="int">
		<case value="0" resultType="DogBean">
			<result property="bone" column="bone" javaType="int"/>
		</case>
		<case value="1" resultType="CatBean">
			<result property="fish" column="fish" javaType="int"/>
		</case>
	</discriminator>
	
</resultMap>

<!-- 查询所有的猫和狗的数据 -->
<select id="findAllPetBean" resultMap="petMap">
	select id,pet_name,pet_type,bone,fish from t_pet;	
</select>

<discriminator>标签表示的就是开启鉴别器,其中的column表示对应的是sql语句中from前面的哪个字段,javaType表示对应的java中的什么类型

<case>标签从字面意思就可以看出是分析不同的情况,其中的value表示的是对应的该字段的值,resultType表示我要返回的对象类型

<result>标签标识我要返回的对象中的属性和表中字段的映射关系,其中property表示java对象的属性,column表示表中对应的字段,javaType表示该属性的java类型。

 

可以看到我们在做结果集映射的时候用的是父类宠物类的引用,因为父类引用可以指向子类对象的实例,这是Java基础的内容。在开启鉴别器后它就会根据具体情况产生对应的实例对象了。

可以看到我们在接口中用了List<PetBean>来接受不同对象的具体实例,父类可以指向子类对象实例,这已经说过了。所以我们在接收到了所有数据之后我们就可以利用循环来判断里面具体的数据,再强转成具体对象,就可以调取对象里面的数据了啊。比如:

List<Pet> pets = petServiceImpl.findAllPetBean();
for (Pet pet : pets) {
	if (pet instanceof Dog) {
		Dog dog = (Dog) pet;
				
	}else {
		Cat cat = (Cat) pet;			
	}
}

鉴别器的用法就介绍完了。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值