myBatis3之SQL映射的XML文件(resultMap元素之五)

myBatis3之SQL映射的XML文件(resultMap元素之五)

----------

 

高级结果映射之association元素(关联)

 

<association  property="author" column="blog_author_id" javaType=" Author"> 
	<id property="id" column="author_id"/> 
	<result property="username" column="author_username"/> 
</association> 

关联元素处理“有一个”类型的关系。比如,在我们的示例中,一个博客有一个用户。关联映射就工作于这种结果之上。你指定了目标属性,来获取值的列,属性的java类型(很多情况下MyBatis可以自己算出来),如果需要的话还有jdbc类型,如果你想覆盖或获取的结果值还需要类型控制器。关联中不同的是你需要告诉MyBatis如何加载关联。MyBatis在这方面会有两种不同的方式: 

嵌套查询:通过执行另外一个SQL映射语句来返回预期的复杂类型。 

嵌套结果:使用嵌套结果映射来处理重复的联合结果的子集。 

 

首先,然让我们来查看这个元素的属性。所有的你都会看到。

属性  描述 
property

映射到列结果的字段或属性。如果匹配的是存在的,和给定名称相同的JavaBeans 的属性,那么就会使用。

否则MyBatis将会寻找给定名称的字段。这两种情形你可以使用通常点式的复杂属性导航。比如,你可以这样映射一 些 东 西 :“ username ”, 或 者 映 射 到 一 些 复 杂 的 东 西 :“address.street.number”

column

来自数据库的列名 , 或重命名的列标签 。 这和通常传递给resultSet.getString(columnName)方法的字符串是相同的。注意:要处理复合主键,你可以指定多个列名通过column=”{prop1=col1,prop2=col2}”

这种语法来传递给嵌套查询语句。这会引起prop1 和 prop2 以参数对象形式来设置给目标嵌套查询语句。

javaType

一个 Java 类的完全限定名,或一个类型别名(参加上面内建类型别名的列表)。如果你映射到一JavaBean

,MyBatis通常可以断定类型。然而,如果你映射到的是HashMap,那么你应该明确地指定javaType 来保证所需的行为。

jdbcType 在这个表格之前的所支持的JDBC类型列表中的类型。JDBC类型是仅仅需要对插入,更新和删除操作可能为空的列进行处理。。这是JDBC 的需要,而不是 MyBatis 的。如果你直接使用JDBC 编程,你需要指定这个类型-但仅仅对可能为空的值。
typeHandler  我们在前面讨论过默认的类型处理器。使用这个属性,你可以覆盖默认的类型处理器。这个属性值是类的完全限定名或者是一个类型处理器的实现,或者是类型别名
select 

另外一个映射语句的 ID,可以加载这个属性映射需要的复杂类型。获取的在列属性中指定的列的值将被传递给目标select 语句作为参数。表格后面有一个详细的示例。 

注意:要处理复合主键,你可以指定多个列名通过 column=”{prop1=col1,prop2=col2}”这种语法来传递给嵌套查询语句。这会引起prop1 和 prop2 以参数对象形式来设置给目标嵌套查询语句。

示例: 

 

<resultMap id=”blogResult” type=”Blog”> 
	<association property="author" column="blog_author_id" 
	javaType="Author" select=”selectAuthor”/> 
</resultMap> 
<select id=”selectBlog” parameterType=”int” resultMap=”blogResult”> 
	SELECT * FROM BLOG WHERE ID = #{id} 
</select> 
<select id=”selectAuthor” parameterType=”int” resultType="Author"> 
	SELECT * FROM AUTHOR WHERE ID = #{id} 
</select> 

我们有两个查询语句:一个来加载博客,另外一个来加载作者,而且博客的结果映射描述了“selectAuthor”语句应该被用来加载它的author属性。 其他所有的属性将会被自动加载,假设它们的列和属性名相匹配。 这种方式很简单,但是对于大型数据集合和列表将不会表现很好。问题就是我们熟知的N+1查询问题”。概括地讲,N+1查询问题可以是这样引起的:

 

1.你执行了一个单独的SQL语句来获取结果列表(就是“+1”)。 

2.对返回的每条记录,你执行了一个查询语句来为每个加载细节(就是“N”)。 

这个问题会导致成百上千的SQL语句被执行。这通常不是期望的。 

MyBatis能延迟加载这样的查询就是一个好处,因此你可以分散这些语句同时运行的消耗。然而,如果你加载一个列表,之后迅速迭代来访问嵌套的数据,你会调用所有的延迟加载,这样的行为可能是很糟糕的。 所以还有另外一种方法。  

关联的嵌套结果

resultMap  这是结果映射的 ID,可以映射关联的嵌套结果到一个合适的对象图中。这是一种替代方法来调用另外一个查询语句。这允许你联合多个表来合成到一个单独的结果集。这样的结果集可能包含重复,数据的重复组需要被分解,合理映射到一个嵌套的对象图。为了使它变得容易,MyBat is 让你“链接”结果映射,来处理嵌套结果。

下面这个是一个非常简单的示例来说明它如何工作。代替了执行一个分离的语句,我们联合博客表和作者表在一起,就像:

<select id="selectBlog" parameterType="int" resultMap="blogResult"> 
	select 
		B.id as blog_id, 
		B.title as blog_title, 
		B.author_id as blog_author_id, 
		A.id as author_id, 
		A.username as author_username, 
		A.password as author_password, 
		A.email as author_email, 
		A.bio as author_bio 
	From Blog B left outer join Author A on B.author_id = A.id 
	where B.id = #{id} 
</select> 

 

注意这个联合查询,以及采取保护来确保所有结果被唯一而且清晰的名字来重命名。这使得映射非常简单。现在我们可以映射这个结果: 

<resultMap id="blogResult" type="Blog"> 
	<id property=”blog_id” column="id" /> 
	<result property="title" column="blog_title"/> 
	<association property="author" column="blog_author_id" javaType="Author" 
		resultMap=”authorResult”/> 
</resultMap> 
<resultMap id="authorResult" type="Author"> 
	<id property="id" column="author_id"/> 
	<result property="username" column="author_username"/> 
	<result property="password" column="author_password"/> 
	<result property="email" column="author_email"/> 
	<result property="bio" column="author_bio"/> 
</resultMap> 

非常重要:在嵌套映射中 id元素扮演了非常重要的角色。应该通常指定一个或多个属性,它们可以用来唯一标识结果。实际上就是如果你离开她了,MyBatis仍然可以工作。选择的属性越少越好,它们可以唯一地标识结果。主键就是一个显而易见的选择(尽管是联合主键)。 现在,上面的示例用了外部的结果映射元素来映射关联。这使得Author结果映射可以重用。然而,如果你不需要重用它的话,你可以嵌套结果映射。

这里给出使用这种方式的相同示例: 

<resultMap id="blogResult" type="Blog"> 
	<id property=”blog_id” column="id" /> 
	<result property="title" column="blog_title"/> 
	<association property="author" column="blog_author_id" javaType="Author"> 
		<id property="id" column="author_id"/> 
		<result property="username" column="author_username"/> 
		<result property="password" column="author_password"/> 
		<result property="email" column="author_email"/> 
		<result property="bio" column="author_bio"/> 
	</association> 
</resultMap> 

 上面你已经看到了如何处理“有一个”类型关联。但是“有很多个”是怎样的?见下一篇。

你可能感兴趣的:(resultMap)