iBatis.net入门指南

iBatis.net入门指南

 

iBatis.net入门指南    - 1 -

什么是iBatis.net ?    - 3 -

iBatis.net的原理    - 3 -

新人指路    - 3 -

iBatis.net的优缺点    - 4 -

SQL Mapping金典案例    - 5 -

情景一基本标签(insert,update ,select)及属性(parameterClass,resultClass)    - 5 -

情景二子标签()及转义处理    - 7 -

情景三高阶标签()及属性(resultMap)    - 8 -

情景四储存过程标及属性parameterMap    - 10 -

ISqlMapper接口    - 12 -

深度私塾    - 14 -

向sql语句中传入多个参数    - 14 -

自动生成键selectkey    - 14 -

Oracle    - 14 -

SqlServer    - 14 -

MySQL    - 14 -

SQLite    - 14 -

储存过程调用方法    - 15 -

SqlServer    - 15 -

Oracle    - 15 -

Reference    - 16 -

 

 

 

参与人员:

作者

联系方式

毛凌志

[email protected]

   

 

发布记录

版本

日期

作者

说明

0.0

2009-08-21

毛凌志

初稿

       

 

什么是iBatis.net ?

 

以SQL Mapping为核心,提供基于ado.net之上的一层简单抽象,将数据库中数据映射到领域模型的持久层框架

iBatis.net入门指南_第1张图片

iBatis.net的原理

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

新人指路

  1. 新建工程,添加2个引用文件

iBatis.net入门指南_第2张图片

  1. 添加并修改配置3个配置文件

iBatis.net入门指南_第3张图片

  1. 根据数据库的表结构及业务设计领域模型(可以手动,或利用codesmith等生成器半自动完成
  2. 由模板或手动生成SQL Mapping文件(e.g.Account.xml),并根据业务需求撰写sql语句

更详细的使用过程,可参见视频。

iBatis.net的优缺点

优点

缺点

  • 集中管理,聚焦,减少代码量
  • 传入参数仅能一个,多于一个需要进行包装
  • 细粒度控制
  • 混合型解决方案
  • 思维方式
  • 非强类型,运行时,非编译时

 

SQL Mapping金典案例

 

    情景一 基本标签(insert,update ,select)及属性(parameterClass,resultClass)

iBatis.net原理一节示例了使用ibatis.net进行insert和select操作,下面展示介绍如何具体的进行SqlMapping。

在SqlMapping的配置文件本例中为Account.xml文件中,添加如下的标签段

iBatis.net入门指南_第4张图片

    并将此Account.xml文件的路径加入到sqlmap.config中

在iBatis.net中提供了五种常用的标签如下表示

 

表1 基本SQL Mapping标签

标签

说明

 

删除sql语句

 

更新sql语句

 

选取sql语句

 

删除sql语句

 

调用储存过程

 

在这些容器标签中有一些常用的属性如下所示

表2 基本SQL Mapping标签属性

属性

说明

Id

用于唯一标识一条sql语句

resultClass

用于将sql语句返回的字段和resultClass提定的类进行隐式的自动映射

parameterClass

用于指定输入参数的类型,如果输入参数有多个应使用Hashtable或是类进行包装

下面是关于这两条SQL语句的调用方法和测试

iBatis.net入门指南_第5张图片

    

情景二 子标签()及转义处理

在一些复杂的情景中,为了简化SQL的编写工作,ibatis.net提供了一些标签用于简化SQL的编写操作。可以将可复用的sql语句写在标签中,然后中

select Id, ReferenceId, ReferenceName, ReferenceType, ReferenceImage, ReferenceTime, Title, Pros, Cons, Content, Score, ViewCount, ReplyCount, UsefulVoteCount, UselessVoteCount, UserId, UserImage, UserLevelId, UserRegisterTime, UserProvince, UserIp, CreationTime, Status, Remark

from Comment with (nolock)

where Id = #value# and Status >= 0

虽然看着十分正常,但是却是问题的关键,因为parameterClass是string,当Ibatis.net动态组成的sql语句会将其默认定为一个nvchar(36)来对数据库进行查询,这样与原有数据库的类型不一样,

造成了全表扫描,解决办法是制定传入类型的dbType(inline方法为):

当然也可以使用parameterMap来解决(具体参考Ibatis手册)。通过这个办法Club数据库压力已经只有17%左右,非常有效。我认为在string作为参数且数据库字段是一个varchar的时候都可以使用该方法,且效率很高。

 
posted @ 2011-05-21 15:43 awp110 阅读(43) 评论(0) 编辑
 
 
IBatis.Net学习笔记(六):Castle.DynamicProxy的使用
Castle是另外一个框架,包含了AOP、IOC、ORM等多个方面,其中的Castle.DynamicProxy可以实现动态代理的功能,这个也是很多框架的基础。在IBatis.Net中就是使用了Castle.DynamicProxy来实现数据库连接等动态操作的。同时在NHibernet等其他框架中也使用到了这个技术。
下面我通过一个简单例子来看一下如何在我们的代码中调用Castle.DynamicProxy:
一般情况下要有三个类:
1、接口类:
using  System;
using  System.Collections.Generic;
using  System.Text;

namespace  GSpring.CastleTest
{
    
public interface ITest
    
{
        
string GetName(string pre);
    }

}

2、实现类:
using  System;
using  System.Collections.Generic;
using  System.Text;

namespace  GSpring.CastleTest
{
    
public class Test : ITest
    
{
        
public string GetName(string pre)
        
{
            
return pre + ",GSpring";
        }

    }

}

这两个都很普通的接口和实现
3、代理类:
using  System;
using  System.Collections;
using  System.Reflection;
using  Castle.DynamicProxy;

namespace  GSpring.CastleTest
{
    
/**//// 
    
/// Summary description for DaoProxy.
    
/// 

    public class InterceptorProxy : IInterceptor
    
{
         
public object Intercept(IInvocation invocation, params object[] arguments)
        
{
            Object result 
= null;

            
//这里可以进行数据库连接、打日志、异常处理、权限判断等共通操作
            result = invocation.Proceed(arguments);

            
return result;
        }


    }

}

这个类首先实现接口IInterceptor,然后就可以在方法Intercept中加入我们自己的逻辑

然后看一下调用的方式:
        ProxyGenerator proxyGenerator  =   new  ProxyGenerator();
        IInterceptor handler 
=   new  InterceptorProxy();
        Type[] interfaces 
=   typeof(ITest) } ;
        Test test 
