ibatis框架详解

在开发过程中最能帮助你的是什么?是框架,一个优秀的框架可以极大的提高你的效率。struts给了我们什么?MVC的实现,国际化、灵活。还有很多。不过,在一个通常的WEB应该中,

是不能缺少数据库的,而struts在这方面并没有给我们提供什么有效的帮助。通常情况下我们做这个的时候有几个选择。
   最直接的当然是JDBC啊,自己写connect、statment和resultset等等的代码,结果是累死自己。
   然后一种方法是EJB,EJB确实是一个好东西,可惜在很多场合用不上,起码它很烦,速度很慢
   还有一种选择就是JDO及类似的东西。最著名是free的应该是castor,hibernate等。
  现在我们又多了一种选择,就是ibatis Db Layer,它的主页是http://www.ibatis.com,为什么说它好,让我们来看看作者自己的说明吧,使用ibatis的理由
  10、知道怎样操作10种以上的数据库
  9 、可配置的caching(包括从属)
  8、支持DataSource、local transaction managemen和global transaction
  7、简单的XML配置文档
  6、支持Map, Collection, List和简单类型包装(如Integer, String)
  5、支持JavaBeans类(get/set 方法)
  4、支持复杂的对象映射(如populating lists, complex object models)
  3、对象模型从不完美(不需要修改)
  2、数据模型从不完美(不需要修改)
  1、你已经知道SQL,为什么还要学习其他东西
  另外一点它是100% Open Source Freeware
  下面我们就来看一看,做一个简单的ibatis需要哪一些工作。然后一步一步深入探索它的强大功能。在实践中来看它的好处在哪里。
  在ibatis的网站上有一个它自己的petstore,在我个人看来是最简洁的petstore了,跟struts1.0结合。应该说是一个不错的教程。希望大家能够好好研究。当然,作为入门。我们先来做

