??xml version="1.0" encoding="utf-8" standalone="yes"?>轻轻色免费在线视频,97视频精彩视频在线观看,不卡中文字幕avhttp://www.aygfsteel.com/realzar/category/11155.html皇家撒拉哥萨zh-cnThu, 01 Mar 2007 14:22:24 GMTThu, 01 Mar 2007 14:22:24 GMT60Zstruts+spring+ibatis的轻量J2EE开?/title><link>http://www.aygfsteel.com/realzar/archive/2006/06/05/50379.html</link><dc:creator>开源爱好?/dc:creator><author>开源爱好?/author><pubDate>Sun, 04 Jun 2006 16:09:00 GMT</pubDate><guid>http://www.aygfsteel.com/realzar/archive/2006/06/05/50379.html</guid><wfw:comment>http://www.aygfsteel.com/realzar/comments/50379.html</wfw:comment><comments>http://www.aygfsteel.com/realzar/archive/2006/06/05/50379.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/realzar/comments/commentRss/50379.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/realzar/services/trackbacks/50379.html</trackback:ping><description><![CDATA[     摘要: 多数 IT l织都必解决三个主要问题: 1 Q帮助组l减成? 2 Q增加ƈ且保持客? 3 Q加快业务效率。完成这些问题一般都需要实现对多个业务pȝ的数据和业务逻辑的无~访问,也就是说Q要实施pȝ集成工程Q以便联l业务流E、实现数据的讉K与共享?..  <a href='http://www.aygfsteel.com/realzar/archive/2006/06/05/50379.html'>阅读全文</a><img src ="http://www.aygfsteel.com/realzar/aggbug/50379.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/realzar/" target="_blank">开源爱好?/a> 2006-06-05 00:09 <a href="http://www.aygfsteel.com/realzar/archive/2006/06/05/50379.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>iBatis DAO入门与进?/title><link>http://www.aygfsteel.com/realzar/archive/2006/05/30/49067.html</link><dc:creator>开源爱好?/dc:creator><author>开源爱好?/author><pubDate>Tue, 30 May 2006 09:27:00 GMT</pubDate><guid>http://www.aygfsteel.com/realzar/archive/2006/05/30/49067.html</guid><wfw:comment>http://www.aygfsteel.com/realzar/comments/49067.html</wfw:comment><comments>http://www.aygfsteel.com/realzar/archive/2006/05/30/49067.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/realzar/comments/commentRss/49067.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/realzar/services/trackbacks/49067.html</trackback:ping><description><![CDATA[ <center> <b> <span style="FONT-SIZE: 20px">iBatis DAO入门与进?/span> </b> </center> <br /> <center>作者:Sunil Patil</center> <br /> <center>译?<a target="_new">rotter_pal</a></center> <br /> <br /> <br /> <br /> <br /> <span style="COLOR: red">版权声明QQ何获得Matrix授权的网站,转蝲时请<b>务必</b>以超链接形式标明文章原始出处和作者信息及本声?/span> <br />作?Sunil Patil;<a target="_new">rotter_pal</a><br />原文地址:<a target="_new">http://www.onjava.com/pub/a/onjava/2005/08/10/ibatisdao.html</a><br />中文地址:<a target="_new">http://www.matrix.org.cn/resource/article/44/44058_iBatis+DAO.html</a><br />关键词: iBatis DAO<br /><br /><br />在核心J2EE模式中是q样介绍DAO模式的:Z建立一个健壮的J2EE应用Q应该将所有对数据源的讉K操作抽象装在一个公共API中。用E序设计的语a来说Q就是徏立一个接口,接口中定义了此应用程序中会用到的所有事务方法。在q个应用E序中,当需要和数据源进行交互的时候则使用q个接口Qƈ且编写一个单独的cL实现q个接口在逻辑上对应这个特定的数据存储?br /><br />比如考虑在iBatis: SQL Maps中的应用例子。这是一个Struts应用允许对一个关p表执行SELECT, INSERT, UPDATE和DELETE的SQLh。在q个应用中,使用SQL Maps做持l性框架。现在我们要修改q个应用Q将q个关系表储存在一个XML文g中而不是存在关pL据库中,或者用Hibernate来实现SELECThQ而用SQL Map来执行其他请求,因ؓHibernate提供了对高速缓存更好的支持。这L修改很难实现Q或者即使我们能修改而实Cq个功能Q也会是很؜q解决Ҏ?br /><br /><br />对于q类问题更好的解x法是建立一个ContactDAO接口Q在q个接口中定义处理SELECT, INSERT, UPDATE, 和DELETE h的事务方法。然后根据不同的事务逻辑建立不同的类实现各个Ҏ。所以可能会有一个类处理使用SQL Maps同关p表q行交互的情况,而另外一个类处理用XML文g存放关系表而不是关pL据库的情况,{等。在目中,Ҏ实际的需要从不同的ContactDAO中选择相应的实现。这U关p见?Q?br /><br /><img onmouseover="javascript:imgShowTip(this);" style="DISPLAY: inline" onclick="javascript:imgClick(this);" alt="image" src="http://www.matrix.org.cn/resource/upload/article/2005_12_18_224911_SOAyTyFzWZ.gif" onload="javascript:imgLoad(this);" border="0" resized="0" /><br />?. ContactDAO 接口及实?br /><br />iBatis DAO是由ApacheL的开源框枉目,主要目标是ؓ了解册c问题。它允许在工E中以DAO模式为基建立应用。这意味着可以建立一个XML文gQƈ声明XMLContactDAO.java是ContactDAO的实现类Q这个类知道如何从XML文g中读写数据。SQLMapContactDAO则知道如何用SQL Maps作ؓ持箋化框架与关系表进行交互。在工程中,如果向DAO框架提交一个需要XML的ContactDAOhQ框架则会返回一个XMLContactDAO对象。同LDAO框架提供了唯一的接口处理事务管理,q个接口能实C数据的存储方式无兟뀂它同样考虑了底层连接管理细节和初始化存储框架?br /><br />q篇文章是关于如何一步一步的在项目中应用iBatis DAO框架的基指导。我们将由如何把SQL Maps一文中的应用实例改为应用DAO框架入手。然后,我们要讨论DAO框架的构造。再下一步,我们x事务理是如何在DAO框架中得到支持的。最后一部分是关于如何徏立自q事务理模块?br /><br /><b><span style="FONT-SIZE: 16px">CZ应用</span></b><br /><br />首先Q我们将SQL Maps一文中的例子改为应用DAO框架?br />1.        ibatis-dao-2.jar文g复制到WEB-INF/lib目录下?br />2.        在Java源程序的目录里新Z个如下的DAOMap.xml文g<br /><b>清单1Q?/b><br /><pre class="overflow"><daoConfig><br /> <context id="sqlmap"><br />  <transactionManager type="SQLMAP"><br />  <property name="SqlMapConfigResource" value=<br />   "com/sample/contact/dao/sqlmap/SqlMapConfig.xml"/><br />  </transactionManager><br />  <dao interface="com.sample.contact.dao.ContactDAO"<br />   implementation=<br />   "com.sample.contact.dao.sqlmap.SQLMapContactDAO"/><br /> </context><br /></daoConfig></pre><br /><br />DAOMap.xml是发布iBatis DAO框架的配|文件?lt;daoConfig>是根元素Q每?lt;context>元素描述了一U存储机制。在q个例子中只使用了SQL Maps来存储,所以我们这里只有一?lt;context>元素。每U存储机制必d含一?lt;transactionManager>元素Q这个元素描q连接它后面的数据存储所用的理器,q且标记事务的界限。我们将在稍后再讨论transactionManager?br /><br /><context>元素q包括一lDAO用于描述其他的存储管理机制。在q个例子中,我们生成一个用SQL Maps存储的ContactDAOQ所以在配置文g中添加一个ie<dao>标记来定义SQLMapContactDAO?br /><br />3.        建立ContactDAO.java,如下Q?br /><b>清单2Q?/b><br /><pre class="overflow">public interface ContactDAO extends DAO {<br />    public int insertContact(Contact contact);<br />    public int updateContact(Contact contact);<br />    public Contact selectContact(int contactId);<br />    public int deleteContact(int contactId);<br />} </pre>   <br /><br />ContactDAO.java定义了用户和一个关p表q行交互所需要用到的所有事务处理方法。请注意到ContactDAO.java中的所有方法都一个Contact对象作ؓ参数Q这是一个用来携带数据的数据传递对象?br /><br /><br />4.        建立一个SQLMapContactDAO.java文gQ如?br /><b>清单3Q?/b><br /><pre class="overflow">public class SQLMapContactDAO extends<br /> SqlMapDaoTemplate implements ContactDAO {<br />  public SQLMapContactDAO(DaoManager arg0) {<br />      super(arg0);<br />  }<br />  public int deleteContact(int contactId) {<br />    return super.delete("deleteContact",<br />    new Integer(contactId));<br />  }<br />  public int insertContact(Contact contact) {<br />    Integer contactId =(Integer)super.insert<br />      ("insertContact",contact);<br />    return contact.getContactId();<br />  }<br />  public Contact selectContact(int contactId) {<br />    return (Contact)super.queryForObject("getContact",<br />      new Integer(contactId));<br />  }<br />  public int updateContact(Contact contact) {<br />    return super.update("updateContact",contact);<br />  }<br />}</pre><br /><br />SQLMapContactDAO是ContactDAO接口的具体实玎ͼ它用SQL Maps作ؓ存储理机制。注意到我们q没有写M代码来或者初始化SQL MapsQ或得到一个连接,或者在cM标注一个事务的界限。相反,我们l承SqlMapDaoTemplate.javac,它帮我们处理下层的、反复的操作。我们在SQLMapContactDAOcM需要考虑的唯一的事情就是事务处理逻辑?br /><br />5.        修改ContactSelectAction.javacM的execute()ҎQ如下:<br /><b>清单4Q?/b><br /><pre class="overflow">Contact contactForm = (Contact) form;<br />Reader reader=<br />  Resources.getResourceAsReader("DAOMap.xml");<br />DaoManager daoManager =<br />  DaoManagerBuilder.buildDaoManager(reader);<br />ContactDAO contactDAO =<br />  (ContactDAO) daoManager.getDao(<br />ContactDAO.class,"sqlmap");<br /><br />request.setAttribute("contactDetail",<br />  contactDAO.selectContact(<br />    contactForm.getContactId()));</pre><br /><br />最后一步是修改ContactSelectActioncM的execute()ҎQ它用DAO框架。ؓ了初始化DAO框架Q我们需要一个ؓDAOMap.xml 准备一个Reader对象。iBatis框架为我们提供了ҎResources.getResourceAsReader()来读取资源。一旦有了Reader对象来读取DAOMap.xmlQ就能将它们d至DAOManagerBuilder.buildDaoManager()Q返回一个DaoManager实例Q将来用于与DAO框架q行交互。从理论上来_应该在项目启动的时候初始化DAO框架Q在我们q个E序中,可以这个模块放入Struts插g中,但是Z化这个例子,我们初始化模块攑օexecuteҎ中?br /><br />有了DaoManager实例后,可以调用相应的接口和存储实现c??lt;context>元素中的id属性?的getDao()Ҏ。在我们的例子中Q需要一个SQLMapContactDAO的实例,所以以ContactDAO为接口名Uͼ“sqlmap”ؓ存储机制。一旦实CSQLMapContactDAO实例Q就可以在调用其中的事务Ҏ?br /><br />在最后的资源章节中可以下载到q个例子的源码?br /><br /><b><span style="FONT-SIZE: 16px">DAO框架架构</span></b><br /><br />׃有了一个可以运行的CZQ让我们得以_略了解DAO框架是如何运作的。在?表示的顺序图中演CZDAO的工作方式:<br /><br /><img onmouseover="javascript:imgShowTip(this);" style="DISPLAY: inline" onclick="javascript:imgClick(this);" height="450" alt="image" src="http://www.matrix.org.cn/resource/upload/article/2005_12_18_224916_OkWdiCStgH.gif" width="553" onload="javascript:imgLoad(this);" border="0" resized="1" /><br />?. DAO序?br /><br />在开始时Q调用DaoManagerBuilder.buildDaoManager()q传入DAOMap.xml来初始化DAO框架。在q个Ҏ中DAO框架会读取DAOMap.xmlq且由此生成相应的DAOManager对象。这个对象包括了Ҏ持的数据存储机制的描q。哪个接口会被实玎ͼ哪个是接口和存储机制l合的实现类Q基本上q是和DAOMap.xml文g相等?Java对象?br /><br />当有了DAOManager对象Q可以从中得到ContactDAO接口的SQL Map实例。DAO框架会返回一个包装了实现cȝDaoProxy对象。在本例子中给SQLMapContactDAOq回一个DaoProxy对象。这个DaoProxy对象允许DAO框架截获调用商业Ҏ。本例中Q当调用 contactDAO.selectContact()ӞDAO框架会截莯个调用ƈ查事务处理是否已l开始执行,如果没有Q它调用事务管理器中的startTransaction()创徏一个新的事务处理调用。如果处理已l开始,DaoProxy对象会调用事务中的SQLMapContactDAO中的selectContact()Ҏ。当selectContact()调用q回的时候,DaoProxy对象截获q回q提交给事务?br /><br />如果不希望事务在Ҏ层上可见Q或者希望在一个事务中调用多个不同的方法,则可在调用ContactDAO中的商业Ҏ前调用daoManager.startTransaction()Q然后在daoManager.startTransaction()执行完以后再提交商业Ҏ?br /><br />那么现在剩下要关心的事情是那个模块负责存储机制的初始化q传递控制给存储机制。在q个例子中,意味着由哪个模块负责将SqlMapConfig.xml的\径传递给SQL Map框架q给它初始化。同h味着哪个模块负责和SQL Maps框架q行实际的交互。DAO框架为每U存储提供了Templatec,在工E中Q可以从q个TemplatecMl承实例c,q只要自qҎ中编写商业事务逻辑。然后将控制传递给q个模板c,它将负责和存储机制的交互。在我们的例子中调用super.queryForObject("getContact",new Integer(contactId))Q意味着SqlMapDaoTemplate负责SQL Maps的初始化和与之交互?br /><br />初始化存储机刉要相关的一些信息,在例子中初始化需要SqlMapConfig.xml的\径,q个文g中包含驱动类的名字、JDBC URL、登陆信息之cȝ信息。这些特定的事务理器需要的信息会在DaoMap.xml文g中作Z个属性元素传递给理器。下一节,我们讨论DAO框架支持哪些事务理器,每个理器需要哪些初始化信息?br /><br /><b><span style="FONT-SIZE: 16px">支持的存储管理机?/span></b><br /><br />DAO框架提供了内|的对一些存储管理机制的支持。ؓ了用其中的一个内|的transactionManagersQ需要做两g事情Q?br />1.在DAOMap.xml中增加一?lt;transactionManager>元素来声明对存储理机制的支持?br />2.在生成DAO实现cȝ时候ؓtransactionManagerl承适当的TemplatecR?br /><br />下面我们要研I内|transactionManagersq找出在应用E序中用如何用它们?br /><br /><b>JDBC</b><br />如果不想使用M存储框架Q不惌己写JDBC代码Q那么JDBC事务理器是很好的选择。如果用JDBC作ؓ存储机制Q则可以使用以下三种q接理之一Q?br /><br />SIMPLEQ如果要使用iBatis'自己的连接池实例Q可以把SIMPLE作ؓDataSource元素的倹{将通常的JDBC属?DriverManagerc, JDBC URLQ等{?传入作ؓProperties。在iBatis在线文档中查看更多的q接属性?br /><b>清单5Q?/b><br /><pre class="overflow"><transactionManager type="JDBC"><br /> <property name="DataSource" value="SIMPLE"/><br /> <property name="JDBC.Driver"<br />  value="com.ibm.db2j.jdbc.DB2jDriver"/><br /> <property name="JDBC.ConnectionURL"<br />  value="jdbc:db2j:D:\cloudscape\wpsdb"/><br /> <property name="JDBC.Username"<br />  value="db2admin"/><br /> <property name="JDBC.Password"<br />  value="db2admin"/><br /> <property name="JDBC.DefaultAutoCommit"<br />  value="true" /><br /></transactionManager></pre><br /><br /><br />DBCPQ用Apache DBCP作ؓq接理。请查看DAO在线指导获得如何配置DBCPq接池的信息?br /><br />JNDIQ当要用应用服务器的连接池Q那么要做的是提供连接池的JNDI名,DAO框架则用这个名U获得一个连接?br /><b>清单6Q?/b><br /><pre class="overflow"><transactionManager type="JDBC"><br /> <property name="DataSource" value="JNDI"/><br /> <property name="DBJndiContext"<br />  value="java:comp/env/jdbc/MyDataSource"/><br /></transactionManager></pre><br /><br /><br />然后要徏立一个类l承JdbcDaoTemplate.java来实C务方法借口。在CZ中,我们建立了JDBCContactDAO.java。在事务Ҏ中,可以调用getConnection()向父c请求连接。因为我们没有用Q何存储框Ӟ所以我们只能徏立ƈ执行我们自己的SQLh?br /><b>清单7Q?/b><br /><pre class="overflow">public int updateContact(Contact contact) {<br /> try {<br />  Connection conn = getConnection();<br />  PreparedStatement updateStmt =<br />   conn.prepareStatement("UPDATE DB2ADMIN.CONTACT<br />    SET FIRSTNAME=?,LASTNAME=? WHERE CONTACTID=?");<br />  updateStmt.setString(1, contact.getFirstName());<br />  updateStmt.setString(2, contact.getLastName());<br />  updateStmt.setInt(3, contact.getContactId());<br />  return updateStmt.executeUpdate();<br /> } catch (SQLException ex) {<br />    throw new DaoException(ex);<br /> }<br />}</pre><br /><br />使用JDBC transactionManager的时候,DAO框架会调用Connection 对象中的commit和rollbackҎ来控制事务处理。所以事务会在Connection层被处理Q而不参与全局事务处理?br /><br /><b>JTA</b><br />如果目是J2EE应用Q那么用应用服务器提供的连接池会更有利Q因为它比SIMPLE 或者DBCP q接池有更好的性能。同LQ用J2EE应用QRDBMS是唯一的处理源Q除了RDBMSq需要包含JCA、MQ Server{功能。因Z能在q接层开始和处理事务Q而要特别的在全局事务处理时在一个UserTransaction对象中调用begin()和commit()Ҏ。所以对于这c请求,可以使用JTA 作ؓtransctionManager,既可以向JNDI URL提供数据源连接池Q也可以在里面包含UserTransaction对象?br /><b>清单8Q?/b><br /><pre class="overflow"><transactionManager type="JTA"><br /> <property name="DBJndiContext"<br />  value="java:comp/env/jdbc/MyDataSource"/><br /> <property name="UserTransaction"<br />  value="java:comp/env/UserTransaction"/><br /></transactionManager></pre><br /><br /><b>Hibernate</b><br />因ؓHibernate是很常见的存储框ӞiBatis DAO也提供了对它的支持。ؓ了在目中用HibernateQ像下面那样在DAOMap.xml增加<transactionManager>元素Q?br /><b>清单9Q?/b><br /><pre class="overflow"><transactionManager type="HIBERNATE"><br /> <property name="hibernate.dialect"<br />  value="net.sf.hibernate.dialect.Cloudscape"/><br /> <property name="hibernate.connection.driver_class"<br />  value="com.ibm.db2j.jdbc.DB2jDriver"/><br /> <property name="hibernate.connection.url"<br />  value="jdbc:db2j:D:\cloudscape\wpsdb"/><br /> <property name="hibernate.connection.username"<br />  value="db2admin/><br /> <property name="hibernate.connection.password"<br />  value="db2admin"/><br /> <property name="class.1"<br />  value="com.sample.contact.Contact"/><br /></transactionManager></pre><br /><br /><br />同样的,需要徏立一个DAOcȝ承HibernateDaoTemplate。在q个DAO内,可以通过调用getSession()Ҏ来获得Hibernate Session对象的入口?br /><br /><b>SQL MAP</b><br />h看示?在资源小节中)了解如何在项目中使用SQL Map存储框架的细节?br /><br /><b>外部理</b><br />外部的事务管理器允许事务处理在外部被DAO框架控制。这U行为有利于处理和非关系数据库数据源的交互。下一节,我们讨论如何用DAO框架处理以XML文g作ؓ数据源的情况?br /><br /><br /><b><span style="FONT-SIZE: 16px">部vxml事务Map</span></b><br /><br />你可能也l常遇到q种情况Q需要从xml中读取数据,而不是从RDBMS中读取,假想你正在从事一个银行项目,你ƈ不能够直接接触到银行的数据库Q所有的用户信息暂时都会通过一个XML文g传输l你Q你必须使用q个XML文gq行开发,开发完毕再部v到真正的使用RDBMS的环境中Q?br />q样的话Q你需要做一下改变:<br /><br />1. 在DAOMap.xml 中增加对外部的transactionManager 的支持?br />2. 新徏一个XMLContactDAO.java文g:<br /><b>清单10Q?/b><br /><pre class="overflow">public class XMLContactDAO implements ContactDAO {<br /> public static final String<br />  CONTACTXMLNAME = "c:\\Contact.xml";<br /> public XMLContactDAO(DaoManager manager) {<br />    super(manager);<br /> }<br /> public int insertContact(Contact contact) {<br />  HashMap contactMap = loadChanges();<br />  if (contactMap.get(new Integer<br />    (contact.getContactId())) == null)<br />   contactMap.put(new<br />    Integer(contact.getContactId()), contact);<br />  saveChanges(contactMap);<br />  return contact.getContactId();<br /> }<br /> public Contact selectContact(int contactId) {<br />  HashMap contactMap = loadChanges();<br />  return (Contact) contactMap.get(<br />   new Integer(contactId));<br /> }<br /> public HashMap loadChanges() {<br />  HashMap contactMap = null;<br />  try {<br />   XStream xstream = new XStream(new DomDriver());<br />   xstream.alias("contact", Contact.class);<br />   contactMap =<br />    (HashMap) xstream.fromXML(<br />     new FileReader(CONTACTXMLNAME),HashMap.class);<br />  } catch (FileNotFoundException e) {<br />    e.printStackTrace();<br />    return new HashMap();<br />  }<br />  return contactMap;<br /> }<br /> public void saveChanges(HashMap contactMap) {<br />  try {<br />   XStream xstream = new XStream();<br />   xstream.alias("contact", Contact.class);<br />   xstream.toXML(contactMap,<br />    new FileWriter(CONTACTXMLNAME));<br />   } catch (IOException e) {<br />   e.printStackTrace();<br />  }<br /> }<br />}</pre><br /><br />q个例子中,XMLContactDAO实现了ContactDAO事务接口。因为我们用了一个EXTERNAL事务理器,所以不能用Q何已l存在的TemplatecR在我们的类中,我们使用XStream框架新徏了两个简单的Ҏ——loadChanges()和saveChanges()——实现对XML文g的读写。XStream是一个开源框Ӟ实现一个XML文g看作一个对象来dQ将对象保存为XML文g的功能?br /><br /><b><span style="FONT-SIZE: 16px">l论</span></b><br />当今Q有很多新的存储框架出现。这对于一个程序员既有好处也有坏处。好处是有更多的选择余地。坏处是因ؓ你必MZ个选择Q更p糕的是不得不在目开始的时候就选择一U框Ӟq就意味着你可能不能完全清楚的了解目的需求,或者不能完全确信这U框架是否能完全满目的需求。DAO是一U容易用ƈ且功能强大的框架能够处理存储机制的改变。你在前期作Z付出Q但是它肯定会在最后对你有帮助的?br /><br /><b><span style="FONT-SIZE: 16px">资源</span></b><br />·Matrix-Java开发者社?<a target="_new">http://www.matrix.org.cn</a><br />·onjava.com:<a target="_new">onjava.com</a><br />·q篇文章的示例代码:Q注Q与译文攑օ同一压羃包中Q?<a target="_new">http://www.onjava.com/onjava/2005/08/10/examples/SampleDAO.zip</a><br />·iBatis主页Q?a target="_new">http://ibatis.apache.org/</a><br />·核心 J2EE 模式Q数据存储对象:<a target="_new">http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html</a><br />·Hibernate主页 (或者CodeZoo: Hibernate) Q?a target="_new">http://www.hibernate.org/</a><br />·使用XStream序列化Java对象Q?a target="_new">http://www.xml.com/pub/a/2004/08/18/xstream.html</a>        <br />·XStream (或?CodeZoo: XStream) Qhttp://xstream.codehaus.org/ ( http://www.codezoo.com/ Qhttp://www.codezoo.com/pub/component/3551 )<br /><br /><b><span style="FONT-SIZE: 16px">关于作?/span></b><br />Sunil Patil对J2EE技术领域的研究过5q时间。他Ҏ兴趣的领域是与对象相关的映射工具、UI框架和Portals<br /><br /><img src ="http://www.aygfsteel.com/realzar/aggbug/49067.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/realzar/" target="_blank">开源爱好?/a> 2006-05-30 17:27 <a href="http://www.aygfsteel.com/realzar/archive/2006/05/30/49067.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring与iBATIS的集?/title><link>http://www.aygfsteel.com/realzar/archive/2006/05/20/47131.html</link><dc:creator>开源爱好?/dc:creator><author>开源爱好?/author><pubDate>Fri, 19 May 2006 16:14:00 GMT</pubDate><guid>http://www.aygfsteel.com/realzar/archive/2006/05/20/47131.html</guid><wfw:comment>http://www.aygfsteel.com/realzar/comments/47131.html</wfw:comment><comments>http://www.aygfsteel.com/realzar/archive/2006/05/20/47131.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/realzar/comments/commentRss/47131.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/realzar/services/trackbacks/47131.html</trackback:ping><description><![CDATA[iBATISg已远M说纷U的OR框架之列Q通常Z寚w常流行的Hibernate情有独钟。但正如Spring: A Developer's Notebook作者Bruce Tate 和Justin Gehtland所说的那样Q与其他的OR框架相比QiBATIS独辟y径:“iBATIS不是试图从根本上掩盖SQLQ实际上Q它是在拥抱SQL。?br /><br />但别犯愁QSQL本n具备了一些重要的功能Qƈ且通过模板的用,在Spring应用中采用iBATIS昑־轻而易举。在此摘录中Q两位作者将和你一起安装iBATISq将光成进你的Spring应用中。他们也阐明了怎样取得你已~写的SQL语句及把他们映射liBATIS使用的Bean。最后,q讨ZiBATIS的优~点Q及Z么是q样的一U方式,x谓的“在完全OR与JDBC之间的一个幽雅的折衷。?br /><br />pDeveloper's Notebook pd中所有的书一P你将q接的且实用的方式获得信息Q这些信息包含了完成你工作所需的细节。换a之:“一切来自实战,没有讲义。?br /><br />作?<a target="_new">czyczy</a><br />原文:<a target="_new">http://www.matrix.org.cn/resource/article/44/44304_Spring+iBATIS.html</a><br />关键?Spring;iBATIS<br /><br /><b><span style="FONT-SIZE: 16px">对象关系持久化(OR PersistenceQ?/span></b><br /><br />本章所涉及的内容ؓQ?br /><span style="COLOR: blue">· 与iBATIS的集?br />· 在Spring的应用中使用JDO<br />· 在Spring的应用中使用Hibernate<br />· q行试用例</span><br /><br />L住处不远的地方,名ؓ啤酒q׃有一个臭名远扬的山地自行车道。我想不出它Z会得到这L名字Q因为在下山的时候你要保持完全地清醒甚至于全诏注。据我所知,那决不是Ua的攀爬(或不曄开自行车步行)。大多数为那很荒谬,哪怕只是去试一下而已。这座山q起伏Q异帔R峭,它的表面覆盖了松散的岩石和大量的岩脊。我x一定是太厌烦我的余生了Q因Zq半来我一直不断地在攀爬。在我看来,那样的一座山峰就像是一个困隄~程问题。我已多ơ重新启E,在到辑ֱ峰的途中Q尝试过越许多岩脊和惔砾丛的不同途径。ؓ了攀爬啤酒山Q?我需要改良自行RQ提高R技Q加l?br /><br />对Java 开发h员而言Q对象关pL已然成为那c问题了。我们需要处理功能(processing powerQ、较佌计模式及更好持久化框架的l合Q从而解决持久化设计变得更加清晰。最l,我们开始取得实质性的q展。现在,我们已D山峰Q象Springq样的框架就象是方程式的一部分Q因Z们让对象关系映射QORMQ花较少的精力来做更多的事情。在本章中,你将看到三种框架QiBATIS, JDO及Hibernate:<br /><br />·iBATIS 是一UJDBC助手cLӞ它给了你一些OR映射及用OR的好处,但不?有太多的风险?br />·JDO是一U饱受争议的持久化标准,但它有着一些独特的实现Q这使得JDO在行业中也算得上是最完美的持久化框架之一?br />·Hibernate 是在JBossl织控制下的一开源持久化框架。它可能是时下最为流行的持久化框架。大量的客户采用它,而且客户的数量还在持l稳定地增长。       ?br /><br />在本章中Q我们会Ҏ提的三个框架q行试Q而不必对应用的其余部分的代码做Q何变更?br /><br /><span style="FONT-SIZE: 6px">与iBATIS集成</span><br /><br />常言?“树大招风”。在大肆宣扬的J2EE?Net之争? Sun的一CZ应用E序被用来作量应用服务器在运行时的各Ҏ能的核心基准?.Net非常好地打|了基于EJB的J2EE版本, 且方兴未艾。Clinton Begin 开发了iBATIS的持久化框架Q他在iBATIS中用PetStore的简化版Q且自从那以后iBATISp来越行。Spring提供非常优良的与iBATIS的集成功能, 在此章中对其进行介l?br /><br />q所有的问题都非帔R合持久化框架这늛开的花朵,中等隑ֺ的问题是最合适的环境。没有正的技巧或不相U的问题Q可能就会误入歧途。跟我一h评Ted NewardQ?他是《Effective Enterprise Java》一书的作者,他经常把构徏或采用持久化框架与美国的南战争拿来做比较,q入q样的两场战争是很诱人的Q但最l都很难赢得胜利Q而且此二例中q不存在着行之有效的策略。关于这一话题Q你仍可查阅http://www.neward.net上的相关内容?br /><br />然而,我不x得太q。尝试一下象iBATIS SqlMaps的框架给了你OR的用模型又何尝不可呢?当然Q我们不会强q你一口吞下一只大象。具体来_iBATIS让你Q?br />·映射字段和SQL语句到关键字<br />·使用SQL的全部功能而没有乏味的JDBC<br />·从你的代码中剥离SQL<br />Spring 与iBATIS的集成给了你q些及更多的裨益Q?让我们ؓ此而忙乎v来?br /><br /><b>我该怎么做?</b><br /><br /><br />首先Q你需要安装iBATIS。由于iBATIS的配|会在你的Spring 应用上下文中完成Q因此你不需要立即配|它。在http://www.ibatis.com/(译注Q最新的|址为:http://ibatis.apache.org/QiBATIS已于2004-08-16q入Apache 软g基金?上可以下载ƈ安装。在本书中我们?.3.1版本。把iBATIS提供的jars(ibatis-sqlmap.jar, ibatis-dao.jar, and ibatis-common.jar)和Spring提供的jdom.jar(在Spring?lib 目录?攑ֈ你的目目录/war/WEB-INF/lib中?br /><br />You’ve already got the interface for the fa&ccedil;ade and the model, so you need an implementation of the fa&ccedil;ade and the SQL statement.  First, you can implement the fa&ccedil;ade for the application, as in Example 5-1.<br />你已l有了门Pfa&ccedil;adeQ和模型Qmodel)的接口,因而你需要facade和SQL语句的实现。首先,你可以象CZ5-1那样Q在你的应用中实现fa&ccedil;ade的接口?br /><br /><b>CZ 5-1 IBatisRentABike.java</b><br /><br /><pre class="overflow">public class IBatisRentABike extends SqlMapDaoSupport<br />                 implements RentABike {<br /><br />        private String storeName ="";<br /><br />        public void setStoreName(String storeName) {<br />                this.storeName= storeName;<br />        }<br /><br />        public String getStoreName( ) {<br />                return this.storeName;<br />        }<br /><br />        public List getBikes() {<br />                return getSqlMapTemplate().executeQueryForList("getBikes", null);<br />        }<br /><br />        public Bike getBike(String serialNo) {<br />                return (Bike) getSqlMapTemplate().<br />                        executeQueryForObject("getBikeBySerialNo", serialNo);<br />        }<br /><br />        public Bike getBike(int bikeId) {<br />                return (Bike) getSqlMapTemplate().<br />                        executeQueryForObject("getBikeByID", new Integer(bikeId));<br />        }<br /><br />        public void saveBike(Bike bike) {<br />                getSqlMapTemplate().executeUpdate("saveBike", bike);<br />        }<br /><br />        public void deleteBike(Bike bike) {<br />                getSqlMapTemplate().executeUpdate("deleteBike", bike);<br />        }<br /><br />        public List getCustomers() {<br />                return getSqlMapTemplate().executeQueryForList("getCustomers", null);<br />        }<br /><br />        public Customer getCustomer(int custId) {<br />                return (Customer) getSqlMapTemplate().<br />                    executeQueryForObject("getCustomer", new Integer(custId));<br />        }<br />        <br />        public List getReservations() {<br />                return getSqlMaptemplate().<br />                    executeQueryForList("getReservations", null);<br />        }<br /><br />        public List getReservations(Customer customer) {<br />                return getSqlMaptemplate().<br />                    executeQueryForList("getReservationsForCustomer", customer);<br />        }<br /><br />        public List getReservations(Bike bike) {<br />                return getSqlMaptemplate().<br />                    executeQueryForList("getReservationsForBike",bike);<br />        }<br /><br />        public List getReservations(Date date) {<br />                return getSqlMaptemplate().<br />                    executeQueryForList("getReservationsForDate", date);<br />        }<br /><br />        public Reservation getReservation(int resId) {<br />                return getSqlMaptemplate().<br />                    executeQueryForObject("getReservation", new Integer(resId));<br />        }<br />}</pre><br /><br />q些是命名式查询。iBATIS每一查询分成一个独立的映射Q那样你可以用名字来执行查询?br /><br />SqlMapTemplate由Spring的SqlMapDaoSupport cL供,我们的RentABike实现必须来承这个类。SqlMapTemplate负责建立和管理底层数据存储的q接Q同时也解释了你所提供的映文件。你可以把template 看成是你对于iBATIS命名式查询所做那些事情的默认实现?<br /><br />你也需要创建SQL语句Q可以给每条SQL语句取一个名字。然后,把结果映给Java Bean。在q里你有两种选择Q你可以在SQL中把每个Bean属性作为别名来引用Q或在查询和Bean 之间建立昑ּ映射Q就象示?-2那样。在此例中我们也建立了Customer 与Reservation的映?br /><br /><b>CZ5-2.  Bike.xmlQiBATIS SQL 映射文gQ?/b><br /><pre class="overflow"><?xml version="1.0" encoding="UTF-8" ?><br /><br /><br /><sql-map name="Bike" ><br />    <result-map name="result" class="com.springbook.Bike" ><br />       <property name="bikeId" column="bikeId" columnIndex="1" /><br />       <property name="manufacturer" column="manufacturer" columnIndex="2" /><br />       <property name="model" column="model" columnIndex="3" /><br />       <property name="frame" column="frame" columnIndex="4" /><br />       <property name="serialNo" column="serialNo" columnIndex="5" /><br />       <property name="weight" column="weight" columnIndex="6" /><br />       <property name="status" column="status" columnIndex="7" /><br />    </result-map><br />    <br />    <mapped-statement name="getBikes" result-map="result"><br />        select bikeId, manufacturer, model, frame, serialNo, status<br />        from bikes<br />    </mapped-statement><br /><br />    <mapped-statement name="getBikeBySerialNo" result-map="result"><br />        select bikeId, manufacturer, model, frame, serialNo, status<br />        from bikes<br />       where serialNo=#value#<br />    </mapped-statement><br /><br />    <mapped-statement name="getBikeByID" result-map="result"><br />        select bikeId, manufacturer, model, frame, serialNo, weight, status<br />        from bikes<br />        where bikeId=#value#<br />    </mapped-statement><br /><br />    <mapped-statement name="saveBike" ><br />        insert into bikes<br />        (bikeId, manufacturer, model, frame, serialNo, weight, status)<br />        values(#bikeId#, #manufacturer#, #model#, #frame#, #serialNo#, <br />        #weight#, #status#)<br />    </mapped-statement><br /><br />    <mapped-statement name="deleteBike" ><br />        delete from bikes <br />        where bikeId = #bikeId#<br />    </mapped-statement><br /></sql-map></pre><br /><br /><b>CZ5-3. Customer.xml </b><br /><pre class="overflow"><?xml version="1.0" encoding="UTF-8" ?><br /><br /><br /><sql-map name="Customer" ><br />    <result-map name="result" class="com.springbook.Customer" ><br />       <property name="custId" column="custId" columnIndex="1" /><br />       <property name="firstName" column="firstName" columnIndex="2" /><br />       <property name="lastName" column="lastName" columnIndex="3" /><br />    </result-map><br />    <br />    <mapped-statement name="getCustomers" result-map="result"><br />            select custId, <br />                    firstName,<br />                    lastName<br />             from customers<br />    </mapped-statement><br /><br />    <mapped-statement name="getCustomer" result-map="result"><br />            select custId, <br />                    firstName,<br />                    lastName<br />            from customers<br />            where custId = #value#<br />    </mapped-statement><br /></sql-map></pre><br /><br /><b>CZ 5-4. Reservation.xml</b><br /><pre class="overflow"><?xml version="1.0" encoding="UTF-8" ?><br /><br /><br /><sql-map name="Reservation" ><br />    <result-map name="result" class="com.springbook.Customer" ><br />       <property name="reservationId" column="resId" columnIndex="1" /><br />       <property name="bike" column="bikeId" columnIndex="2" /><br />       <property name="customer" column="custId" columnIndex="3" /><br />       <property name="reservationDate" column="resDate" columnIndex="4" /><br />    </result-map><br />    <br />    <mapped-statement name="getReservations" result-map="result"><br />            select resId, <br />                   bikeId,<br />                              custId,<br />                              resDate           <br />             from reservations<br />    </mapped-statement><br /><br />    <mapped-statement name="getReservationsForCustomer" result-map="result"><br />            select resId, <br />                   bikeId,<br />                              custId,<br />                              resDate           <br />             from reservations<br />             where custId = #value#<br />    </mapped-statement><br /><br />    <mapped-statement name="getReservationsForBike" result-map="result"><br />            select resId, <br />                   bikeId,<br />                              custId,<br />                              resDate           <br />             from reservations<br />             where bikeId = #value#<br />    </mapped-statement><br /><br />    <mapped-statement name="getReservationsForDate" result-map="result"><br />            select resId, <br />                   bikeId,<br />                              custId,<br />                              resDate           <br />             from reservations<br />             where resDate = #value#<br />    </mapped-statement><br /><br />    <mapped-statement name="getReservation" result-map="result"><br />            select resId, <br />                   bikeId,<br />                              custId,<br />                              resDate           <br />             from reservations<br />             where resId = #value#<br />    </mapped-statement><br /></sql-map></pre><br /><br />The <result-map> portion provides an explicit map between columns in the database and properties of a persistent class.  The <mapped-statement> can then simply define the SQL queries necessary to execute the needed functionality, and the map handles creation of the resultant Java object.  In addition to the Bike version above, your application currently also requires a map for Customer and Reservation.<br /><result-map>部分提供了数据库字段与持久化cd性之间的一昑ּ映射?lt;mapped-statement>接着可以单定义运行所需功能的必要的SQL查询Q而映负责创建合成的Java 对象。除了上q的Bike 版本之外Q你的应用程序目前也需要一个关于Customer 和Reservation的映?br /><br />你将不得不做一些OR框架通常为我们所做的z,如创建标识符。在此例中,你将使用MySQL生成的序列(是数据库表中的那些AUTO_INCREMENT字段Q。你只需在数据库表定义时单地把bikeId标ؓAUTO_INCREMENTQ这样当增加一条新记录Ӟ你就可以在SQL语句中略qbikeId字段。我们映中SaveBike语句成了示?-5?br /><br /><b>CZ5-5. Bike.xml </b><br /><pre class="overflow">    <mapped-statement name="saveBike" ><br />        insert into bikes<br />        (manufacturer, model, frame, serialNo, weight, status)<br />        values(#manufacturer#, #model#, #frame#, #serialNo#, #weight#,<br />        #status#)<br />    </mapped-statement></pre><br /><br />若你是在使用Oracle, Spring和iBATIS也支持Oracle生成的序列?br /><br />下一步,你可以更新应用上下文Q且需要列出我们的新fa&ccedil;adeQ而fa&ccedil;ade要有SQL映射。把SQL 引入PROPERTIES 文gQ就象我们对待JDBC 的参C栗?此外Q你q需要配|事务策略? CZ5-6)<br /><br /><b>CZ5-6. .RentABikeApp-servlet.xml</b><br /><pre class="overflow"><beans><br /><bean id="dataSource"<br />class="org.springframework.jdbc.datasource.DriverManagerDataSource"><br /><property name="driverClassName"><br /><value>com.mysql.jdbc.Driver</value><br /></property><br /><property name="url"><br /><value>jdbc:mysql://localhost/bikestore</value><br /></property><br /><property name="username"><br /><value>bikestore</value><br /></property><br /></bean><br /><bean id="rentaBike" class="com.springbook.IBatisRentABike"><br /><property name="storeName"><value>Bruce's Bikes</value></property><br /><property name="dataSource"><ref local="dataSource"/></property><br /><property name="sqlMap"><ref local="sqlMap"/></property><br /></bean><br /><bean id="sqlMap"<br />class="org.springframework.orm.ibatis.SqlMapFactoryBean"><br /><property name="configLocation"><br /><value>/WEB-INF/ibatis.config</value><br /></property><br /></bean><br /><bean id="transactionManager"<br />class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><br /><property name="dataSource"><ref local="dataSource"/></property><br /></bean></pre><br /><br />q个事务{略在应用上下文中Q你不必来管理提交适宜Q因为Spring 会ؓ你完成。你在W六章中更完整地探讨事务{略。                                               ?br /><br /><b>CZ5-7. . ibatis.config</b><br /><pre class="overflow"><?xml version="1.0" encoding="UTF-8"?><br /><br /><sql-map-config><br /><sql-map resource="Bike.xml" /><br /><sql-map resource="Customer.xml" /><br /><sql-map resource="Reservation.xml" /><br /></sql-map-config></pre><br /><br />E后我们会谈C务策略?br /><br /><b>发生了什么事?</b><br /><br />你没看到OR映射。OR框架会有意地一个数据库表与一个类或多个类兌h。在此例中,iBATIS会将查询l果赋予一个类。这意味着iBATISq未试图对你隐藏SQLl节。实际上Q它是在拥抱SQL?br /><br />Spring打算通过模板来简化iBATIS的用。iBATIS模板会给出类似JDBC模板的用模型,你只需指定数据源和iBATIS映射的SQL语句?br /><br />当执行SQL语句ӞSpring与iBATIS一起ؓ你管理资源,q按要求来创建和关闭q接。Spring会把映射的SQL语句传给iBATIS, 由iBATIS来运行映的语句Q且若需要,iBATIS会把l果集传l给你映SQL语句时所指定的Bean。如果你已有了Q何参敎ͼ那就可将那些l果集放入hash map中ƈ把结果集传给带有映射的SQL语句的模ѝ?br /><br />然而,从内部所表现的来看,iBATIS或许q不象是一个OR框架Q但使用模型的确有OR的趋向?构徏带有操作数据存储的数据访问对象(data access objectQ,你不会在代码中看到SQL语句Q因为它已被保存在配|文件中了,且iBATIS使用对象集合而不是结果集。简而言之,q是在全部OR与JDBC之间的一个幽雅的折衷?br /><br /><b>关于?/b><br /><br />一切都适合iBATIS吗? ׃q种使用模型与OR模型是那么的怼Q且许多应用对他们可能生成的SQL需要有更多的控Ӟ或许你們֐于普遍地使用iBATIS。尽如此,象JDO和Hibernate的OR框架仍拥有着属于自己的舞台。OR框架l了你更多的灉|性和更强大的功能Q?br />·一些高U的对象模型D了非常复杂的SQLQ把q些复杂的SQL交由ORM来完成是最好的处理方式?例如Q扉K常使得原始的JDBC API操作变得更ؓ复杂?br />·一些高U的性能特征Q象延迟加蝲和数据抓取群l,要求Ҏ效地的自动控刉要一个更正式的模型。然而,完美C化后的JDBC臛_要和ORM一样快速。相对于使用原始的JDBC而言Q由ORM提供的性能优化选项Ҏ些类型的问题更获得较x能?br />·ORM使某些问题变得更加有。操作对象比创徏一套的SQL查询更加易。ORM很适合带有单的查找Q创建,更新Q根据主键读取数据库中的数据以及删除记录的应用?br /><br />如若你的应用有快速的数据模型和对象模型的变更QiBATIS׃很适合。如果你有了CRUDcd的应用,那么Q用iBATIS可能׃有点乏味。相反地Q如果你正寻找一U好的SQL讉K方式及在ORM和原始的JDBC间有效的折衷Q那么,iBATIS可能׃l了你所需的一切?br /><img src ="http://www.aygfsteel.com/realzar/aggbug/47131.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/realzar/" target="_blank">开源爱好?/a> 2006-05-20 00:14 <a href="http://www.aygfsteel.com/realzar/archive/2006/05/20/47131.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ZiBatis的通用持久层对?/title><link>http://www.aygfsteel.com/realzar/archive/2006/05/20/47130.html</link><dc:creator>开源爱好?/dc:creator><author>开源爱好?/author><pubDate>Fri, 19 May 2006 16:13:00 GMT</pubDate><guid>http://www.aygfsteel.com/realzar/archive/2006/05/20/47130.html</guid><wfw:comment>http://www.aygfsteel.com/realzar/comments/47130.html</wfw:comment><comments>http://www.aygfsteel.com/realzar/archive/2006/05/20/47130.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/realzar/comments/commentRss/47130.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/realzar/services/trackbacks/47130.html</trackback:ping><description><![CDATA[ <strong>ibatis介绍<br /></strong>  使用ibatis 提供的ORM机制Q对业务逻辑实现人员而言Q面对的是纯_的Java对象Q?q一层与通过Hibernate 实现ORM 而言基本一_而对于具体的数据操作QHibernate 会自动生成SQL 语句Q而ibatis 则要求开发者编写具体的SQL 语句。相对Hibernate{?“全自动”ORM机制而言Qibatis 以SQL开发的工作量和数据库移植性上的让步,为系l?设计提供了更大的自由I间。作为“全自动”ORM 实现的一U有益补充,ibatis 的出现显 得别h义?br /><br />作?<a target="_new">fellow99</a><br />原文:<a target="_new">http://www.matrix.org.cn/resource/article/44/44410_iBatis.html</a><br />关键?iBatis;ORM<br /><br /><b>一、ؓ什么要设计“通用”的东西</b><br />  在大多数时候,我们所需要的持久层对象(POQ大多都是一张表Qor视图Q对应一个类。按照Hibernate的思想Q就是抛开数据库的束缚Q把焦点集中C务对象中。而很多自动化工具的确让做C通过表结构生成对应的对象Qor通过对象自动生成表。对于小目来说Q一切都是简单的Q对于有规范设计的项目来_PO的设计也不是一件困隄工作。但是对于那些业务变动频J的目来说Q改动PO可能成了一件很J重的工作。试想一下,假设某个表需要增加一个字D:对于HibernateQor iBaitsQ,首先要改配置文gQ然后POQ然后DAOQ也许没有)Q然后业务逻辑Q然后JOQ然后界面,etcQ诏通了全部层次?br />  恩,写程序的都不喜欢q些重复力_Q但是做企业U应用的谁不是每天在q些工作中打滚?br />  研究qiBaits以后Q发现有些通用的方法可以解冻I是设计一个通用的持久层对象?br /><br /><b>二、基于什么技?/b><br />  iBatis可以使用Map对象作ؓPOQHibernate好像也有相关的功能(我没有细看,不确定)?br />  iBatis执行一条指令的q程大概是这LQ?br /><br /><img height="333" alt="111.JPG" src="http://www.aygfsteel.com/images/blogjava_net/realzar/ibatis/111.JPG" width="532" border="0" /><br /><br />其中圈圈1??描述了iBatis最重要的三个对象?br /><br />圈圈1Qstatement单来说就是存储sql语句的配|信息,一个最单的statementQ?br /><pre class="overflow"><br /><statement id=”insertTestProduct?><br />    insert into PRODUCT (PRD_ID, PRD_DESCRIPTION) values (1, “Shih Tzu?<br /></statement><br /></pre><br />其中id属性是q个statement的唯一标识Q全局不能重复?br /><br />以上当然是最单的了,没有参数也不需要返回|但实际情况下基本都需要传入参敎ͼ下面是介绍参数?br /><br />圈圈2Q参数对象主要分两种cdQparameterMap、parameterClass和Inline Parameter?br /><br />  其中parameterMap是配|文件定义传入参数表Q如下:<br /><pre class="overflow"><br /><parameterMap id=”insert-product-param?class=”com.domain.Product?gt;<br /><br /></parameterMap><br />    <statement id=”insertProduct?parameterMap=”insert-product-param?gt;<br />        insert into PRODUCT (PRD_ID, PRD_DESCRIPTION) values (?,?);<br />    </statement><br /></pre><br />  而parameterClass是传入参数对象(JavaBeanQ,如下Q?br /><pre class="overflow"><br /><statement id=”statementName?parameterClass=?examples.domain.Product?gt;<br />    insert into PRODUCT values (#id#, #description#, #price#)<br /></statement><br /></pre><br />  Inline Parameter则是强化版的parameterClassQ如下:<br /><pre class="overflow"><br /> <statement id=”insertProduct?parameterClass=”com.domain.Product?gt;<br />    insert into PRODUCT (PRD_ID, PRD_DESCRIPTION)<br />        values (#id:NUMERIC:-999999#, #description:VARCHAR:NO_ENTRY#);<br /></statement><br /></pre><br />  其中W一U方法看着复杂,实际是ؓ了兼容老版本留下来的,所以parameterClass是我们最常用的方法。官Ҏ档对parameterClass介绍很详l,因ؓq是核心之一Q具体请自己查阅。有3个特性说明一下:<br /><br />  a. parameterClass对象可以传入一个Map对象Qor Map子类Q。本来如果是传入JavaBeanQ程序会通过get/set来分析取得参敎ͼ而Map是key-valuel构的,那程序会直接通过key来分析取参数?br /><br />  b. 看以下语句:<br /><pre class="overflow"><br /><statement id=”statementName?parameterClass=?examples.domain.Product?gt;<br />    insert into PRODUCT values (#id#, #description#, #price#, #classify.id#)<br /></statement><br /></pre><br />  蓝色部分#classify.id#译q来实际是product.getClassify().getId()Qclassify是Product对象的一个子对象?br /><br />  c. 在模板sql语句中除了?”以外,q有?”,它们两代表的意思当然不同了Q?br /><pre class="overflow"><br /><statement id=”getProduct?resultMap=”get-product-result?gt;<br />    select * from PRODUCT order by $preferredOrder$<br /></statement><br /></pre><br />  ?”在生成sql语句的过E中Q会变成?”,同时在参数表中增加一个参敎ͼ<br /><br />  ?”则会直接替换成参数对象对应的|例如上面的preferredOrder的值可能是“price”,则生成的sql语句是Qselect * from PRODUCT order by price?br /><br />  *需要特别说明的是传入参数这一部分会是后面正题“通用持久层对象”的核心Q怎么个通用法,怎么设计模板sql语句Q都是在q部分上?br /><br /><br /><br />圈圈3Q结果对象跟参数对象差不多,也有两种QresultMap和resultClassQ如下:<br /><br />  resultMap是配置文g中预定义了要取得的字D:<br /><pre class="overflow"><br /><resultMap id=”get-product-result?class=”com.ibatis.example.Product?gt;<br />    <result property=”id?column=”PRD_ID?><br />    <result property=”description?column=”PRD_DESCRIPTION?><br /></resultMap><br /><statement id=”getProduct?resultMap=”get-product-result?gt;<br />    select * from PRODUCT<br /></statement><br /></pre><br />  resultClass则是通过分析q回的字D,来填充结果对象:<br /><pre class="overflow"><br /><statement id="getPerson" parameterClass=”int?resultClass="examples.domain.Person"><br />    SELECT PER_ID as id, PER_FIRST_NAME as firstName <br />        FROM PERSON WHERE PER_ID = #value#<br /></statement><br /></pre><br />  跟参数对象相反,l果对象一般用resultMap形式。引用官方的话:使用resultClass的自动映存在一些限Ӟ无法指定输出字段的数据类型(如果需要的话)Q无法自动装入相关的数据Q复杂属性)Qƈ且因为需要ResultSetMetaData的信息,会对性能有轻微的不利影响。但使用resultMapQ这些限刉可以很容易解冟?br /><br /><br /><b>三、正题来了,怎么做“通用持久层对象?/b><br /><br />1. 表结构:<br /><br />  每个表都必须包含两个字段Qid和parentIdQ其他字D|照需求来定义Q其他各U烦引、约束、关pMcȝ也按需求定义?br /><br />2. 通用的持久层对象QCustomPOQ?br /><pre class="overflow"><br />public class CustomPO {<br />    protected String moduleTable;  //该PO对应的表名(视图名)<br />    protected int id;  //表的id<br />    protected int parentID;  //父表的idQ如果有的话Q?br />    protected Map fieldMap;  //字段MapQ核心,用于存储字段及其?br />    public String getModuleTable()<br />    public void setModuleTable(String moduleTable)<br />    public int getId()<br />    public void setId(int id) <br />    public int getParentID() <br />    public void setParentID(int parentID) <br />    public Map getFieldMap()<br />    public void setFieldMap(Map fieldMap)<br />    public void copyFieldMap(Map fieldMap)<br />    //取得字段名列?br />    public List getFieldList()<br />    //讄字段名列表。如果fieldMap没有相应的字D,则增加,字段gؓnullQ如果有则不增加?br />    public void setFieldList(List fieldList)<br />    //q回字段的“字D名 - 字段值”列表,使用com.fellow.pub.util.KeyValuePair对象作ؓ存储<br />    public List getFieldValueList()<br />}<br /></pre><br />  那些成员变量的get/set没什么说的,主要说说getFieldValueList()q个Ҏ。该Ҏq回一个列表,列表元素是一个key-valuel构Q简单来说就是把字段map序列化。在构造模板sql语句时会体现它的用途?br /><br />3. iBatis对象配置文gCustomPO.xmlQ?br /><pre class="overflow"><br /><sqlMap namespace="CustomPO"><br />  <!--定义别名--><br />  <typeAlias alias="customPO" type="com.fellow.component.customPO.CustomPO"/><br />    <!--<br />        通过id查找<br />        特点Qiterateq个fieldList列表Q生成要输出的字D?br />    --><br />  <select id="customPO_findByID" resultClass="java.util.HashMap" parameterClass="customPO"><br />    SELECT id, parentID<br />      <iterate property="fieldList" conjunction=","><br />        $fieldList[]$<br />      </iterate><br />     FROM $moduleTable$ WHERE id = #id#<br />  </select><br />  <br />    <!--<br />        插入一条新U录<br />        特点Qiterateq个fieldValueList列表Q分别取得其元素的key和value?br />        注意$号和#L使用ҎQ还有最后怎么取得insert后的id|各种数据库都可能不同Q?br />    --><br />  <insert id="customPO_insert" parameterClass="customPO"><br />    INSERT INTO $moduleTable$ (parentID<br />      <iterate property="fieldValueList" prepend="," conjunction=","><br />        $fieldValueList[].key$<br />      </iterate><br />      )<br />    VALUES (#parentID#<br />      <iterate property="fieldValueList" prepend="," conjunction=","><br />        #fieldValueList[].value#<br />      </iterate><br />      )<br />    <selectKey resultClass="int" keyProperty="id"><br />      SELECT last_insert_id()<br />    </selectKey><br />  </insert><br /><br />    <!--<br />        更新一条纪?br />        特点Qiterateq个fieldValueList列表Q分别取得其元素的key和value?br />        注意$号和#L使用Ҏ<br />    --><br />  <update id="customPO_update" parameterClass="customPO"><br />    UPDATE $moduleTable$ SET<br />      <iterate property="fieldValueList" conjunction=","><br />        $fieldValueList[].key$ = #fieldValueList[].value#<br />      </iterate><br />     WHERE id = #id#<br />  </update><br /><br />    <!--删除一条纪?-><br />  <delete id="customPO_delete" parameterClass="customPO"><br />    DELETE FROM $moduleTable$ WHERE id = #id#<br />  </delete><br /></pre><br />  要注意的地方如下Q?br /><br />  a. 跟一般的ibatis配置文g不一P该配|中没有包含resultMapQ用的是resultClass的方式(效率没那么高的那U)。当Ӟ也可以用resultMapQ这样就要ؓ每个表写自己的配|文件了。因此,在该设计没完成前Q我暂时先用resultClass的方式?br /><br />  b. 上面只列举了最单的增删改以及按id查询Qƈ没有更复杂的查询Qؓ什么呢Q因为我q在研究中。。。研I用的模板sql的写法?br /><br />4. CustomPO对应的DAOQ?br /><br />  我用了ibaits提供的DAO框架Q很好用Q不单支持ibatis的框Ӟq支持Hibernate、JDBC{等Q而且是与ibatis本n独立的,完全可以单独使用。以后就不用自己写DAO框架了。一下是该DAO接口Q?br /><pre class="overflow"><br />public interface ICustomDAO {<br />    /**<br />     * 通过传入moduleTable和id取得一条记?br />     */<br />    CustomPO findByID(String moduleTable, int id) throws Exception;<br /><br />    /**<br />     * 通过传入CustomPO对象取得一条记?br />     * @param po CustomPO 该对象在传入前应该先讄moduleTable和id参数Q?br />     * q且使用setFieldList()函数讄字段列表Q该讄军_所q回的字D)?br />     */<br />    CustomPO findByID(CustomPO po) throws Exception;<br /><br />    /**<br />     * 通过传入moduleTable和parentID取得一条记?br />     */<br />    CustomPO findByParentID(String moduleTable, int parentID) throws Exception;<br /><br />    /**<br />     * 通过传入CustomPO对象插入一条记?br />     * @param po CustomPO 该对象在传入前应该先讄moduleTable和id参数Q?br />     * q且使用setFieldMap()函数讄“字D?值”对?br />     */<br />    void insert(CustomPO po) throws Exception;<br /><br />    /**<br />     * 通过传入CustomPO对象更新一条记?br />     * @param po CustomPO 该对象在传入前应该先讄moduleTable和id参数Q?br />     * q且使用setFieldMap()函数讄“字D?值”对?br />     */<br />    void update(CustomPO po) throws Exception;<br /><br />    /**<br />     * 删除moduleTable和id所对应的记?br />     */<br />    void delete(String moduleTable, int id) throws Exception;<br />}<br /></pre><br />  我没有把所有的Ҏ都列出来Q反正挺单的Q跟一般的DAO没什么分别?br /><br />  另外列几个实现的片断Q?br /><br />  a. l一的数据装填函敎ͼ需要手工把id和parentID字段L?br /><pre class="overflow"><br />    protected void fill(Map result, CustomPO po) {<br />        Long returnId = (Long) result.get("id");<br />        Long returnParentID = (Long) result.get("parentID");<br />        result.remove("id");<br />        result.remove("parentID");<br />        if (returnId != null) po.setId(returnId.intValue());<br />        if (returnParentID != null) po.setParentID(returnParentID.intValue());<br />        po.setFieldMap(result);<br />    }<br /></pre><br />  b. 一般的查询Q返回的是一个mapQ然后再用fill()函数<br /><pre class="overflow"><br />    //查询<br />     Map result = (Map)this.queryForObject("customPO_findByID", po);<br /><br />    //处理q回l果<br />    if(result == null)<br />        po = null;<br />    else<br />        fill(result, po);<br /></pre><br />  c. 增删改,没有q回|值得一提的是增加操作完成后Qpo里面的id会更斎ͼ具体看前面相关的statement?br /><pre class="overflow"><br />    //增删?br />    this.insert("customPO_insert", po);<br />    this.update("customPO_update", po);<br />    this.delete("customPO_delete", po);<br /></pre><br /><br />5. 前面是通用的部分,光是通用是不够的。因此我另外建立了一套配|文Ӟ记录字段对应关系。看看我所定义的一个配|文Ӟ挺简单的Q?br /><pre class="overflow"><br /><struct name="userInfo" table-name="tblUserInfo"><br />    <field name="늧" column="NICK_NAME" type="string" not-null="true" unique="false" /><br />    <field name="姓名" column="FULL_NAME" type="string" not-null="true" unique="false" /><br />    <field name="性别" column="SEX" type="string" not-null="false" unique="false" /><br />    。。?br /></struct><br /></pre><br />  其中Qname是字D名Qcolumn是字D对应数据表的字D名Qtype是字D늱型,not-null是是否不能ؓI,unique是是否唯一。只有nameq个属性是必填的,column如果不填默认与name相等Qtype默认为stringQnot-null和unique默认为false?br /><br />  配置文g的读取类在这里就省略了?br /><br />  Z么要自己定义一套这个框Ӟ好像挺多此一丄Q但是没办法Qibatis配置文g的信息是闭的,我无法取得。另外我考虑的是Q?br />  a. viewer层:在web开发中Q我可以在这套配|框架的基础上,建立自己的标{,实现数据自动l定的功能;GUI开发中也可以做相应的功能?br />  b. module层:可以做通用的业务操作,不需要ؓ每个业务都都做独立的业务逻辑?br /><br /><b>四、有什么优炏V缺?/b><br /><br />1. 优点Q?br /> a. “通用”,一切都是ؓ了通用Qؓ了减重复劳动,一个个目面对不同的业务,其实说到底都是那些操作。各U持久成框架已经带给我们不少的方便,但是在实际业务逻辑的处理上好像q没有一个这L框架?br /> b. 极大地减代码量。前面说了,数据库改一个字D,PO、DAO、module、JO、viewer、validator全都要改一遍。用了q套东西Q可以把l大部分的劳动都攑֜配置文g和UI上。当Ӟq是完美的设惻I对于很多情况Q业务逻辑q是要手工写的?br /> c. 好像没有c了?br /><br />2. ~点Q?br /> a. 通常通用的东襉K~Z灉|性,在我的实际应用中也发Cq样那样的问题,解决Ҏ都是以通用为基本原则。但是如果针对的是某个项目,那就可以针对业务来修改了?br /> b. 性能问题。因Z用resultClassQ按照文档所说的Q性能没有resultMap好。当然也可以使用resultMapQ如前所_pҎ个PO写配|文件了Q工作量也不?br /> c. 也好像没有c了?br /><br /><b>五、后?/b><br />  我L喜欢写一些通用的东西,Lx它设计成万能的。但是经q多ơ失败ȝ出来Q我发现通用的东西在很多情况下都{于不能用。但我就是喜Ƣ往通用斚w惻Iq个毛病不知道什么时候才能改得了。其实在Delphiq_中,我早实C相关的东西,但是用delphiL限制于ADO+Data Moduleq样掉牙的模式。现在{向javaQ发现有ibatis、hibernateq么多好的持久层框架Q自然有UL必要了?br /><img src ="http://www.aygfsteel.com/realzar/aggbug/47130.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/realzar/" target="_blank">开源爱好?/a> 2006-05-20 00:13 <a href="http://www.aygfsteel.com/realzar/archive/2006/05/20/47130.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>UML-JpetStore专题http://www.aygfsteel.com/realzar/archive/2006/05/16/46363.html开源爱好?/dc:creator>开源爱好?/author>Tue, 16 May 2006 03:25:00 GMThttp://www.aygfsteel.com/realzar/archive/2006/05/16/46363.htmlhttp://www.aygfsteel.com/realzar/comments/46363.htmlhttp://www.aygfsteel.com/realzar/archive/2006/05/16/46363.html#Feedback0http://www.aygfsteel.com/realzar/comments/commentRss/46363.htmlhttp://www.aygfsteel.com/realzar/services/trackbacks/46363.htmlUML-JpetStore专题

]]>
ibatis开发h员指?一)http://www.aygfsteel.com/realzar/archive/2006/05/16/46356.html开源爱好?/dc:creator>开源爱好?/author>Tue, 16 May 2006 03:08:00 GMThttp://www.aygfsteel.com/realzar/archive/2006/05/16/46356.htmlhttp://www.aygfsteel.com/realzar/comments/46356.htmlhttp://www.aygfsteel.com/realzar/archive/2006/05/16/46356.html#Feedback0http://www.aygfsteel.com/realzar/comments/commentRss/46356.htmlhttp://www.aygfsteel.com/realzar/services/trackbacks/46356.html ibatis开发h员指?一)
作者:紫龙