=   new  Test();
        ITest iTest 
=  (proxyGenerator.CreateProxy(interfaces, handler, test)  as  ITest);
        
string  result  =  iTest.GetName( " Hello " );
最后一句调用的地方,实际会首先执行InterceptorProxy类中的Intercept方法。
 
posted @ 2011-05-21 15:39 awp110 阅读(54) 评论(0) 编辑
 
 
IBatis.Net学习笔记(七):在IBatis.Net中调用存储过程
其实调用方式比较简单,主要也就是两种类型的存储过程:
1、更新类型的存储过程
2、查询类型的存储过程
下面就来看看具体的调用方式:
1、更新类型的存储过程
sp_InsertAccount:
CREATE   PROCEDURE   [ dbo ] . [ sp_InsertAccount ]
    
--  Add the parameters for the stored procedure here
    @Account_ID   int ,
   
@Account_FirstName   varchar ( 32 ),
   
@Account_LastName   varchar ( 32 ) AS
BEGIN
insert   into  accounts (account_id, account_firstname, account_lastname) 
    
values  ( @Account_ID , @Account_FirstName , @Account_LastName  )
END
Map配置文件:
         < procedure  id ="InsertAccountViaStoreProcedure"  parameterMap ="insert-params_new" >
            sp_InsertAccount
        
procedure >

    
< parameterMap  id ="insert-params_new"  class ="Account" >
      
< parameter  property ="Id"   />
      
< parameter  property ="FirstName"   />
      
< parameter  property ="LastName"   />
    
parameterMap >

这里要注意的就是ParameterMap中的参数个数和顺序要和sp_InsertAccount存储过程中的一致

Ado中的调用代码:

         public   void  InsertAccountViaStoreProcedure(Account account)
        
{
            
try
            
{
                sqlMap.Insert(
"InsertAccountViaStoreProcedure", account);
            }

            
catch (DataAccessException ex)
            
{
                
throw new DataAccessException("Error executing InsertAccountViaStoreProcedure. Cause :" + ex.Message, ex);
            }

        }

这里使用的是sqlMap.Insert的方法,为了看起来直观一点,其实使用sqlMap.QueryForObject方法的话效果也是一样的:)

2、查询类型的存储过程
GetAccountByName

CREATE   PROCEDURE   [ dbo ] . [ GetAccountByName ]
    