一个简单的程序。所采用的库嘛,就仍然是用petstore的了。数据库也是选择Oracle(为什么选择Oracle,很多朋友不理解,怎么不用mysql之类的呢,一个主要的原因是个人爱好,Oracle毕

竟是商业数据库,有它的强大之处,另外在linux下它也是免费的,:)。废话少说,先用jpetstore3.1提供的ddl建立一个库吧。
  然后在eclipse里建立一个ibatisDemo的工程。加入ibatis提供的库,建立相就的目录。看一下一个最简单的程序需要哪一些文件。我们选择一个简单表,即Category这个表的操作来演示功


  
  文件路径
  功能说明
  备注
  config/properties/petstore.properties
  可变参数配置文件,所有根据环境不同的参数都放在这里
  
  config/properties/simple/dao.xml
  dao配置文件,主要存放dao对象和数据池设置
  
  config/properties/simple/sql-map-config-storedb.xml
  真正的核心配置文件
  
  config/sqlmap/Category.xml
  存放Category的数据操作的SQL
  
  com.ewuxi.champion.exception.DaoException.java
  自定义的Exception类,不用说了吧
  
  com.ewuxi.champion.Service.java
  一个服务类,用于初始化
  
  com.ewuxi.champion.persistence.dao.DaoCommon
  Dao层的统一操作类,提供一些公共函数
  
  com.ewuxi.champion.persistence.dao.CategoryDb
  Category的操作类
  
  com.ewuxi.champion.persistence.vo.Category
  valueObject 值对象
  
  com.ewuxi.champion.persistence.dao.CategoryDbTest
  单元测试类
  下面一个一个文件详细说明
  petstore.properties
  
  ##################################################################
  SIMPLE CONFIGURATION SECTION
  ##################################################################
  ## SimpleDataSource properties
  ## Use only if useSimpleConfiguration=true
  SimpleDriver=oracle.jdbc.OracleDriver
  SimpleUrl=jdbc:oracle:thin:@10.0.0.5:1521:champion
  SimpleUsername=pet
  SimplePassword=pet
  这个不用解释,就是数据库的连接串,如果你在自己的机器上运行,当然这些都是需要改的。
  dao.xml
  
  <?xml version="1.0" encoding="UTF-8"?>
  <!DOCTYPE dao-config
  PUBLIC "-//iBATIS.com//DTD DAO Configuration 1.0//EN"
  "http://www.ibatis.com/dtd/dao.dtd">
  <dao-config>
  <context name="StoreDaoManager" default="true">
  <!-- Configure the transaction pool. -->
  <transaction-pool implementation="com.ibatis.db.dao.jdbc.SqlMapDaoTransactionPool">
  <property name="sql-map-config-file" value="properties/simple/sql-map-config-storedb.xml"/>
  </transaction-pool>
  </context>
  </dao-config>
  上面这一段也是很简单的,连一个dao也没有配置,也就是说,用的是默认的Dao。其中<context name="StoreDaoManager" default="true">表示它是默认的数据库配置(它可以根据

名字不同同时连接几个数据库的)。
  sql-map-config-storedb.xml
  
  <?xml version="1.0" encoding="UTF-8"?>
  <!DOCTYPE sql-map-config
  PUBLIC "-//iBATIS.com//DTD SQL Map Config 1.0//EN"
  "http://www.ibatis.com/dtd/sql-map-config.dtd">
  <sql-map-config>
  <properties resource="properties/petstore.properties" />
  <settings
  maxExecute="0"
  maxExecutePerConnection="0"
  maxTransactions="0"
  cacheModelsEnabled="true"
  statementCacheSize="175"
  useBeansMetaClasses="false"
  useGlobalTransactions="false" />
  <datasource name="jpestoreSimple"
  factory-class="com.ibatis.db.sqlmap.datasource.DbcpDataSourceFactory"
  default="true" >
  <property name="JDBC.Driver" value="${SimpleDriver}"/>
  <property name="JDBC.ConnectionURL" value="${SimpleUrl}"/>
  <property name="JDBC.Username" value="${SimpleUsername}"/>
  <property name="JDBC.Password" value="${SimplePassword}"/>
  <property name="Pool.MaximumActiveConnections" value="15"/>
  <property name="Pool.MaximumIdleConnections" value="15"/>
  <property name="Pool.MaximumWait" value="1000"/>
  </datasource>
  <sql-map resource="sqlmap/Category.xml" />
  </sql-map-config>
  这里真正实现了数据库连接,我们使用的是dbcp的连接池。JDBC的配置大家都很熟了。${SimpleDriver}就是指的前面petstore.properties中的SimpleDriver的内容。
  而<sql-map resource="sqlmap/Category.xml" />则表示包含Category.xml这个文件。
  Category.xml
  
  <?xml version="1.0" encoding="UTF-8"?>
  <!DOCTYPE sql-map
  PUBLIC "-//iBATIS.com//DTD SQL Map 1.0//EN"
  "http://www.ibatis.com/dtd/sql-map.dtd">
  <sql-map name="Category">
  <result-map name="result" class="com.ewuxi.champion.persistence.vo.Category">
  <property name="categoryId" column="CATID" columnIndex="1" />
  <property name="name" column="NAME" columnIndex="2"/>
  <property name="description" column="DESCN" columnIndex="3"/>
  </result-map>
  <mapped-statement name="findByPrimaryKeyCategoryDao" result-map="result">
  select CATID, NAME, DESCN from CATEGORY where CATID = #categoryId#
  </mapped-statement>
  <dynamic-mapped-statement name="findCategoryDao" result-map="result">
  select CATID, NAME, DESCN from CATEGORY
  <dynamic prepend="where">
  <isNotNull prepend="and" property="categoryId" >
  CATID = #categoryId#
  </isNotNull>
  <isNotNull prepend="and" property="name" >
  NAME = #name#
  </isNotNull>
  <isNotNull prepend="and" property="description">
  DESCN = #description#
  </isNotNull>
  </dynamic>
  </dynamic-mapped-statement>
  <mapped-statement name="findCategoryDaoCount" result-class="java.lang.Integer">
  select count(1) as value from CATEGORY
  </mapped-statement>
  <!-- =============================================
  mapped-statement
  ============================================= -->
  <dynamic-mapped-statement name="updateByPrimaryKeyCategoryDao">
  update CATEGORY
  <dynamic prepend="set">
  <isNotNull prepend="," property="name" >
  NAME = #name#
  </isNotNull>
  <isNotNull prepend="," property="description">
  DESCN = #description#
  </isNotNull>
  </dynamic>
  where
  CATID =#categoryId#
  </dynamic-mapped-statement>
  <!-- =============================================
  mapped-statement
  ============================================= -->
  <mapped-statement name="deleteByPrimaryKeyCategoryDao">
  delete from CATEGORY
  where CATID =#categoryId#
  </mapped-statement>
  <!-- =============================================
  OPTIONAL EXPLICIT PARAMETER MAP
  ============================================= -->
  <parameter-map name="insert-params">
  <property name="categoryId"/>
  <property name="name" type="VARCHAR"/>
  <property name="description" type="VARCHAR"/>
  </parameter-map>
  <!-- =============================================
  MAPPED STATEMENTS - w/Explicit Parameter Map
  ============================================= -->
  <mapped-statement name="insertCategoryDao" parameter-map="insert-params" >
  insert into CATEGORY (
  CATID,NAME,DESCN)
  values (
  ?,?,?
  )
  </mapped-statement>
  </sql-map>
  上述文件就是真正的SQL所存在的地方。
  
  <result-map name="result" class="com.ewuxi.champion.persistence.vo.Category">
  <property name="categoryId" column="CATID" columnIndex="1" />
  <property name="name" column="NAME" columnIndex="2"/>
  <property name="description" column="DESCN" columnIndex="3"/>
  </result-map>
  这一段的内容表示返回的对象是com.ewuxi.champion.persistence.vo.Category,也就是我们值对象。当执行查询的时候,dblay会封装出一个Category对象或者一个Category的list集合

