ibatis框架中在*SqlMap.xml中配置SQL语句,与ScriptRunner 类执行SQL语句脚本文件的区别

james_zhw 2008-12-17 04:27:24
ibatis框架中在*SqlMap.xml中配置简单的SQL,语句可以,但是复杂的Sql语句配置就比较麻烦了,还容易出错
如果用ibatis框架中的ScriptRunner 类执行写好的SQL语句脚本的话,那还有啥意义,不就等同与JDBC+sqL语句了嘛
刚接触IBATIS,至少目前我没发现ibaitis有啥好的,复杂的SQL语句在XML文件中很难配的~~~
希望高手能给解惑。
...全文
310 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
hbwhwang 2008-12-17
  • 打赏
  • 举报
回复
那你说说复杂的SQL语句用什么不复杂?Hibernate吗?Toplink吗?
这些工具都讲明只能解决你80%的重复劳动,而不是解决你所有的问题。
conald 2008-12-17
  • 打赏
  • 举报
回复
和我一样的疑问,
1. 简介 1.1. 概览 1.2. 使用场景 2. Spring 2.0 的新特性 2.1. 简介 2.2. 控制反转(IoC)容器 2.2.1. 更简单的XML配置 2.2.2. 新的bean作用域 2.2.3. 可扩展的XML编写 2.3. 面向切面编程(AOP) 2.3.1. 更加简单的AOP XML配置 2.3.2. 对@AspectJ 切面的支持 2.4. 间层 2.4.1. 在XML里更为简单的声明性事务配置 2.4.2. JPA 2.4.3. 异步的JMS 2.4.4. JDBC 2.5. Web层 2.5.1. Spring MVC的表单标签库 2.5.2. Spring MVC合理的默认值 2.5.3. Portlet 框架 2.6. 其他特性 2.6.1. 动态语言支持 2.6.2. JMX 2.6 .3. 任务规划 2.6.4. 对Java 5(Tiger)的支持 2.7. 移植到Spring 2.0 2.7.1. 一些变化 2.7.1.1. Jar包 2.7.1.2. XML配置 2.7.1.3. Deprecated的和方法 2.7.1.4. Apache OJB 2.7.1.5. iBatis 2.8. 更新的样例应用 2.9. 改进的文档 I. 核心技术 3. 控制反转容器 3.1. 简介 3.2. 容器和bean的基本原理 3.2.1. 容器 3.2.1.1. 配置元数据 3.2.2. 实例化容器 3.2.2.1. 组成基于XML配置元数据 3.2.3. 多种bean 3.2.3.1. 命名bean 3.2.3.2. 实例化bean 3.2.4. 使用容器 3.3. 依赖 3.3.1. 注入依赖 3.3.1.1. Setter注入 3.3.1.2. 构造器注入 3.3.1.3. 一些例子 3.3.2. 构造器参数的解析 3.3.2.1. 构造器参数型匹配 3.3.2.2. 构造器参数的索引 3.3.3. bean属性及构造器参数详解 3.3.3.1. 直接量(基本型、Strings型等。) 3.3.3.2. 引用其它的bean(协作者) 3.3.3.3. 内部bean 3.3.3.4. 集合 3.3.3.5. Nulls 3.3.3.6. XML-based configuration metadata shortcuts 3.3.3.7. 组合属性名称 3.3.4. 使用depends-on 3.3.5. 延迟初始化bean 3.3.6. 自动装配(autowire)协作者 3.3.6.1. 设置Bean使自动装配失效 3.3.7. 依赖检查 3.3.8. 方法注入 3.3.8.1. Lookup方法注入 3.3.8.2. 自定义方法的替代方案 3.4. bean的作用域 3.4.1. Singleton作用域 3.4.2. Prototype作用域 3.4.3. 其他作用域 3.4.3.1. 初始化web配置 3.4.3.2. Request作用域 3.4.3.3. Session作用域 3.4.3.4. global session作用域 3.4.3.5. 作用域bean与依赖 3.4.4. 自定义作用域 3.5. 定制bean特性 3.5.1. Lifecycle接口 3.5.1.1. 初始化回调 3.5.1.2. 析构回调 3.5.2. 了解自己 3.5.2.1. BeanFactoryAware 3.5.2.2. BeanNameAware 3.6. bean定义的继承 3.7. 容器扩展点 3.7.1. 用BeanPostProcessor定制bean 3.7.1.1. 使用BeanPostProcessor的Hello World示例 3.7.1.2. RequiredAnnotationBeanPostProcessor示例 3.7.2. 用BeanFactoryPostProcessor定制配置元数据 3.7.2.1. PropertyPlaceholderConfigurer示例 3.7.2.2. PropertyOverrideConfigurer示例 3.7.3. 使用FactoryBean定制实例化逻辑 3.8. ApplicationContext 3.8.1. 利用MessageSource实现国际化 3.8.2. 事件 3.8.3. 底层资源的访问 3.8.4. ApplicationContext在WEB应用的实例化 3.9. 粘合代码和可怕的singleton 3.9.1. 使用Singleton-helper 4. 资源 4.1. 简介 4.2. Resource 接口 4.3. 内置 Resource 实现 4.3.1. UrlResource 4.3.2. ClassPathResource 4.3.3. FileSystemResource 4.3.4. ServletContextResource 4.3.5. InputStreamResource 4.3.6. ByteArrayResource 4.4. ResourceLoader 4.5. ResourceLoaderAware 接口 4.6. 把Resource作为属性来配置 4.7. Application context 和Resource 路径 4.7.1. 构造application context 4.7.1.1. 创建 ClassPathXmlApplicationContext 实例 - 简介 4.7.2. Application context构造器资源路径的通配符 4.7.2.1. Ant风格的pattern 4.7.2.2. classpath*: 前缀 4.7.2.3. 其他关于通配符的说明 4.7.3. FileSystemResource 提示 5. 校验,数据绑定,BeanWrapper,与属性编辑器 5.1. 简介 5.2. 使用Spring的Validator接口进行校验 5.3. 从错误代码到错误信息 5.4. Bean处理和BeanWrapper 5.4.1. 设置和获取属性值以及嵌套属性 5.4.2. 内建的PropertyEditor实现 5.4.2.1. 注册用户自定义的PropertyEditor 6. 使用Spring进行面向切面编程(AOP) 6.1. 简介 6.1.1. AOP概念 6.1.2. Spring AOP的功能和目标 6.1.3. Spring的AOP代理 6.2. @AspectJ支持 6.2.1. 启用@AspectJ支持 6.2.2. 声明一个切面 6.2.3. 声明一个切入点(pointcut) 6.2.3.1. 切入点指定者的支持 6.2.3.2. 合并切入点表达式 6.2.3.3. 共享常见的切入点(pointcut)定义 6.2.3.4. 示例 6.2.4. 声明通知 6.2.4.1. 前置通知(Before advice) 6.2.4.2. 返回后通知(After returning advice) 6.2.4.3. 抛出后通知(After throwing advice) 6.2.4.4. 后通知(After (finally) advice) 6.2.4.5. 环绕通知(Around Advice) 6.2.4.6. 通知参数(Advice parameters) 6.2.4.7. 通知(Advice)顺序 6.2.5. 引入(Introductions) 6.2.6. 切面实例化模型 6.2.7. 例子 6.3. Schema-based AOP support 6.3.1. 声明一个切面 6.3.2. 声明一个切入点 6.3.3. 声明通知 6.3.3.1. 通知(Advice) 6.3.3.2. 返回后通知(After returning advice) 6.3.3.3. 抛出异常后通知(After throwing advice) 6.3.3.4. 后通知(After (finally) advice) 6.3.3.5. 通知 6.3.3.6. 通知参数 6.3.3.7. 通知顺序 6.3.4. 引入 6.3.5. 切面实例化模型 6.3.6. Advisors 6.3.7. 例子 6.4. AOP声明风格的选择 6.4.1. Spring AOP还是完全用AspectJ? 6.4.2. Spring AOP使用@AspectJ还是XML? 6.5. 混合切面型 6.6. 代理机制 6.7. 编程方式创建@AspectJ代理 6.8. 在Spring应用使用AspectJ 6.8.1. 在Spring使用AspectJ来为domain object进行依赖注入 6.8.1.1. @Configurable object的单元测试 6.8.1.2. 多application context情况下的处理 6.8.2. Spring其他的AspectJ切面 6.8.3. 使用Spring IoC来配置AspectJ的切面 6.8.4. 在Spring应用使用AspectJ Load-time weaving(LTW) 6.9. 其它资源 7. Spring AOP APIs 7.1. 简介 7.2. Spring的切入点API 7.2.1. 概念 7.2.2. 切入点实施 7.2.3. AspectJ切入点表达式 7.2.4. 便利的切入点实现 7.2.4.1. 静态切入点 7.2.4.2. 动态切入点 7.2.5. 切入点的基 7.2.6. 自定义切入点 7.3. Spring的通知API 7.3.1. 通知的生命周期 7.3.2. Spring里的通知型 7.3.2.1. 拦截around通知 7.3.2.2. 前置通知 7.3.2.3. 异常通知 7.3.2.4. 后置通知 7.3.2.5. 引入通知 7.4. Spring里的advisor(Advisor) API 7.5. 使用ProxyFactoryBean创建AOP代理 7.5.1. 基础 7.5.2. JavaBean属性 7.5.3. 基于JDK和CGLIB的代理 7.5.4. 对接口进行代理 7.5.5. 对进行代理 7.5.6. 使用“全局”advisor 7.6. 简化代理定义 7.7. 使用ProxyFactory通过编程创建AOP代理 7.8. 操作被通知对象 7.9. 使用“自动代理(autoproxy)”功能 7.9.1. 自动代理bean定义 7.9.1.1. BeanNameAutoProxyCreator 7.9.1.2. DefaultAdvisorAutoProxyCreator 7.9.1.3. AbstractAdvisorAutoProxyCreator 7.9.2. 使用元数据驱动的自动代理 7.10. 使用TargetSources 7.10.1. 热交换目标源 7.10.2. 池化目标源 7.10.3. 原型目标源 7.10.4. ThreadLocal目标源 7.11. 定义新的通知型 7.12. 更多资源 8. 测试 8.1. 简介 8.2. 单元测试 8.3. 集成测试 8.3.1. Context管理和缓存 8.3.2. 测试fixture的依赖注入 8.3.3. 事务管理 8.3.4. 方便的变量 8.3.5. 示例 8.3.6. 运行集成测试 8.4. 更多资源 II. 间层数据访问 9. 事务管理 9.1. 简介 9.2. 动机 9.3. 关键抽象 9.4. 使用资源同步的事务 9.4.1. 高层次方案 9.4.2. 低层次方案 9.4.3. TransactionAwareDataSourceProxy 9.5. 声明式事务管理 9.5.1. 理解Spring的声明式事务管理实现 9.5.2. 第一个例子 9.5.3. 回滚 9.5.4. 为不同的bean配置不同的事务语义 9.5.5. 有关的设置 9.5.6. 使用 @Transactional 9.5.6.1. @Transactional 有关的设置 9.5.7. 插入事务操作 9.5.8. 结合AspectJ使用 @Transactional 9.6. 编程式事务管理 9.6.1. 使用 TransactionTemplate 9.6.2. 使用 PlatformTransactionManager 9.7. 选择编程式事务管理还是声明式事务管理 9.8. 与特定应用服务器集成 9.8.1. BEA WebLogic 9.8.2. IBM WebSphere 9.9. 公共问题的解决方案 9.9.1. 对一个特定的 DataSource 使用错误的事务管理器 9.10. 更多的资源 10. DAO支持 10.1. 简介 10.2. 一致的异常层次 10.3. 一致的DAO支持抽象 11. 使用JDBC进行数据访问 11.1. 简介 11.1.1. Spring JDBC包结构 11.2. 利用JDBC核心实现JDBC的基本操作和错误处理 11.2.1. JdbcTemplate 11.2.2. NamedParameterJdbcTemplate 11.2.3. SimpleJdbcTemplate 11.2.4. DataSource接口 11.2.5. SQLExceptionTranslator接口 11.2.6. 执行SQL语句 11.2.7. 执行查询 11.2.8. 更新数据库 11.3. 控制数据库连接 11.3.1. DataSourceUtils 11.3.2. SmartDataSource接口 11.3.3. AbstractDataSource 11.3.4. SingleConnectionDataSource 11.3.5. DriverManagerDataSource 11.3.6. TransactionAwareDataSourceProxy 11.3.7. DataSourceTransactionManager 11.4. 用Java对象来表达JDBC操作 11.4.1. SqlQuery 11.4.2. MappingSqlQuery 11.4.3. SqlUpdate 11.4.4. StoredProcedure 11.4.5. SqlFunction 12. 使用ORM工具进行数据访问 12.1. 简介 12.2. Hibernate 12.2.1. 资源管理 12.2.2. 在Spring的application context创建 SessionFactory 12.2.3. HibernateTemplate 12.2.4. 不使用回调的基于Spring的DAO实现 12.2.5. 基于Hibernate3的原生API实现DAO 12.2.6. 编程式的事务划分 12.2.7. 声明式的事务划分 12.2.8. 事务管理策略 12.2.9. 容器资源 vs 本地资源 12.2.10. 在应用服务器使用Hibernate的注意点 12.3. JDO 12.3.1. 建立PersistenceManagerFactory 12.3.2. JdoTemplate和JdoDaoSupport 12.3.3. 基于原生的JDO API实现DAO 12.3.4. 事务管理 12.3.5. JdoDialect 12.4. Oracle TopLink 12.4.1. SessionFactory 抽象层 12.4.2. TopLinkTemplate 和 TopLinkDaoSupport 12.4.3. 基于原生的TopLink API的DAO实现 12.4.4. 事务管理 12.5. iBATIS SQL Maps 12.5.1. iBATIS 1.x和2.x的概览与区别 12.5.2. iBATIS SQL Maps 1.x 12.5.2.1. 创建SqlMap 12.5.2.2. 使用 SqlMapTemplate 和 SqlMapDaoSupport 12.5.3. iBATIS SQL Maps 2.x 12.5.3.1. 创建SqlMapClient 12.5.3.2. 使用 SqlMapClientTemplate 和 SqlMapClientDaoSupport 12.5.3.3. 基于原生的iBATIS API的DAO实现 12.6. JPA 12.6.1. 在Spring环境建立JPA 12.6.1.1. LocalEntityManagerFactoryBean 12.6.1.2. LocalContainerEntityManagerFactoryBean 12.6.1.3. 处理多个持久化单元 12.6.2. JpaTemplate 和 JpaDaoSupport 12.6.3. 基于原生的JPA实现DAO 12.6.4. 异常转化 12.6.5. 事务管理 12.6.6. JpaDialect III. Web 13. Web框架 13.1. 介绍 13.1.1. 与其他web框架的集成 13.1.2. Spring Web MVC框架的特点 13.2. DispatcherServlet 13.3. 控制器 13.3.1. AbstractController 和 WebContentGenerator 13.3.2. 其它的简单控制器 13.3.3. MultiActionController 13.3.4. 命令控制器 13.4. 处理器映射(handler mapping) 13.4.1. BeanNameUrlHandlerMapping 13.4.2. SimpleUrlHandlerMapping 13.4.3. 拦截器(HandlerInterceptor) 13.5. 视图与视图解析 13.5.1. 视图解析器 13.5.2. 视图解析链 13.5.3. 重定向(Rediret)到另一个视图 13.5.3.1. RedirectView 13.5.3.2. redirect:前缀 13.5.3.3. forward:前缀 13.6. 本地化解析器 13.6.1. AcceptHeaderLocaleResolver 13.6.2. CookieLocaleResolver 13.6.3. SessionLocaleResolver 13.6.4. LocaleChangeInterceptor 13.7. 使用主题 13.7.1. 简介 13.7.2. 如何定义主题 13.7.3. 主题解析器 13.8. Spring对分段文件上传(multipart file upload)的支持 13.8.1. 介绍 13.8.2. 使用MultipartResolver 13.8.3. 在表单处理分段文件上传 13.9. 使用Spring的表单标签库 13.9.1. 配置标签库 13.9.2. form标签 13.9.3. input标签 13.9.4. checkbox标签 13.9.5. radiobutton标签 13.9.6. password标签 13.9.7. select标签 13.9.8. option标签 13.9.9. options标签 13.9.10. textarea标签 13.9.11. hidden标签 13.9.12. errors标签 13.10. 处理异常 13.11. 惯例优先原则(convention over configuration) 13.11.1. 对控制器的支持: ControllerClassNameHandlerMapping 13.11.2. 对模型的支持:ModelMap (ModelAndView) 13.11.3. 对视图的支持: RequestToViewNameTranslator 13.12. 其它资源 14. 集成视图技术 14.1. 简介 14.2. JSP和JSTL 14.2.1. 视图解析器 14.2.2. 'Plain-old' JSPs versus JSTL 'Plain-old' JSP与JSTL 14.2.3. 帮助简化开发的额外的标签 14.3. Tiles 14.3.1. 需要的资源 14.3.2. 如何集成Tiles 14.3.2.1. InternalResourceViewResolver 14.3.2.2. ResourceBundleViewResolver 14.4. Velocity和FreeMarker 14.4.1. 需要的资源 14.4.2. Context 配置 14.4.3. 创建模板 14.4.4. 高级配置 14.4.4.1. velocity.properties 14.4.4.2. FreeMarker 14.4.5. 绑定支持和表单处理 14.4.5.1. 用于绑定的宏 14.4.5.2. 简单绑定 14.4.5.3. 表单输入生成宏 14.4.5.4. 重载HTML转码行为并使你的标签符合XHTML 14.5. XSLT 14.5.1. 写在段首 14.5.1.1. Bean 定义 14.5.1.2. 标准MVC控制器代码 14.5.1.3. 把模型数据转化为XML 14.5.1.4. 定义视图属性 14.5.1.5. 文档转换 14.5.2. 小结 14.6. 文档视图(PDF/Excel) 14.6.1. 简介 14.6.2. 配置和安装 14.6.2.1. 文档视图定义 14.6.2.2. Controller 代码 14.6.2.3. Excel视图子 14.6.2.4. PDF视图子 14.7. JasperReports 14.7.1. 依赖的资源 14.7.2. 配置 14.7.2.1. 配置ViewResolver 14.7.2.2. 配置View 14.7.2.3. 关于报表文件 14.7.2.4. 使用 JasperReportsMultiFormatView 14.7.3. 构造ModelAndView 14.7.4. 使用子报表 14.7.4.1. 配置子报表文件 14.7.4.2. 配置子报表数据源 14.7.5. 配置Exporter的参数 15. 集成其它Web框架 15.1. 简介 15.2. 通用配置 15.3. JavaServer Faces 15.3.1. DelegatingVariableResolver 15.3.2. FacesContextUtils 15.4. Struts 15.4.1. ContextLoaderPlugin 15.4.1.1. DelegatingRequestProcessor 15.4.1.2. DelegatingActionProxy 15.4.2. ActionSupport 15.5. Tapestry 15.5.1. 注入 Spring 托管的 beans 15.5.1.1. 将 Spring Beans 注入到 Tapestry 页面 15.5.1.2. 组件定义文件 15.5.1.3. 添加抽象访问方法 15.5.1.4. 将 Spring Beans 注入到 Tapestry 页面 - Tapestry 4.0+ 风格 15.6. WebWork 15.7. 更多资源 16. Portlet MVC框架 16.1. 介绍 16.1.1. 控制器 - MVC的C 16.1.2. 视图 - MVC的V 16.1.3. Web作用范围的Bean 16.2. DispatcherPortlet 16.3. ViewRendererServlet 16.4. 控制器 16.4.1. AbstractController和PortletContentGenerator 16.4.2. 其它简单的控制器 16.4.3. Command控制器 16.4.4. PortletWrappingController 16.5. 处理器映射 16.5.1. PortletModeHandlerMapping 16.5.2. ParameterHandlerMapping 16.5.3. PortletModeParameterHandlerMapping 16.5.4. 增加 HandlerInterceptor 16.5.5. HandlerInterceptorAdapter 16.5.6. ParameterMappingInterceptor 16.6. 视图和它们的解析 16.7. Multipart文件上传支持 16.7.1. 使用PortletMultipartResolver 16.7.2. 处理表单里的文件上传 16.8. 异常处理 16.9. Portlet应用的部署 IV. 整合 17. 使用Spring进行远程访问与Web服务 17.1. 简介 17.2. 使用RMI暴露服务 17.2.1. 使用 RmiServiceExporter 暴露服务 17.2.2. 在客户端链接服务 17.3. 使用Hessian或者Burlap通过HTTP远程调用服务 17.3.1. 为Hessian配置DispatcherServlet 17.3.2. 使用HessianServiceExporter暴露你的bean 17.3.3. 客户端连接服务 17.3.4. 使用Burlap 17.3.5. 对通过Hessian或Burlap暴露的服务使用HTTP基础认证 17.4. 使用HTTP调用器暴露服务 17.4.1. 暴露服务对象 17.4.2. 在客户端连接服务 17.5. Web服务 17.5.1. 使用JAXI-RPC暴露服务 17.5.2. 访问Web服务 17.5.3. 注册bean映射 17.5.4. 注册自己的处理方法 17.5.5. 使用XFire来暴露Web服务 17.6. 对远程接口不提供自动探测 17.7. 在选择这些技术时的一些考虑 18. Enterprise Java Bean(EJB)集成 18.1. 简介 18.2. 访问EJB 18.2.1. 概念 18.2.2. 访问本地的无状态Session Bean(SLSB) 18.2.3. 访问远程SLSB 18.3. 使用Spring提供的辅助实现EJB组件 19. JMS 19.1. 简介 19.2. 使用Spring JMS 19.2.1. JmsTemplate 19.2.2. 连接工厂 19.2.3. (消息)目的地管理 19.2.4. 消息侦听容器 19.2.4.1. SimpleMessageListenerContainer 19.2.4.2. DefaultMessageListenerContainer 19.2.4.3. ServerSessionMessageListenerContainer 19.2.5. 事务管理 19.3. 发送一条消息 19.3.1. 使用消息转换器 19.3.2. SessionCallback 和ProducerCallback 19.4. 接收消息 19.4.1. 同步接收 19.4.2. 异步接收 - 消息驱动的POJOs 19.4.3. SessionAwareMessageListener 接口 19.4.4. MessageListenerAdapter 19.4.5. 事务的多方参与 20. JMX 20.1. 介绍 20.2. 输出bean到JMX 20.2.1. 创建一个MBeanServer 20.2.2. 复用现有的MBeanServer 20.2.3. MBean的惰性初始化 20.2.4. MBean的自动注册 20.2.5. 控制注册行为 20.3. 控制bean的管理接口 20.3.1. MBeanInfoAssembler 接口 20.3.2. 使用源码级元数据 20.3.3. 使用JDK 5.0注解 20.3.4. 源代码级的元数据型 20.3.5. 接口AutodetectCapableMBeanInfoAssembler 20.3.6. 用Java接口定义管理接口 20.3.7. 使用MethodNameBasedMBeanInfoAssembler 20.4. 控制bean的 ObjectName 20.4.1. 从Properties读取ObjectName 20.4.2. 使用 MetadataNamingStrategy 20.5. JSR-160连接器 20.5.1. 服务器端连接器 20.5.2. 客户端连接器 20.5.3. 基于Burlap/Hessian/SOAP的JMX 20.6. 通过代理访问MBeans 20.7. 通知 20.7.1. 为通知注册监听器 20.7.2. 发布通知 20.8. 更多资源 21. JCA CCI 21.1. 介绍 21.2. 配置CCI 21.2.1. 连接器配置 21.2.2. 在Spring配置ConnectionFactory 21.2.3. 配置CCI连接 21.2.4. 使用一个 CCI 单连接 21.3. 使用Spring的 CCI访问支持 21.3.1. 记录转换 21.3.2. CciTemplate 21.3.3. DAO支持 21.3.4. 自动输出记录生成 21.3.5. 总结 21.3.6. 直接使用一个 CCI Connection 接口和Interaction接口 21.3.7. CciTemplate 使用示例 21.4. 建模CCI访问为操作对象 21.4.1. MappingRecordOperation 21.4.2. MappingCommAreaOperation 21.4.3. 自动输出记录生成 21.4.4. 总结 21.4.5. MappingRecordOperation 使用示例 21.4.6. MappingCommAreaOperation 使用示例 21.5. 事务 22. Spring邮件抽象层 22.1. 简介 22.2. Spring邮件抽象结构 22.3. 使用Spring邮件抽象 22.3.1. 可插拔的MailSender实现 22.4. 使用 JavaMail MimeMessageHelper 22.4.1. 创建一条简单的MimeMessage,并且发送出去 22.4.2. 发送附件和嵌入式资源(inline resources) 23. Spring的定时调度(Scheduling)和线程池(Thread Pooling) 23.1. 简介 23.2. 使用OpenSymphony Quartz 调度器 23.2.1. 使用JobDetailBean 23.2.2. 使用 MethodInvokingJobDetailFactoryBean 23.2.3. 使用triggers和SchedulerFactoryBean来包装任务 23.3. 使用JDK Timer支持 23.3.1. 创建定制的timers 23.3.2. 使用 MethodInvokingTimerTaskFactoryBean 23.3.3. 打包:使用TimerFactoryBean来设置任务 23.4. SpringTaskExecutor抽象 23.4.1. TaskExecutor接口 23.4.2. 何时使用TaskExecutor接口 23.4.3. TaskExecutor型 23.4.4. 使用TaskExecutor接口 24. 动态语言支持 24.1. 介绍 24.2. 第一个例子 24.3. 定义动态语言支持的bean 24.3.1. 公共概念 24.3.1.1. 元素 24.3.1.2. Refreshable bean 24.3.1.3. 内置动态语言源文件 24.3.1.4. 理解dynamic-language-backed bean context的构造器注入 24.3.2. JRuby beans 24.3.3. Groovy beans 24.3.4. BeanShell beans 24.4. 场景 24.4.1. Spring MVC控制器脚本化 24.4.2. Validator脚本化 24.5. 更多的资源 25. 注解和源代码级的元数据支持 25.1. 简介 25.2. Spring的元数据支持 25.3. 注解 25.3.1. @Required 25.3.2. Spring的其它@Annotations 25.4. 集成Jakarta Commons Attributes 25.5. 元数据和Spring AOP自动代理 25.5.1. 基本原理 25.5.2. 声明式事务管理 25.5.3. 缓冲 25.5.4. 自定义元数据 25.6. 使用属性来减少MVC web层配置 25.7. 元数据属性的其它用法 25.8. 增加对额外元数据API的支持 A. XML Schema-based configuration A.1. Introduction A.2. XML Schema-based configuration A.2.1. Referencing the schemas A.2.2. The util schema A.2.2.1. A.2.2.2. A.2.2.3. A.2.2.4. A.2.2.5. A.2.2.6. A.2.3. The jee schema A.2.3.1. (simple) A.2.3.2. (with single JNDI environment setting) A.2.3.3. (with multiple JNDI environment settings) A.2.3.4. (complex) A.2.3.5. (simple) A.2.3.6. (complex) A.2.3.7. A.2.4. The lang schema A.2.5. The tx (transaction) schema A.2.6. The aop schema A.2.7. The tool schema A.2.8. The beans schema A.3. Setting up your IDE A.3.1. Setting up Eclipse A.3.2. Setting up IntelliJ IDEA A.3.3. Integration issues A.3.3.1. XML parsing errors in the Resin v.3 application server B. Extensible XML authoring B.1. Introduction B.2. Authoring the schema B.3. Coding a NamespaceHandler B.4. Coding a BeanDefinitionParser B.5. Registering the handler and the schema B.5.1. META-INF/spring.handlers B.5.2. META-INF/spring.schemas C. spring-beans-2.0.dtd D. spring.tld D.1. Introduction D.2. The bind tag D.3. The escapeBody tag D.4. The hasBindErrors tag D.5. The htmlEscape tag D.6. The message tag D.7. The nestedPath tag D.8. The theme tag D.9. The transform tag E. spring-form.tld E.1. Introduction E.2. The checkbox tag E.3. The errors tag E.4. The form tag E.5. The hidden tag E.6. The input tag E.7. The label tag E.8. The option tag E.9. The options tag E.10. The password tag E.11. The radiobutton tag E.12. The select tag E.13. The textarea tag F. Spring 2.0 开发手册文化项目 F.1. 声明 F.2. 致谢 F.3. 参与人员及任务分配 F.4. Spring 2.0 正式版开发手册翻译说明 F.5. 项目历程 F.5.1. Spring 2.0 RC2 开发手册翻译项目 F.5.2. Spring 2.0 正式版开发手册翻译项目
1.1 引言
约有90%的企业信息化管理系统基于数据库实现,这系统又有超过30%的代码集在数据访问层负责业务数据存取。除了实现数据的增删改查,数据访问层还要提供一些与业务无关功能,例如面向对象的持久化与访问机制、本地事务与分布式事务支持、多数据库支持,这些机制或功能形成相对独立的逻辑领域,其主要目的有:

