mybatis映射系列教程3:复杂字段的高级映射
1、ResultMap的节点属性列表
MyBatis的开发者认为,数据库不可能永远是你所想或所需的那个样子。我们希望每个数据库都具备良好的第三范式或 BCNF 范式,可惜它们不总都是这样。如果能有一种完美的数据库映射模式,所有应用程序都可以使用它,那就太好了,但可惜也没有。 而ResultMap就是MyBatis对这个不完美问题的最完美答案。首先,让我们熟悉一下ResultMap的属性:
属性 | 描述 |
---|---|
id | 当前命名空间中的一个唯一标识,用于标识一个结果映射。 |
type | 类的完全限定名或者一个类型别名。 |
autoMapping | 如果设置这个属性,MyBatis将会为本结果映射开启或者关闭自动映射。 这个属性会覆盖全局的属性 autoMappingBehavior。默认值:未设置(unset)。 |
2、ResultMap的子节点列表
-
constructor- 用于在实例化类时,注入结果到构造方法中
- idArg- ID 参数;标记出作为 ID 的结果可以帮助提高整体性能
- arg- 将被注入到构造方法的一个普通结果
- id– 一个 ID 结果;标记出作为 ID 的结果可以帮助提高整体性能
- result– 注入到字段或 JavaBean 属性的普通结果
-
association– 一个复杂类型的关联;许多结果将包装成这种类型
- 嵌套结果映射 – 关联本身可以是一个 resultMap元素,或者从别处引用一个
-
collection– 一个复杂类型的集合
- 嵌套结果映射 – 集合本身可以是一个 resultMap元素,或者从别处引用一个
-
discriminator– 使用结果值来决定使用哪个
resultMap
-
case– 基于某些值的结果映射
- 嵌套结果映射 – case本身可以是一个 resultMap元素,因此可以具有相同的结构和元素,或者从别处引用一个
-
case– 基于某些值的结果映射
2.1、id & result 子节点用法
<id property="id" column="post_id"/>
<result property="subject" column="post_subject"/>
这些是结果映射最基本的内容。id 和 result 元素都将一个列的值映射到一个简单数据类型(String, int, double, Date 等)的属性或字段。
这两者之间的唯一不同是,id 元素表示的结果将是对象的标识属性,这会在比较对象实例时用到。 这样可以提高整体的性能,尤其是进行缓存和嵌套结果映射(也就是连接映射)的时候。
两个元素都有一些属性:
属性 | 描述 |
---|---|
property | 映射到列结果的字段或属性。如果用来匹配的 JavaBean 存在给定名字的属性,那么它将会被使用。否则 MyBatis 将会寻找给定名称的字段。 无论是哪一种情形,你都可以使用通常的点式分隔形式进行复杂属性导航。 比如,你可以这样映射一些简单的东西:“username”,或者映射到一些复杂的东西上:“address.street.number”。 |
column | 数据库中的列名,或者是列的别名。一般情况下,这和传递给 resultSet.getString(columnName)方法的参数一样。 |
javaType | 一个 Java 类的完全限定名,或一个类型别名(关于内置的类型别名,可以参考上面的表格)。 如果你映射到一个 JavaBean,MyBatis 通常可以推断类型。然而,如果你映射到的是 HashMap,那么你应该明确地指定 javaType 来保证行为与期望的相一致。 |
jdbcType | JDBC 类型,所支持的 JDBC 类型参见这个表格之后的“支持的 JDBC 类型”。 只需要在可能执行插入、更新和删除的且允许空值的列上指定 JDBC 类型。这是 JDBC 的要求而非 MyBatis 的要求。如果你直接面向 JDBC 编程,你需要对可能存在空值的列指定这个类型。 |
typeHandler | 我们在前面讨论过默认的类型处理器。使用这个属性,你可以覆盖默认的类型处理器。 这个属性值是一个类型处理器实现类的完全限定名,或者是类型别名。 |
支持的 JDBC 类型
为了以后可能的使用场景,MyBatis 通过内置的 jdbcType 枚举类型支持下面的 JDBC 类型。
BIT | FLOAT | CHAR | TIMESTAMP | OTHER | UNDEFINED |
TINYINT | REAL | VARCHAR | BINARY | BLOB | NVARCHAR |
SMALLINT | DOUBLE | LONGVARCHAR | VARBINARY | CLOB | NCHAR |
INTEGER | NUMERIC | DATE | LONGVARBINARY | BOOLEAN | NCLOB |
BIGINT | DECIMAL | TIME | NULL | CURSOR | ARRAY |
2.2 构造方法
构造方法注入允许你在初始化时为类设置属性的值,而不用暴露出公有方法。constructor 元素就是为此而生的。
看看下面这个构造方法:
public class User
{
//...
public User(Integer id, String username, int age)
{
//...
}
//...
}
为了将SQL查询结果注入构造方法,MyBatis 需要通过某种方式定位相应的构造方法。 在下面的例子中,MyBatis 搜索一个声明了三个形参的的构造方法,参数类型以 java.lang.Integer, java.lang.String 和 int 的顺序给出。
<constructor>
<idArg column="id" javaType="int"/>
<arg column="username" javaType="String"/>
<arg column="age" javaType="_int"/>
</constructor>
当你在处理一个带有多个形参的构造方法时,很容易搞乱 arg 元素的顺序。 从版本 3.4.3 开始,可以在指定参数名称的前提下,以任意顺序编写 arg 元素。下面是一个等价的例子,尽管函数签名中第二和第三个形参的顺序与 constructor 元素中参数声明的顺序不匹配。
<constructor>
<idArg column="id" javaType="int" name="id" />
<arg column="age" javaType="_int" name="age" />
<arg column="username" javaType="String" name="username" />
</constructor>
未完待续...