ibatis教程简介模版课件_第1页
ibatis教程简介模版课件_第2页
ibatis教程简介模版课件_第3页
ibatis教程简介模版课件_第4页
ibatis教程简介模版课件_第5页
已阅读5页,还剩36页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、ibatis简介1为什么要使用Ibatis?在系统的开发过程中,你可能碰到如下一些问题:1.系统的部分或全部数据都来源于现有数据库,出于安全考虑,客户只给你提供一些select sql语句(或存储过程)来获取数据,具体的表结构不公开。(金融行业项目常见)2.开发规范过程中要求,所有涉及到业务逻辑部分的数据库表的操作,必顺通过存储过程进行实现3.系统数据处理量巨大,对性能要求非常高请问此时你将选择Hibernate来操作,还是选择JDBC呢?当你选择使用Hibernate,却发现其优点荡然无存!当你选择使用JDBC,却发现拖沓的代码到处存在!2什么是Ibatis?半自动化ORM框架相对于Hibe

2、rnate等“一站式”ORM框架,Ibatis是一种“半自动化”的ORM框架实现。也就是说,ORM概念中,Ibatis只强调O/R部分的内容,而将M(mapping)这部分概念进行了淡化。因为它将对于SQL语句的操作权,最终交还给了程序员。上面提到的“半自动化”这个概念可能大家理解起来比较生涩,通过我们对Hibernate或EJB3的了解,可以发现在它们都是针对POJO到数据库提供了一种较为完整的封装。程序只需要对POJO进行操作,就达到操作数据库持久层的目的,我们程序员对SQL语句都不需要太多的了解,因为Hibrenate会根椐POJO的映射关系生成对应的SQL语句,最终调用JDBC完成操作

3、。大部分情况, Hibernate这种操作机制无往不利,但是在特定的情况下,这种“一站式”的解决方案却不见得灵光。我们来思考在开发过程中的一些问题:3什么是Ibatis?使用Ibatis解决前述问题 使用“半自动化”化的Ibatis框架,可以解决前面系统开发过程中存在的问题。针对Hibernate在POJO与数据库之间建立映射,以及自动生成SQL并执行的过程,Ibatis着力点,则在于POJO与SQL语句之间的映射。也就是说,Ibatis在运行过程中不会自动生成SQL语句执行,具体的SQL语句由程序员编写,然后通过映射配置文件,将SQL语句所需的参数,获得的返回结果字段映射到指定的POJO。使

4、用Ibatis提供的ORM机制,在业务逻辑层实现人员而言,操作的是JAVA对象,这一层面与Hibernate机制中一样的。对于具体的数据库操作,Hibernate会自动生成SQL并执行,而Ibatis要求开发人员具体编写SQL语句。Ibatis通过在数据库移植性和SQL开发工作量上面做出了让步,换来了为系统设计更多的灵活性和自由空间。 4如何使用Ibatis?准备工作 导入Ibatis相关的jar包 目前ibatis的最新版本为。使用ibatis非常简单,只需要将相关的jar包复制到指定的目录下便可,具体情况如下表: 的一个主要的关注点是管理并降低JAR文件的依赖性。因此,如果您用的是,IBA