1、 提供简单易用的数据库访问方法,提高开发效率;

2、 提供面向对象的方式来简化对数据库访问与操作,也就是ORMap方式;

3、 屏蔽数据库差异,使开发出的产品容易在不同数据库产品上移植。

为了适应软件快速开发的需要,软件企业应该借助组件产品或开源软件项目来搭建这些基础设施。在.Net平台上,目前比较成功和应用较广的开源项目有NHibernate和IBatisNet等,它们在ORMap方面的表现尤为突出。依赖这些平台,软件开发效率和产品质量都得到了极大提高,ORMap机制渐渐成为大势所趋。

本公司致力于软件组件开发,提供的AppFramework数据库访问组件具有高效的ORMap机制,调用接口简单灵活,支持各种主流的数据库平台,是个非常优秀的数据访问组件。本文详尽描述了AppFramework数据库访问组件使用的方法和技巧,有助于开发者最大程度发挥出AppFramework的优势。

1.2 各种优秀ORMap工具比较
NHibernate和IBatisNet等虽然都实现了ORMap,但它们的设计侧重点有所不同,有着各自的优势和缺陷,适合于特定的项目。NHibernate实现了纯对象化的ORMap,在屏蔽数据库差异、面向对象方面做的非常好,但在访问与操作海量数据时其性能表现较差,也不易实现复杂的查询统计功能。NHibernate适合那些数据量不大、性能要求不高、复杂度不高的场合。