介绍

Ƣ迎来到iBATIS Database Layer!q个框架让你能够更好的在JAVA应用中设计和实现实体层。这个框架有两个主要的组成部分,一个是SQL MapsQ另一个是Data Access Objects。另外还包括一些可能很有用的工兗?/p>

SQL Maps

Sql Maps是这个框架中最Ȁ动h心的部分Q它是整个iBATIS Database Layer的核心h值所在。通过使用Sql Maps你可以显著的节约数据库操作的代码量。SQL Maps使用一个简单的XML文g来实CjavaBean到SQL statements的映。跟其他的框架或者对象映工L比,SQL Maps最大的优势是简单。它需要学习的东西很少Q在q接表或复杂查询时也不需要复杂的scheme(怎么complex scheme?)Q用SQL MapsQ?你可以自q使用SQL语句?/p>

Data Access Objects (DAO)

当我们开发灵zȝJAVA应用Ӟ有一个好L是通过一个通用API层把实体操作的细节封装v来。Data Access Objects允许你通过一个简单接口的来操作数据,从而隐藏了实现的细节。用DAOQ你可以动态配|你的应用程序来讉K不同的实体存储机制。如果你有一个复杂的应用需要用到几个不同的数据库,DAO可以让你建立一个一致的APIQ让pȝ的其他部分来调用?/p>