。其中数据列CATID就对象javabean的categoryId值。name是自定义的
  
  <mapped-statement name="findByPrimaryKeyCategoryDao" result-map="result">
  select CATID, NAME, DESCN from CATEGORY where CATID = #categoryId#
  </mapped-statement>
  此处result-map="result"表示返回结果以后,就会参照前面的result来返回对象。select CATID, NAME, DESCN from CATEGORY where CATID = #categoryId#标准的SQL,只不过这

一点CATID = #categoryId#有些不同,#categoryId#表示传递一个Category对象时,Dblay会自动取得categoryId的值来执行SQL
  再来看一个
  
  <dynamic-mapped-statement name="updateByPrimaryKeyCategoryDao">
  update CATEGORY
  <dynamic prepend="set">
  <isNotNull prepend="," property="name" >
  NAME = #name#
  </isNotNull>
  <isNotNull prepend="," property="description">
  DESCN = #description#
  </isNotNull>
  </dynamic>
  where
  CATID =#categoryId#
  </dynamic-mapped-statement>
  这个地方就体现了dblayer的强大之处,动态SQL。平常我们经常碰到的情况是根据不同的情况,执行的SQL有一点点不一样。写在程序里,要写不少的if then之类的,在这里,dbLayer

给你一下解决了。比如在这里,我们三个值都是String对象,所以通过isNotNull就可以实现几种不同的update了,比如,如果我只想修改DESCN这个字段,只要传过去的Category对象只有

categoryId和description有值,就会生成update CATEGORY set DESCN = #description# where CATID =#categoryId#。同样如果传递的对象只有categoryId和name有值,就会生成

update CATEGORY set NAME = #name# where CATID =#categoryId#。是否很强大?:)
  前面这两种,参数的传递方式是内置参数,也就是CATID =#categoryId#这种,大家可能不太习惯,那就看一看标准的写法吧。
  
  <!-- =============================================
  OPTIONAL EXPLICIT PARAMETER MAP
  ============================================= -->
  <parameter-map name="insert-params">
  <property name="categoryId"/>
  <property name="name" type="VARCHAR"/>
  <property name="description" type="VARCHAR"/>
  </parameter-map>
  <!-- =============================================
  MAPPED STATEMENTS - w/Explicit Parameter Map
  ============================================= -->
  <mapped-statement name="insertCategoryDao" parameter-map="insert-params" >
  insert into CATEGORY (
  CATID,NAME,DESCN)
  values (
  ?,?,?
  )
  </mapped-statement>
  </sql-map>
  这里面的insert语句想来大家都很熟了吧?这个时候怎么取得参数呢?关键在于这里parameter-map="insert-params",表示会读取<parameter-map name="insert-params">的设置,

而这个设置也不用多解释了吧,就是按顺序,三个?分别对应三个值。还能指明他们的数据类型。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值