Presentation is loading. Please wait.

Presentation is loading. Please wait.

IBatis介绍 Java.

Similar presentations


Presentation on theme: "IBatis介绍 Java."— Presentation transcript:

1 iBatis介绍 Java

2 Agenda iBatis SQL Map简介 SQL Map XML配置文件 SQL Map XML映射文件
使用SQL Map API编程 iBatis与Hibernate的简单比较

3 iBATIS SQL Map简介-SQL Map概念
SQL Map API让开发人员可以轻易地将Java Bean映射成PreparedStatement的输入参数和ResultSet结果集。 开发SQL Map的想法很简单:提供一个简洁的架构,能够用20%的代码实现80%JDBC的功能。

4 iBATIS SQL Map简介-SQL Map如何工作?

5 iBATIS SQL Map简介-SQL Map如何工作?
SQL Map提供了一个简洁的框架,使用简单的XML描述文件将Java Bean,Map实现和基本数据类型的包装类(String,Integer等)映射成JDBC的PreparedStatement。 以下流程描述了SQL Maps的高层生命周期: 1)将一个对象作为参数(对象可以是Java Bean,Map实现和基本类型的包装类),参数对象将为SQL修改语句和查询语句设定参数值。 2) 执行mapped statement。这是SQL Maps最重要的步骤。SQL Map框架将创建一个PreparedStatement实例,用参数对象为PreparedStatement实例设定参数,执行PreparedStatement并从ResultSet中创建结果对象。 3) 执行SQL的更新数据语句时,返回受影响的数据行数。执行查询语句时,将返回一个结果对象或对象的集合。和参数对象一样,结果对象可以是Java Bean,Map实现和基本数据类型的包装类。

6 iBATIS SQL Map简介-安装SQL Maps
安装SQL Maps,把相关的JAR文件复制到类路径下即可。类路径或者是JVM启动是指定的类路径(java命令参数),或者是Web应用中的/WEB-INF/lib目录。 安装iBatis需要在类路径下放置以下JAR文件: ibatis-common.jar IBATIS公用的工具类 必须 ibatis-sqlmap.jar IBATIS SQL Maps框架 必须 ibatis-dao.jar IBATIS DAO 框架 可选

7 SQL Map XML配置文件-例子 SQL Map使用XML配置文件统一配置不同的属性,包括DataSource的详细配置信息,SQL Map和其他可选属性,如线程管理等 SqlMapConfig.xml例子

8 SQL Map XML配置文件-<properties>元素
SQL Map配置文件拥有唯一的<properties>元素,用于在配置文件中使用标准的Java属性文件(name=value)。这样做后,在属性文件中定义的属性可以作为变量在SQL Map配置文件及其包含的所有SQL Map映射文件中引用。 例如,如果属性文件中包含属性:driver=org.hsqldb.jdbcDriver SQL Map配置文件及其每个映射文件都可以使用占位符${driver}来代表值org.hsqldb.jdbcDriver。 例如:<property name="JDBC.Driver" value="${driver}"/> 属性文件可以从类路径中加载(使用resource属性),也可以从合法的URL中加载(使用url属性)。 例如,要加载固定路径的属性文件,使用:<properties url=”file:///c:/config/my.properties” />

9 SQL Map XML配置文件-<setting>元素
<setting>元素用于配置和优化SqlMapClient实例的各选项。 <setting>元素本身及其所有的属性都是可选的 例子: lazyLoadingEnabled 全局性地启用或禁用SqlMapClient的所有延迟加载。调试程序时使用。 例子:lazyLoadingEnabled=“true” 缺省值:true(启用)

10 SQL Map XML配置文件-<typeAlias>元素
例如:<typeAlias alias="shortname"type="com.long.class.path.Class"/> 在SQL Map配置文件预定义了几个别名。它们是: 事务管理器别名 JDBC com.ibatis.sqlmap.engine.transaction.jdbc.JdbcTransactionConfig JTA com.ibatis.sqlmap.engine.transaction.jta.JtaTransactionConfig EXTERNAL com.ibatis.sqlmap.engine.transaction.external.ExternalTransactionConfig Data Source Factory别名 SIMPLE com.ibatis.sqlmap.engine.datasource.SimpleDataSourceFactory DBCP com.ibatis.sqlmap.engine.datasource.DbcpDataSourceFactory JNDI com.ibatis.sqlmap.engine.datasource.JndiDataSourceFactory