Utilities

iBATIS Database Layer包含一pd的有用的工具Q比如SimpleDataSourceQJDBC DataSource 2.0(也包?.0)的一个轻量实现。ScriptRunner也提供了从单元测试到自动发布的数据库准备工作?/p>

Examples

 跟这个框架一h一个examples.zipQ包含了一pd单的实例Q在http://www.ibatis.com上有更多的例子,包括非常著名的JpestoreQ?一个在U商店?译者注Q蓝色天IZ有一pd的中文介l和实例)

About this Document

本文介绍了iBATIS Database Layer最重要的功能,q有一些功用没有写出来Q凡是没有写出来的这些,可以认ؓ是不支持或者正在修攏V这些功能可能不l过通知׃改了Q所以最好不要用它们。本文将可能保持与框架同步。请认你两者是否匹配?/p>

SQL Maps (com.ibatis.db.sqlmap.*)

概念

SQL Map API允许E序员很单的把JAVA对象映射到PreparedStatement参数或者ResultSets。SQL Maps的机制很单,提供一个框Ӟ来实现用20%的代码来实现80%JDBC的功能?/p>

How does it work?

SQL Maps提供一个简单的框架Q通过XML描述来映JAVABeansQMAP implementations甚至原始cd的包?String,Integer{?到JDBC PreparedStatement。想法很单,基本的步骤如下:

1)提供一个对象作为参?either a JavaBean, Map or primitive wrapper)QThe parameter object
will be used setting input values in an update statement, or query values in a where clause (etc.).(感觉不译为好Q你说呢Q?

2)执行q个映射的statementQ这一步是术发生的地斏VSQL Maps框架徏立一个PreparedStatement实例(instance)Q用前面提供的对象的参敎ͼ执行statementQ然后从ResultSet中徏立一个返回对象?/p>

