ibatis的包组成中从历史版本中我们能看到他是有:ibatis-dao.jar,ibatis-common.jar,ibatis-sqlmap.jar三个包组成,所以学习源码之前,我们先澄清一些东西,同时让大家弄清楚什么时候该引入什么包,一般情况下如果你的项目只是用到了ibatis,没有其他容器使用,那么你可以考虑使用ibatis-dao+ibatis-common+ibatis-sqlmap,如果你使用了spring做为容器,那么其实你将不需要引入ibatis-dao,同时有时候我们也会发现有ibatis-core的包,这个是在ibatis的2.2以后将ibatis-common.jar和ibatis-sqlmap.jar二合一之后的结果,所以看到ibatis-core之后基本就不需要引入common和sqlmap这两个包了,如果你引入了ibatis-dao.jar那么ibatis-core是必须引入的。
这里就需要弄明白为什么会有ibatis-dao.jar,为什么2.3.x的版本中不在引入。这都要从ibatis-dao.jar的功能及设计初衷谈起。
首先DAO是J2EE的一种设计模式即DAO设计模式,ibatis-dao.jar的存在是更面向应用层的,SQL Map组件相对要更底层一些,靠近数据源层,DAO组件可以通过调用SQL Map组件来实现业务处理,ibatis提供的DAO层不但可以继承Ibatis的SQLMap组件想成一个一个一体的解决方案,同时还可以融入其他多种ORM组件,如Hibernate、Apache Ojb、TopLink、甚至包括JDBC、JTA。
在我们检出的jpetstore项目中我们会看到一个类DaoConfig
public class DaoConfig {
private static final String resource = "com/ibatis/jpetstore/persistence/dao.xml";
private static final DaoManager daoManager;
static {
try {
daoManager = newDaoManager(null);
Properties props = Resources.getResourceAsProperties("properties/database.properties");
String url = props.getProperty("url");
String driver = props.getProperty("driver");
String username = props.getProperty("username");
String password = props.getProperty("password");
if (url.equals("jdbc:hsqldb:mem:jpetstore")) {
Class.forName(driver).newInstance();
Connection conn = DriverManager.getConnection(url, username, password);
try {
ScriptRunner runner = new ScriptRunner(conn, false, false);
runner.setErrorLogWriter(null);
runner.setLogWriter(null);
runner.runScript(Resources.getResourceAsReader("ddl/hsql/jpetstore-hsqldb-schema.sql"));
runner.runScript(Resources.getResourceAsReader("ddl/hsql/jpetstore-hsqldb-dataload.sql"));
} finally {
conn.close();
}
}
} catch (Exception e) {
throw new RuntimeException("Description. Cause: " + e, e);
}
}
public static DaoManager getDaoManager() {
return daoManager;
}
public static DaoManager newDaoManager(Properties props) {
try {
Reader reader = Resources.getResourceAsReader(resource);
return DaoManagerBuilder.buildDaoManager(reader, props);
} catch (Exception e) {
throw new RuntimeException("Could not initialize DaoConfig. Cause: " + e, e);
}
}
}
其中
public static DaoManager newDaoManager(Properties props) {
try {
Reader reader = Resources.getResourceAsReader(resource);
return DaoManagerBuilder.buildDaoManager(reader, props);
} catch (Exception e) {
throw new RuntimeException("Could not initialize DaoConfig. Cause: " + e, e);
}
}
上面的代码加载了一个resource,这个resource正是一个名字叫dao.xml的文件
文件内容大致如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE daoConfig
PUBLIC "-//ibatis.apache.org//DTD DAO Configuration 2.0//EN"
"http://ibatis.apache.org/dtd/dao-2.dtd">
<daoConfig>
<context>
<transactionManager type="SQLMAP">
<property name="SqlMapConfigResource"
value="com/ibatis/jpetstore/persistence/sqlmapdao/sql/sql-map-config.xml"/>
</transactionManager>
<dao interface="com.ibatis.jpetstore.persistence.iface.ItemDao"
implementation="com.ibatis.jpetstore.persistence.sqlmapdao.ItemSqlMapDao"/>
<dao interface="com.ibatis.jpetstore.persistence.iface.SequenceDao"
implementation="com.ibatis.jpetstore.persistence.sqlmapdao.SequenceSqlMapDao"/>
<dao interface="com.ibatis.jpetstore.persistence.iface.AccountDao"
implementation="com.ibatis.jpetstore.persistence.sqlmapdao.AccountSqlMapDao"/>
<dao interface="com.ibatis.jpetstore.persistence.iface.CategoryDao"
implementation="com.ibatis.jpetstore.persistence.sqlmapdao.CategorySqlMapDao"/>
<dao interface="com.ibatis.jpetstore.persistence.iface.ProductDao"
implementation="com.ibatis.jpetstore.persistence.sqlmapdao.ProductSqlMapDao"/>
<dao interface="com.ibatis.jpetstore.persistence.iface.OrderDao"
implementation="com.ibatis.jpetstore.persistence.sqlmapdao.OrderSqlMapDao"/>
</context>
</daoConfig>
这个文件就是ibatis-dao.jar的入口文件,也是核心文件,后续的所有操作将依照这个文件进行。在此向置于文件头,后续会多次用到
在ibatis-dao.jar包中我们可以看到他有两个子包组成分别为:client、engine.共计34个类
1.client主要作为对外的接口部分。
2.engine主要是其内部实现。
client中包含:5个类(或接口)一个子包(包含6个类/接口)
Dao类:该类是一个接口,只是一个表示接口,没有任何约束,主要用来表述所有实现该接口的类都是操作数据的类,ibatis DAO中的所有业务dao类都要事先client中的Dao接口
DaoException类:该类继承RuntimeException类,用来统一异常输出
DaoManager类:核心接口,用来定义所有管理ibatis的dao对象实现必须遵守的规则,包括获取dao实现类,获取事务,以及事务的打开、提交、关闭
DaoManagerBuilder类:该类用来创建DaoManager类,但其本身不做处理,通过传入配置文件生成DaoManager,具体实现还是需要调用engine包下的XmlDaoManagerBuilder,XmlDaoManagerBuilder功能就是将dao.xml文件实例化成client中的的各个实例对象,是DaoManager类的工厂类。
DaoTransaction类:统一的事务操作接口
client包下还有一个template包,该包中的类都是根据模版原则,定义了不同orm的DAO操作规范
DaoTemplate,一个实现了Dao的抽象类
HibernateDaoTemplate.java :针对Hibernate定义的Dao模板类
JdbcDaoTemplate.java:JDBC定义的Dao的简单封装
OjbBrokerDaoTemplate.java
SqlMapDaoTemplate.java
ToplinkDaoTemplate.java
engine下的文件包含三部分:build ,负责通过解析dao.xml(可以为别的名字,跟DaoManager最终加载的文件名同名即可)文件生成client中的实例对象;impl组件,为build组件提供支持,用来将build中解析的字符串封装成impl中的实例,impl是client的具体实现。transaction负责集中ORM的事务管理。
首先介绍build,build中包含两个类:
DaoClasspathEntityResolver.java:实现了org.xml.sax.EntityResolver,作为自定义的xml解析器,负责从ClassPath中加载DTD文件,同时将其作为流输出,后续再解析dao.xml中需要。
XmlDaoManagerBuilder.java:该类主要用来解析dao.xml生成impl中的对象,也是ibatis-dao.xml的核心类
下面介绍 impl部分:
impl部分主要包含:
DaoContext.java :这个类是用来封装上面dao.xml中的context节点的实现类
DaoImpl.java:这个类是用来封装context节点下的所有dao节点的实现类
DaoProxy.java:负责创建Dao接口的代理对象。
DaoTransactionState.java:事务的状态信息,内部实现采用自关联
StandardDaoManager.java:ibatis-dao的管理类。idContextMap属性用来按照context的id存放所有的context实例,typeContextMap用来存放key为daoimpl的实现类接口,value为dao归属的context的实现类;daoImplMap包含两种key-value组合:key:负责存放有daoImpl的代理类,value:daoimpl,key:dao实现类的实例;
所有的操作都起始于DaoManagerBuilder的buildDaoManager的方法,最终调用new XmlDaoManagerBuilder().buildDaoManager(reader, props);加载dao.xml并解析,获取到创建imp下的所有实例并组装,在ibatis-dao中所有数据库操作都是源于transaction,其中包含6中事务类型,根据自己的实际需要使用,这个也决定了最终你的配置文件中<transactionManager type="JDBC">这个节点的type属性是什么目前ibatis-dao支持的类型有:见XmlDaoManagerBuilder类构造函数
public XmlDaoManagerBuilder() {
typeAliases.put("EXTERNAL", ExternalDaoTransactionManager.class.getName());
typeAliases.put("HIBERNATE", HibernateDaoTransactionManager.class.getName());
typeAliases.put("JDBC", JdbcDaoTransactionManager.class.getName());
typeAliases.put("JTA", JtaDaoTransactionManager.class.getName());
typeAliases.put("OJB", "com.ibatis.dao.engine.transaction.ojb.OjbBrokerTransactionManager");
typeAliases.put("SQLMAP", SqlMapDaoTransactionManager.class.getName());
typeAliases.put("TOPLINK", "com.ibatis.dao.engine.transaction.toplink.ToplinkDaoTransactionManager");
}
所以也就出现了上边dao.xml文件中的SQLMAP,这个最终是在该构造函数中匹配到了SqlMapDaoTransactionManager.class.getName()该类,所以如果你定义了这里没有的,那么可能就需你使用全限定名了
同时ibatis-dao中用到了很多ibatis-common.jar中的工具类,如Resource,这个是主要是获取文件转换为inputStream或者转为Reader,加载类,实例化类,ClassInfo,ibatis中很强大的一个类,后边在介绍common包的时候会单独介绍。
至此dao包就基本讲完了,没有大篇幅的介绍代码主要是我比较懒,同时内容太多容易让人生烦,而且也容易跑题,所以就不一一介绍了,但是34个类的功能基本清楚了,具体的实现进一步去看问题应该就不大了。之所以将这个包主要出于一下目的:
1.平时我们经常看到很多人用spring直接使用了sqlmapclient,却还要去加载dao包,这就是没有弄明白dao包的作用。
2.从dao的实现我们略微可以收获一下结论,简单容器的实现,如context的实现,该包后续没有发展,估计也有一部分原因是因为spring的强大(我意淫的),使作者放弃了继续搞的打算,不过我还是觉得对于业务调用来说,早期的dao还是很方便了,即便你有多个数据源,只需要配置多个context便可以了,对于业务调用他只要从DaoManager中get就好了,不用管底层到底调用了那个数据源,这一点我觉得还是很有必要的。
3.dao的包装类,daoimpl很有想法,通过代理来操作事务,隐藏了很多操作,简化了开发
4.xml文档的解析可以看看XmlDaoManagerBuilder这个类,虽然代码比较多,不过结构很清晰,而且从第一行看到最后一行也绝对不会混乱,因为代码就是从上到下实现的。
这里我们整理一下两个过程
1.文件解析及其加载的过程:
一、客户端调用XmlDaoManagerBuilderde.buildDaoManager方法
二、XmlDaoManagerBuilder对象创建一个StandardDaoManager对象
三、读取配置文件中的daoConfig节点下的context个数,XmlDaoManagerBuilder对象循环创建1个或者多个DaoContext对象
四、根据配置文件中的context节点下transactionManager的个数,XmlDaoManagerBuilder对象创建TransactionManager对象
五、把Transaction对象赋值给DaoContext对象,由于DaoContext对象只有一个Transaction属性,所以如果配置文件配置多个TransactionManager最后只能是最后一个有效
六、根据context节点下DAO的个数XmlDaoManagerBuilder对象实例化多个DaoImpl对象
七、每个DaoImpl实例化对象根据获得的dao节点中的implementation属性采用constructor.newInstance方法动态实例化dao的的实现类赋值给daoImpl.setDaoInstance(dao);
八、调用daoImpl的// 生成dao的代理 daoImpl.initProxy();赋值给impl的proxy属性最终作为DaoManager的get参数被使用,从而保证调用到的是代理后的daoimpl,可以达到隐藏调用transaction的效果
九、将所有的daoImpl加入到DaoContext的Map中
十、将所有的DaoContext遍历加入到StandardDaoManager对象的Map变量中,同时将所有的DaoImpl放入到StandardDaoManager的Map属性中,具体参加文章上部分标红内容
十一、XmlDaoManagerBuilder返回获取到的StandardDaoManager对象。
2.Dao的调用过程:
一、客户端调用某个实现了Dao的类
二、通过DaoManager获取到的是DaoImpl的代理类,所以调用其invoke方法
三、DaoProxy对象的invoke方法执行过程通过DaoImpl获取StandardDaoManager对象
四、判断是否启用了transaction,执行五、六、七,跳过后续,否则执行以下所有
五、如果启用了,则获取DaoImpl的DaoContext对象
六、通过DaoContext开启事务:context.startTransaction();
七、执行Impl中的方法,method.invoke(daoImpl.getDaoInstance(), args);
八、context.commitTransaction();
九、context.endTransaction();
关于xml文件的解析分为两种
- SAX基于事件流的解析
- DOM基于XML文档树结构的解析
在对dao.xml的解析中,采用了二者结合的方式。对于dao.xml的格式是否正确,这里采用的是DTD文件,它包括一些常用的xml语法规则,如:XML文档必须有根元素、XML文档必须关闭等等。这些校验规则需要通过SAX的EnityResolver接口的实现类来处理的,比如本包中的DaoClasspathEntityResolver。
Ok,本篇文章就到这里。
在这里
感谢ibatis官方的无私
感谢《IBATIS框架源码剖析》作者
分享到:
相关推荐
内容概要:本文全面介绍了Scratch编程语言,包括其历史、发展、特点、主要组件以及如何进行基本和进阶编程操作。通过具体示例,展示了如何利用代码块制作动画、游戏和音乐艺术作品,并介绍了物理模拟、网络编程和扩展库等功能。 适合人群:编程初学者、教育工作者、青少年学生及对编程感兴趣的各年龄段用户。 使用场景及目标:①帮助初学者理解编程的基本概念和逻辑;②提高学生的创造力、逻辑思维能力和问题解决能力;③引导用户通过实践掌握Scratch的基本和高级功能,制作个性化作品。 其他说明:除了基础教学,文章还提供了丰富的学习资源和社区支持,帮助用户进一步提升技能。
mmexport1734874094130.jpg
基于simulink的悬架仿真模型,有主动悬架被动悬架天棚控制半主动悬架 [1]基于pid控制的四自由度主被动悬架仿真模型 [2]基于模糊控制的二自由度仿真模型,对比pid控制对比被动控制,的比较说明 [3]基于天棚控制的二自由度悬架仿真 以上模型,说明文档齐全,仿真效果明显
内容概要:本文档是《组合数学答案-网络流传版.pdf》的内容,主要包含了排列组合的基础知识以及一些经典的组合数学题目。这些题目涵盖了从排列数计算、二项式定理的应用到容斥原理的实际应用等方面。通过对这些题目的解析,帮助读者加深对组合数学概念和技巧的理解。 适用人群:适合初学者和有一定基础的学习者。 使用场景及目标:可以在学习组合数学课程时作为练习题参考,也可以在复习考试或准备竞赛时使用,目的是提高解决组合数学问题的能力。 其他说明:文档中的题目覆盖了组合数学的基本知识点,适合逐步深入学习。每个题目都有详细的解答步骤,有助于读者掌握解题思路和方法。
YOLO系列算法目标检测数据集,包含标签,可以直接训练模型和验证测试,数据集已经划分好,包含数据集配置文件data.yaml,适用yolov5,yolov8,yolov9,yolov7,yolov10,yolo11算法; 包含两种标签格:yolo格式(txt文件)和voc格式(xml文件),分别保存在两个文件夹中,文件名末尾是部分类别名称; yolo格式:<class> <x_center> <y_center> <width> <height>, 其中: <class> 是目标的类别索引(从0开始)。 <x_center> 和 <y_center> 是目标框中心点的x和y坐标,这些坐标是相对于图像宽度和高度的比例值,范围在0到1之间。 <width> 和 <height> 是目标框的宽度和高度,也是相对于图像宽度和高度的比例值; 【注】可以下拉页面,在资源详情处查看标签具体内容;
操作系统实验 Ucore lab5
基于matlab开发的学生成绩管理系统GUI界面,可以实现学生成绩载入,显示,处理及查询。
老版本4.0固件,(.dav固件包),支持7700N-K4,7900N-K4等K51平台,升级后出现异常或变砖可使用此版本。请核对自己的机器信息,确认适用后在下载。
YOLO系列算法目标检测数据集,包含标签,可以直接训练模型和验证测试,数据集已经划分好,包含数据集配置文件data.yaml,适用yolov5,yolov8,yolov9,yolov7,yolov10,yolo11算法; 包含两种标签格:yolo格式(txt文件)和voc格式(xml文件),分别保存在两个文件夹中,文件名末尾是部分类别名称; yolo格式:<class> <x_center> <y_center> <width> <height>, 其中: <class> 是目标的类别索引(从0开始)。 <x_center> 和 <y_center> 是目标框中心点的x和y坐标,这些坐标是相对于图像宽度和高度的比例值,范围在0到1之间。 <width> 和 <height> 是目标框的宽度和高度,也是相对于图像宽度和高度的比例值; 【注】可以下拉页面,在资源详情处查看标签具体内容;
YOLO算法-杂草检测项目数据集-3970张图像带标签-杂草.zip
E008 库洛米(3页).zip
内容概要:本文详细阐述了基于西门子PLC的晶圆研磨机自动控制系统的设计与实现。该系统结合了传感器技术、电机驱动技术和人机界面技术,实现了晶圆研磨过程的高精度和高效率控制。文中详细介绍了控制系统的硬件选型与设计、软件编程与功能实现,通过实验测试和实际应用案例验证了系统的稳定性和可靠性。 适合人群:具备一定的自动化控制和机械设计基础的工程师、研究人员以及从事半导体制造的技术人员。 使用场景及目标:本研究为半导体制造企业提供了一种有效的自动化解决方案,旨在提高晶圆研磨的质量和生产效率,降低劳动强度和生产成本。系统适用于不同规格晶圆的研磨作业,可以实现高精度、高效率、自动化的晶圆研磨过程。 阅读建议:阅读本文时,重点关注晶圆研磨工艺流程和技术要求,控制系统的硬件和软件设计方法,以及实验测试和结果分析。这将有助于读者理解和掌握该自动控制系统的实现原理和应用价值。
YOLO系列算法目标检测数据集,包含标签,可以直接训练模型和验证测试,数据集已经划分好,包含数据集配置文件data.yaml,适用yolov5,yolov8,yolov9,yolov7,yolov10,yolo11算法; 包含两种标签格:yolo格式(txt文件)和voc格式(xml文件),分别保存在两个文件夹中,文件名末尾是部分类别名称; yolo格式:<class> <x_center> <y_center> <width> <height>, 其中: <class> 是目标的类别索引(从0开始)。 <x_center> 和 <y_center> 是目标框中心点的x和y坐标,这些坐标是相对于图像宽度和高度的比例值,范围在0到1之间。 <width> 和 <height> 是目标框的宽度和高度,也是相对于图像宽度和高度的比例值; 【注】可以下拉页面,在资源详情处查看标签具体内容;
深圳建筑安装公司“挖掘机安全操作规程”
YOLO系列算法目标检测数据集,包含标签,可以直接训练模型和验证测试,数据集已经划分好,包含数据集配置文件data.yaml,适用yolov5,yolov8,yolov9,yolov7,yolov10,yolo11算法; 包含两种标签格:yolo格式(txt文件)和voc格式(xml文件),分别保存在两个文件夹中,文件名末尾是部分类别名称; yolo格式:<class> <x_center> <y_center> <width> <height>, 其中: <class> 是目标的类别索引(从0开始)。 <x_center> 和 <y_center> 是目标框中心点的x和y坐标,这些坐标是相对于图像宽度和高度的比例值,范围在0到1之间。 <width> 和 <height> 是目标框的宽度和高度,也是相对于图像宽度和高度的比例值; 【注】可以下拉页面,在资源详情处查看标签具体内容;
大题解题方法等4个文件.zip
保障性安居工程考评内容和评价标准.docx
监督机构检查记录表.docx
该项目适合初学者进行学习,有效的掌握java、swing、mysql等技术的基础知识。资源包含源码、视频和文档 资源下载|如果你正在做毕业设计,需要源码和论文,各类课题都可以,私聊我。 商务合作|如果你是在校大学生,正好你又懂语言编程,或者你可以找来需要做毕设的伙伴,私聊我。。内容来源于网络分享,如有侵权请联系我删除。另外如果没有积分的同学需要下载,请私信我。
218) Leverage - 创意机构与作品集 WordPress 主题 2.2.7.zip