@name   varchar ( 32 )
AS
BEGIN
select   *   from  accounts  where  Account_FirstName  like   ' % '   +   @name   +   ' % '
END

Map配置文件:
     < procedure  id ="GetAccountByNameViaStoreProcedure"  resultMap ="account-result"  parameterMap ="selectpro-params" >
      GetAccountByName
    
procedure >

    
< parameterMap  id ="selectpro-params"  class ="string" >
      
< parameter  property ="name" />
    
parameterMap >
这里parameterMap也是和上面的要求一样,至于property的名字在这里没有实际作用,可以任意取名的

Ado中的调用代码:
         public  ArrayList GetAccountByNameViaStoreProcedure( string  strName)
        
{
            
try
            
{
                ArrayList list 
= (ArrayList)sqlMap.QueryForList("GetAccountByNameViaStoreProcedure", strName);
                
return list;
            }

            
catch (DataAccessException ex)
            
{
                
throw new DataAccessException("Error executing SqlAccountViaSqlMapDao.GetAccountById. Cause :" + ex.Message, ex);
            }

        }
 
posted @ 2011-05-21 15:39 awp110 阅读(21) 评论(0) 编辑
 
 
IBatis.Net学习笔记(五)--动态选择Dao的设计分析
在IBatis.Net中可以通过配置文件动态选择数据库、动态选择Dao对象。
Dao对象也就是操作数据库的类,通过配置文件我们可以选择DataMapper的方式、Ado的方式、NHibernet的方式以前其他第三方的方式来操作数据库。有利于系统的灵活性和可扩展性。
通过分析动态选择Dao的设计可以加深对IBatis.Net的理解,更好的使用它,同时也可以借鉴它的好的设计模式,应用到我们的程序开发中去。

源代码是最好的分析方式,下面是一些重点代码和说明:
前提:需要在dao.config中配置:
     < daoFactory >
            
< dao  interface = " GSpring.Dao.Interfaces.IAccountDao, GSpring.Dao "  implementation = " GSpring.Dao.Implementations.AccountDao, GSpring.Dao " />
    
daoFactory >

在代码中首先需要进行初始化:
    DomDaoManagerBuilder builder  =   new  DomDaoManagerBuilder();
    builder.Configure(
" dao.config " );
这段代码实际上做了很多事情,其中就有:将所有的配置的dao的接口和实现注册到DaoManager类的静态属性中去。也就是在整个应用程序或网站启动时注册一次就可以了,以后直接从静态属性中取出来使用就可以了。

和dao注册相关的代码如下:
        dao.Implementation  =  NodeUtils.GetStringAttribute(prop,  " implementation " );
        dao.Interface 
=  NodeUtils.GetStringAttribute(prop,  " interface " );
        
        _daoInstance 