5、TIS仅仅依赖于Jakarta Commons Logging框架。 Ibatis中可能需要的一些jar包5如何使用Ibatis?构建基础代码 ibatis的基础代码包括以下几个部分: ibatis实例配置( ) Pojo(Plain Ordinary Java Object) 映射文件 引用dtd文件用于配置和优化SqlMapClient实例的各选项配置事务管理服务引入映射文件6如何使用Ibatis?构建基础代码假设我们在数据库中建立了一个Person表,其中包括三个字段:Create table Person( pid number(10) primary key, pname varch

6、ar2(30) not null, sex char(1)public class Person implements Serializable private Integer pid; private String pname; private String sex; setter/getter Pojo对象类7如何使用Ibatis?构建基础代码与Hibernate不同,因为需要人工手动编写SQL,所以Ibatis的映射文件一般通过手动编写的方式完成。select * from Person where PID = #id# Person.xml(Ibatis映射文件)为实体类定义别名定义查

7、询操作SQL 8如何使用Ibatis?创建SqlMapClient对象使用Ibatis通过SqlMapClient对象以及调用此对象上面的API,可以完成通过Ibatis进行持久层操作。使用SqlMapClient对象完成持久化的步骤1、读取文件2、创建SqlMapClientBuilder对象3、创建SqlMapClient对象4、调用SqlMapClient对象相关API通过使用comibatiscommonresourcesResources对象来读取文件(要求位于classpath下面)结合问题statictryReader resource=Resources.getResource

8、AsReader);client=SqlMapClientBuilder.buildSqlMapClient(resource);catch(Exception k)();读取位于classpath下面的文件tryclient.startTransaction();/开始事务处理Person obj=new Person();obj.setPname(测试2);obj.setSex(0);client.insert(insertPerson, obj);mitTransaction();/提交事务catch(Exception k)k.printStackTrace();finally try

9、 client.endTransaction();/结束事务 catch(Exception k) k.printStackTrace(); 通过ibatis实现保存方法此名称来源于文件Person obj=null;tryobj=(Person)client.queryForObject(getPersonOfObject, 1);catch(Exception k)k.printStackTrace();通过ibatis查询方法9配置文件说明元素元素用于配置和优化SqlMapClient实例的各选项。元素本身及其所有的属性都是可选的。下表列出了元素支持的属性及其功能:maxRequests

10、同时执行SQL语句的最大线程数。大于这个值的线程将阻塞直到另一个线程执行完成。通常这个值应该至少是maxTransactions(参见以下)的10倍,并且总是大于maxSessions和maxTranactions。减小这个参数值通常能提高性能。maxSessions同一时间内活动的最大session数。它应该总是大于或等于maxTransactions并小于maxRequests。减小这个参数值通常能减少内存使用。 maxTransactions同时进入SqlMapClient.startTransaction()的最大线程数。大于这个值的线程将阻塞直到另一个线程退出。lazyLoading

11、Enabled全局性地启用或禁用SqlMapClient的所有延迟加载。调试程序时使用。(默认值为:true)useStatementNamespaces如果启用本属性,必须使用全限定名来引用mapped statement。Mapped statement的全限定名由sql-map的名称和mapped-statement的名称合成。如(默认值为:false )queryForObject(“sqlMapName.statementName”);10配置文件说明元素元素让您为一个通常较长的、全限定类名指定一个较短的别名。 在ibatis中默认定义了几个别名,如下: 11配置文件说明元素元素让您

12、为SQL Map配置事务管理服务。属性type指定所使用的事务管理器类型。这个属性值可以是一个类名,也可以是一个别名。包含在框架的三个事务管理器分别是:JDBC,JTA和EXTERNAL。JDBC:通过常用的Connection commit()和rollback()方法,让JDBC管理事务。JTA:本事务管理器使用一个JTA全局事务,使SQL Map的事务包括在更大的事务范围内,这个更大的事务范围可能包括了其他的数据库和事务资源。EXTERNAL:这个配置可以让您自己管理事务。您仍然可以配置一个数据源,但事务不再作为框架生命周期的一部分被提交或回退。这意味着SQL Map外部应用的一部分必须

13、自己管理事务。也可以用于没有事务管理的数据库配置(比如说只读性质的数据库操作) 12配置文件说明元素是的一部分,为SQL Map数据源设置了一系列参数。 目前为止,ibatis支持三种数据源,如下:SimpleDataSourceFactory 为DataSource提供了一个基本的实现,适用于在没有J2EE容器提供DataSource的情况。DbcpDataSourceFactory 实现使用Jakarta DBCP(Database Connection Pool)的DataSource API提供连接池服务。适用于应用/Web容器不提供DataSource服务的情况。JndiDataSo