IBatisNet是一个轻量级ORMap工具,它把所有的SQL脚本以模板的方式集到若干个XML配置文件里,用反射的方式向把C#实体对象属性与SQL模板的参数绑定,动态生成参数化的SQL语句发送给数据库执行,查询的结果集也用反射的方式构造为对象集合返回给程序。由于提供了灵活的SQL模板机制,在海量数据的访问与操作方面其性能比NHibernate要高得多,也很容易实现各种复杂的数据查询统计功能。但是IBatisNet也存在许多几个不足之处,有些还是先天因素造成的:

第一,数据库可移植性差。IBatisNet获得高性能与灵活性也是付出代价的,它牺牲了数据库可移植性:由于编写SQL模板不得不用到数据库产品的一些语法差异,例如ORACLE的TO_DATE、Length()、SYSDATE等,为了把产品移植到其它数据库,开发人员不得不对大量的SQL模板进行翻译。

第二,无法方便地向数据库插入NULL值。因为IBatisNet是直接把C#的基本型(如int/DateTime)插入到数据库字段的。对于一些C#值型,例如int,并没有NULL状态。于是不得不采用一些特殊的值来表示NULL,例如int.MinValue。IBatisNet数据映射器会自动把int.MinValue转换为NULL插入到数据库,而从数据库获得NULL时,也会转化为C#的int.MinValue。这样,程序就要对int.MinVaue这个值进行特殊处理,例如不能把int.MinValue直接显示在DataGrid里或界面上。有一种规避的方法,就是避免向数据库插入NULL,即要求所有业务数据入库的值都不为空。但这样作实际上是限制了程序的行为能力,例如无法实现单据草稿的保存。

