- 浏览: 932067 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (251)
- WebService (17)
- IBatis (22)
- Hibernate (1)
- SpringMVC - 基础篇 (32)
- Spring (15)
- Java (11)
- JVM及调优 - 基础篇 (4)
- 集群 (14)
- 数据库 (17)
- WebSphere (5)
- 多线程 (4)
- 集合、容器 (2)
- DB Pool (1)
- Power Designer (5)
- Maven基础 (5)
- JS (14)
- WEB 前端 (5)
- 实用小工具 (17)
- 社会、人 (2)
- 乱七八糟 (18)
- ASM&CGLIB - 基础篇 (12)
- 缓存 (1)
- 性能 (1)
- 设计之殇 (1)
- 分布式事务 (1)
- 单点登录 (11)
- 分布式 Session (4)
- Memcached - 基础篇 (6)
最新评论
-
一笑_奈何:
楼主写的还真行不错。
扫盲贴 - J2EE集群之JNDI集群实现 -
xuezhongyu01:
博主写的很详细,但最后还是没明白,最后调用BasicDataS ...
Spring中的destroy-method方法 -
Mr梁:
commons-fileupload.jar commons- ...
SpringMVC 中文件上传 MultipartResolver -
Eywa:
总结的很不错
ORACLE CASE WHEN 及 SELECT CASE WHEN的用法 -
TryRelax:
fastjson 比 jackson 好用吧?
Spring MVC Jackson DateFormat
复杂类型用以表示在数据库中相互关系为一对一,一对多的数据。
映射文件:
<!--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配置文件:
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN" "http://www.ibatis.com/dtd/sql-map-2.dtd"> <sqlMap namespace="Classes"> <typeAlias alias="classes" type="com.alibaba.webx.biz.dataobject.Classes" /> <typeAlias alias="student" type="com.alibaba.webx.biz.dataobject.Student" /> <typeAlias alias="teacher" type="com.alibaba.webx.biz.dataobject.Teacher" /> <resultMap class="student" id="studentResultMap" groupBy="id"> <result property="id" column="stuId" /> <result property="name" column="stuName" /> </resultMap> <resultMap class="teacher" id="teacherResultMap" groupBy="id"> <result property="id" column="terId" /> <result property="name" column="terName" /> </resultMap> <resultMap class="classes" id="classesResultMap" groupBy="id"> <result property="id" column="id" /> <result property="name" column="name" /> <result property="studentList" resultMap="Classes.studentResultMap"/> <result property="teacherList" resultMap="Classes.teacherResultMap"/> </resultMap> <select id="findAllClasses" resultMap="Classes.classesResultMap"> SELECT c.id,c.name,s.id stuId,s.name stuName,t.id terId,t.name terName FROM class c JOIN student s ON c.id=s.classid JOIN teacher t ON c.id=t.classid ORDER BY c.id; </select> </sqlMap>
类:
public class Classes { private Integer id; private String name; private List<Student> studentList; private List<Teacher> teacherList; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public List<Student> getStudentList() { return studentList; } public void setStudentList(List<Student> studentList) { this.studentList = studentList; } public List<Teacher> getTeacherList() { return teacherList; } public void setTeacherList(List<Teacher> teacherList) { this.teacherList = teacherList; } } public class Student { private Integer id; private String name; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } } public class Teacher { private Integer id; private String name; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
上面的方法可以一次性查询出所有的记录,ibatis会自动分组,这个可以解决数据量比较小的情况。
但是如果多的一端比如班级的学生数据量比较大,需要分页的话,就不行了。
如果一的一端数据量比较大,比如班级比较多,需要分页的话,我的解决方法是:首先只查询出一页数据的ids,然后再通过ids,
用in的方法查询出数据,很多人说in的性能差,但总比n+1的性能要好很多吧。
发表评论
-
iBATIS缓存
2011-12-12 21:33 1164为了提高应用程序性 ... -
iBatis批处理(batch)
2011-09-05 23:47 6956spring集成了ibatis的批量提交的功能,我们只要调用A ... -
一个Spring+iBatis框架进行batch处理的问题
2011-09-05 23:23 1621在使用org.springframework.jdbc.dat ... -
ibatis 注意点
2011-08-08 19:28 1381insert,update,delete 返回值 inser ... -
ibatis 之 动态SQL查询(dynamic )
2011-06-12 12:13 2288映射文件: <select id=" ... -
ibatis 之 复杂类型集合的属性
2011-06-12 12:10 2147Result Map还可以装入代表复杂类型对象集合(List) ... -
ibatis 之 java.util.Map作为parameterClass和resultClass
2011-06-12 11:21 51601.Map作为parameterClass 映射 ... -
ibatis Tips 之 resultMap
2011-05-29 21:04 1209转载:http://xulongfa.iteye.com/bl ... -
ibatis Tips之parameterMap
2011-05-29 21:03 1342转载:http://xulongfa.iteye.com/bl ... -
iBatis查询API
2011-05-29 12:34 1856转载:http://sarin.iteye.com/blog/ ... -
iBatis查询select详解
2011-05-29 12:20 2216转载:http://sarin.iteye.com/blog/ ... -
ibatis 表与表的关联查询
2011-05-22 15:04 1265ibatis高级特性,处理表与表之间的关联。ibatis中,提 ... -
ibatis 动态映射机制
2011-05-22 14:15 1456对于这个组合查询页 ... -
sqlMapConfig.xml配置文件详解
2011-05-22 13:04 3553sqlMapConfig.xml配置文件详解: X ... -
ibatis缓存
2011-05-22 12:52 1363iBatis的缓存配置比较简单易懂,以我使用的iBati ... -
ibatis resultclass "java.util.hashmap" 缓存问题
2011-05-22 12:13 1522在做ibatis项目过程中遇到如下样式动态查询 <se ... -
ibatis # $区别
2011-05-22 11:55 14381、#可以进行预编译,进行类型匹配,#变量名# 会转化为 j ... -
iBATIS入门示例及注释
2011-05-08 18:20 1796工程的结构: 一、SqlMapConf ... -
iBATIS 三个版本小细节对比
2011-05-08 16:12 1204iBATIS 三个版本小细节对比 sqlMapConfig ... -
深入分析 iBATIS 框架之系统架构与映射原理
2011-05-07 12:48 1221原文:http://www.ibm.com/developer ...
相关推荐
在iBatis中,输入输出参数类型的支持非常丰富,几乎涵盖了Java中常见的所有基本数据类型及其封装类,同时也支持自定义JavaBean类型的传递。这使得开发者在处理数据库操作时具有很高的灵活性。 - **基本数据类型**: ...
标题 "ibatis类型" 暗示我们讨论的是关于iBATIS这个持久层框架的一些特定类型或组件。iBATIS是Java开发中的一个流行数据库访问框架,它允许开发者将SQL语句直接集成到XML配置文件中,实现了SQL与Java代码的分离,...
iBatis的插件机制允许用户自定义拦截器,实现对Executor、StatementHandler、ParameterHandler和ResultSetHandler四个关键组件的增强。源码中的`org.apache.ibatis.plugin.Interceptor`和`org.apache.ibatis.plugin....
同时,它还支持简单类型、复杂类型(如Map或自定义对象)的参数传递。 3. 结果映射:通过`<resultMap>`标签,可以定义如何将查询结果映射到Java对象,包括一对一、一对多、多对一、自定义类型转换等多种映射方式。...
4. **ResultMap**:定义了结果集如何映射到Java对象,支持复杂的列名到Java属性的映射,如一对一、一对多、多对多的关系映射。 5. **Transaction**:处理数据库事务,提供了开始、提交、回滚等操作。 **二、iBATIS...
### 经典开源插件之ibatis #### 概述 ibatis(现称为MyBatis)是一款优秀的持久层框架,它将SQL语句与Java代码分离,支持自定义SQL查询、存储过程以及高级映射等功能。ibatis的灵活性使得开发者能够通过简单的XML...
- 支持复杂类型:可以通过自定义类型处理器处理复杂的参数类型。 #### 6. ResultMap - **定义**: 结果映射定义了结果集中列名与对象属性之间的映射关系。 - **作用**: - 自动填充对象属性:根据结果集中的列名...
4. **代码生成**:这个工具的实现原理可能包括解析数据库元数据,根据表结构生成相应的Java实体类,包括属性、getter和setter方法、构造函数等,同时也可能生成与之对应的Mapper接口和XML配置文件。 5. **Demo编写*...
7. **结果映射**:iBATIS能自动将查询结果映射到Java对象,通过结果映射配置,可以指定字段与Java属性之间的映射关系,支持自定义类型处理器以处理复杂类型的映射。 8. **参数映射**:在调用SQL时,iBATIS可以自动...
- **动态SQL元素**:iBatis支持使用动态SQL来构建复杂的查询条件。例如,可以使用`<isNotEmpty>`元素来根据条件添加`ORDER BY`子句。 ```xml ORDER BY #orderField# ``` - **自定义SQL片段**:通过`...
iBatis的核心配置文件(mybatis-config.xml)定义了全局属性,包括数据源、事务管理器、类型别名、插件等。同时,每个Mapper XML文件则包含了具体的SQL映射,如插入、更新、删除和查询语句。 3. **SQL映射**: ...
总结来说,iBatis提供了一种简单但强大的方式来管理数据库操作,通过XML配置文件,我们可以自定义SQL,控制事务,并实现对象与数据库记录之间的映射。这种灵活性使得iBatis成为J2EE开发中一个受欢迎的工具,尤其适用...
缓存(Cache)功能是iBATIS提高性能的重要手段,它提供了几种类型的缓存策略,包括MEMORY类型(基于内存的缓存,可能使用WeakReference防止内存泄漏)、LRU(Least Recently Used,最近最少使用,一种淘汰算法)和...
4. **结果集映射**:Ibatis通过`<resultMap>`标签定义结果集映射,可以处理复杂的一对多、一对一、多对多关系,以及自定义类型转换等。 5. **事务管理**:在Spring环境中,可以使用Spring的...
总结起来,Ibatis的动态查询语句配置提供了强大的灵活性,使得我们可以根据实际业务需求构建各种复杂的SQL语句,而无需硬编码。通过熟练掌握和运用这些动态SQL标签,开发者可以提高代码的可读性和维护性,同时减少...
通过定义`<resultMap>`,我们可以指定列名与Java属性的对应关系,甚至处理一对一、一对多、多对多等复杂关系。 4. **事务管理**:iBatis可以方便地进行事务控制,通过SqlSessionFactory和SqlSession对象,我们可以...
5. **参数映射**:支持多种参数类型,包括简单类型、复杂对象和自定义类型,使得参数传递更加灵活。 6. **结果集映射**:可以处理多表联查的结果集,通过配置文件定义复杂的结果集映射规则。 **IBatis.DataAccess....