14、urceFactory 在应用容器内部从JNDI Context中查找DataSource实现。最佳实践:版本只允许一个数据源。要使用多个数据源,最好使用多个属性文件,不同的系统使用不同的属性文件,或在创建SQLMapClient时传入不同的属性文件。SimpleDataSourceFactoryDbcpDataSourceFactory 使用JDBC进行事务处理 基于JTA进行事务管理13配置文件说明元素 元素用于包括SQL Map映射文件和其他的SQL Map配置文件。每个SqlMapClient对象使用的所有SQL Map映射文件都要在此声明。映射文件作为stream resource从

15、类路径或URL读入。您必须在这里指定所有的SQL Map文件。14SQL Map XML文件说明Mapped StatementsSQL Map的核心概念是Mapped Statement。Mapped Statement可以使用任意的SQL语句,并拥有parameter map(输入)和result map(输出)。如果是简单情况,Mapped Statement可以使用Java类来作为parameter和result。Mapped Statement也可以使用缓存模型,在内存中缓存常用的数据。Mapped Statement的结构如下所示: SQL语句 Statement有多种类型 在上面

16、的表达式中,括号里的部分时可选的属性,并且在某些情况下只有特定的组合才是合法的15SQL Map XML文件说明Statement的类型元素是个通用声明,可以用于任何类型的SQL语句。通常,使用具体的statement类型是个好主意。具体statement类型提供了更直观的XML DTD,并拥有某些元素没有的特性。下表总结了statement类型及其属性和特性: 16SQL Map XML文件说明SQL语句SQL显然是mapped statement中最重要的部分,可以使用对于数据库和JDBC Driver合法的任意SQL语句。只要JDBC Driver支持,可以使用任意的函数,甚至是多条语句

17、。因为SQL语句是嵌在XML文档中的,因此有些特殊的字符不能直接使用,例如大于号和小于号()。幸运的是,解决的办法很简单,只需将包含特殊字符的SQL语句放在XML的CDATA区里面就可以了。例如: #value# 17SQL Map XML文件说明parameterClass属性parameterClass属性的值是Java类的全限定名(即包括类的包名)。parameterClass属性是可选的,但强烈建议使用。它的目的是限制输入参数的类型为指定的Java类,并优化框架的性能。如果您使用parameterMap,则没有必要使用parameterClass属性。例如,如果要只允许Java类“”作