第三,在插入数据时无法方便的使用字段默认值。最明显的就是似于LAST_UPDATE_TIME了,通常为了保证这个字段的一致性,通常在插入新记录时采用当前数据库时间作为字段值。但IBatisNet接收的实体对象属性都是普通C#型,并不具备传入表达式的能力。如果采用动态SQL,则会导致SQL模板和参数实体过于复杂,将极大降低性能。

第四,在查询返回大量对象时,用反射的方式构造实体的方式性能损失是相当大的。实体属性数目越多、返回记录数越多,用到反射的次数也越多,查询性能降低就越明显。

第五,不能方便地限定查询语句返回的字段。ADO.Net执行查询时,select语句里设置了几个字段就返回几个字段到DataTable。而IBatisNet若要返回不同的字段就要定义多套ResultMap,否则就定义一套所有字段的ResultMap,任何查询都返回所有字段。这样无疑浪费了数据库服务器与应用服务器之间的网络带宽,在进行海量数据访问时性能将严重降低。

第六,返回的结果IList不能够方便地进行二次查询。相比之下,ADO.Net返回的DataTable虽然性能差一些,但可以实现在应用程序内存灵活和高性能的二次查询。

第七,无法直接利用数据库的特殊语法支持海量数据的分页查询功能。众所周知Oracle提供了ROWNUM实现数据数据库内分页功能,若要利用这一特性,就要在SQL模板里直接硬编码这些特殊语法,这必然导致大量的移植工作。