3)如果是UpdateQ则q回有多行修改了,如果是查询,则返回一个对象或者对象的集合。跟参数一Pq回对象也可以是一个JAVABEANQMAP或者一个primitive type wrapper?/p>

程囑֦下:

程?jpg

]]>
ibatis开发h员指??http://www.aygfsteel.com/realzar/archive/2006/05/16/46357.html开源爱好?/dc:creator>开源爱好?/author>Tue, 16 May 2006 03:08:00 GMThttp://www.aygfsteel.com/realzar/archive/2006/05/16/46357.htmlhttp://www.aygfsteel.com/realzar/comments/46357.htmlhttp://www.aygfsteel.com/realzar/archive/2006/05/16/46357.html#Feedback0http://www.aygfsteel.com/realzar/comments/commentRss/46357.htmlhttp://www.aygfsteel.com/realzar/services/trackbacks/46357.html ibatis开发h员指??
作者:紫龙

本篇文章的第一部分带你走q一pd的“fash Track”,带你览一遍SQL maps的简单应用。在walkthrough之后Q将有详l的?

Fast Track: Preparing to Use SQL Maps

SQL Maps对不好的数据库模型甚臛_象模型都有很强的容忍度。尽如此,q是推荐你用最佛_跉|设计你的的数据库模型和对象模型。通过q样Q你得到更q净的设计和更好的性能?/p>

 最单的开始就是分析你在做的内容,商业模型是什么样的,表结构是什么样的,它们怎么样互相发生关pR第一个例子,我们q单的实现一个典型的PersioncR?/p>
