MyBatis的ResultMap用于映射查询结果集中的每一行数据到Java对象上,并赋值给相应的属性字段。下面是讲解“mybatis resultmap如何为对象赋值的调用顺序”的攻略。
1. ResultMap的调用顺序
在对查询结果集进行映射时,MyBatis会按照以下的调用顺序进行:
- 如果存在自定义的映射方法(typeHandler)或者列为null,则直接跳过这一列的赋值。
- 如果映射了一个嵌套查询,则会调用查询语句并将结果映射到相应的对象属性上。
- 如果定义了枚举类型,会根据结果集中的值设置相应的枚举值。
- 如果定义了TypeHandler类型,则会使用TypeHandler对象对结果进行转换,并赋值给相应的属性。
- 如果使用了ResultSetHandler,会进行自动映射或构造器注入。
2. ResultMap的示例
(1)使用TypeHandler类型进行结果映射
首先,我们定义一个TypeHandler来进行类型转换。假设我们要将数据库中存储的JSON格式字符串转换成Java对象,我们可以这样实现:
public class JsonTypeHandler<T> extends BaseTypeHandler<T> {
private final Class<T> clazz;
public JsonTypeHandler(Class<T> clazz) {
if (clazz == null) {
throw new IllegalArgumentException("Type argument cannot be null");
}
this.clazz = clazz;
}
@Override
public void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {
ps.setString(i, JSON.toJSONString(parameter));
}
@Override
public T getNullableResult(ResultSet rs, String columnName) throws SQLException {
String jsonStr = rs.getString(columnName);
return resolveJson(jsonStr);
}
@Override
public T getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
String jsonStr = rs.getString(columnIndex);
return resolveJson(jsonStr);
}
@Override
public T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
String jsonStr = cs.getString(columnIndex);
return resolveJson(jsonStr);
}
@SuppressWarnings("unchecked")
private T resolveJson(String jsonStr) {
if (StringUtils.isBlank(jsonStr)) {
return null;
}
return (T) JSON.parseObject(jsonStr, clazz);
}
}
接下来,我们定义一个User类:
public class User {
private Long id;
private String name;
private Address address;
// 省略getter和setter方法
}
在接下来的XML配置中,我们为User类的address属性定义一个ResultMap,并指定我们自己定义的TypeHandler对其进行转换:
<resultMap id="userResult" type="User">
<id property="id" column="id" />
<result property="name" column="name" />
<result property="address" column="address" typeHandler="JsonTypeHandler"/>
</resultMap>
在进行查询时,MyBatis会将查询结果集中address列的值转换成Address类型的对象,并赋值给User对象的address属性。
(2)使用构造函数注入进行结果映射
假设我们有一个User类,其中id和name属性直接与数据库列进行映射,而address属性则需要根据city和street两列构造Address对象进行赋值。我们可以这样实现:
public class User {
private Long id;
private String name;
private Address address;
public User(Long id, String name, String city, String street) {
this.id = id;
this.name = name;
this.address = new Address(city, street);
}
// 省略getter和setter方法
}
public class Address {
private String city;
private String street;
public Address(String city, String street) {
this.city = city;
this.street = street;
}
// 省略getter和setter方法
}
在XML配置中,我们使用构造注入的方式对User对象进行赋值。首先,我们定义一个
<resultMap id="userResult" type="User">
<!-- 先映射id和name属性 -->
<id property="id" column="id" />
<result property="name" column="name" />
<!-- 再使用构造函数注入生成Address对象,并赋值给address属性 -->
<constructor>
<arg column="city" javaType="string" property="city"/>
<arg column="street" javaType="string" property="street"/>
</constructor>
</resultMap>
在执行查询操作时,MyBatis会自动调用User类的构造函数,将city和street列映射成Address对象并赋值给User对象的address属性。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:mybatis resultmap 如何为对象赋值的调用顺序 - Python技术站