18、为输入参数,可以这样作: insert into PRODUCT values (#id#, #description#, #price#) 与java类的属性名称一样 最佳实践:虽然向后兼容,但强烈建议使用parameterClass(除非没必要)。通过提供parameterClass,您可以获得更好的性能。18SQL Map XML文件说明parameterMap属性属性parameterMap的值等于一个预先定义的元素的名称。parameterMap的基本思想是定义一系列有次序的参数系列,用于匹配JDBC PreparedStatement的值符号: insert into PRODUC

19、T (PRD_ID, PRD_DESCRIPTION) values (?,?); 说明:parameterMap属性很少使用,更多的是使用上面的parameterClass和inline parameter19SQL Map XML文件说明Inline Parameter简介parameterMap的语法虽然简单,但很繁琐。还有一种更受欢迎更灵活的方法,可以大大简化定义和减少代码量。这种方法把Java Bean的属性名称嵌在Mapped Statement的定义中(即直接写在SQL语句中)。缺省情况下,任何没有指定parameterMap的Mapped Statement都会被解析成inli

20、ne parameter(内嵌参数)。用上面的例子(即Product)来说,就是 insert into PRODUCT (PRD_ID, PRD_DESCRIPTION) values (#id#, #description#); 20SQL Map XML文件说明基本类型输入参数假如没必要写一个Java Bean作为参数,可以直接使用基本类型的包装类(即String,Integer,Date等)作为参数。例如:假设PRD_ID的数据类型是NUMERIC,要调用上面的mapped statement,可以传入一个对象作为参数。Integer对象的值将代替#value#参数。当使用基本类型包装

21、类代替Java Bean时,切记要使用#value#作为参数。 select * from PRODUCT where PRD_ID = #value# 可以使用int简写代替 21SQL Map XML文件说明Map类型输入参数假如没必要写一个Java Bean作为参数,而要传入的参数又不只一个时,可以使用Map类(如HashMap,TreeMap等)作为参数对象。可以注意到mapped statement的形式完全没有区别!上面的例子中,如果把Map对象作为输入参数去调用mapped statement,Map对象必须包含键值“catId”和“code”。键值引用的对象必须是合适的类型,以

22、上面的例子来说,必须是Integer和String。Result Map也支持使用Map类型作为结果参数。 select * from PRODUCT where PRD_CAT_ID = #catId# and PRD_CODE = #code# 22SQL Map XML文件说明resultClass属性resultClass属性的值是Java类的全限定名(即包括类的包名)。resultClass属性可以让您指定一个Java类,根据ResultSetMetaData将其自动映射到JDBC的ResultSet。只要是Java Bean的属性名称和ResultSet的列名匹配,属性自动赋值给列

23、值。这使得查询mapped statement变得很短。 SELECT PER_ID as id, PER_FIRST_NAME as firstName, PER_LAST_NAME as lastName, PER_BIRTH_DATE as birthDate, PER_WEIGHT_KG as weightInKilograms, PER_HEIGHT_M as heightInMeters FROM PERSON WHERE PER_ID = #value# 也可以使用别名代替 一般情况下,列名和属性名称不匹配,就需要使用“as”关键字23SQL Map XML文件说明resultM

24、ap属性resultMap是最常用和最重要的属性。ResultMap属性的值等于预先定义的resultMap元素的name属性值。使用resultMap可以控制数据如何从结果集中取出,以及哪一个属性匹配哪一个字段。不象使用resultClass的自动映射方法,resultMap属性可以允许指定字段的数据类型,NULL的替代值复杂类型映射(包括其他Java Bean,集合类型和基本类型包装类)。 select * from PRODUCT 24SQL Map XML文件说明基本类型的Result(即String,Integer,Boolean)除了支持符合Java Bean规范的Java类,Re

25、sult Map还可以给基本类型包装类如String,Integer,Boolean等赋值。基本类型可以象Java Bean一样映射,只是要记住一个限制,基本类型只能有一个属性,名字可以任意取(常用“value”或“val”)。例如,如果您要获得所有产品描述的一个列表而不是整个Product类,Result Map如下:更简单的办法: select count(1) as value from PRODUCT 25SQL Map XML文件说明Map类型的ResultResult Map也可以方便为一个Map(如HashMap或TreeMap)对象赋值。使用下面讨论的API(参见queryFo

26、rList()),还可以得到Map对象的集合(即Map的List)。Map对象与Java Bean同样的方式映射,只是使用name属性值作为Map的键值,用它来索引相应的数据库字段值,而不是象Java Bean一样给属性赋值。例如,如果您要将Product对象的数据装入Map,可以这样做: select * from PRODUCT select * from PRODUCT 26SQL Map XML文件说明xmlResultName属性当直接把查询结果映射成XML document时,属性xmlResultName的值等于XML document根元素的名称。例如: SELECT PER_

27、ID as id, PER_FIRST_NAME as firstName, PER_LAST_NAME as lastName, PER_BIRTH_DATE as birthDate, PER_WEIGHT_KG as weightInKilograms, PER_HEIGHT_M as heightInMeters FROM PERSON WHERE PER_ID = #value# 指定xml的根元素名称 1 Clinton Begin 1900-01-01 89 1.77 27ibatis常用APISqlMapClientBuilder此类的主要作用用于读取指定位置的(一般情况下位于

28、classpath下),创建一个SqlMapClient接口的对象。SqlMapClient insertObject insert(Stringid)Object insert(Stringid, ObjectparameterObject) deleteint delete(Stringid, ObjectparameterObject)int delete(Stringid) updateint id) int update(Stringid, ObjectparameterObject) queryexecuteString resource = “”; Reader reader =

29、 (resource); SqlMapClient sqlMap = SqlMapClientBuilder.buildSqlMap(reader); 指定配置文件位置 28ibatis常用API事务处理缺省情况下,调用SqlMapClient对象的任意executeXxxx()方法将缺省地自动COMMIT/ROLLBACK。这意味着每次调用executeXxxx()方法都是一个独立的事务。这确实很简单,但对于需要在同一个事务中执行多个语句的情况(即只能同时成功或失败),并不适用。这正是事务处理要关心的事情。 如果您在使用Global Transaction(在SQL Map配置文件中设置),