11 SQL Map XML配置文件-<transactionManager>元素
<transationManager>元素让您为SQL Map配置事务管理服务。属性type指定所使用的事务管理器类型。这个属性值可以是一个类名,也可以是一个别名。包含在框架的三个事务管理器分别是:JDBC,JTA和EXTERNAL。 JDBC:通过常用的Connection commit()和rollback()方法,让JDBC管理事务。 JTA:本事务管理器使用一个JTA全局事务,使SQL Map的事务包括在更大的事务范围内,这个更大的事务范围可能包括了其他的数据库和事务资源。这个配置需要一个UserTransaction属性,以便从JNDI获得一个UserTransaction。 EXTERNAL:这个配置可以让您自己管理事务。您仍然可以配置一个数据源,但事务不再作为框架生命周期的一部分被提交或回退。这意味着SQL Map外部应用的一部分必须自己管理事务。这个配置也可以用于没有事务管理的数据库(例如只读数据)

12 SQL Map XML配置文件-<transactionManager>元素
<datasource>元素的配置,是<transactionManager>的一部分,为SQL Map数据源设置参数 SimpleDataSourceFactory 为DataSource提供了一个基本的实现,适用于在没有J2EE容器提供DataSource的情况。它基于iBatis的SimpleDataSource连接池实现。 DbcpDataSourceFactory 实现使用Jakarta DBCP(Database Connection Pool)的DataSource API提供连接池服务。适用于应用/Web容器不提供DataSource服务的情况,或执行一个单独的应用。 JndiDataSourceFactory 在应用容器内部从JNDI Context中查找DataSource实现。当使用应用服务器,并且服务器提供了容器管理的连接池和相关DataSource实现的情况下,可以使用JndiDataSourceFactory。使用JDBC DataSource的标准方法是通过JNDI来查找

13 SQL Map XML配置文件- <sqlMap>元素
<sqlMap>元素用于包括SQL Map映射文件和其他的SQL Map配置文件。每个SqlMapClient对象使用的所有SQL Map映射文件都要在此声明。映射文件作为stream resource从类路径或URL读入。您必须在这里指定所有的SQL Map文件。 例子如下: <!-- CLASSPATH RESOURCES --> <sqlMap resource="com/ibatis/examples/sql/Customer.xml" /> <sqlMap resource="com/ibatis/examples/sql/Account.xml" /> <sqlMap resource="com/ibatis/examples/sql/Product.xml" /> <!-- URL RESOURCES --> <sqlMap url="file:///c:/config/Customer.xml " /> <sqlMap url="file:///c:/config/Account.xml " /> <sqlMap url="file:///c:/config/Product.xml" />

14 SQL Map XML映射文件 例子: <sqlMap id=”Product”> </sqlMap>
<cacheModel id=”productCache” type=”LRU”> <flushInterval hours=”24”/> <property name=”size” value=”1000” /> </cacheModel> <typeAlias alias=”product” type=”com.ibatis.example.Product” /> <parameterMap id=”productParam” class=”product”> <parameter property=”id”/> </parameterMap> <resultMap id=”productResult” class=”product”> <result property=”id” column=”PRD_ID”/> <result property=”description” column=”PRD_DESCRIPTION”/> </resultMap> <select id=”getProduct” parameterMap=”productParam” resultMap=”productResult” cacheModel=”product-cache”> select * from PRODUCT where PRD_ID = ? </select> </sqlMap>

15 SQL Map XML映射文件 简化的例子 <sqlMap id=”Product”> </sqlMap>
<select id=”getProduct” parameterClass=” com.ibatis.example.Product” resultClass=”com.ibatis.example.Product”> select PRD_ID as id, PRD_DESCRIPTION as description from PRODUCT where PRD_ID = #id# </select> </sqlMap>