第八、缺少代码生成和检查工具。程序里的变量名与Sql模板里的变量经常会出现不一致,而这些错误无法在编译时发现,靠人工检查很容易造成错误泄漏。也没提供工具直接生成SQL模板和映射配置文件

第九,IBatisNet的SqlMap文件里的SQL语句以明文存放,容易被修改造成重大安全隐患,尤其不适合开发C/S应用程序。

第十,由于Sql模板采用动态加载的方式,如果写错了SQL,程序里难以跟踪调试,这对初学者来说无疑是对耐心和信心的极大考验。

总之,IBatisNet虽然提灵活、高性能的ORMap机制,但却损失了数据库可移植性的,在使用方便性和局部性能方面也都有很大提高的余地。

1.3 AppFramework数据访问组件的组成和优势
AppFramework数据访问组件由下列文件组成:

1、 AppFramework.DBAccess.dll

提供多数据库统一的访问接口,提供DAO管理器、数据库会话管理器。

2、 AppFramework.Data.dll

提供核心的数据结构和基础

3、 AppFramework.Tools.CodeGenPlugin.msi

提供集成于Visual Studio 2005的C#代码生成器插件,用于生成DAO/Model/各种接口。

4、 DBAccess.config

配置数据库连接串。

5、 CodeGenPlogin.config

配置代码生成器参数。

6、 *.DaoGen文件

配置DAO生成信息,并由CodeGenPlugin解析生成代码。



AppFramework数据库访问组件针对IBatisNet的种种缺陷提出相应的解决方案,相比之下有如下优势:

1、 从扩展基础数据型入手,解决了空值问题和默认值问题;

2、 提供了内置的数据库内分页访问机制,极大地提高了海量查询的响应速度;

3、 增加ObjectTable泛型来承载查询返回的对象集,不但比IList更加强型化,还提供了二分查找功能,使得对象结果集可以在应用程序内存进行重排序和快速查找;

4、 提供了强大的QueryFilter构造查询条件,使得实现数据查询不再需要编写复杂的SQL语句

5、 提供IBatisNet的Sql模板功能,为复杂的查询统计提供较直观的开发模式;

6、 提供代码生成工具,生成的代码的同时可以之间的继承关系和接口实现关系,所有DAO方法均以接口作为参数,使得代码更加具有可扩展性和灵活性。

