- 浏览: 127872 次
- 性别:
- 来自: 北京
最新评论
-
C_J:
有必要这么鸡冻咩?
编写自己的ClassLoader知识点 -
jason61719:
你这不是说了等于没说吗……就解析个loadClass(),谁不 ...
编写自己的ClassLoader知识点 -
jiming:
tedeyang 写道很好的改进,不过话说回来,mybatis ...
开源,从关注产品社区做起(ibatis3.x的最近一个issue展示) -
C_J:
独爱Java 写道好像实际用处并不是很大,只是多了解了有这个东 ...
Java内存模型笔记 -
独爱Java:
好像实际用处并不是很大,只是多了解了有这个东西而已。。。
Java内存模型笔记
ibatis版本号:
2.3.0
Build Date: 2006/11/30 17:16
Build Number: 677
ibatis的技术是从xml里面字符串转换成JAVA对象,对象填充JDBC的statement查询,然后从resultset取对象返回,另外利用ThreadLocal实现线程安全,JDBC保证了事务控制,cache(三方库)实现缓存的dao框架。
各大包结构和作用:
1,accessplan—
2,builder.xml
3,cache
4,datasource
5,exchange—ResultMap(sql结果类型结构)和ParameterMap(sql条件类型结果)与值的相互转换
6,execution
7,impl
8,mapping
9,scop
10,transaction
11,type—jdbc的Statement和ResultSet 与 java.lang.Object对象的相互转换。
Accessplan
uml:
Accessplan对外只提供个Factory,这种“封闭”设计可以借鉴:
对外接口调用如下:
parameterPlan = AccessPlanFactory.getAccessPlan(parameterMap.getParameterClass(), parameterPropNames);
其中parameterMap.getParameterClass(),是映射的CLASS,就是XML里parameterXXX里的类,后面那个是类的成员变量,ParameterMapping是映射元素类,如下:
// 从某个映射对象中取出所有元素
ParameterMapping[] parameterMappings = parameterMap.getParameterMappings();
String[] parameterPropNames = new String[parameterMappings.length];
for (int i = 0; i < parameterPropNames.length; i++) {
// 从元素中取出被映射对象的成员名
parameterPropNames[i] = parameterMappings[i].getPropertyName();
}
UML:
ResultGetter和ParameterSetter的设计看来是为了TypeHandlerCallback扩展的复杂数据类型所用。为什么需要在这中间加一层呢? 可能是因为数据的复杂性吧,把特例和一般分离出来,代码看上去似乎优雅些。继续深入。
元数据接口
TypeHandler接口的抽象意义——Interface for getting data into, and out of a mapped statement,主要的作用是把Object那些对象set到jdbc的statement,以及从resultset结果集中获取那些Object对象。
/** * Interface for getting data into, and out of a mapped statement */ public interface TypeHandler { // para向第i个位置填充ps. public void setParameter(PreparedStatement ps, int i, Object parameter, String jdbcType) throws SQLException; // 根据rs结果集某字段名取值 public Object getResult(ResultSet rs, String columnName) throws SQLException; public Object getResult(ResultSet rs, int columnIndex) throws SQLException; /** * Converts the String to the type that this handler deals with */ public Object valueOf(String s); public boolean equals(Object object, String string); }
TypeHandlerCallback接口抽象意义为:
A simple interface for implementing custom type handlers.
Using this interface, you can implement a type handler that
will perform customized processing before parameters are set
on a PreparedStatement and after values are retrieved from
a ResultSet.
public interface TypeHandlerCallback { public void setParameter(ParameterSetter setter, Object parameter) // 同上 throws SQLException; public Object getResult(ResultGetter getter) // 同上 throws SQLException; public Object valueOf(String s); }
StringTypeHandler——String类型帮助类
public class StringTypeHandler extends BaseTypeHandler implements TypeHandler { public void setParameter(PreparedStatement ps, int i, Object parameter, String jdbcType) throws SQLException { ps.setString(i, ((String) parameter)); } public Object getResult(ResultSet rs, String columnName) throws SQLException { Object s = rs.getString(columnName); // 很熟悉的jdbc编程吧 if (rs.wasNull()) { return null; } else { return s; } } public Object getResult(ResultSet rs, int columnIndex) throws SQLException { Object s = rs.getString(columnIndex); if (rs.wasNull()) { return null; } else { return s; } } }
最后“元数据”这块剩下最后一个Factory管理类:TypeHandlerFactory
/** * Not much of a suprise, this is a factory class for TypeHandler objects. */ public class TypeHandlerFactory { private final Map typeHandlerMap = new HashMap(); // 用final Map来存储类型转换的帮助类 private final TypeHandler unknownTypeHandler = new UnknownTypeHandler(this); private final HashMap typeAliases = new HashMap();// 保存type助记符,为什么呢? /** * Default constructor */ public TypeHandlerFactory() { TypeHandler handler; handler = new BooleanTypeHandler(); register(Boolean.class, handler);// 实际上把handler放入布尔值的map,然后再放入typeMap里。 register(boolean.class, handler); handler = new ByteTypeHandler(); register(Byte.class, handler); register(byte.class, handler); register(String.class, new StringTypeHandler()); register(String.class, "CLOB", new CustomTypeHandler(new ClobTypeHandlerCallback())); register(String.class, "LONGVARCHAR", new CustomTypeHandler(new ClobTypeHandlerCallback())); register(byte[].class, new ByteArrayTypeHandler()); register(byte[].class, "BLOB", new CustomTypeHandler(new BlobTypeHandlerCallback())); register(byte[].class, "LONGVARBINARY", new CustomTypeHandler(new BlobTypeHandlerCallback())); .... putTypeAlias("string", String.class.getName()); putTypeAlias("byte", Byte.class.getName()); putTypeAlias("long", Long.class.getName()); .... } /* Public Methods */ public TypeHandler getTypeHandler(Class type, String jdbcType) { Map jdbcHandlerMap = (Map) typeHandlerMap.get(type); TypeHandler handler = null; if (jdbcHandlerMap != null) { handler = (TypeHandler) jdbcHandlerMap.get(jdbcType); if (handler == null) { handler = (TypeHandler) jdbcHandlerMap.get(null); } } return handler; } /** * When in doubt, get the "unknown" type handler * * @return - if I told you, it would not be unknown, would it? */ public TypeHandler getUnkownTypeHandler() { return unknownTypeHandler; } /** * Tells you if a particular class has a TypeHandler * * @param type - the class * * @return - true if there is a TypeHandler */ public boolean hasTypeHandler(Class type) { return getTypeHandler(type) != null; } /** * Register (add) a type handler for a class and JDBC type * * @param type - the class * @param jdbcType - the JDBC type * @param handler - the handler instance */ public void register(Class type, String jdbcType, TypeHandler handler) { Map map = (Map) typeHandlerMap.get(type); if (map == null) { map = new HashMap(); typeHandlerMap.put(type, map); } map.put(jdbcType, handler); } /** * Lookup an aliased class and return it's REAL name * * @param string - the alias * * @return - the REAL name */ public String resolveAlias(String string) { String key = null; if(string != null) key = string.toLowerCase(); String value = null; if (typeAliases.containsKey(key)) { value = (String) typeAliases.get(key); } else { value = string; } return value; } /** * Adds a type alias that is case insensitive. All of the following String, string, StRiNg will equate to the same alias. * @param alias - the alias * @param value - the real class name */ public void putTypeAlias(String alias, String value) { String key = null; if(alias != null) key = alias.toLowerCase(); if (typeAliases.containsKey(key) && !typeAliases.get(key).equals(value)) { throw new SqlMapException("Error in XmlSqlMapClientBuilder. Alias name conflict occurred. The alias '" + key + "' is already mapped to the value '" + typeAliases.get(alias) + "'."); } typeAliases.put(key, value); } }
Mapping包
--parameter包意义——主要负责数据类型转换,把xml写的字符串映射成正确的类型,以上type包是解决了object到type的转换。
UML:
ParameterMap接口
public interface ParameterMap { public String getId(); public void setParameters(RequestScope request, PreparedStatement ps, Object[] parameters) throws SQLException; public Object[] getParameterObjectValues(RequestScope request, Object parameterObject); public CacheKey getCacheKey(RequestScope request, Object parameterObject); public void refreshParameterObjectValues(RequestScope request, Object parameterObject, Object[] values); public ParameterMapping[] getParameterMappings(); public Class getParameterClass(); }
ParameterMapping接口
public interface ParameterMapping { public String getPropertyName(); public boolean isOutputAllowed(); }
BasicParameterMapping实现类:
public class BasicParameterMapping implements ParameterMapping { private static final String MODE_INOUT = "INOUT"; private static final String MODE_OUT = "OUT"; private static final String MODE_IN = "IN"; private String propertyName; // 从XML文件里读取需要转换的类型名 private TypeHandler typeHandler; // 对象转换相应类型的工具map private String typeName; // this is used for REF types or user-defined types private int jdbcType; private String jdbcTypeName; private String nullValue; private String mode; private boolean inputAllowed; private boolean outputAllowed; private Class javaType; // 需要转换的类型class private String resultMapName; // 结果map名称 private Integer numericScale; private String errorString; public BasicParameterMapping() { mode = "IN"; inputAllowed = true; outputAllowed = false; } public void setJavaTypeName(String javaTypeName) { try { if (javaTypeName == null) { this.javaType = null; } else {// 通过getClassLoader().loadClass(className);来获得实例 this.javaType = Resources.classForName(javaTypeName); } } catch (ClassNotFoundException e) { throw new SqlMapException("Error setting javaType property of ParameterMap. Cause: " + e, e); } } }
BasicParameterMap实现类
public class BasicParameterMap implements ParameterMap { private String id; private Class parameterClass; private ParameterMapping[] parameterMappings; private DataExchange dataExchange; private String resource; private Map parameterMappingIndex = new HashMap(); private SqlMapExecutorDelegate delegate; public void setParameterMappingList(List parameterMappingList) { this.parameterMappings = (BasicParameterMapping[]) parameterMappingList.toArray(new BasicParameterMapping[parameterMappingList.size()]); for (int i = 0; i < parameterMappings.length; i++) { parameterMappingIndex.put(parameterMappings[i].getPropertyName(), new Integer(i)); } Map props = new HashMap(); props.put("map", this); dataExchange = delegate.getDataExchangeFactory().getDataExchangeForClass(parameterClass); dataExchange.initialize(props); } /** * @param ps * @param parameters * @throws java.sql.SQLException */ public void setParameters(RequestScope request, PreparedStatement ps, Object[] parameters) throws SQLException { ErrorContext errorContext = request.getErrorContext(); errorContext.setActivity("applying a parameter map"); errorContext.setObjectId(this.getId()); errorContext.setResource(this.getResource()); errorContext.setMoreInfo("Check the parameter map."); if (parameterMappings != null) { for (int i = 0; i < parameterMappings.length; i++) { BasicParameterMapping mapping = (BasicParameterMapping) parameterMappings[i]; errorContext.setMoreInfo(mapping.getErrorString()); if (mapping.isInputAllowed()) { setParameter(ps, mapping, parameters, i); } } } } public Object[] getParameterObjectValues(RequestScope request, Object parameterObject) { return dataExchange.getData(request, this, parameterObject); } public CacheKey getCacheKey(RequestScope request, Object parameterObject) { return dataExchange.getCacheKey(request, this, parameterObject); } public void refreshParameterObjectValues(RequestScope request, Object parameterObject, Object[] values) { dataExchange.setData(request, this, parameterObject, values); } protected void setParameter(PreparedStatement ps, BasicParameterMapping mapping, Object[] parameters, int i) throws SQLException { Object value = parameters[i]; // Apply Null Value String nullValueString = mapping.getNullValue(); if (nullValueString != null) { TypeHandler handler = mapping.getTypeHandler(); if (handler.equals(value, nullValueString)) { value = null; } } // Set Parameter TypeHandler typeHandler = mapping.getTypeHandler(); if (value != null) { typeHandler.setParameter(ps, i + 1, value, mapping.getJdbcTypeName()); } else if (typeHandler instanceof CustomTypeHandler) { typeHandler.setParameter(ps, i + 1, value, mapping.getJdbcTypeName()); } else { int jdbcType = mapping.getJdbcType(); if (jdbcType != JdbcTypeRegistry.UNKNOWN_TYPE) { ps.setNull(i + 1, jdbcType); } else { ps.setNull(i + 1, Types.OTHER); } } } }
发表评论
-
iOS入门(ongoing)
2012-09-13 11:32 1301Record it: The overview of ... -
Stuff about Android
2011-07-09 16:15 1065Foreword: long time ... -
JQuery初体验(Demo)
2011-05-22 13:43 1458Demo:Show <meta content ... -
Java内存模型笔记
2011-04-13 15:48 1538题记: 看到C/C++ ... -
Radiant_The Popular Ruby's CMS Demo篇
2011-04-02 14:49 1241题记: 上篇 记录我第一次安装Rodiant经过和 ... -
Radiant_The Popular Ruby’s CMS安装篇
2011-03-28 00:48 1278题记: 今天第一次参加JE的线下活动,robbin等 ... -
关于Azul 并发垃圾回收器
2011-03-26 14:40 1317题记: 总感觉JE讨论的帖子的东西都比较滞后,所以会 ... -
phpCMS & jQuery是我该做的(阉割了)
2011-02-27 23:02 81WD讲究以plugin挂载为结构,我需要构造一个p ... -
我的玩意:J2ME的Criteria初探
2011-01-20 21:59 1019题记: 前几天跟初中同学聊天,他问我能不能做一个GP ... -
编写自己的ClassLoader知识点
2011-01-13 14:41 1871题记: 看到InfoQ关于ClassLoader的文 ... -
周末好玩,用短信控制你的计算机
2011-01-10 16:34 2986Snapshot: 详情 ... -
About Dock Plugin on Mac
2010-11-21 22:47 1462题记: 第一次接触MAC的开发..... ... -
可变hashcode的隐患和序列化安全
2010-10-25 00:55 1369可变hashcode的隐患 为识别对象,JDK ... -
体验OSGi(helloworld.jar)—富app的热拔插
2010-10-18 23:22 2436记得以前工作的时候,有天direct manager问 ... -
MongoDB on DAO with Java Language
2010-08-26 19:17 1425A Quick Tour Using the Java d ... -
Getting Start on Mongodb
2010-08-26 01:29 1504题记: 最近老和同学聊到non-relational ... -
Java Media Framework本地玩转摄像头
2010-08-04 00:57 17341、简介The JavaTM Media Framework ... -
从WeakLogHandler应用看Java的引用、引用队列
2010-06-14 00:58 1499题记: 前几天讨论到WeakHashMap(这个是个弱引用的 ... -
《重构》读书笔记
2010-05-09 00:05 1045Martin Fowler于2003年出版 ... -
RPC之WebServices&RMI&JMS,phprpc框架?(待续)
2010-05-06 22:31 55前段时间写过基本的WebServices,也没再做深入 ...
相关推荐
包含IBatis.net 开发所需的Castle.DynamicProxy.dll,IBatisNet.Common.dll,IBatisNet.DataAccess.dll,IBatisNet.Common.dll以及相关配置文件
ibatis-2.3.3.720.jar
标题和描述中提到的"IBatisNet.Common.1.6.2、IBatis.DataAccess.1.9.2、IBatis.DataMapper.1.6.2"是针对一个名为IBatisNet的框架的不同组件的版本号。IBatisNet是一个在.NET平台上实现的开源持久层框架,它源于Java...
这里提到的是iBATIS的三个不同版本的jar包:ibatis-2.3.4.726.jar、ibatis-2.3.0.677.jar以及ibatis-2.3.3.720.jar。 首先,让我们深入了解iBATIS的核心概念和功能: 1. **SQL Map配置**:iBATIS的核心是SQL Map...
本篇将深入探讨IBatis.Net的核心组件——IBatis.DataAccess.1.9.2和IBatis.DataMapper.1.6.2,以及它们在数据访问中的关键作用。 **一、IBatis.DataAccess** IBatis.DataAccess是IBatis.net框架的一部分,主要负责...
本篇文章将围绕"IBatis.DataMapper.1.6.2.bin.zip"和"IBatis.DataMapper.1.9"这两个开发包,深入探讨其核心概念、功能特性以及版本间的差异,帮助开发者更好地理解和应用这一框架。 1. **IBatis DataMapper简介** ...
Ibatis,全称为MyBatis,是一个优秀的Java持久层框架,它主要负责简化数据库操作,将SQL语句与Java代码分离,使得开发人员能够更加专注于业务逻辑。在本主题中,我们将深入探讨Ibatis的两个特定版本:ibatis2.3.4.8....
《深入解析iBatis-SQLMap 2.3.4.726源码》 在Java开发领域,iBatis作为一个优秀的持久层框架,深受广大开发者喜爱。它将SQL语句与Java代码分离,提高了代码的可读性和可维护性。本篇将围绕iBatis-SQLMap 2.3.4.726...
根据提供的文件信息,本书《Manning iBATIS in Action Jan. 2007 eBook-BBL》主要介绍了iBATIS框架的基本概念、安装配置方法、核心功能及其在实际项目中的应用。下面将针对该书籍中提及的主要知识点进行详细阐述。 ...
在本实例中,"ibatis2.3.4.726增删改查源码实例" 提供了一个完整的基于Ibatis 2.3.4.726版本的开发案例,涵盖了数据库的基本操作,即增(INSERT)、删(DELETE)、改(UPDATE)和查(SELECT)。 首先,我们来了解...
iBATIS 框架源码剖析.iso 源代码网站版 261 MB
解析这个XML文件的过程涉及到DOM或SAX解析器,源码中这部分功能通常在`org.apache.ibatis.io.Resources`和`org.apache.ibatis.builder.Configuration`类中实现。 三、Executor执行器 Executor执行器是iBatis的核心...
iBATIS,作为Java开发中的一个持久层框架,它的出现极大地简化了数据库操作与应用程序的集成。这个开源项目由Clinton Begin在2001年创立,最初是为了解决密码软件开发中的问题,但随着时间的发展,它逐渐演变成了一...
ibatis2.3.4.726.jar ibatis2.3.4.726.jar ibatis2.3.4.726.jar ibatis2.3.4.726.jar
Ibatis,一个强大的Java持久层框架,以其轻量级、高度灵活的特点在众多开发者中备受青睐。2.3.0.677是Ibatis的一个重要版本,被誉为“最稳定”的版本,它提供了可靠的性能和稳定性,使得开发人员在处理数据库操作时...
《深入解析ibatis-2.3.2.715.jar》 在Java开发领域,Ibatis作为一个轻量级的持久层框架,以其灵活、易用的特点深受开发者喜爱。本次我们将详细探讨`ibatis-2.3.2.715.jar`这个特定版本的Ibatis库,它为开发者提供了...
org.apache.ibatis.logging org.apache.ibatis.logging.commons org.apache.ibatis.logging.jdbc org.apache.ibatis.logging.jdk14 org.apache.ibatis.logging.log4j org.apache.ibatis.logging.log4j2 org.apache....
通过分析这份文件,我们可以清晰地知道哪些外部库是iBatis运行所必需的,以便在实际应用中正确配置。 "META-INF"目录下通常包含了项目元数据,如MANIFEST.MF文件,它描述了JAR文件的结构和属性。在这里,我们可以...