16 SQL Map XML映射文件-Mapped Statements
SQL Map的核心概念是Mapped Statement。Mapped Statement可以使用任意的SQL语句,并拥有parameter map(输入)和result map(输出)。如果是简单情况,Mapped Statement可以使用Java类来作为parameter和result。 Mapped Statement的结构如下所示: <statement id=”statementName” [parameterClass=”some.class.Name”] [resultClass=”some.class.Name”] [parameterMap=”nameOfParameterMap”] [resultMap=”nameOfResultMap”] [cacheModel=”nameOfCache”] > select * from PRODUCT where PRD_ID = [?|#propertyName#] order by [$simpleDynamic$] </statement>

17 SQL Map XML映射文件-Mapped Statements类型
<statement>元素是个通用声明,可以用于任何类型的SQL语句。通常,使用具体的statement类型是个好主意。

18 SQL Map XML映射文件-Mapped Statements类型

19 SQL Map XML映射文件-Mapped Statements中的SQL 语句
SQL显然是mapped statement中最重要的部分,可以使用对于数据库和JDBC Driver合法的任意SQL语句。只要JDBC Driver支持,可以使用任意的函数,甚至是多条语句。 例如大于号和小于号(<>),只需将包含特殊字符的SQL语句放在XML的CDATA区里面就可以直接使用特殊的字符不能直接使用了。例如: <statement id="getPersonsByAge" parameterClass=”int” resultClass="examples.domain.Person"> <![CDATA[ SELECT * FROM PERSON WHERE AGE > #value# ]]> </statement>

20 SQL Map XML映射文件-Mapped Statements中自动生成主键
SQL Map通过<insert>的子元素<selectKey>来支持自动生成的键值。它同时支持预生成(如Oracle)和后生成两种类型(如MS-SQL Server)。 下面是两个例子: <!—Oracle SEQUENCE Example --> <insert id="insertProduct-ORACLE" parameterClass="com.domain.Product"> <selectKey resultClass="int" keyProperty="id" > SELECT STOCKIDSEQUENCE.NEXTVAL AS ID FROM DUAL </selectKey> insert into PRODUCT (PRD_ID,PRD_DESCRIPTION) values (#id#,#description#) </insert> <!— Microsoft SQL Server IDENTITY Column Example --> <insert id="insertProduct-MS-SQL" parameterClass="com.domain.Product"> insert into PRODUCT (PRD_DESCRIPTION) values (#description#) SELECT AS ID

21 SQL Map XML映射文件-Mapped Statements中parameterClass
parameterClass属性的值是Java类的全限定名(即包括类的包名)。parameterClass属性是可选的,但强烈建议使用。它的目的是限制输入参数的类型为指定的Java类,并优化框架的性能。如果您使用parameterMap,则没有必要使用parameterClass属性。 例如,如果要只允许Java类“examples.domain.Product”作为输入参数,可以这样作: <statement id=”statementName” parameterClass=” examples.domain.Product”> insert into PRODUCT values (#id#, #description#, #price#) </statement> 重要提示:通过提供parameterClass,您可以获得更好的性能,因为如果框架事先知道这个类,就可以优化自身的性能。如果不指定parameterClass参数,任何带有合适属性(get/set方法)的Java Bean都可以作为输入参数

22 SQL Map XML映射文件-Mapped Statements中Inline Parameter Map
Inline Parameter Map把Java Bean的属性名称嵌在Mapped Statement的定义中(即直接写在SQL语句中)。 缺省情况下,任何没有指定parameterMap的Mapped Statement都会被解析成inline parameter(内嵌参数) 例子: <statement id=”insertProduct” parameterClass=”com.domain.Product”> insert into PRODUCT (PRD_ID, PRD_DESCRIPTION) values (#id:NUMERIC: #, #description:VARCHAR:NO_ENTRY#); </statement> 在内嵌参数中,要指定NULL的替代值,必须要先指定数据类型。 如需要在查询时也使用NULL替代值,必须同时在resultMap中定义(如下说明)。

23 SQL Map XML映射文件-Mapped Statements中基本类型作为参数
例子: <statement id=”insertProduct” parameter=”java.lang.Integer”> select * from PRODUCT where PRD_ID = #value# </statement> 必须使用基本类型的包装类作为参数

24 SQL Map XML映射文件-Mapped Statements中resultClass
resultClass属性的值是Java类的全限定名(即包括类的包名)。resultClass属性可以让您指定一个Java类,根据ResultSetMetaData将其自动映射到JDBC的ResultSet。只要是Java Bean的属性名称和ResultSet的列名匹配,属性自动赋值给列值。 例如: <statement id="getPerson" parameterClass=”int” resultClass="examples.domain.Person"> 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# </statement>

25 SQL Map XML映射文件-Mapped Statements中Result Map
resultMap负责将结果集的列值映射成Java Bean的属性值。 resultMap的结构如下: <resultMap id=”resultMapName” class=”some.domain.Class” [extends=”parent-resultMap”]> <result property=”propertyName” column=”COLUMN_NAME” [columnIndex=”1”] [javaType=”int”] [jdbcType=”NUMERIC”] [nullValue=” ”] [select=”someOtherStatement”] /> ……………… </resultMap>

26 SQL Map XML映射文件-Mapped Statements中Result Map
property属性 property的值是mapped statement返回结果对象的Java Bean属性的名称(get方法)。 column属性 column的值是ResultSet中字段的名称,该字段赋值给names属性指定的Java Bean属性。同一字段可以多次使用。注意,可能某些JDBC Driver(例如,JDBC/ODBC桥)不允许多次读取同一字段。 columnIndex属性 columnIndex是可选的,用于改善性能。属性columnIndex的值是ResultSet中用于赋值Java Bean属性的字段次序号。在99%的应用中,不太可能需要牺牲可读性来换取性能。使用columnIndex,某些JDBC Driver可以大幅提高性能,某些则没有任何效果。 jdbcType属性 jdbctype用于指定ResultSet中用于赋值Java Bean属性的字段的数据库数据类型(而不是Java类名)。虽然resultMap没有NULL值的问题,指定type属性对于映射某些类型(例如Date属性)还是有用的。因为Java只有一个Date类型,而SQL数据库可能有几个(通常至少有3个),为保证Date(和其他)类型能正确的赋值,某些情况下指定type还是有必要的。同样地,String类型的赋值可能来自VARCHAR,CHAR和CLOB,因此同样也有必要指定type属性(取决于JDBC Driver)。 javaType属性 javaType用于显式地指定被赋值的Java Bean属性的类型。正常情况下,这可以通过反射从Java Bean的属性获得,但对于某些映射(例如Map和XML document),框架不能通过这种方法来获知。如果没有设置javaType,同时框架也不能获知类型信息,类型将被假定为Object。

27 SQL Map XML映射文件-Mapped Statements中Result Map
nullValue属性 nullValue指定数据库中NULL的替代值。因此,如果从ResultSet中读出NULL值,Java Bean属性将被赋值属性null指定的替代值。属性null的值可以指定任意值,但必须对于Java Bean属性的类型是合法的。 如果数据库中存在NULLABE属性的字段,但您需要用指定的常量代替NULL,您可以这样设置resultMap: <resultMap id=”get-product-result” class=”com.ibatis.example.Product”> <result property=”subCode” column=”PRD_SUB_CODE” nullValue=”-999”/> </resultMap> 上面的例子中,如果PRD_SUB_CODE的值是NULL,subCode属性将被赋值-999。这让您在Java类中用基本类型的属性映射数据库中的NULLABE字段。记住,如果您要在查询和更新中同样使用这个功能,必须同时在parameterMap中指定nullValue属性。 select属性 select用于描述对象之间的关系,并自动地装入复杂类型(即用户定义的类型)属性的数据。属性select的值必须是另外一个mapped statement元素的名称。在同一个result元素中定义的数据库字段(column属性)以及property属性,将被传给相关的mapped statement作为参数。因此,字段的数据类型必须是SQL Map支持的简单数据类型。

28 SQL Map XML映射文件-Mapped Statements中隐式Result Map和基本类型的Result
<statement id=”getProduct” resultClass=”com.ibatis.example.Product”> select PRD_ID as id, PRD_DESCRIPTION as description from PRODUCT where PRD_ID = #value# </statement> 基本类型的Result例子: <statement id=”getProductCount” resultClass=”java.lang.Integer”> select count(1) as value

29 SQL Map XML映射文件-Mapped Statements中cacheModel
例子 <cacheModel id="product-cache" imlementation="LRU"> <flushInterval hours="24"/> <flushOnExecute statement="insertProduct"/> <flushOnExecute statement="updateProduct"/> <flushOnExecute statement="deleteProduct"/> <property name=”size” value=”1000” /> </cacheModel> <statement id=”getProductList” parameterClass=”int” cacheModel=”product-cache”> select * from PRODUCT where PRD_CAT_ID = #value# </statement>

30 SQL Map XML映射文件-动态Mapped Statement
一个简单的例子: <statement id="someName" resultMap="account-result" > select * from ACCOUNT <dynamic prepend="where"> <isGreaterThan prepend="and" property="id" compareValue="0"> ACC_ID = #id# </isGreaterThan> <isNotNull prepend=”and" property="lastName"> ACC_LAST_NAME = #lastName# </isNotNull> </dynamic> order by ACC_LAST_NAME </statement>

31 SQL Map XML映射文件-动态Mapped Statement
<dynamic>元素和条件元素都有“prepend”属性,它是动态SQL代码的一部分,在必要情况下,可以被父元素的“prepend”属性覆盖。

32 SQL Map XML映射文件-动态Mapped Statement中二元条件元素
二元条件元素的属性: prepend - 可被覆盖的SQL语句组成部分,添加在语句的前面(可选) property - 被比较的属性(必选) compareProperty - 另一个用于和前者比较的属性(必选或选择compareValue) compareValue - 用于比较的值(必选或选择compareProperty)

33 SQL Map XML映射文件-动态Mapped Statement中二元条件元素

34 SQL Map XML映射文件-动态Mapped Statement中一元条件元素
一元条件元素的属性: prepend - 可被覆盖的SQL语句组成部分,添加在语句的前面(可选) property - 被比较的属性(必选)

35 SQL Map XML映射文件-动态Mapped Statement中其他元素
Parameter Present:这些元素检查参数对象是否存在。 Parameter Present的属性: prepend - 可被覆盖的SQL语句组成部分,添加在语句的前面(可选)

36 SQL Map XML映射文件-动态Mapped Statement中其他元素
Iterate:遍历整个集合,并为List集合中的元素重复元素体的内容。 Iterate的属性: prepend - 可被覆盖的SQL语句组成部分,添加在语句的前面(可选) property - 类型为java.util.List的用于遍历的元素(必选) open - 整个遍历内容体开始的字符串,用于定义括号(可选) close -整个遍历内容体结束的字符串,用于定义括号(可选) conjunction - 每次遍历内容之间的字符串,用于定义AND或OR(可选)

37 使用SQL Map API编程-配置SQL Map
SQL Map使用XmlSqlMapClientBuilder来创建。这个类有一个静态方法叫buildSqlMap。方法buildSqlMap简单地用一个Reader对象为参数,读入sqlMap-config.xml文件(不必是这个文件名)的内容。 String resource = “com/ibatis/example/sqlMap-config.xml”; Reader reader = Resources.getResourceAsReader (resource); SqlMapClient sqlMap = SqlMapClientBuilder.buildSqlMap(reader);

38 使用SQL Map API编程-自动事务处理
缺省情况下,调用SqlMapClient对象的任意executeXxxx()方法将缺省地自动COMMIT/ROLLBACK。 这意味着每次调用executeXxxx()方法都是一个独立的事务

39 使用SQL Map API编程-自动事务处理
private Reader reader = new Resources.getResourceAsReader ("com/ibatis/example/sqlMapconfig.xml"); private SqlMapClient sqlMap = XmlSqlMapBuilder.buildSqlMap(reader); public updateItemDescription (String itemId, String newDescription) throws SQLException { try { Item item = (Item) sqlMap.queryForObject ("getItem", itemId); item.setDescription (“TX1”); //No transaction demarcated, so transaction will be automatic (implied) sqlMap.update ("updateItem", item); item.setDescription (newDescription); item.setDescription (“TX2”); sqlMap.update("updateItem", item);} catch (SQLException e) {throw (SQLException) e.fillInStackTrace(); }}

40 使用SQL Map API编程-全局事务 SQL Map框架可以管理全局事务。要支持受管理的全局事务,必须在SQL Map配置文件中设定<transactionManager>的type属性为JTA,并设定“UserTransaction”属性为JNDI的全名,以使SqlMapClient实例能找到UserTransaction对象

41 使用SQL Map API编程-全局事务 try { storeSqlMap.startTransaction();
orderSqlMap.insertOrder(…); orderSqlMap.updateQuantity(…); storeSqlMap.commitTransaction(); } finally { storeSqlMap.endTransaction() }}

42 使用SQL Map API编程-用SqlMapClient执行SQL语句
SqlMapCient类提供了执行所有mapped statement的API。 public int insert(String statementName, Object parameterObject) throws SQLException public Object queryForObject(String statementName, public List queryForList(String statementName, public Map queryForMap (String statementName, Object parameterObject,String keyProperty) throws SQLException 在上面的每个方法中,Mapped Statement的名称作为第一个参数。这个名称要对应<statement>的名称属性。另外,第二个参数总是参数对象。如果不需要参数对象,可以为null

43 使用SQL Map API编程-用SqlMapClient执行SQL语句
例子1:执行update(insert,update,delete) sqlMap.startTransaction(); Product product = new Product(); product.setId (1); product.setDescription (“Shih Tzu”); int rows = sqlMap.insert (“insertProduct”, product); sqlMap.commitTransaction(); 例子2:查询成对象(select) Integer key = new Integer (1); Product product = (Product)sqlMap.queryForObject (“getProduct”, key);

44 使用SQL Map API编程-用SqlMapClient执行SQL语句
例子3:用预赋值的结果对象查询成对象(select) sqlMap.startTransaction(); Customer customer = new Customer(); sqlMap.queryForObject(“getCust”, parameterObject, customer); sqlMap.queryForObject(“getAddr”, parameterObject, customer); sqlMap.commitTransaction(); 例子4:查询成对象List(select) List list = sqlMap.queryForList (“getProductList”, null);

45 使用SQL Map API编程-用SqlMapClient执行SQL语句
例子5:自动提交 //当没调用startTransaction的情况下,statements会自动提交。 //没必要commit/rollback。 int rows = sqlMap.insert (“insertProduct”, product); 例子6:用结果集边界查询成对象List(select) sqlMap.startTransaction(); List list = sqlMap.queryForList (“getProductList”, null, 0, 40); sqlMap.commitTransaction();

46 使用SQL Map API编程-用SqlMapClient执行SQL语句
例子7:用RowHandler执行查询(select) public class MyRowHandler implements RowHandler { public void handleRow (Object object, List list) throws SQLException { Product product = (Product) object; product.setQuantity (10000); sqlMap.update (“updateProduct”, product); // Optionally you could add the result object to the list. // The list is returned from the queryForList() method.}} sqlMap.startTransaction(); RowHandler rowHandler = new MyRowHandler(); List list = sqlMap.queryForList (“getProductList”, null, rowHandler); sqlMap.commitTransaction();

47 使用SQL Map API编程-用SqlMapClient执行SQL语句
例子8:查询成Paginated List(select) PaginatedList list = sqlMap.queryForPaginatedList (“getProductList”, null, 10); list.nextPage(); list.previousPage(); 例子9:查询成Map(select) sqlMap.startTransaction(); Map map = sqlMap.queryForMap (“getProductList”, null, “productCode”); sqlMap.commitTransaction(); Product p = (Product) map.get(“EST-93”);

48 iBatis与Hibernate的简单比较
10 Reasons to use iBatis 1. Works with any database that has a JDBC driver(no plugins required) 2. Configurable caching (including dependencies) 3. Local and Global transaction support and management (JTA) 4. Simple XML mapping document structure 5. Supports Map, Collection, List and Primitive Wrappers (Integer, String etc.)

49 iBatis与Hibernate的简单比较
10 Reasons to use iBatis 6. Supports JavaBeans classes (get/set methods) 7. Supports complex object mappings (populating lists, complex object models etc.) 8. Object models are never perfect (no changes required!) 9. Database designs are never perfect (no changes required!) 10. You already know SQL, why waste time learning something else?

50 iBatis与Hibernate的简单比较

51 参考文献 http://ibatis.apache.org/javadownloads.cgi

52 Q&A! Thank you !


Download ppt "IBatis介绍 Java."

Similar presentations


Ads by Google