7、 Sql模板和ORMap直接生成.cs原代码,编译为可执行代码,各种ORMap映射文件无需再随主程序集一起部署,提高了代码的安全性,提高了代码的可调试性,也提高了ORMap的性能。



下面三张表格罗列的测试数据,可以明显看出AppFramework数据库访问组件的性能全面超越了IBatisNet:



表I –10并发20循环(数据库和测试机分开)

对比项目
iBatis2.0

(毫秒)
AppFramework

(毫秒)
后者前者性能对比

(倍)

根据主键获取实体

(20次单条select)
19.8
16.1

QueryFilter:18.0
1.23

1.10

每秒插入实体

(20次insert)
41
21
1.95

更新实体

(20次单条update)
27
19

SqlMap:24
1.42

1.13

查询结果集(平均101行)

(2循环200次select)
1100
690

不定字段:720
1.59

1.53




表II –50并发4循环(数据库和测试机分开)

对比项目
iBatis2.0

(毫秒)
AppFramework

(毫秒)
后者前者性能对比

(倍)

根据主键获取实体

(20次单条select)
17.5
13.3

QueryFilter:14.5
1.32

1.21

插入实体

(20次insert)
36.1
17.4
2.07

更新实体

(20次单条update)
23.5
15.9

SqlMap:20.3
1.48

1.16

查询结果集(平均101行)

(1循环200次select)
1055.1
666.8

不定字段:710.1
1.58

1.50




表III –50并发10循环(数据库和测试机同机)

对比项目
iBatis2.0

(毫秒)
AppFramework

(毫秒)
后者前者性能对比

(倍)

根据主键获取实体

(20次单条select)
6.1
5.3

QueryFilter: 5.75
1.15

1.06

插入实体

(20次insert)
15.1
10.8
1.40

更新实体

(20次单条update)
10.4
7.5

SqlMap:9.3
1.38

1.12

查询结果集(平均101行)

(1循环200次select)
560
360

不定字段:380
1.56

1.47




总之,AppFramework数据库访问组件是一个高性能、接口简单、可移植性强、高灵活性的综合数据访问解决方案。使用AppFramework数据库访问组件,可以降低企业的开发人员培训成本,提高产品的开发速度,提高产品稳定可靠性,提高产品的可伸缩性和可移植性。下文将分入门、精通、高级三个篇章,详细讲述如何使用AppFramework数据库访问组件来搭建应用程序。
代码生成器,ORMap,支持Oracle/SqlServer/MSAccess,性能大大优于iBatisNet,终身免费,随意使用。
===========
软件说明:
1.1 引言
约有90%的企业信息化管理系统基于数据库实现,这系统又有超过30%的代码集在数据访问层负责业务数据存取。除了实现数据的增删改查,数据访问层还要提供一些与业务无关功能,例如面向对象的持久化与访问机制、本地事务与分布式事务支持、多数据库支持,这些机制或功能形成相对独立的逻辑领域,其主要目的有:

1、 提供简单易用的数据库访问方法,提高开发效率;

2、 提供面向对象的方式来简化对数据库访问与操作,也就是ORMap方式;

3、 屏蔽数据库差异,使开发出的产品容易在不同数据库产品上移植。

为了适应软件快速开发的需要,软件企业应该借助组件产品或开源软件项目来搭建这些基础设施。在.Net平台上,目前比较成功和应用较广的开源项目有NHibernate和IBatisNet等,它们在ORMap方面的表现尤为突出。依赖这些平台,软件开发效率和产品质量都得到了极大提高,ORMap机制渐渐成为大势所趋。

本公司致力于软件组件开发,提供的AppFramework数据库访问组件具有高效的ORMap机制,调用接口简单灵活,支持各种主流的数据库平台,是个非常优秀的数据访问组件。本文详尽描述了AppFramework数据库访问组件使用的方法和技巧,有助于开发者最大程度发挥出AppFramework的优势。

1.2 各种优秀ORMap工具比较
NHibernate和IBatisNet等虽然都实现了ORMap,但它们的设计侧重点有所不同,有着各自的优势和缺陷,适合于特定的项目。NHibernate实现了纯对象化的ORMap,在屏蔽数据库差异、面向对象方面做的非常好,但在访问与操作海量数据时其性能表现较差,也不易实现复杂的查询统计功能。NHibernate适合那些数据量不大、性能要求不高、复杂度不高的场合。

IBatisNet是一个轻量级ORMap工具,它把所有的SQL脚本以模板的方式集到若干个XML配置文件里,用反射的方式向把C#实体对象属性与SQL模板的参数绑定,动态生成参数化的SQL语句发送给数据库执行,查询的结果集也用反射的方式构造为对象集合返回给程序。由于提供了灵活的SQL模板机制,在海量数据的访问与操作方面其性能比NHibernate要高得多,也很容易实现各种复杂的数据查询统计功能。但是IBatisNet也存在许多几个不足之处,有些还是先天因素造成的:

第一,数据库可移植性差。IBatisNet获得高性能与灵活性也是付出代价的,它牺牲了数据库可移植性:由于编写SQL模板不得不用到数据库产品的一些语法差异,例如ORACLE的TO_DATE、Length()、SYSDATE等,为了把产品移植到其它数据库,开发人员不得不对大量的SQL模板进行翻译。

第二,无法方便地向数据库插入NULL值。因为IBatisNet是直接把C#的基本型(如int/DateTime)插入到数据库字段的。对于一些C#值型,例如int,并没有NULL状态。于是不得不采用一些特殊的值来表示NULL,例如int.MinValue。IBatisNet数据映射器会自动把int.MinValue转换为NULL插入到数据库,而从数据库获得NULL时,也会转化为C#的int.MinValue。这样,程序就要对int.MinVaue这个值进行特殊处理,例如不能把int.MinValue直接显示在DataGrid里或界面上。有一种规避的方法,就是避免向数据库插入NULL,即要求所有业务数据入库的值都不为空。但这样作实际上是限制了程序的行为能力,例如无法实现单据草稿的保存。

第三,在插入数据时无法方便的使用字段默认值。最明显的就是似于LAST_UPDATE_TIME了,通常为了保证这个字段的一致性,通常在插入新记录时采用当前数据库时间作为字段值。但IBatisNet接收的实体对象属性都是普通C#型,并不具备传入表达式的能力。如果采用动态SQL,则会导致SQL模板和参数实体过于复杂,将极大降低性能。

第四,在查询返回大量对象时,用反射的方式构造实体的方式性能损失是相当大的。实体属性数目越多、返回记录数越多,用到反射的次数也越多,查询性能降低就越明显。

第五,不能方便地限定查询语句返回的字段。ADO.Net执行查询时,select语句里设置了几个字段就返回几个字段到DataTable。而IBatisNet若要返回不同的字段就要定义多套ResultMap,否则就定义一套所有字段的ResultMap,任何查询都返回所有字段。这样无疑浪费了数据库服务器与应用服务器之间的网络带宽,在进行海量数据访问时性能将严重降低。

第六,返回的结果IList不能够方便地进行二次查询。相比之下,ADO.Net返回的DataTable虽然性能差一些,但可以实现在应用程序内存灵活和高性能的二次查询。

第七,无法直接利用数据库的特殊语法支持海量数据的分页查询功能。众所周知Oracle提供了ROWNUM实现数据数据库内分页功能,若要利用这一特性,就要在SQL模板里直接硬编码这些特殊语法,这必然导致大量的移植工作。