=  _daoImplementation.GetConstructor(Type.EmptyTypes).Invoke( null as  IDao;
        _proxy 
=  DaoProxy.NewInstance( this );
也就是把配置文件中的interface和implementation读取,然后生成代理。

最主要的就是最后一句代码,DaoProxy.NewInstance的实现如下:
            Castle.DynamicProxy.ProxyGenerator proxyGenerator  =   new  ProxyGenerator();
            IInterceptor handler 
=   new  DaoProxy(dao);
            Type[] interfaces 
=   {dao.DaoInterface, typeof(IDao)} ;

            
return  (proxyGenerator.CreateProxy(interfaces, handler, dao.DaoInstance)  as  IDao);
这里我们看到其中使用了Castle.DynamicProxy中的方法( Castle是另外一个开源框架,我和在以后的博客中再说)
DaoProxy实现IInterceptor接口,也就是AOP中常有的拦截机。以后当我们通过IDao接口调用实际的Dao时,都会先通过DaoProxy,由DaoProxy拦截后进行一些必要的处理,然后再动态决定调用哪一个Dao来进行数据库操作

生成好之后都会放在DaoManager的静态属性中,下次要用的时候直接从里面去就可以了:
         public  IDao  this [Type daoInterface]
        
{
            
get
            
{
                Dao dao 
= _daoMap[daoInterface] as Dao;
                
if (dao == null
                
{
                    
throw new DataException("There is no DAO implementation found for " + daoInterface.Name + " in this context.");
                }

                IDao idao 
= dao.Proxy;
                
return idao;
            }

        }

以上涉及到的主要的类图如下:
iBatis.net入门指南_第17张图片
 
posted @ 2011-05-21 15:38 awp110 阅读(38) 评论(0) 编辑
 
 
IBatis.Net学习笔记(三)--常用的查询方式
在项目开发过程中,查询占了很大的一个比重,一个框架的好坏也很多程度上取决于查询的灵活性和效率。
在IBatis.Net中提供了方便的数据库查询方式。

在Dao代码部分主要有两种方式:
1、查询结果为一个对象:
                ISqlMapper sqlMap  =  sqlMapDaoSession.SqlMap;

                
return  (Account) sqlMap.QueryForObject( " GetAccountViaColumnName " , accountID);
2、查询结果为一个列表:
                ISqlMapper sqlMap  =  sqlMapDaoSession.SqlMap;

                
return  (ArrayList)sqlMap.QueryForList( " GetAccountAsHashtableResultClass " 1 );
这两种方法同时都提供了面向泛型的重载方法。这两个方法的第一个参数对应配置文件中的select id,第二个参数表示传入查询的条件

配置文件的写法:
在IBatis.Net中提供了多种查询配置的写法,我这里列出几种比较常用的方式:
1、获得一张表的所有数据
         < select id = " GetAllAccountsAsHashMapViaResultMap "
                        resultMap
= " account-hashtable-result " >
            select 
*
            from Accounts
            order by Account_ID
        
select >
这是最简单的方式,其中resultMap是返回查询结果的形式,需要另外配置:
         < resultMap id = " account-hashtable-result "   class = " Hashtable " >
            
< result property = " Id "            column = " Account_ID " />
            
< result property = " FirstName "     column = " Account_FirstName " />
            
< result property = " LastName "      column = " Account_LastName " />
            
< result property = " EmailAddress "  column = " Account_Email " />
        
resultMap >
表示:得到的结果的每一条记录都映射成一个Hashtable,这个Hashtable中包含四个Key(Id,FirstName......)

2、根据条件查询(简单方式):
         < select id = " GetAccountViaColumnIndex "
                parameterClass
= " int "
                resultMap
= " indexed-account-result " >
            select
            Account_ID,
            Account_FirstName,
            Account_LastName,
            Account_Email
            from Accounts
            where Account_ID 
=  #value#
        
select >
只有一个条件,传入参数的类型是int型,拼写sql时直接用 #value#就可以了

3、根据条件查询(较复杂方式):
         < select id = " GetAccountsDynamic "  resultMap = " account-result "  parameterClass = " Hashtable "   >
            select top $MaximumAllowed$ 
*  from Accounts
            
< dynamic prepend = " where " >
                    
< isParameterPresent >
                    
< isNotEmpty prepend = " and "  property = " FirstName "   >
                            Account_FirstName LIKE 
' %$FirstName$% '
                    
isNotEmpty >
                    
< isNotEmpty prepend = " and "  property = " LastName "   >
                            Account_LastName LIKE 
' %$LastName$% '
                    
isNotEmpty >
                    
< isNotEmpty prepend = " and "  property = " EmailAddress "    >
                            Account_Email LIKE 
' %$EmailAddress$% '
                    
isNotEmpty >
                    
isParameterPresent >
                
dynamic >
                order by Account_LastName
        
select >
传入参数是一个Hashtable, MaximumAllowed等表示的是Hashtable里的key值,用$$包含起来。
并且查询时可以根据条件是否为空动态拼写sql语句
PS:输入参数同样可以使用Account类,注意对应的键要和类中的属性名一致(大小写也要一样)

4、多表查询
多表查询时返回参数有三种方式,一种是新建一个类,在这个类中包含这多个表的所有属性,还有一种就是直接返回Hastable就可以了:
         < select id = " GetAccountAsHashtableResultClass "
    resultClass
= " HashMap " >
            select
            a.
* ,b. *
            from a,b
            where a.Account_ID 
=  b.Account_ID         select >
PS:这里的HashMap实际上就是Hashtable

第三种方式是使用IBatis中的复杂属性( 感谢 Anders Cui 的提醒)
比如现在有两张表Account和Degree,使用Account_ID关联,那么需要在原有的基础上修改:
1、修改Account实体类,加入一个属性:
         private  Degree _degree;
        
public  Degree Degree
        
{
            
get
            
{
                
return _degree;
            }

            
set
            
{
                _degree 
= value;
            }

        }
这样是一个1:1的关系,也可以加入IList DegreeList的属性,这样查询的结果就是一个1:n的关系

2、修改配置文件:
resultMaps节加入:
     < resultMap id = " comresult "    class = " Account "   >
      
< result property = " Id "            column = " Account_ID " />
      
< result property = " FirstName "     column = " Account_FirstName " />
      
< result property = " LastName "      column = " Account_LastName " />
      
< result property = " EmailAddress "  column = " Account_Email "  nullValue = " [email protected] " />
      
< result property = " Degree "  column = " Account_ID=Account_ID "   select = " degreeretrive "   />
    
resultMap >
对于Degree属性,还可以加入 lazyLoad=true 延迟加载,优化性能(也就是开始时并没有实际查询数据库,当用到属性Degree时,才实际的查询相应的数据)

statements节加入:
     < statement id = " degreeretrive "
      parameterClass
= " Hashtable "
      resultClass
= " Degree " >
      select 
*
      from Degree
      where Account_id 
=  #Account_ID#
    
statement >

    
< select id = " GetComTables "
      resultMap
= " comresult " >
      select 
*
      from Accounts
      order by Account_ID
    
select >
这样可以正确的查询出结果,符合OO,但是也有两个小问题:
1、比较麻烦,不够灵活
2、性能受影响:
    这种方式其实和Hibernet比较类似了,查询时首先执行
    select *        from Accounts        order by Account_ID
    然后根据这条语句的结果,比如有100条记录,那就要执行100次以下的语句:
     select *        from Degree        where Account_id =  @param0

关于输入输出:
从上面可以看到输入时可以使用: parameterClass和parameterMap,输出时可以使用:resultClass和resultMap
对于resultMap和parameterMap我们需要另外进行配置(如上所示)
对于parameterClass和resultClass,如果是C#固有类型可以直接使用,如果是我们自定义类可以在SqlMap.config中先统一声明一下:
     < alias >
        
< typeAlias alias = " Account "  type = " GSpring.Domain.Account " />
    
alias >
 
posted @ 2011-05-21 15:37 awp110 阅读(36) 评论(0) 编辑
 
 
IBatis.Net学习笔记(四)--再谈查询
在上一篇文章中我提到了三种方式,都是各有利弊:
第一种方式当数据关联很多的情况下,实体类会很复杂;
第二种方式比较灵活,但是不太符合OO的思想(不过,可以适当使用 );
第三种方式最主要的问题就是性能不太理想,配置比较麻烦。

下面是第四种多表查询的方式,相对第二种多了一点配置,但是其他方面都很好
(当然可能还有其他更好地解决方法,希望能多提宝贵意见-_-)
例子还是一样:两张表Account和Degree,使用Account_ID关联,需要查出两张表的所有纪录

首先:修改实体类,增加以下属性:
         private  Degree _degree;
        
public  Degree Degree
        
{
            
get
            
{
                
return _degree;
            }

            
set
            
{
                _degree 
= value;
            }

        }
(和第三种方法一样)

然后:修改配置文件,这也是最重要的地方(PS:IBatis.Net中的配置文件真的很强)
resultMaps节加入:
     < resultMap id = " com2result "    class = " Account "   >
      
< result property = " Id "            column = " Account_ID " />
      
< result property = " FirstName "     column = " Account_FirstName " />
      
< result property = " LastName "      column = " Account_LastName " />
      
< result property = " EmailAddress "  column = " Account_Email "  nullValue = " [email protected] " />
      
< result property = " Degree "   resultMapping = " Account.Degree-result " />
    
resultMap >

    
< resultMap id = " Degree-result "    class = " Degree " >
      
< result property = " Id "            column = " Account_ID " />
      
< result property = " DegreeName "     column = " DegreeName " />
    
resultMap >
这里最主要的就是使用了resultMapping属性, resultMapping="Account.Degree-result",其中Account是当前配置文件的namespace:
  ......

statements节加入:
     < select id = " GetCom2Tables "
     resultMap
= " com2result " >
      select Accounts.
* , Degree. *
      from Accounts,Degree
      where Accounts.Account_ID 
=  Degree.Account_ID
    
select >
这样就可以随心所欲的写自己需要的sql,性能也很好,不会出现第三种方法中的1+n条的查询语句了。
 
posted @ 2011-05-21 15:37 awp110 阅读(12) 评论(0) 编辑
 
 
IBatis.Net学习笔记(二)--数据库的缓存模式

在IBatis中提供了数据库缓存的模式,可以提高访问效率。对于一些不常更新的表可以直接利用IBatis的缓存方式。

要使用IBatis的数据库缓存,只要利用配置文件就可以了,实现起来比较简单:

         < select id = " GetCachedAccountsViaResultMap "
                    resultMap
= " account-result "
                    cacheModel
= " account-cache "   >
            select 
*
            from Accounts
            order by Account_ID
        
select >
最主要的就是 cacheModel="account-cache",指定缓存的方式,如下,是具体配置缓存的地方:
     < cacheModels >
        
< cacheModel id = " account-cache "  implementation = " MEMORY "   >
            
< flushInterval hours = " 24 " />
            
< flushOnExecute  statement = " UpdateAccountViaInlineParameters " />
            
< flushOnExecute  statement = " UpdateAccountViaParameterMap " />
      
< flushOnExecute  statement = " InsertAccountViaParameterMap " />
      
< property name = " Type "  value = " Weak " />
        
cacheModel >         
    
cacheModels >

其中:implementation="MEMORY"是设置缓存的实现方式,可以指定LRU、FIFO等,有点类似于内存的页替换策略。MEMORY是最常使用的一种方式。

flushOnExecute设置的是当执行了这些语句时更新缓存。

配置好之后我进行了一个简单的测试,基本上是可以的,但也有一点问题:
1、第一次查询结果是4条记录,当我手工往数据库中插入一条记录时,第二次查询还是4条记录
2、当我把系统时间改成第二天(24小时后),再查,得到的结果是5条记录
3、当我执行了InsertAccountViaParameterMap语句插入一条记录时,再查询得到的是6条记录

也就是说:当系统中的表从不进行手工维护,也不由第三方程序修改时,可以使用数据库缓存的方式提高效率

 
posted @ 2011-05-21 15:36 awp110 阅读(16) 评论(1) 编辑
 
 
IBatis.Net学习笔记(一)--两种常用的DAO
在IBatis中我们可以灵活的选择DAO类型,也就是可以在底层选用不同的数据库操作方式。有常规方式、配置文件的方式、Hibernet的方式等:
1、常规方式
和我们之前的ADO.NET开发较为类似,都是将sql语句写在cs代码中进行调用:
首先通过配置文件初始化:
            DomDaoManagerBuilder builder  =   new  DomDaoManagerBuilder();
            builder.Configure(
" dao "   +   " _ "   +  ConfigurationManager.AppSettings[ " database " +   " _ "
                
+  ConfigurationManager.AppSettings[ " providerType " +   " .config " );
            daoManager 
=  DaoManager.GetInstance( " SimpleDao " );        
相对应的配置文件如下:
     < context id = " SimpleDao "   default = " true " >
        
< properties resource = " http://www.cnblogs.com/database.config " />
        
        

        
< database >
            

            
< provider name = " sqlServer1.1 " />
            
< dataSource name = " iBatisNet "  connectionString = " data source=${datasource};database=${database};user id=${userid};password=${password};connection reset=false;connection lifetime=5; min pool size=1; max pool size=50 " />
        
database >
        
        
< daoFactory >
            
< dao  interface = " IBatisNet.DataAccess.Test.Dao.Interfaces.IAccountDao, IBatisNet.DataAccess.Test "  implementation = " IBatisNet.DataAccess.Test.Dao.Implementations.Ado.AccountDao, IBatisNet.DataAccess.Test " />
        
daoFactory >
    
context >
然后在对应的,比如AccountDao中写具体的查询sql等

2、配置方式
将sql语句放在配置文件中,书写和修改较灵活, 这也是比较常用的方式
首先通过配置文件初始化:
            DomDaoManagerBuilder builder  =   new  DomDaoManagerBuilder();
            builder.Configure(
" dao "   +   " _ "   +  ConfigurationManager.AppSettings[ " database " +   " _ "
                
+  ConfigurationManager.AppSettings[ " providerType " +   " .config " );
            daoManager 
=  DaoManager.GetInstance( " SqlMapDao " );        
相对应的配置文件如下:
     < context id = " SqlMapDao " >
        
< properties resource = " http://www.cnblogs.com/database.config " />
        

        
< database >
            
< dataSource name = " iBatisNet "  connectionString = " data source=${datasource};database=${database};user id=${userid};password=${password};connection reset=false;connection lifetime=5; min pool size=1; max pool size=50 " />
        
database >         
        
        
< daoSessionHandler id = " SqlMap " >
            

            
< property name = " resource "  value = " SqlMap_MSSQL_SqlClient.config " />

            

            

        
daoSessionHandler >
        
        
< daoFactory >
            
< dao  interface = " IBatisNet.DataAccess.Test.Dao.Interfaces.IAccountDao, IBatisNet.DataAccess.Test "  implementation = " IBatisNet.DataAccess.Test.Dao.Implementations.DataMapper.AccountDao, IBatisNet.DataAccess.Test " />
        
daoFactory >
    
context >
然后可以将每一张表的sql语句单独放在一个配置文件中,比如:
         < select id = " GetAccountsDynamic "  resultMap = " account-result "  parameterClass = " Hashtable "   >
            select top $MaximumAllowed$ 
*  from Accounts
            
< dynamic prepend = " where " >
                    
< isParameterPresent >
                    
< isNotEmpty prepend = " and "  property = " FirstName "   >
                            Account_FirstName LIKE 
' %$FirstName$% '
                    
isNotEmpty >
                    
< isNotEmpty prepend = " and "  property = " LastName "   >
                            Account_LastName LIKE 
' %$LastName$% '
                    
isNotEmpty >
                    
< isNotEmpty prepend = " and "  property = " EmailAddress "    >
                            Account_Email LIKE 
' %$EmailAddress$% '
                    
isNotEmpty >
                    
isParameterPresent >
                
dynamic >
                order by Account_LastName
        
select >

3、使用Hibernet方式
也就是使用Hibernet的数据库操作。

 
posted @ 2011-05-21 15:35 awp110 阅读(37) 评论(0) 编辑
 
 
使用IBatis开发心得

最近这段时间一直在用IBatis来进行开发。现在把这段时间的一些开发心得写出来,跟大家一起分享。

首先,IBatis可以说转变了我以前的一些思想。我们以前开发项目的时候,总是先建立好数据库,分析清楚表与表之间的关系,才开始根据这些表进行实际的开发。实际上并没有完全把面向对象的优势展现出来。

现在的使用IBatis。顺序可以是这样,首先项目经理会分析整个项目,可以分成为几个对象,每个对象具有什么属性,什么方法。同时会用visio画出UML图来。这样可以说把面向对象的优势完全体现出来了。 然后程序员会根据UML图来操作对象,实现每个对象的属性和方法。这样就可以完全脱离数据库,去考虑程序的问题。这种开发方式特别适合于团队开发,团队中有专门的人去负责数据的建立,他可以根据项目中的Maps图清晰的知道每个数据表中的字段。

 
posted @ 2011-05-21 15:33 awp110 阅读(40) 评论(0) 编辑
 
 
iBatis中使用动态查询

iBatis中的动态查询还是比较好用的

如果想深入学习,可以参考 Manning.iBATIS.in.Action.Jan.2007

下面给出几个例子和dtd定义:



   update SGS_KEY_FLOW set
  
     KEY_FLOW_ID =#keyFlowId#
   
     BRANCH_NAME = #branchName#
   

   
     OPERATION = #operation#
   

   
     INITIATOR = #initiator#
   

   
     INITIATOR_EMAIL = #initiatorEmail#
   

   
     INIT_DATE = #initDate#
   

   
     APPROVER = #approver#
   

   
     APPROVER_EMAIL = #approverEmail#
   

   
     APPROVE_DATE = #approveDate#
   

   
     KEY_NUM = #keyNum#
   

   
     APPLY_REASON = #applyReason#
   

   
     REJECT_REASON = #rejectReason#
   
                       
  

   where
    KEY_FLOW_ID =#keyFlowId#

0:26 2008-2-20补充:

让iBatis中的insert返回主键 [ibatis insert 返回 自增主键]

iBatis SQL-map 文件书写注意事项

 

http://ibatis.apache.org/dtd/sql-map-2.dtd 中有的定义


prepend CDATA #IMPLIED
open CDATA #IMPLIED
close CDATA #IMPLIED
>


prepend CDATA #IMPLIED
open CDATA #IMPLIED
close CDATA #IMPLIED
property CDATA #IMPLIED
removeFirstPrepend (true|false) #IMPLIED
>


prepend CDATA #IMPLIED
open CDATA #IMPLIED
close CDATA #IMPLIED
property CDATA #IMPLIED
removeFirstPrepend (true|false) #IMPLIED
>


prepend CDATA #IMPLIED
open CDATA #IMPLIED
close CDATA #IMPLIED
property CDATA #REQUIRED
removeFirstPrepend (true|false) #IMPLIED
>


prepend CDATA #IMPLIED
open CDATA #IMPLIED
close CDATA #IMPLIED
property CDATA #REQUIRED
removeFirstPrepend (true|false) #IMPLIED
>


prepend CDATA #IMPLIED
open CDATA #IMPLIED
close CDATA #IMPLIED
property CDATA #IMPLIED
removeFirstPrepend (true|false) #IMPLIED
compareProperty CDATA #IMPLIED
compareValue CDATA #IMPLIED
>


prepend CDATA #IMPLIED
open CDATA #IMPLIED
close CDATA #IMPLIED
property CDATA #IMPLIED
removeFirstPrepend (true|false) #IMPLIED
compareProperty CDATA #IMPLIED
compareValue CDATA #IMPLIED
>


prepend CDATA #IMPLIED
open CDATA #IMPLIED
close CDATA #IMPLIED
property CDATA #IMPLIED
removeFirstPrepend (true|false) #IMPLIED
compareProperty CDATA #IMPLIED
compareValue CDATA #IMPLIED
>


prepend CDATA #IMPLIED
open CDATA #IMPLIED
close CDATA #IMPLIED
property CDATA #IMPLIED
removeFirstPrepend (true|false) #IMPLIED
compareProperty CDATA #IMPLIED
compareValue CDATA #IMPLIED
>


prepend CDATA #IMPLIED
open CDATA #IMPLIED
close CDATA #IMPLIED
property CDATA #IMPLIED
removeFirstPrepend (true|false) #IMPLIED
compareProperty CDATA #IMPLIED
compareValue CDATA #IMPLIED
>


prepend CDATA #IMPLIED
open CDATA #IMPLIED
close CDATA #IMPLIED
property CDATA #IMPLIED
removeFirstPrepend (true|false) #IMPLIED
compareProperty CDATA #IMPLIED
compareValue CDATA #IMPLIED
>


prepend CDATA #IMPLIED
open CDATA #IMPLIED
close CDATA #IMPLIED
property CDATA #IMPLIED
removeFirstPrepend (true|false) #IMPLIED
>


prepend CDATA #IMPLIED
open CDATA #IMPLIED
close CDATA #IMPLIED
property CDATA #IMPLIED
removeFirstPrepend (true|false) #IMPLIED
>


prepend CDATA #IMPLIED
open CDATA #IMPLIED
close CDATA #IMPLIED
removeFirstPrepend (true|false) #IMPLIED
>


prepend CDATA #IMPLIED
open CDATA #IMPLIED
close CDATA #IMPLIED
removeFirstPrepend (true|false) #IMPLIED
>


prepend CDATA #IMPLIED
property CDATA #IMPLIED
removeFirstPrepend (true|false|iterate) #IMPLIED
open CDATA #IMPLIED
close CDATA #IMPLIED
conjunction CDATA #IMPLIED
>

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/alex197963/archive/2008/11/27/3391551.aspx

 
posted @ 2011-05-21 15:22 awp110 阅读(85) 评论(0) 编辑
 
 
iBatis解决sql注入

iBatis解决sql注入

(1) ibatis xml配置:下面的写法只是简单的转义 name like '%$name$%'

(2) 这时会导致sql注入问题,比如参数name传进一个单引号“'”,生成的sql语句会是:name like '%'%'

(3) 解决方法是利用字符串连接的方式来构成sql语句 name like '%'||'#name#'||'%'

(4) 这样参数都会经过预编译,就不会发生sql注入问题了。

(5) #与$区别:

#xxx# 代表xxx是属性值,map里面的key或者是你的pojo对象里面的属性, ibatis会自动在它的外面加上引号,表现在sql语句是这样的 where xxx = 'xxx' ;

$xxx$ 则是把xxx作为字符串拼接到你的sql语句中, 比如 order by topicId , 语句这样写 ... order by #xxx# ibatis 就会把他翻译成 order by 'topicId' (这样就会报错) 语句这样写 ... order by $xxx$ ibatis 就会把他翻译成 order by topicId

转载于:https://www.cnblogs.com/panlijuan/archive/2011/12/09/2282300.html

你可能感兴趣的:(iBatis.net入门指南)