ibatis是什么?ibatis是一个基于Java的"半自动化"的持久框架,"半自动化"是指ibatis并不会在运行期自动生成sql语句执行,而是具体的sql需要通过配置文件进行编写,并将所需的参数,以及返回的结果字段映射到指定的POJO.
ibatis的核心类图
SqlMapClient类是ibatis的门面,通过ibatis完成的持久化操作都是通过调用SqlMapClient类完成的,SqlMapClient将所有的操作都转给类SqlMapExecutorDelegate类,SqlMapExecutorDelegate类存放解析配置文件生成的类,比如数据源,parameterMap,resultMap, MappedStatement(对增删改查语句的封装)等,SqlExecutor是最终执行sql语句的地方.MappedStatement类包含对参数数组进行包装的ParameterMapping[]数组,对执行结果进行包装的ResultMapping[]数组,还有对各种不同的sql的包装类Sql
比如对于一个插入语句,传进来的是一个对象,ibatis就会根据参数的数组包装类ParameterMapping[]将参数赋值.这个赋值是通过DataExchange类完成的,代码如下:
public Object[] getProperties(Object object) {
- int i = 0;
- Object[] values = new Object[propertyNames.length];
- try {
- for (i = 0; i < propertyNames.length; i++) {
- try {
- values[i] = getters[i].invoke(object, NO_ARGUMENTS);
- } catch (Throwable t) {
- throw ClassInfo.unwrapThrowable(t);
- }
- }
- } catch (Throwable t) {
- throw new RuntimeException("Error getting property '" + getters[i].getName() + "' of '" + object + "'. Cause: " + t, t);
- }
- return values;
- }
其中object是传进来的要插入的对象,propertyNames就是ParameterMapping[]的参数数组,getters是object类的所有get方法的Method方法数组
对于一个查询语句,对执行结果的处理,是通过对ResultMapping[]进行循环处理的,核心代码如下:
- for (int i = 0; i < getResultMappings().length; i++) {
- ResultMapping mapping = (ResultMapping) getResultMappings()[i];
- errorContext.setMoreInfo(mapping.getErrorString());
- if (mapping.getStatementName() != null) {
- if (resultClass == null) {
- throw new SqlMapException("The result class was null when trying to get results for ResultMap named " + getId() + ".");
- } else if (Map.class.isAssignableFrom(resultClass)) {
- Class javaType = mapping.getJavaType();
- if (javaType == null) {
- javaType = Object.class;
- }
- columnValues[i] = getNestedSelectMappingValue(statementScope, rs, mapping, javaType);
- } else if (DomTypeMarker.class.isAssignableFrom(resultClass)) {
- Class javaType = mapping.getJavaType();
- if (javaType == null) {
- javaType = DomTypeMarker.class;
- }
- columnValues[i] = getNestedSelectMappingValue(statementScope, rs, mapping, javaType);
- } else {
- Probe p = ProbeFactory.getProbe(resultClass);
- Class type = p.getPropertyTypeForSetter(resultClass, mapping.getPropertyName());
- columnValues[i] = getNestedSelectMappingValue(statementScope, rs, mapping, type);
- }
- foundData = foundData || columnValues[i] != null;
- } else if (mapping.getNestedResultMapName() == null) {
- columnValues[i] = getPrimitiveResultMappingValue(rs, mapping);
- if (columnValues[i] == null) {
- columnValues[i] = doNullMapping(columnValues[i], mapping);
- } else {
- foundData = true;
- }
- }
- }
其中,type为参数的java类型, Probe p = ProbeFactory.getProbe(resultClass),Class type = p.getPropertyTypeForSetter(resultClass, mapping.getPropertyName())是通过反射获取java类型的
getNestedSelectMappingValue(statementScope, rs, mapping, type)调用了prepareBeanParameterObject(StatementScope statementScope, ResultSet rs, ResultMapping mapping, Class parameterType)方法,方法如下:
private Object prepareBeanParameterObject(StatementScope statementScope, ResultSet rs, ResultMapping mapping, Class parameterType)
- throws InstantiationException, IllegalAccessException, SQLException {
- TypeHandlerFactory typeHandlerFactory = getDelegate().getTypeHandlerFactory();
-
- Object parameterObject;
- if (parameterType == null) {
- parameterObject = new HashMap();
- } else {
- parameterObject = ResultObjectFactoryUtil.createObjectThroughFactory(parameterType);
- }
- String complexName = mapping.getColumnName();
-
- if (complexName.indexOf('=') > -1
- || complexName.indexOf(',') > -1) {
- StringTokenizer parser = new StringTokenizer(complexName, "{}=, ", false);
- while (parser.hasMoreTokens()) {
- String propName = parser.nextToken();
- String colName = parser.nextToken();
- Class propType = PROBE.getPropertyTypeForSetter(parameterObject, propName);
- TypeHandler propTypeHandler = typeHandlerFactory.getTypeHandler(propType);
- Object propValue = propTypeHandler.getResult(rs, colName);
- PROBE.setObject(parameterObject, propName, propValue);
- }
- } else {
-
- TypeHandler propTypeHandler = typeHandlerFactory.getTypeHandler(parameterType);
- if (propTypeHandler == null) {
- propTypeHandler = typeHandlerFactory.getUnkownTypeHandler();
- }
- parameterObject = propTypeHandler.getResult(rs, complexName);
- }
-
- return parameterObject;
typeHandlerFactory根据参数parameterType的类型决定采用哪个handler处理ResultSet的结果,以
StringTypeHandler为例,其getResult(ResultSet rs, String columnName)方法如下:
- public Object getResult(ResultSet rs, String columnName)
- throws SQLException {
- Object s = rs.getString(columnName);
- if (rs.wasNull()) {
- return null;
- } else {
- return s;
- }
- }
分享到:
相关推荐
Ibatis允许开发者自定义插件,通过拦截器模式增强SqlSession或Executor的行为,例如日志记录、性能分析等。 这个自己编写的Ibatis框架实现,虽然可能在功能上与官方版本有所差异,但基本原理和核心思想是一致的,...
**深入分析 iBATIS 框架之系统架构与映射原理** iBATIS 是一个优秀的持久层框架,它允许开发者将 SQL 语句与 Java 代码分离,从而简化了数据库访问层的开发工作。本篇文章将深入探讨 iBATIS 的核心系统架构以及其...
通过深入分析iBATIS的源码,开发者不仅可以了解其工作原理,还能学习到设计模式、数据库访问的最佳实践以及如何优雅地处理数据库操作。对于提升Java开发者的技能和理解数据库访问层的实现有极大的帮助。在实际开发中...
在这个2.3.4.726版本的源码中,我们可以深入理解iBATIS DAO的工作原理,并通过添加注释来帮助我们更好地掌握其实现细节。 首先,iBATIS DAO的核心概念是SQL Maps,它们定义了数据库操作的SQL语句,并将其映射到Java...
本篇文章基于“Ibatis3手册 Ibatis3参考手册”的标题及描述,深入解析Ibatis3的核心概念、架构特点以及如何进行实际操作,旨在帮助读者全面理解Ibatis3的工作原理与应用场景。 ### 一、Ibatis3简介 Ibatis3是一款...
描述中的"ibatis框架源码剖析书中附带的光盘,ibatis源码分析"暗示这可能是一个学习资源,用于深入理解iBATIS的工作原理,可能包括了对源码的详细解读和分析。 **iBATIS核心知识点** 1. **SQL映射**:iBATIS的核心...
本书详细介绍了iBATIS这一流行开源框架的核心概念、工作原理以及在实际项目中的应用技巧,是iBATIS学习者和使用者不可或缺的参考资料。 ### IBATIS哲学 iBATIS的哲学强调简洁性与灵活性,它旨在提供一个轻量级的...
这个文档可能会涵盖如何在Spring中配置和使用iBATIS,以及它们之间的协同工作原理。 2. **iBATIS-SqlMaps-2_cn.pdf**:这很可能是iBATIS SQL Maps 2版本的中文版官方文档。SQL Maps是iBATIS的核心组件,负责定义SQL...
这本指南对于初学者和有经验的开发者来说都是宝贵的资源,它帮助读者理解iBatis的工作原理,掌握其核心特性和最佳实践,从而更高效地进行数据库操作。通过阅读《iBatis 开发指南》,开发者可以更好地掌握Java世界的...
《iBATIS-SqlMaps》则可能更侧重于实战和案例分析,通过具体的项目场景来展示如何设计和实施iBATIS解决方案,以及如何利用iBATIS实现更高效的数据操作。 两本书结合阅读,开发者可以从理论到实践全面掌握iBATIS框架...
深入研究iBatis源码有助于理解其内部工作原理,包括如何解析XML配置文件,如何执行SQL语句,以及如何进行结果映射。源码分析可以帮助开发者更好地定制和优化自己的应用。 六、iBatis实践项目 通过实践项目,可以...
通过阅读这三份文档,你将能够深入理解iBATIS的工作原理,掌握其配置和使用技巧,同时也能学习到如何有效地利用iBATIS实现数据库操作的半封装,提高开发效率。在实际项目中,iBATIS可以很好地适应各种复杂的数据库...
5. **缓存机制**:分析Ibatis的一级和二级缓存,以及如何自定义缓存策略。 6. **事务管理**:讨论Ibatis的自动和手动事务控制,以及如何与Spring事务管理结合使用。 7. **插件机制**:介绍如何编写和使用Ibatis的...
在描述中提到的博文链接是一个ITEYE博客的文章,可能提供了更多关于iBATIS使用或分析的详细信息,但具体内容由于没有给出,我们只能根据常规的iBATIS知识进行讲解。 **iBATIS 概述** iBATIS 是由 Apache Software ...
在标签中提到的“源码”可能意味着博主分析了iBATIS的源代码来解释其分页机制,这有助于深入理解iBATIS的工作原理,以及如何根据具体需求进行定制。而“工具”可能是指一些辅助工具,如MyEclipse、IntelliJ IDEA中的...
通过分析这个“ibatisDemo”,开发者不仅能理解Ibatis的基本工作原理,还能学习到如何在实际项目中配置和使用Ibatis,提高数据库操作的效率和代码质量。这是一个非常有价值的实践案例,对于提升Java Web开发技能具有...
- **日志库**:如log4j或slf4j,用于记录Ibatis的执行日志,帮助调试和性能分析。 - **其他依赖**:如ognl,用于表达式语言支持,使得在XML中可以执行更复杂的逻辑。 学习Ibatis,除了理解这些基本概念,还需要...
iBATIS,全称为“Java SQL Mapping Framework”,是一款在Java应用程序中进行数据库操作的开源框架..."iBATIS test"这个文件可能是用于测试iBATIS模板配置和功能的示例,你可以通过分析和运行它来加深对iBATIS的理解。
《深入解析iBatis 2.3.0.677源码》 ...总之,通过对iBatis 2.3.0.677源码的分析,我们可以掌握其设计理念和工作原理,提升我们在Java持久层开发中的技术水平。无论是初学者还是经验丰富的开发者,都能从中受益匪浅。