鉴别器:有时一个单独的数据库查询也许返回很多不同(但是希望有些关联)数据类型的结果集。鉴别器元素就是被设计来处理这个情况的,还有包括类的继承层次结构。[抄了一个定义,不是很理解,还是看例子吧]
1. 交通工具表vehicle
create table test.vehicle (
id bigint(10) primary key AUTO_INCREMENT,
vin varchar(10),
year date,
color varchar(10),
vendor varchar(10),
vehicle_type int, //类型:1表示car, 2表示boat
door_count int, //车门数量,car独有属性
quant varchar(10) //船桨,boat独有属性
);
2. java对应的实体类Vehicle,Car,Boat
package com.yjq.entity;
import java.sql.Date;
public class Vehicle {
private int id;
private String vin; //交通登记号码
private Date year;
private String color;
private String vendor;
private int vehicleType;
public Vehicle() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getVin() {
return vin;
}
public void setVin(String vin) {
this.vin = vin;
}
public Date getYear() {
return year;
}
public void setYear(Date year) {
this.year = year;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public String getVendor() {
return vendor;
}
public void setVendor(String vendor) {
this.vendor = vendor;
}
public int getVehicleType() {
return vehicleType;
}
public void setVehicleType(int vehicleType) {
this.vehicleType = vehicleType;
}
}
package com.yjq.entity;
public class Car extends Vehicle {
private int doorCount;
public Car() {
}
public int getDoorCount() {
return doorCount;
}
public void setDoorCount(int doorCount) {
this.doorCount = doorCount;
}
}
package com.yjq.entity;
public class Boat extends Vehicle {
private String quant; //船桨
public Boat() {
}
public String getQuant() {
return quant;
}
public void setQuant(String quant) {
this.quant = quant;
}
}
3. 如何将查询结果映射为不同的对象呢?鉴别器登场
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yjq.entity.Vehicle">
<resultMap id="vehicleResult" type="Vehicle">
<id property="id" column="id" />
<result property="vin" column="vin"/>
<result property="year" column="year"/>
<result property="vendor" column="vendor"/>
<result property="color" column="color"/>
<result property="vehicleType" column="vehicle_type"/>
<discriminator javaType="int" column="vehicle_type">
<case value="1" resultMap="carResult"/>
<case value="2" resultMap="boatResult"/>
</discriminator>
</resultMap>
<resultMap id="carResult" type="Car">
<result property="vehicleType" column="vehicle_type"/>
<result property="doorCount" column="door_count" />
</resultMap>
<resultMap id="boatResult" type="Boat">
<result property="vehicleType" column="vehicle_type"/>
<result property="quant" column="quant" />
</resultMap>
<select id="selectVehicle" parameterType="int" resultMap="vehicleResult">
select * from vehicle where id =#{id};
</select>
</mapper>
4. 表中的数据
5. dao代码,看看查询效果
package com.yjq.dao;
import org.apache.ibatis.session.SqlSession;
import com.yjq.db.DbFactory;
import com.yjq.entity.Boat;
import com.yjq.entity.Car;
import com.yjq.entity.Vehicle;
public class VehicleDao {
public Vehicle selectVehicleById(int id) {
SqlSession session = DbFactory.getInstance().openSession();
Vehicle vehicle = (Vehicle) session.selectOne("com.yjq.entity.Vehicle.selectVehicle", id);
session.commit();
session.close();
return vehicle;
}
public static void print(Vehicle v) {
if(v instanceof Car) {
Car c = (Car)v;
System.out.println("Car: [id=" + c.getId() + ", vehicleType="
+ c.getVehicleType() + ", doorCount=" + c.getDoorCount() + "]");
} else if (v instanceof Boat) {
Boat b = (Boat)v;
System.out.println("Boat: [id=" + b.getId() + ", vehicleType="
+ b.getVehicleType() + ", quant=" + b.getQuant() + "]");
} else {
System.out.println("Vehicle: [id=" + v.getId() + ", vehicleType="
+ v.getVehicleType() + "]");
}
}
public static void main(String[] args) {
VehicleDao dao = new VehicleDao();
Vehicle v1 = dao.selectVehicleById(1);
Vehicle v2 = dao.selectVehicleById(2);
Vehicle v3 = dao.selectVehicleById(3);
VehicleDao.print(v1);
VehicleDao.print(v2);
VehicleDao.print(v3);
}
}
//output
Car: [id=1, vehicleType=1, doorCount=4]
Boat: [id=2, vehicleType=2, quant=lxj]
Vehicle: [id=3, vehicleType=3]
6. 蛋疼的地方
a) 重复配置:为了在Car,Boat,Vehicle类中能获取vehicleType属性,<result property="vehicleType" column="vehicle_type"/>配置了三次。
b) 多个resultMap:
i. 将查询语句的resultMap修改下,再看看输出:将所有的查询结果强行映射为Car了
<select id="selectVehicle" parameterType="int" resultMap="carResult">
select * from vehicle where id =#{id};
</select>
//output
Car: [id=1, vehicleType=1, doorCount=4]
Car: [id=2, vehicleType=2, doorCount=0]
Car: [id=3, vehicleType=3, doorCount=0]
7. 鉴别器的另外一种写法,试了下,好像没起作用,先不管了
<resultMap id="vehicleResult" type="Vehicle">
<id property="id" column="id" />
<result property="vin" column="vin"/>
<result property="year" column="year"/>
<result property="vendor" column="vendor"/>
<result property="color" column="color"/>
<result property="vehicleType" column="vehicle_type"/>
<discriminator javaType="int" column="vehicle_type">
<case value="1" resultMap="carResult" type="Car">
<result property="doorCount" column="door_count" />
</case>
<case value="2" resultMap="boatResult" >
<result property="quant" column="quant" />
</case>
</discriminator>
</resultMap>