Person.java
package examples.domain;
//imports implied?
public class Person {
private int id;
private String firstName;
private String lastName;
private Date birthDate;
private double weightInKilograms;
private double heightInMeters;
public int getId () {
return id;
}
public void setId (int id) {
this.id = id;
}
//…let’s assume we have the other getters and setters to save space?br />}

现在persion对象怎么映射到数据库QSQL Mapsq不U束你必要一个表一个对象或者多个表一个对象这U映关pR因Z可以自由使用SQL语句Q所以约束很。在q个例子里,我们使用下面单的表,实现一个表对象一个对象的映射关系?/p>
Person.sql
CREATE TABLE PERSON(
PER_ID NUMBER (5, 0) NOT NULL,
PER_FIRST_NAME VARCHAR (40) NOT NULL,
PER_LAST_NAME VARCHAR (40) NOT NULL,
PER_BIRTH_DATE DATETIME ,
PER_WEIGHT_KG NUMBER (4, 2) NOT NULL,
PER_HEIGHT_M NUMBER (4, 2) NOT NULL,
PRIMARY KEY (PER_ID)
)

Fast Track: The SQL Map Configuration File

当我们对我们的工作感到很舒适时Q最好的开始就是SQL Map的配|文件。这个文件是SQL Map实现的根配置?/p>

配置文g是XML文gQ我们用它来配置属性,JDBC DataSources ?SQL Maps。它l我们一个便利的地方可以集中配置不同的DataSource。这个框架支持iBATIS SimpleDataSource, Jakarta DBCP (Commons)Q以及其他Q何可以通过JNDI context来访问的DataSource。我们在以后详l讨个问题。现在我们用Jakarta DBCPQ结构很单,象上面这个例子,它的配置文g如下?/p>

SqlMapConfigExample.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">


<!-- Always ensure to use the correct XML header as above! -->

<sql-map-config>

<!-- The properties (name=value) in the file specified here can be used placeholders in this config
file (e.g. ?{driver}? The file is relative to the classpath and is completely optional. -->

<properties resource="examples/sqlmap/maps/SqlMapConfigExample.properties" />

<!-- These settings control SqlMap configuration details, primarily to do with transaction
management. They are all optional (more detail later in this document). -->

<settings maxExecute="300"
        maxExecutePerConnection="1"
        maxTransactions="10"
        statementCacheSize="75"
        useGlobalTransactions="false"
        useBeansMetaClasses=”true?>
<!-- Configure a datasource to use with this SQL Map using Jakarta DBCP.
Notice the use of the properties from the above resource -->
<datasource name="basic" default = "true"
factory-class="com.ibatis.db.sqlmap.datasource.DbcpDataSourceFactory">
        <property name="JDBC.Driver" value="${driver}"/>
        <property name="JDBC.ConnectionURL" value="${url}"/>
        <property name="JDBC.Username" value="${username}"/>
        <property name="JDBC.Password" value="${password}"/>
        <property name="Pool.MaximumActiveConnections" value="10"/>
        <property name="Pool.MaximumIdleConnections" value="5"/>
        <property name="Pool.MaximumWait" value="60000"/>
</datasource>

<!-- Identify all SQL Map XML files to be loaded by this SQL map. Notice the paths
are relative to the classpath. For now, we only have one?-->

<sql-map resource="examples/sqlmap/maps/Person.xml" />

</sql-map-config>

SqlMapConfigExample.properties

# This is just a simple properties file that simplifies automated configuration
# of the SQL Maps configuration file (e.g. by Ant builds or continuous
# integration tools for different environments?etc.)
# These values can be used in any property value in the file above (e.g. ?{driver}?
# Using a properties file such as this is completely optional.


driver=oracle.jdbc.driver.OracleDriver
url=jdbc:oracle:thin:@localhost:1521:oracle1
username=jsmith
password=test

Fast Track: The SQL Map File(s)

    现在我们已经配置好DataSource了,然后p准备核心配置文g了。我们需要准备一个实际的SQL Map文g来存放SQL语句和以及用作映的参数对象和结果对象(分别是输入和输出Q?/p>

l箋我们上面的示例。让我们为PersoncdPerson表徏立映关pR我们先建立一个标准结构,和一个简单的select说明?/p>

Person.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="Person">

    <mapped-statement name="getPerson" result-class="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#
    </mapped-statement>
</sql-map>

上面的示例显CZ一个SQL map的一个最单的l成。它使用了SQL Maps的一个特性,是自动Ҏ字段名和JAVABean属?Map的主?名徏立对应关pR?value#象征着一个输入参敎ͼ多情况下Q?value"意味着我们使用一个基本类?(e.g. Integer; but we’re not limited to this).

因ؓ非常单,所以用这U方法有一些限制。首先不能明指定每个字D늚输入cd。没有办法自动加载相x据(复杂cdQ,同时有一些性能影响Q因为它使用了ResultSetMetaData。通过使用result-mapQ我们可以克服所有这些限制。但是现在,单是我们的目标。同是,以后我们可以随便修改成其他方式(不需要修改java代码Q?/p>

多数JAVAE序不仅d数据Q还要更Ҏ据。我们已l看到怎样在Map-statement里用select 了,那Update,delete和Insert是什么样的?一个好消息Q跟select没有什么区别。下面我们就完成一个我们的Person Sql MapQ包括一pd的statement用来操作和修Ҏ据?/p>

Person.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="Person">

<!-- Use primitive wrapper type (e.g. Integer) as parameter and allow results to

be auto-mapped results to Person object (JavaBean) properties -->

<mapped-statement name="getPerson" result-class="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#

</mapped-statement>

<!-- Use Person object (JavaBean) properties as parameters for insert. Each of the

parameters in the #hash# symbols is a JavaBeans property. -->

<mapped-statement name="insertPerson" >

INSERT INTO

PERSON (PER_ID, PER_FIRST_NAME, PER_LAST_NAME,

PER_BIRTH_DATE, PER_WEIGHT_KG, PER_HEIGHT_M)

VALUES (#id#, #firstName#, #lastName#,

#birthDate#, #weightInKilograms#, #heightInMeters#)

</mapped-statement>

<!-- Use Person object (JavaBean) properties as parameters for update. Each of the

parameters in the #hash# symbols is a JavaBeans property. -->

<mapped-statement name="updatePerson" >

UPDATE PERSON

SET (PER_ID = PER_FIRST_NAME = #firstName#,

PER_LAST_NAME = #lastName#, PER_BIRTH_DATE = #birthDate#,

PER_WEIGHT_KG = #weightInKilograms#,

PER_HEIGHT_M = #heightInMeters#)

WHERE PER_ID = #id#

</mapped-statement>

<!-- Use Person object (JavaBean) “id?properties as parameters for delete. Each of the

parameters in the #hash# symbols is a JavaBeans property. -->

<mapped-statement name="deletePerson" >

DELETE PERSON

WHERE PER_ID = #id#

</mapped-statement>

</sql-map>

Fast Track: Programming with the SQL Map Framework

现在我们已经完成了所有的配置和映,剩下的就是写JAVA代码了。第一步是配置SQL Map。加载我们前面配|好的SQL Map XML文g是很单的。加载XML以后Q就可以在框枉使用资源cR?/p>
String resource = “com/ibatis/example/sql-map-config.xml?
Reader reader = Resources.getResourceAsReader (resource);
SqlMap sqlMap = XmlSqlMapBuilder.buildSqlMap(reader);

SQL Map对象是线E安全的Q意味着是长期生存的。对于一个运行的pȝ来说Q你只要配置一ơ。所以它可以很好的成Z个基cȝ静态对象(比如Q一个BASE Daoc)Q也怽更喜Ƣ集中配|ƈ成ؓ全局可见Q你可以把它包装在你自己的工L中。比如说Q?/p>

private MyAppSqlConfig {

private static final SqlMap sqlMap;

static {

try {

String resource = “com/ibatis/example/sql-map-config.xml?

Reader reader = Resources.getResourceAsReader (resource);

sqlMap = XmlSqlMapBuilder.buildSqlMap(reader);

} catch (Exception e) {

// If you get an error at this point, it matters little what it was. It is going to be

// unrecoverable and we will want the app to blow up good so we are aware of the

// problem. You should always log such errors and re-throw them in such a way that

// you can be made immediately aware of the problem.

e.printStackTrace();

throw new RuntimeException (“Error initializing MyAppSqlConfig class. Cause: ?+ e);

}

}

public static getSqlMapInstance () {

return sqlMap;

}

}

从数据库d对象

 现在SQL Map实例已经完成初始化,q且很容易访?我们可以使用它了。首先我们用它从数据库中取得一个Person对象?举例Q我们假设数据库中有10条记录,PER_ID分别从是1?0)

Z从数据库中取得一个Person对象Q我们需要SQL Map实例Qmapped statement的名UC及PER_ID?让我们读?5。 

?br />SqlMap sqlMap = MyAppSqlMapConfig.getSqlMapInstance(); // as coded above
?br />Integer personPk = new Integer(5);
Person person = (Person) sqlMap.executeQueryForObject (“getPerson? personPk);
?/td>

把对象写到数据库?/p>

 现在我们已经从数据库取得一个对象,让我们修改一些|我们修改n高和体重。  ?/p>
?br />person.setHeightInMeters(1.83); // person as read from the database above
person.setWeightInKilograms(86.36);
?br />sqlMap.executeUpdate(“updatePerson? person);
?/td>

如果我们要删除一个对象,也一L单?/p>
?br />sqlMap.executeUpdate(“deletePerson? person);
?/td>

同样的,新插入一个对象也cM?/p>
Person newPerson = new Person();
newPerson.setId(11); // you would normally get the ID from a sequence or custom table
newPerson.setFirstName(“Clinton?;
newPerson.setLastName(“Begin?;
newPerson.setBirthDate (null);
newPerson.setHeightInMeters(1.83);
newPerson.setWeightInKilograms(86.36);
?br />sqlMap.executeUpdate (“insertPerson? newPerson);
?/td>

End of Fast Track(l束?

This is the end of the quick walkthrough. The next several sections will discuss the features of the
SqlMap framework in more detail.



]]>
ibatis介绍http://www.aygfsteel.com/realzar/archive/2006/05/16/46324.html开源爱好?/dc:creator>开源爱好?/author>Tue, 16 May 2006 01:40:00 GMThttp://www.aygfsteel.com/realzar/archive/2006/05/16/46324.htmlhttp://www.aygfsteel.com/realzar/comments/46324.htmlhttp://www.aygfsteel.com/realzar/archive/2006/05/16/46324.html#Feedback0http://www.aygfsteel.com/realzar/comments/commentRss/46324.htmlhttp://www.aygfsteel.com/realzar/services/trackbacks/46324.html ibatis介绍
作者:紫龙
  在开发过E中最能帮助你的是什么?是框Ӟ一个优U的框架可以极大的提高你的效率。strutsl了我们什么?MVC的实玎ͼ国际化、灵zR还有很多。不q,在一个通常的WEB应该中,是不能缺数据库的,而struts在这斚wq没有给我们提供什么有效的帮助。通常情况下我们做q个的时候有几个选择?br />            最直接的当然是JDBC啊,自己写connect、statment和resultset{等的代码,l果是篏死自己?br />            然后一U方法是EJBQEJB实是一个好东西Q可惜在很多场合用不上,L它很烦,速度很慢
            q有一U选择是JDO及类似的东西。最著名是free的应该是castorQhibernate{?

现在我们又多了一U选择Q就是ibatis Db LayerQ它的主|http://www.ibatis.comQؓ什么说它好Q让我们来看看作者自q说明吧,使用ibatis的理?/p>10、知道怎样操作10U以上的数据?br />9 、可配置的caching(包括从属)
8、支持DataSource、local transaction managemen和global transaction
7、简单的XML配置文档
6、支持Map, Collection, List和简单类型包?如Integer, String)
5、支持JavaBeansc?get/set Ҏ)
4、支持复杂的对象映射(如populating lists, complex object models)
3、对象模型从不完?不需要修?
2、数据模型从不完?不需要修?
1、你已经知道SQLQؓ什么还要学习其他东?

另外一点它?00% Open Source Freeware

下面我们来看一看,做一个简单的ibatis需要哪一些工作。然后一步一步深入探索它的强大功能。在实践中来看它的好处在哪里?/p>

在ibatis的网站上有一个它自己的petstoreQ在我个人看来是最z的petstore了,跟struts1.0l合。应该说是一个不错的教程。希望大家能够好好研I。当Ӟ作ؓ入门。我们先来做一个简单的E序。所采用的库嘛,׃然是用petstore的了。数据库也是选择Oracle(Z么选择OracleQ很多朋友不理解Q怎么不用mysql之类的呢Q一个主要的原因是个人爱好,Oracle毕竟是商业数据库Q有它的强大之处Q另外在linux下它也是免费的,:)。废话少_先用jpetstore3.1提供的ddl建立一个库吧?/p>

然后在eclipse里徏立一个ibatisDemo的工E。加入ibatis提供的库,建立相就的目录。看一下一个最单的E序需要哪一些文件。我们选择一个简单表Q即Categoryq个表的操作来演C功?/p>
文g路径功能说明备注
config\properties\petstore.properties可变参数配置文gQ所有根据环境不同的参数都放在这?/td> 
config\properties\simple\dao.xmldao配置文gQ主要存放dao对象和数据池讄 
config\properties\simple\sql-map-config-storedb.xml真正的核心配|文?/td> 
config\sqlmap\Category.xml存放Category的数据操作的SQL 
com.ewuxi.champion.exception.DaoException.java自定义的Exceptionc,不用说了?/td> 
com.ewuxi.champion.Service.java一个服务类Q用于初始化 
com.ewuxi.champion.persistence.dao.DaoCommonDao层的l一操作c,提供一些公共函?/td> 
com.ewuxi.champion.persistence.dao.CategoryDbCategory的操作类 
com.ewuxi.champion.persistence.vo.CategoryvalueObject 值对?/td> 
com.ewuxi.champion.persistence.dao.CategoryDbTest单元试c?/td> 

下面一个一个文件详l说?/p>

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

 

q个不用解释Q就是数据库的连接串Q如果你在自q机器上运行,当然q些都是需要改的?/p>

dao.xml

PUBLIC "-//iBATIS.com//DTD DAO Configuration 1.0//EN"
"http://www.ibatis.com/dtd/dao.dtd">





上面q一D也是很单的Q连一个dao也没有配|,也就是说Q用的是默认的Dao。其中表C它是默认的数据库配|?它可以根据名字不同同时连接几个数据库??/p>

sql-map-config-storedb.xml


PUBLIC "-//iBATIS.com//DTD SQL Map Config 1.0//EN"
"http://www.ibatis.com/dtd/sql-map-config.dtd">

maxExecute="0"
maxExecutePerConnection="0"
maxTransactions="0"
cacheModelsEnabled="true"
statementCacheSize="175"
useBeansMetaClasses="false"
useGlobalTransactions="false" />

factory-class="com.ibatis.db.sqlmap.datasource.DbcpDataSourceFactory"
default="true" >







q里真正实现了数据库q接Q我们用的是dbcp的连接池。JDBC的配|大安很熟了?{SimpleDriver}是指的前面petstore.properties中的SimpleDriver的内宏V?/p>

而则表示包含Category.xmlq个文g?/p>

Category.xml


PUBLIC "-//iBATIS.com//DTD SQL Map 1.0//EN"
"http://www.ibatis.com/dtd/sql-map.dtd">

 






select CATID, NAME, DESCN from CATEGORY where CATID = #categoryId#


select CATID, NAME, DESCN from CATEGORY


CATID = #categoryId#


NAME = #name#


DESCN = #description#






select count(1) as value from CATEGORY



mapped-statement
============================================= -->


update CATEGORY


NAME = #name#


DESCN = #description#


where
CATID =#categoryId#


mapped-statement
============================================= -->


delete from CATEGORY
where CATID =#categoryId#

OPTIONAL EXPLICIT PARAMETER MAP
============================================= -->





MAPPED STATEMENTS - w/Explicit Parameter Map
============================================= -->


insert into CATEGORY (
CATID,NAME,DESCN)
values (
?,?,?
)

上述文g是真正的SQL所存在的地斏V?/p>





q一D늚内容表示q回的对象是com.ewuxi.champion.persistence.vo.CategoryQ也是我们值对象。当执行查询的时候,dblay会封装出一个Category对象或者一个Category的list集合。其中数据列CATID对象javabean的categoryId倹{name是自定义?/p>


select CATID, NAME, DESCN from CATEGORY where CATID = #categoryId#

此处result-map="result"表示q回l果以后Q就会参照前面的result来返回对象。select CATID, NAME, DESCN from CATEGORY where CATID = #categoryId#标准的SQLQ只不过q一点CATID = #categoryId#有些不同Q?categoryId#表示传递一个Category对象ӞDblay会自动取得categoryId的值来执行SQL

再来看一?/p>


update CATEGORY


NAME = #name#


DESCN = #description#


where
CATID =#categoryId#

q个地方׃Cdblayer的强大之处,动态SQL。^常我们经常碰到的情况是根据不同的情况Q执行的SQL有一点点不一栗写在程序里Q要写不的if then之类的,在这里,dbLayerl你一下解决了。比如在q里Q我们三个值都是String对象Q所以通过isNotNull可以实现几U不同的update了,比如Q如果我只想修改DESCNq个字段Q只要传q去的Category对象只有categoryId和description有|׃生成update CATEGORY set DESCN = #description# where CATID =#categoryId#。同样如果传递的对象只有categoryId和name有|׃生成update CATEGORY set NAME = #name# where CATID =#categoryId#。是否很强大Q?)

前面q两U,参数的传递方式是内置参数Q也是CATID =#categoryId#q种Q大家可能不太习惯,那就看一看标准的写法吧?/p>

OPTIONAL EXPLICIT PARAMETER MAP
============================================= -->





MAPPED STATEMENTS - w/Explicit Parameter Map
============================================= -->


insert into CATEGORY (
CATID,NAME,DESCN)
values (
?,?,?
)

q里面的insert语句x大家都很熟了吧?q个时候怎么取得参数呢?关键在于q里parameter-map="insert-params"Q表CZd的设|,而这个设|也不用多解释了吧,是按顺序,三个Q分别对应三个倹{还能指明他们的数据cd?/p>

下面来看看Service.java


package com.ewuxi.champion;

import java.io.Reader;
import java.util.Properties;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.ibatis.common.resources.Resources;
import com.ibatis.db.dao.DaoManager;

/**
* @author champion
*
* To change the template for this generated type comment go to
* Window - Preferences - Java - Code Generation - Code and Comments
*/
public class Service {
static Log log = LogFactory.getLog(Service.class);
public static void initSet() {

try {

String resource = null;

resource = "properties/simple/dao.xml";
log.info("Using SIMPLE configuration. (" + resource + ")");

Reader reader = Resources.getResourceAsReader(resource);
DaoManager.configure(reader);

} catch (Exception e) {
throw new RuntimeException(
"Could not initialize BaseLogic. Cause: " + e);
}
}

}

一个静态方法,从resource文g中读出配|,最后用DaoManager.configure(reader);完成配置?/p>

DaoCommon

public static Dao getDefautDao(){
return DaoManager.getInstance().getDao("");
}
public static SqlMap getSqlMap(Dao c) throws DaoException {
try {
DaoManager daoManager = DaoManager.getInstance(c);

if (daoManager == null) {
daoManager = DaoManager.getInstance();
}

SqlMapDaoTransaction trans = (SqlMapDaoTransaction) daoManager.getLocalTransaction();
SqlMap sqlMap = trans.getSqlMap();

return sqlMap;
} catch (Exception e) {
throw new DaoException(e);
}
}

public static SqlMap getSqlMap(String c) throws DaoException {
try {
DaoManager daoManager = DaoManager.getInstance(c);
SqlMapDaoTransaction trans = (SqlMapDaoTransaction) daoManager.getLocalTransaction();
SqlMap sqlMap = trans.getSqlMap();

return sqlMap;
} catch (Exception e) {
throw new DaoException(e);
}
}

三个主要的函敎ͼW一个是得到默认的DAO对象Q后两个是根据一个dao对象或者一个参?也就是前面中是name?。取得SqlMap对象Q这个对象是主要的数据操作接口?/p>
/**
* @throws Exception
* 开始事务,所在session层必M用它
*/
public static void startTransaction() throws Exception {
if (!DaoCommon.inTransaction()) {
DaoManager.getInstance().startTransaction();
}
}

public static boolean inTransaction() throws Exception {
try {
DaoManager.getInstance().getLocalTransaction();

return true;
} catch (Exception e) {
return false;
}
}

/**
* @throws Exception
* 攑ּ事务
*/
public static void rollBack() {

try {
DaoManager.getInstance().rollbackTransaction();
} catch (Exception e) {
LogFactory.getLog(DaoCommon.class).error(e, e);
}
}

/**
* @throws Exception
* 提交事务
*/
public static void commit() throws Exception {
DaoManager.getInstance().commitTransaction();
}

下面的一些函数是对事务的一些封装。想必也很容易理解?/p>

然后让我们来看CategoryDb的内?/p>
/*
* Created on 2003-10-11
*
* To change the template for this generated file go to
* Window - Preferences - Java - Code Generation - Code and Comments
*/
package com.ewuxi.champion.persistence.dao;

import com.ewuxi.champion.exception.DaoException;
import com.ewuxi.champion.persistence.vo.Category;
import com.ibatis.db.sqlmap.SqlMap;

/**
* @author champion
*
*category数据库操作对?br />*/

public class CategoryDb {

/**
* @param vo
* @throws DaoException
* 插入一条记?br />*/
public void insert(Category vo) throws DaoException{
try {
SqlMap sqlMap=DaoCommon.getSqlMap(DaoCommon.getDefautDao());
sqlMap.executeUpdate("insertCategoryDao",vo);
} catch (Exception e) {
throw new DaoException(e);
}
}
/**
* @param vo
* @throws DaoException
* 删除一条记?br />*/
public void delete(Category vo) throws DaoException{
try {
SqlMap sqlMap=DaoCommon.getSqlMap(DaoCommon.getDefautDao());
sqlMap.executeUpdate("deleteByPrimaryKeyCategoryDao",vo);
} catch (Exception e) {
throw new DaoException(e);
}
}
/**
* @param vo
* @throws DaoException
* 修改一条记?br />*/
public void update(Category vo) throws DaoException{
try {
SqlMap sqlMap=DaoCommon.getSqlMap(DaoCommon.getDefautDao());
sqlMap.executeUpdate("updateByPrimaryKeyCategoryDao",vo);
} catch (Exception e) {
throw new DaoException(e);
}
}
/**
* @param vo
* @return
* @throws DaoException
* 查找一条记?br />*/
public Category findByPk(Category vo) throws DaoException{
try {
SqlMap sqlMap=DaoCommon.getSqlMap(DaoCommon.getDefautDao());
return (Category) sqlMap.executeQueryForObject("findByPrimaryKeyCategoryDao",vo);
} catch (Exception e) {
throw new DaoException(e);
}
}

}


每一个函数都很类似的。关键就在这一?Category) sqlMap.executeQueryForList("findByPrimaryKeyCategoryDao",vo);。看?findByPrimaryKeyCategoryDao"Q这个对应于前面Category.xml中的名字。而vo则是一个Category对象?/p>

最后是CategoryDbTestc,q个是我们的单元试E序

/*
* Created on 2003-10-11
*
* To change the template for this generated file go to
* Window - Preferences - Java - Code Generation - Code and Comments
*/
package com.ewuxi.champion.persistence.dao;

import com.ewuxi.champion.exception.DaoException;
import com.ewuxi.champion.persistence.vo.Category;
import com.ibatis.db.sqlmap.SqlMap;

/**
* @author champion
*
*category数据库操作对?br />*/

public class CategoryDb {

/**
* @param vo
* @throws DaoException
* 插入一条记?br />*/
public void insert(Category vo) throws DaoException{
try {
SqlMap sqlMap=DaoCommon.getSqlMap(DaoCommon.getDefautDao());
sqlMap.executeUpdate("insertCategoryDao",vo);
} catch (Exception e) {
throw new DaoException(e);
}
}
/**
* @param vo
* @throws DaoException
* 删除一条记?br />*/
public void delete(Category vo) throws DaoException{
try {
SqlMap sqlMap=DaoCommon.getSqlMap(DaoCommon.getDefautDao());
sqlMap.executeUpdate("deleteByPrimaryKeyCategoryDao",vo);
} catch (Exception e) {
throw new DaoException(e);
}
}
/**
* @param vo
* @throws DaoException
* 修改一条记?br />*/
public void update(Category vo) throws DaoException{
try {
SqlMap sqlMap=DaoCommon.getSqlMap(DaoCommon.getDefautDao());
sqlMap.executeUpdate("updateByPrimaryKeyCategoryDao",vo);
} catch (Exception e) {
throw new DaoException(e);
}
}
/**
* @param vo
* @return
* @throws DaoException
* 查找一条记?br />*/
public Category findByPk(Category vo) throws DaoException{
try {
SqlMap sqlMap=DaoCommon.getSqlMap(DaoCommon.getDefautDao());
return (Category) sqlMap.executeQueryForObject("findByPrimaryKeyCategoryDao",vo);
} catch (Exception e) {
throw new DaoException(e);
}
}

}



]]>
ibatis 开发指? http://www.aygfsteel.com/realzar/archive/2006/05/16/46303.html开源爱好?/dc:creator>开源爱好?/author>Mon, 15 May 2006 16:55:00 GMThttp://www.aygfsteel.com/realzar/archive/2006/05/16/46303.htmlhttp://www.aygfsteel.com/realzar/comments/46303.htmlhttp://www.aygfsteel.com/realzar/archive/2006/05/16/46303.html#Feedback0http://www.aygfsteel.com/realzar/comments/commentRss/46303.htmlhttp://www.aygfsteel.com/realzar/services/trackbacks/46303.html Zstruts+spring+ibatis的轻量J2EE开?/a> [yanwp 2006-01-26]
  • iBATISQ@序渐q介l如何做O/R Mapping...Q?/a> [yanwp 2006-01-26]
  • Zstruts+spring+ibatis的轻量J2EE开? [yanwp 2006-01-26]
  • Hibernate VS iBATIS [yanwp 2006-01-26]
  • 的确不错的iBATIS SQL Maps [yanwp 2006-01-26]
  • 从Jpetstore 开始IBATIS之旅 [yanwp 2006-01-26]
  • Asp.netQIBatis For .NetQDAOFactory在Web开发中的数据表C? [yanwp 2006-01-26]
  • Hibernate、iBATIS ?BLOB [yanwp 2006-01-26]
  • Hibernate、iBATIS ?BLOB [yanwp 2006-01-26]
  • 我的IBatisNet实践 [yanwp 2006-01-26]


  • ]]>
    IBATISNETNET 1.3 开发指南系列文?http://www.aygfsteel.com/realzar/archive/2006/05/16/46302.html开源爱好?/dc:creator>开源爱好?/author>Mon, 15 May 2006 16:44:00 GMThttp://www.aygfsteel.com/realzar/archive/2006/05/16/46302.htmlhttp://www.aygfsteel.com/realzar/comments/46302.htmlhttp://www.aygfsteel.com/realzar/archive/2006/05/16/46302.html#Feedback0http://www.aygfsteel.com/realzar/comments/commentRss/46302.htmlhttp://www.aygfsteel.com/realzar/services/trackbacks/46302.html准备写一个Ibatisnet开发指?/font>,得到非常强烈的反应,最q比较忙Q完成的也很慢。现在很多的开发开始{向DotNet 2.0,IBatisNet 1.3也将直接支持DotNet 2.0的数据方面两大特性:Nullable和泛型,IBatisNet 1.3也直接支持Sql server 2005。所以这个开发指南约定用VS 2005和IBatisNet 1.3版本。IBatisNet 1.3现在q是在beta阶段Q但愿在IBatisNet 1.3正式Release的时候这个指南能够完成?br />    
          Ibatisnet介绍 
          Ibatisnet Quick Start     



    ]]>
    Zstruts+spring+ibatis?J2EE 开?/title><link>http://www.aygfsteel.com/realzar/archive/2006/05/16/46301.html</link><dc:creator>开源爱好?/dc:creator><author>开源爱好?/author><pubDate>Mon, 15 May 2006 16:42:00 GMT</pubDate><guid>http://www.aygfsteel.com/realzar/archive/2006/05/16/46301.html</guid><wfw:comment>http://www.aygfsteel.com/realzar/comments/46301.html</wfw:comment><comments>http://www.aygfsteel.com/realzar/archive/2006/05/16/46301.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/realzar/comments/commentRss/46301.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/realzar/services/trackbacks/46301.html</trackback:ping><description><![CDATA[ <table class="top" cellspacing="0" cellpadding="0" width="96%" align="center" border="0"> <tbody> <tr> <td>1?a target="_blank">Zstruts+spring+ibatis?J2EE 开?5)</a> 2005-04-20</td> </tr> <tr> <td height="5"> </td> </tr> <tr> <td>2?a target="_blank">Zstruts+spring+ibatis?J2EE 开?4)</a> 2005-04-20</td> </tr> <tr> <td height="5"> </td> </tr> <tr> <td>3?a target="_blank">Zstruts+spring+ibatis?J2EE 开?3)</a> 2005-04-20</td> </tr> <tr> <td height="5"> </td> </tr> <tr> <td>4?a target="_blank">Zstruts+spring+ibatis?J2EE 开?2)</a> 2005-04-20</td> </tr> <tr> <td height="5"> </td> </tr> <tr> <td>5?a target="_blank">Zstruts+spring+ibatis?J2EE 开?1)</a> </td> </tr> </tbody> </table> <img src ="http://www.aygfsteel.com/realzar/aggbug/46301.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/realzar/" target="_blank">开源爱好?/a> 2006-05-16 00:42 <a href="http://www.aygfsteel.com/realzar/archive/2006/05/16/46301.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <a href="http://www.aygfsteel.com/" title="狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频">狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频</a> </div> </footer> վ֩ģ壺 <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ţ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ʡ</a>| <a href="http://" target="_blank">۽</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">֥</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">̫</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ͼ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ԭƽ</a>| <a href="http://" target="_blank">̶</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ˮ</a>| <a href="http://" target="_blank">¯</a>| <a href="http://" target="_blank">ء</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">º</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ʡ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ƴ</a>| <a href="http://" target="_blank">۽</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">±</a>| <a href="http://" target="_blank">ţ</a>| <a href="http://" target="_blank">̫</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>