第八、缺少代码生成和检查工具。程序里的变量名与Sql模板里的变量经常会出现不一致,而这些错误无法在编译时发现,靠人工检查很容易造成错误泄漏。也没提供工具直接生成SQL模板和映射配置文件

第九,IBatisNet的SqlMap文件里的SQL语句以明文存放,容易被修改造成重大安全隐患,尤其不适合开发C/S应用程序。

第十,由于Sql模板采用动态加载的方式,如果写错了SQL,程序里难以跟踪调试,这对初学者来说无疑是对耐心和信心的极大考验。

总之,IBatisNet虽然提灵活、高性能的ORMap机制,但却损失了数据库可移植性的,在使用方便性和局部性能方面也都有很大提高的余地。

1.3 AppFramework数据访问组件的组成和优势
AppFramework数据访问组件由下列文件组成:

1、 AppFramework.DBAccess.dll

提供多数据库统一的访问接口,提供DAO管理器、数据库会话管理器。

2、 AppFramework.Data.dll

提供核心的数据结构和基础

3、 AppFramework.Tools.CodeGenPlugin.msi

提供集成于Visual Studio 2005的C#代码生成器插件,用于生成DAO/Model/各种接口。

4、 DBAccess.config

配置数据库连接串。

5、 CodeGenPlogin.config

配置代码生成器参数。

6、 *.DaoGen文件

配置DAO生成信息,并由CodeGenPlugin解析生成代码。



AppFramework数据库访问组件针对IBatisNet的种种缺陷提出相应的解决方案,相比之下有如下优势:

1、 从扩展基础数据型入手,解决了空值问题和默认值问题;

2、 提供了内置的数据库内分页访问机制,极大地提高了海量查询的响应速度;

3、 增加ObjectTable泛型来承载查询返回的对象集,不但比IList更加强型化,还提供了二分查找功能,使得对象结果集可以在应用程序内存进行重排序和快速查找;

4、 提供了强大的QueryFilter构造查询条件,使得实现数据查询不再需要编写复杂的SQL语句

5、 提供IBatisNet的Sql模板功能,为复杂的查询统计提供较直观的开发模式;

6、 提供代码生成工具,生成的代码的同时可以之间的继承关系和接口实现关系,所有DAO方法均以接口作为参数,使得代码更加具有可扩展性和灵活性。

7、 Sql模板和ORMap直接生成.cs原代码,编译为可执行代码,各种ORMap映射文件无需再随主程序集一起部署,提高了代码的安全性,提高了代码的可调试性,也提高了ORMap的性能。



下面三张表格罗列的测试数据,可以明显看出AppFramework数据库访问组件的性能全面超越了IBatisNet:



表I –10并发20循环(数据库和测试机分开)

对比项目
iBatis2.0

(毫秒)
AppFramework

(毫秒)
后者前者性能对比

(倍)

根据主键获取实体

(20次单条select)
19.8
16.1

QueryFilter:18.0
1.23

1.10

每秒插入实体

(20次insert)
41
21
1.95

更新实体

(20次单条update)
27
19

SqlMap:24
1.42

1.13

查询结果集(平均101行)

(2循环200次select)
1100
690

不定字段:720
1.59

1.53




表II –50并发4循环(数据库和测试机分开)

对比项目
iBatis2.0

(毫秒)
AppFramework

(毫秒)
后者前者性能对比

(倍)

根据主键获取实体

(20次单条select)
17.5
13.3

QueryFilter:14.5
1.32

1.21

插入实体

(20次insert)
36.1
17.4
2.07

更新实体

(20次单条update)
23.5
15.9

SqlMap:20.3
1.48

1.16

查询结果集(平均101行)

(1循环200次select)
1055.1
666.8

不定字段:710.1
1.58

1.50




表III –50并发10循环(数据库和测试机同机)

对比项目
iBatis2.0

(毫秒)
AppFramework

(毫秒)
后者前者性能对比

(倍)

根据主键获取实体

(20次单条select)
6.1
5.3

QueryFilter: 5.75
1.15

1.06

插入实体

(20次insert)
15.1
10.8
1.40

更新实体

(20次单条update)
10.4
7.5

SqlMap:9.3
1.38

1.12

查询结果集(平均101行)

(1循环200次select)
560
360

不定字段:380
1.56

1.47




总之,AppFramework数据库访问组件是一个高性能、接口简单、可移植性强、高灵活性的综合数据访问解决方案。使用AppFramework数据库访问组件,可以降低企业的开发人员培训成本,提高产品的开发速度,提高产品稳定可靠性,提高产品的可伸缩性和可移植性。下文将分入门、精通、高级三个篇章,详细讲述如何使用AppFramework数据库访问组件来搭建应用程序。
V1.1比V1.0增强了IDBSession功能,可查询得到 IDataReader;修改了查询 in 操作符的bug。
内含代码生成器,支持Oracle/SqlServer/MSAccess,ORMap性能大大优于iBatisNet,终身免费无限制使用,绝无任何版权问题。
===========
软件说明:
1.1 引言
约有90%的企业信息化管理系统基于数据库实现,这系统又有超过30%的代码集在数据访问层负责业务数据存取。除了实现数据的增删改查,数据访问层还要提供一些与业务无关功能,例如面向对象的持久化与访问机制、本地事务与分布式事务支持、多数据库支持,这些机制或功能形成相对独立的逻辑领域,其主要目的有:

1、 提供简单易用的数据库访问方法,提高开发效率;

2、 提供面向对象的方式来简化对数据库访问与操作,也就是ORMap方式;

3、 屏蔽数据库差异,使开发出的产品容易在不同数据库产品上移植。

为了适应软件快速开发的需要,软件企业应该借助组件产品或开源软件项目来搭建这些基础设施。在.Net平台上,目前比较成功和应用较广的开源项目有NHibernate和IBatisNet等,它们在ORMap方面的表现尤为突出。依赖这些平台,软件开发效率和产品质量都得到了极大提高,ORMap机制渐渐成为大势所趋。

本公司致力于软件组件开发,提供的AppFramework数据库访问组件具有高效的ORMap机制,调用接口简单灵活,支持各种主流的数据库平台,是个非常优秀的数据访问组件。本文详尽描述了AppFramework数据库访问组件使用的方法和技巧,有助于开发者最大程度发挥出AppFramework的优势。

1.2 各种优秀ORMap工具比较
NHibernate和IBatisNet等虽然都实现了ORMap,但它们的设计侧重点有所不同,有着各自的优势和缺陷,适合于特定的项目。NHibernate实现了纯对象化的ORMap,在屏蔽数据库差异、面向对象方面做的非常好,但在访问与操作海量数据时其性能表现较差,也不易实现复杂的查询统计功能。NHibernate适合那些数据量不大、性能要求不高、复杂度不高的场合。

IBatisNet是一个轻量级ORMap工具,它把所有的SQL脚本以模板的方式集到若干个XML配置文件里,用反射的方式向把C#实体对象属性与SQL模板的参数绑定,动态生成参数化的SQL语句发送给数据库执行,查询的结果集也用反射的方式构造为对象集合返回给程序。由于提供了灵活的SQL模板机制,在海量数据的访问与操作方面其性能比NHibernate要高得多,也很容易实现各种复杂的数据查询统计功能。但是IBatisNet也存在许多几个不足之处,有些还是先天因素造成的:

