`
xulongfa
  • 浏览: 70937 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

ibatis Tips 之 复杂类型属性(即自定义类型的属性)

阅读更多

复杂类型用以表示在数据库中相互关系为一对一,一对多的数据。

映射文件:

<!--complex type property that defined by user-->
		<resultMap id="get-product-complex" class="product">
			<result property="id" column="prd_id"/>
			<result property="description" column="prd_description"/>
			<result property="price" column="prd_price"/>
			<result property="category" column="prd_cat_id" select="getCategory-complex"/>
		</resultMap>
		<resultMap id="get-category-complex" class="category">
			<result property="id" column="cat_id"/>
			<result property="description" column="cat_description"/>
		</resultMap>	
		<select id="getCategory-complex" resultMap="get-category-complex">
			<![CDATA[
				select * from t_category where cat_id = #value# 
			]]>
		</select>
		<select id="getProduct-complex" resultMap="get-product-complex" parameterClass="java.lang.Integer">
			<![CDATA[
				select * from t_product where prd_id = #value#
			]]>
		</select> 
		<!--END-->

 DAO层:

public Product getProductUseComplexType(int id) throws SQLException {
		init();
		Product product = (Product)sqlMapClient.queryForObject("getProduct-complex", id);
		return product;
	}

 Test类:

/**
	 * 测试复杂属性类型
	 * @throws SQLException
	 */
	public void getProductUseComplexType() throws SQLException{
		Product product = productDao.getProductUseComplexType(1);
		System.out.println(product);
	}

 结果:

id:1
description:basketball
price206.99
catId:1
catDescription:sports

 

上面的例子中,Product对象拥有一个类型为Category的category属性。因为category是复杂类型(用户定义的类型),JDBC不知道如何给它赋值。通过将category属性值和另一个mapped statement联系起来,为SQL Map引擎如何给它赋值提供了足够的信息。通过执行“getProduct”,“get-product-result”Result Map使用PRD_CAT_ID字段的值去调用“getCategory”。“get-category-result”Result Map将初始化一个Category对象并赋值给它。然后整个Category对象将赋值给Product的category属性。

 

避免N+1 Select(1:1)
上面的方法存在一个问题,就是无论何时加载一个Product,实际上都要执行两个SQL语句(分别加载Product和Category)。只加载一个Product的情况下,这个问题似乎微不足道。但在执行一个获得10个Product的查询时,每得到一个Product都要分别执行一个加载Category的SQL语句。结果共执行了11次查询:一次用于得到一个Product List,每得到一个Product对象都要执行另外一次查询,以获得相应的Category对象(N+1,这个例子是10+1=11)。
解决方法是,使用一个联合查询和嵌套的属性映射来代替两个查询statement。

映射文件:

<!--avoid N+1 select(1:1)-->
		<resultMap id="get-product-complex-promotion" class="product">
			<result property="id" column="PRD_ID"/>
			<result property="description" column="PRD_DESCRIPTION"/>
			<result property="price" column="prd_price"/>
			<result property="category.id" column="CAT_ID" />
			<result property="category.description" column="CAT_DESCRIPTION" />
		</resultMap>
		<statement id="getProduct-complex-promotion" parameterClass="int" resultMap="get-product-complex-promotion">
		<![CDATA[
			select * from t_product, t_category
			where prd_cat_id=cat_id
			and prd_id = #value#
		]]>
		</statement>

 DAO层:

public Product getProductUseComplexTypePromotion(int id)
			throws SQLException {
		init();
		Product product = (Product)sqlMapClient.queryForObject("getProduct-complex-promotion", id);
		return product;
	}

 Test类:

/**
	 * 测试复杂属性类型的改进(避免N+1 select)
	 * @throws SQLException
	 */
	public void getProductUseComplexTypePromotion() throws SQLException{
		Product product = productDao.getProductUseComplexType(1);
		System.out.println(product);
	}

 结果和上面的一样。

 

延迟加载 VS 联合查询(1:1)
必须要声明的是,使用联合查询的方案并不总是最好的。假如很少有必要访问相关的对象(如Product对象的Category属性),则不用联合查询加载所有的Categor属性可能更快。对于牵涉到外部连接或没有索引字段的数据库设计时,更是如此。在这种情况下,使用延迟加载和字节码增强选项的子查询,可能性能会更好。基本的原则是,如果您需要访问相关的对象,则使用联合查询。否则,使用延迟加载和字节码增强选项的子查询。
如果您不知道选择哪种方法,别担心。您可以随时更改选择而不会影响到Java代码。上面两个例子都得到相同的结果,并使用同样的调用方法。唯一要考虑的是,如果您要缓存查询结果,则使用子查询(而不是联合查询)来缓存查询结果。

分享到:
评论

相关推荐

    Ibatis调用Oracle存储过程返回自定义类型

    ### Ibatis调用Oracle存储过程返回自定义类型 在企业级应用开发中,尤其是在金融、保险等业务场景中,往往需要处理复杂的数据结构与逻辑。本文将深入探讨如何使用Ibatis框架来调用Oracle数据库中的存储过程,并实现...

    Ibatis复杂查询语句.doc

    在Ibatis中,复杂查询通常涉及到多个表的联接、条件动态拼接、子查询以及各种数据类型的处理。文档"Ibatis复杂查询语句.doc"所展示的查询语句就是一个很好的例子,展示了Ibatis如何处理复杂的数据库操作。接下来,...

    ibatis自定义数据类型在不支持中文的数据库存储汉字

    总结来说,`iBatis`的自定义数据类型机制允许我们在不支持中文的数据库中存储汉字,通过编写自定义的TypeHandler,我们可以灵活地将中文字符串转换为数据库可以接受的格式,然后在读取时恢复原状。这种方式在无法...

    ibatis 读取oracle clob类型

    ibatis 读取oracle clob类型

    ibatis中输入输出各种类型的参数分析及#与$区别

    在iBatis中,输入输出参数类型的支持非常丰富,几乎涵盖了Java中常见的所有基本数据类型及其封装类,同时也支持自定义JavaBean类型的传递。这使得开发者在处理数据库操作时具有很高的灵活性。 - **基本数据类型**: ...

    ibatis 支持枚举类型

    Ibatis对枚举类型的原生支持可能不如实体类那样直观,但通过一些策略,我们可以实现枚举与数据库字段之间的映射。以下将详细解释如何在Ibatis中处理枚举类型。 首先,我们需要定义枚举类。枚举类通常包含若干枚举...

    自定义Ibatis生成器

    标题中的“自定义Ibatis生成器”指的是在使用MyBatis框架时,为了解决重复的手动编写SQL映射文件和Mapper接口,开发者可以创建自己的代码生成器,以自动化这个过程。Ibatis生成器(也称为MyBatis Generator)允许...

    使用iBatis的类型处理器TypeHandlerCallback

    4. 使用`@TypeHandler`注解:对于实体类的属性,可以直接在字段上使用`@TypeHandler`注解指定对应的类型处理器。 通过深入理解和灵活运用`TypeHandlerCallback`,开发者可以更好地控制数据在Java应用和数据库之间的...

    ibatis demo,ibatis例子,ibatis示例

    Ibatis提供了多种方式来实现映射,如自动类型匹配、自定义类型处理器、复杂关联映射等。 7. **缓存机制**:Ibatis内置了本地缓存和二级缓存,可以提高数据读取速度。本地缓存作用于单个SqlSession,而二级缓存则...

    ibatis类型

    标题 "ibatis类型" 暗示我们讨论的是关于iBATIS这个持久层框架的一些特定类型或组件。iBATIS是Java开发中的一个流行数据库访问框架,它允许开发者将SQL语句直接集成到XML配置文件中,实现了SQL与Java代码的分离,...

    ibatis源码,ibatis源码 ibatis源码 ibatis源码

    iBatis的插件机制允许用户自定义拦截器,实现对Executor、StatementHandler、ParameterHandler和ResultSetHandler四个关键组件的增强。源码中的`org.apache.ibatis.plugin.Interceptor`和`org.apache.ibatis.plugin....

    ibatis api 帮助文档+IBATIS 开发文档

    4. **ResultMap**:定义了结果集如何映射到Java对象,支持复杂的列名到Java属性的映射,如一对一、一对多、多对多的关系映射。 5. **Transaction**:处理数据库事务,提供了开始、提交、回滚等操作。 **二、iBATIS...

    经典开源插件之ibatis

    ### 经典开源插件之ibatis #### 概述 ibatis(现称为MyBatis)是一款优秀的持久层框架,它将SQL语句与Java代码分离,支持自定义SQL查询、存储过程以及高级映射等功能。ibatis的灵活性使得开发者能够通过简单的XML...

    ibatis

    同时,它还支持简单类型、复杂类型(如Map或自定义对象)的参数传递。 3. 结果映射:通过`&lt;resultMap&gt;`标签,可以定义如何将查询结果映射到Java对象,包括一对一、一对多、多对一、自定义类型转换等多种映射方式。...

    iBatis详细使用手册(.net版)

    - 支持复杂类型:可以通过自定义类型处理器处理复杂的参数类型。 #### 6. ResultMap - **定义**: 结果映射定义了结果集中列名与对象属性之间的映射关系。 - **作用**: - 自动填充对象属性:根据结果集中的列名...

    iBATIS教程之快速入门浅析

    与Hibernate等其他ORM框架相比,iBATIS 更为简洁,上手速度更快,适合那些不需要复杂功能但又希望简化数据库访问的项目。 在快速入门iBATIS的过程中,首先要理解其基本概念。iBATIS通过XML配置文件来定义SQL语句与...

    Ibatis应用实例.docx

    总结来说,iBatis提供了一种简单但强大的方式来管理数据库操作,通过XML配置文件,我们可以自定义SQL,控制事务,并实现对象与数据库记录之间的映射。这种灵活性使得iBatis成为J2EE开发中一个受欢迎的工具,尤其适用...

    ibatIS代码生成插件

    ibatIS代码生成插件是一款高效实用的开发工具,它主要应用于Java开发环境中,通过自动化的方式帮助开发者快速生成常见的CRUD(创建、读取、更新、删除)操作代码,极大地提高了开发效率。这款插件基于Abator框架,...

    ibatis jar包

    7. **结果映射**:iBATIS能自动将查询结果映射到Java对象,通过结果映射配置,可以指定字段与Java属性之间的映射关系,支持自定义类型处理器以处理复杂类型的映射。 8. **参数映射**:在调用SQL时,iBATIS可以自动...

    ibatis 开发指南 2004

    9. **插件机制**:介绍iBatis的插件功能,如何自定义插件拦截SQL执行过程,实现如日志记录、性能分析等功能。 10. **缓存机制**:解析iBatis的缓存功能,包括本地缓存和二级缓存,如何配置和使用,以及缓存的生命...

Global site tag (gtag.js) - Google Analytics