30、您可以使用自动提交并且可以得到在同一事务中执行的效果。但为了提高性能,最好是明确地划分事务的范围,因为这样做可以减少连接池的通讯流量和数据库连接的初始化。SqlMapClient对象拥有让您定义事务范围的方法。使用下面SqlMapClient类的方法,可以开始、提交和/或回退事务: public void startTransaction () throws SQLException public void commitTransaction () throws SQLException public void endTransaction () throws SQLException try

31、 (); Item item = (Item) (getItem, itemId); (newDescription); (updateItem, item); (); finally (); 注意:事务不能嵌套。在调用commit()或rollback()之前,从同一线程,将引起抛出例外。换句话说,对于每个SqlMap实例,每个线程最多只能打开一个事务。29ibatis常用API用SqlMapClient执行持久层化操作在上面的每个方法中,Mapped Statement的名称作为第一个参数。这个名称要对应的名称属性。另外,第二个参数总是参数对象。如果不需要参数对象,可以为null。30ib

32、atis常用API用SqlMapClient执行持久层化操作insert()、 update()、 delete()不同之处 上面这些方法用于数据更新(即非查询语句)。这就是说,使用下面的查询方法来执行数据更新操作并不是不可能。但这显得很奇怪,并明显依赖于JDBC的驱动程序。执行update(),返回受影响数据记录的数目。 queryForObject不同之处 queryForObject()方法有两个版本。一个返回查询得到的新对象,另一个用一个事先生成的对象作为参数。后者对于使用多个查询为对象赋值很有用。 (); Product product = new Product(); (1); (

33、“Shih Tzu”); int rows = (“insertProduct”, product); (); sqlMap.startTransaction(); Integer key = new Integer (1); Product product = (Product)sqlMap.queryForObject (“getProduct”, key); sqlMmitTransaction(); 1 查询成对象sqlMap.startTransaction(); Customer customer = new Customer(); sqlMap.queryForObject(“g

34、etCust”, parameterObject, customer); sqlMap.queryForObject(“getAddr”, parameterObject, customer); sqlMmitTransaction(); 2 用预赋值的结果对象查询成对象31ibatis常用API用SqlMapClient执行持久层化操作queryForList()1执行一个查询并返回所有的查询结果(); List list = (“getProductList”, null); (); 2允许指定跳过结果的数目(即开始点)和返回结果的最大数(); List list = (“getProdu

35、ctList”, null, 0, 40); (); 32ibatis常用API用SqlMapClient执行持久层化操作queryForPaginatedList() 对于要返回一个可以向前和向后翻页的数据子集,queryForPaginatedList()方法很有用,它返回一个可管理的List对象。PaginatedList接口中的方法: nextPage() (查询下一页) previousPage() (查询前一页) gotoPage() (跳转到指定页) isFirstPage() isMiddlePage() isLastPage() isPreviousPageAvailable

36、() getPageIndex() getPageSize()PaginatedList list = sqlMap.queryForPaginatedList (“getProductList”, null, 10); list.nextPage(); list.previousPage(); 实现分页查询33ibatis常用API用SqlMapClient执行持久层化操作queryForMap()queryForMap()方法将结果集放在一个Map对象中,这个Map对象用一个传入参数keyProperty作为key值。(); Map map = (“getProductList”, nul

37、l, “productCode”); (); Product p = (Product) map.get(“EST-93”); 34Ibatis高级特性数据关联前面我们讲解的都是针对独立数据的操作,在实际情况中经常碰到数据关联的情况,如每个User对象包含多个Address对象,每个Address描述了对应的User对象,在这种情况下我们该如何处理啦?ibatis中提供了对statement嵌套支持,从而实现数据关联1单向一对多关联 SELECT UID,UNAME FROM T_USER WHERE UID=#id# SELECT AID,ANAME FROM T_ADDRESS WHERE USER_ID=#value# 指定实体类别名 指定User对象的reslutMap 指定addrss属性的state

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论