第一,数据库可移植性差。IBatisNet获得高性能与灵活性也是付出代价的,它牺牲了数据库可移植性:由于编写SQL模板不得不用到数据库产品的一些语法差异,例如ORACLE的TO_DATE、Length()、SYSDATE等,为了把产品移植到其它数据库,开发人员不得不对大量的SQL模板进行翻译。

第二,无法方便地向数据库插入NULL值。因为IBatisNet是直接把C#的基本型(如int/DateTime)插入到数据库字段的。对于一些C#值型,例如int,并没有NULL状态。于是不得不采用一些特殊的值来表示NULL,例如int.MinValue。IBatisNet数据映射器会自动把int.MinValue转换为NULL插入到数据库,而从数据库获得NULL时,也会转化为C#的int.MinValue。这样,程序就要对int.MinVaue这个值进行特殊处理,例如不能把int.MinValue直接显示在DataGrid里或界面上。有一种规避的方法,就是避免向数据库插入NULL,即要求所有业务数据入库的值都不为空。但这样作实际上是限制了程序的行为能力,例如无法实现单据草稿的保存。

第三,在插入数据时无法方便的使用字段默认值。最明显的就是似于LAST_UPDATE_TIME了,通常为了保证这个字段的一致性,通常在插入新记录时采用当前数据库时间作为字段值。但IBatisNet接收的实体对象属性都是普通C#型,并不具备传入表达式的能力。如果采用动态SQL,则会导致SQL模板和参数实体过于复杂,将极大降低性能。

第四,在查询返回大量对象时,用反射的方式构造实体的方式性能损失是相当大的。实体属性数目越多、返回记录数越多,用到反射的次数也越多,查询性能降低就越明显。

第五,不能方便地限定查询语句返回的字段。ADO.Net执行查询时,select语句里设置了几个字段就返回几个字段到DataTable。而IBatisNet若要返回不同的字段就要定义多套ResultMap,否则就定义一套所有字段的ResultMap,任何查询都返回所有字段。这样无疑浪费了数据库服务器与应用服务器之间的网络带宽,在进行海量数据访问时性能将严重降低。

第六,返回的结果IList不能够方便地进行二次查询。相比之下,ADO.Net返回的DataTable虽然性能差一些,但可以实现在应用程序内存灵活和高性能的二次查询。

第七,无法直接利用数据库的特殊语法支持海量数据的分页查询功能。众所周知Oracle提供了ROWNUM实现数据数据库内分页功能,若要利用这一特性,就要在SQL模板里直接硬编码这些特殊语法,这必然导致大量的移植工作。

第八、缺少代码生成和检查工具。程序里的变量名与Sql模板里的变量经常会出现不一致,而这些错误无法在编译时发现,靠人工检查很容易造成错误泄漏。也没提供工具直接生成SQL模板和映射配置文件

第九,IBatisNet的SqlMap文件里的SQL语句以明文存放,容易被修改造成重大安全隐患,尤其不适合开发C/S应用程序。

第十,由于Sql模板采用动态加载的方式,如果写错了SQL,程序里难以跟踪调试,这对初学者来说无疑是对耐心和信心的极大考验。

总之,IBatisNet虽然提灵活、高性能的ORMap机制,但却损失了数据库可移植性的,在使用方便性和局部性能方面也都有很大提高的余地。

1.3 AppFramework数据访问组件的组成和优势
AppFramework数据访问组件由下列文件组成:

1、 AppFramework.DBAccess.dll

提供多数据库统一的访问接口,提供DAO管理器、数据库会话管理器。

2、 AppFramework.Data.dll

提供核心的数据结构和基础

3、 AppFramework.Tools.CodeGenPlugin.msi

提供集成于Visual Studio 2005的C#代码生成器插件,用于生成DAO/Model/各种接口。

4、 DBAccess.config

配置数据库连接串。

5、 CodeGenPlogin.config

配置代码生成器参数。

6、 *.DaoGen文件

配置DAO生成信息,并由CodeGenPlugin解析生成代码。



AppFramework数据库访问组件针对IBatisNet的种种缺陷提出相应的解决方案,相比之下有如下优势:

1、 从扩展基础数据型入手,解决了空值问题和默认值问题;

2、 提供了内置的数据库内分页访问机制,极大地提高了海量查询的响应速度;

3、 增加ObjectTable泛型来承载查询返回的对象集,不但比IList更加强型化,还提供了二分查找功能,使得对象结果集可以在应用程序内存进行重排序和快速查找;

4、 提供了强大的QueryFilter构造查询条件,使得实现数据查询不再需要编写复杂的SQL语句

5、 提供IBatisNet的Sql模板功能,为复杂的查询统计提供较直观的开发模式;

6、 提供代码生成工具,生成的代码的同时可以之间的继承关系和接口实现关系,所有DAO方法均以接口作为参数,使得代码更加具有可扩展性和灵活性。

7、 Sql模板和ORMap直接生成.cs原代码,编译为可执行代码,各种ORMap映射文件无需再随主程序集一起部署,提高了代码的安全性,提高了代码的可调试性,也提高了ORMap的性能。



下面三张表格罗列的测试数据,可以明显看出AppFramework数据库访问组件的性能全面超越了IBatisNet:



表I –10并发20循环(数据库和测试机分开)

对比项目
iBatis2.0

(毫秒)
AppFramework

(毫秒)
后者前者性能对比

(倍)

根据主键获取实体

(20次单条select)
19.8
16.1

QueryFilter:18.0
1.23

1.10

每秒插入实体

(20次insert)
41
21
1.95

更新实体

(20次单条update)
27
19

SqlMap:24
1.42

1.13

查询结果集(平均101行)

(2循环200次select)
1100
690

不定字段:720
1.59

1.53




表II –50并发4循环(数据库和测试机分开)

对比项目
iBatis2.0

(毫秒)
AppFramework

(毫秒)
后者前者性能对比

(倍)

根据主键获取实体

(20次单条select)
17.5
13.3

QueryFilter:14.5
1.32

1.21

插入实体

(20次insert)
36.1
17.4
2.07

更新实体

(20次单条update)
23.5
15.9

SqlMap:20.3
1.48

1.16

查询结果集(平均101行)

(1循环200次select)
1055.1
666.8

不定字段:710.1
1.58

1.50




表III –50并发10循环(数据库和测试机同机)

对比项目
iBatis2.0

(毫秒)
AppFramework

(毫秒)
后者前者性能对比

(倍)

根据主键获取实体

(20次单条select)
6.1
5.3

QueryFilter: 5.75
1.15

1.06

插入实体

(20次insert)
15.1
10.8
1.40

更新实体

(20次单条update)
10.4
7.5

SqlMap:9.3
1.38

1.12

查询结果集(平均101行)

(1循环200次select)
560
360

不定字段:380
1.56

1.47




总之,AppFramework数据库访问组件是一个高性能、接口简单、可移植性强、高灵活性的综合数据访问解决方案。使用AppFramework数据库访问组件,可以降低企业的开发人员培训成本,提高产品的开发速度,提高产品稳定可靠性,提高产品的可伸缩性和可移植性。下文将分入门、精通、高级三个篇章,详细讲述如何使用AppFramework数据库访问组件来搭建应用程序。

67,513

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