http://down2.51aspx.com/StarFramework.rar
https://files.cnblogs.com/hjf1223/iBatisDemo.rar

 使用ibatis框架做项目:
共五层:
一、显示层(Web项目);
二、业务逻辑层(NPetshop.Presentation)
三、数据模型层(NPetshop.Domain)
四、接口(NPetshop.Persistence)(有人叫持久层)
五、服务层(NPetshop.Service)

我觉得流程是这样的:
当显示层(Web项目)需要数据时,它向业务逻辑层(NPetshop.Presentation)发送请求,因此在逻辑层将有一个专门的类来处理与

此请求相似的操作,
此时业务逻辑层将建立一个方法,这个方法直接调用服务层(NPetshop.Service)的方法来实现,而服务层则通过ibatis里的

IBatisNet.DataAccess组件
将数据模型层(NPetshop.Domain)和接口(NPetshop.Persistence.Interfaces)联系起来,而接口层的接口是通过接口层的接口图

(NPetshop.Persistence.MapperDao)来实现的,
最后,接口图则通过继承上面的接口,以及利用ibatis里的IBatisNet.DataMapper组件来实现对数据库的访问。
以上是我看ibatis框架做项目的一点总结,以下是我觉得要弄懂的几个要点:

第一:逻辑层对服务层方法的调用?
第二:服务层如何实现与接口的调用?
第三:接口和接口的继承是如何实现的?
第四:接口类图是如何调用ibatis框架的?
第五:ibatis框架的基层是如何实现对数据库的访问的?

以下是ibatis的一点资料:
ibatis包括DataAccess and DataMapper
整个Solution(工程)包括三个主项目:
IBatisNet.Common
IBatisNet.DataAccess
IBatisNet.DataMapper
和一个辅助项目:IBatisNet.Common.Logging.Log4Net
说明:
Common项目是DataAccess和DataMapper的公共基础,提供通用功能和公共服务;
DataAccess是DAO框架,DataMapper是SqlMap映射框架;Common.Logging.Log4Net是对log4net日志服务的代理,利用log4net日志框

架产生和输出日志。


NetPetshop 研究学习(一)


1  NetPetshop是采用了数据库持久层采用O/RM工具iBatisNet。
  采用了典型的三层结构。分层如下:
  数据访问层:NPetshop.Service,NPetshop.Persistence,NPetshop.Domain
  业务逻辑层:NPetshop.Presentation
  表示层:NPetshop.Web
2 以用户帐户注册页面的为例说明调用关系:
D:\NPetShop\NPetshop\NPetshop.Web\Default.aspx.cs
调用如下类:
D:\NPetShop\NPetshop\NPetshop.Web\UserControls\Accounts\NewAccount.ascx.cs
调用如下类:
D:\NPetShop\NPetshop\NPetshop.Presentation\UserActions\AccountAction.cs
调用如下类:
D:\NPetShop\NPetshop\NPetshop.Service\AccountService.cs
调用如下类:
D:\NPetShop\NPetshop\NPetshop.Persistence\MapperDao\Accounts\AccountSqlMapDao.cs
调用如下类:
D:\NPetShop\NPetshop\NPetshop.Persistence\MapperDao\BaseSqlMapDao.cs

3 如何读取dao.config,SqlMap.config配置文件

D:\NPetShop\NPetshop\NPetshop.Service\ServiceConfig.cs
如下代码:
        static public ServiceConfig GetInstance()
        {
            if (_instance == null)
            {
                lock (_synRoot)
                {
                    if (_instance == null)
                    {
                        ConfigureHandler handler = new ConfigureHandler(ServiceConfig.Reset);

                        DomDaoManagerBuilder builder = new DomDaoManagerBuilder();
                        builder.ConfigureAndWatch("dao.config", handler);

                        _instance = new ServiceConfig();
                        _instance._daoManager = IBatisNet.DataAccess.DaoManager.GetInstance("SqlMapDao");
                    }
                }
            }
            return _instance;
        }

       
       
5 利用<asp:repeater/>控件绑定数据
<asp:repeater id="RepeaterItems" runat="server">
      <headertemplate>
       <table cellpadding="0" cellspacing="1">
        <tr class="gridHead">
         <td>Line</td>
         <td>Item</td>
         <td>Product</td>
         <td>Price</td>
         <td>Quantity</td>
         <td>Subtotal</td>
        </tr>
      </headertemplate>
      <itemtemplate>
       <tr class="gridItem">
        <td><%# DataBinder.Eval(Container.DataItem, "LineNumber") %></td>
        <td><%# DataBinder.Eval(Container.DataItem, "Item.Id") %></td>
        <td><%# DataBinder.Eval(Container.DataItem, "Item.Product.Id") %></td>
        <td class="num"><%# DataBinder.Eval(Container.DataItem, "Item.ListPrice", "{0:c}") %></td>
        <td class="num"><%# DataBinder.Eval(Container.DataItem, "Quantity") %></td>
        <td class="num"><%# DataBinder.Eval(Container.DataItem, "Total", "{0:c}") %></td>
       </tr>
      </itemtemplate>
      <footertemplate></table></footertemplate>
</asp:repeater>


我会跟着该例子创建一个实例代码.

补充以下,IBatisNet包括两个部分Data Mapper和DataAccess,这个实例主要针对 Data Mapper的.

1.在我们MSSQL中建立表如下:

create database IBatisDemo go use IBatisDemo if exists(select * from sysobjects where type='u' and name='Person') drop table dbo.Person go create table dbo.Person ( PER_ID int not null, PER_FIRST_NAME varchar(20) null, PER_LAST_NAME varchar(20) null, PER_BIRTH_DATE smalldatetime null, PER_WEIGHT_KG decimal null, PER_HEIGHT_M decimal null, primary key(PER_ID) )

2.使用VS2003创建WebProject,名称为WebIBatis(注意大小写)

3.在项目目录下建立lib目录,复制IBatisNet必需的dll,如下:
IBatisNet.Common.dll
IBatisNet.DataMapper.dll
IBatisNet.DataAccess.dll
log4net.dll
Castle.DynamicProxy.dll
并在项目中添加这些dll的引用

4.创建模型对象
在项目中创建目录 Model,并在该目录下创建Person类文件

using System; namespace WebIBatis.Model { /// /// Person 的摘要说明。 /// public class Person { private int _Id; public int Id { get { return _Id; } set { _Id = value; } } private string _FirstName; public string FirstName { get { return _FirstName; } set { _FirstName = value; } } private string _LastName; public string LastName { get { return _LastName; } set { _LastName = value; } } private DateTime _BirthDate; public DateTime BirthDate { get { return _BirthDate; } set { _BirthDate = value; } } private decimal _WeightInKilograms; public decimal WeightInKilograms { get { return _WeightInKilograms; } set { _WeightInKilograms = value; } } private decimal _HeightInMeters; public decimal HeightInMeters { get { return _HeightInMeters; } set { _HeightInMeters = value; } } } }


这个类就是对Person的一个描述,只包含一些属性,这就是这个系统的数据的载体

4.定义实体定义的XML
在项目目录下建Maps目录下,在该目录下建立Person.xml

xml version="1.0" encoding="utf-8" ?> <sqlMap namespace="Person" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="SqlMap.xsd"> XML "behind" document for the People service class. --> <alias> <typeAlias alias="Person" type="WebIBatis.Model.Person, WebIBatis" /> alias> <resultMaps> <resultMap id="SelectResult" class="Person"> <result property="Id" column="PER_ID" /> <result property="FirstName" column="PER_FIRST_NAME" /> <result property="LastName" column="PER_LAST_NAME" /> <result property="BirthDate" column="PER_BIRTH_DATE" /> <result property="WeightInKilograms" column="PER_WEIGHT_KG" /> <result property="HeightInMeters" column="PER_HEIGHT_M" /> resultMap> resultMaps> <statements> <select id="Select" parameterClass="int" resultMap="SelectResult"> select PER_ID, PER_FIRST_NAME, PER_LAST_NAME, PER_BIRTH_DATE, PER_WEIGHT_KG, PER_HEIGHT_M from PERSON <dynamic prepend="WHERE"> <isParameterPresent> PER_ID = #value# isParameterPresent> dynamic> select> <insert id="Insert" parameterClass="Person" resultClass="int"> 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#) insert> <update id="Update" parameterClass="Person" resultClass="int"> update PERSON set PER_FIRST_NAME = #FirstName#, PER_LAST_NAME = #LastName#, PER_BIRTH_DATE = #BirthDate#, PER_WEIGHT_KG = #WeightInKilograms#, PER_HEIGHT_M = #HeightInMeters# where PER_ID = #Id# update> <delete id="Delete" parameterClass="int" resultClass="int"> delete from PERSON where PER_ID = #value# delete> statements> sqlMap>

 

<typeAlias alias="Person" type="WebIBatis.Model.Person, WebIBatis" />表示为WebIBatis.Model.Person取了个别名,这样在下面的class=别名就可以了
resultMap 是数据库字段和Person的类的对应关系,也是SQL语句操作的结果的载体,其作用就是,SQL语句操作返回的数据的值根据这个resultMap的定义,将相应的字段的值赋给Person类对应的属性.

5.定义数据连接
在项目根目录下定义 sqlmap.config

xml version="1.0" encoding="UTF-8" ?> <sqlMapConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="SqlMapConfig.xsd"> <settings> <setting useStatementNamespaces="false"/> <setting cacheModelsEnabled="true"/> settings> <database> <provider name="sqlServer1.1"/> <dataSource name="iBatisTutorial" connectionString="server=.;User ID=sa;Password=;database=IBatisDemo;
Connection Reset=FALSE"/> database> <sqlMaps> <sqlMap resource="Maps/Person.xml"/> sqlMaps> sqlMapConfig>

并拷贝providers.config文件到根目录,该文件定义各种数据库的驱动,包括SqlServer, Oracle, MySQL, PostgreSQL, DB2 and OLEDB, ODBC

 

 

6.定义Mapper
在根目录下创建Mapper类,该类是得到单一的SqlMapper对象

using IBatisNet.Common.Utilities; using IBatisNet.DataMapper; namespace WebIBatis { /// /// Mapper 的摘要说明。 /// public class Mapper { private static volatile SqlMapper _mapper = null; protected static void Configure (object obj) { _mapper = (SqlMapper) obj; } protected static void InitMapper() { ConfigureHandler handler = new ConfigureHandler (Configure); _mapper = SqlMapper.ConfigureAndWatch (handler); } public static SqlMapper Instance() { if (_mapper == null) { lock (typeof (SqlMapper)) { if (_mapper == null) // double-check InitMapper(); } } return _mapper; } public static SqlMapper Get() { return Instance(); } } }

 

7.取数据
在Webform1.aspx窗体添加一DataGrid,在后置代码的Page_Load中添加代码如下:

IList list = Mapper.Instance().QueryForList("Select",null); DataGrid1.DataSource = list; DataGrid1.DataBind();

其中Select是在Person中定义的statements

8.其他操作的写法

//添加 Person newperson = new Person(); //给person赋值 newperson.FirstName = "姚"; //.... Mapper.Instance().Insert("Insert",newperson); //查看明细和修改 //根据ID得到明细 int id = 1; //得到Person对象 Person person = Mapper.Instance().QueryForObject("Select",id) as Person; //修改person的值 person.LastName = "国荣"; Mapper.Instance().Update("Update",person);

IBatisNet系列-执行存储过程

映射xml文件书写如下
<?xml version="1.0" encoding="utf-8" ?>

<sqlMap namespace="Member" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="SqlMap.xsd">
    <resultMaps>
        <resultMap id="SelectResult" class="PlatAdmin.Model.Member">
            <result property="Id" column="id" />
            <result property="Identityno" column="identityno" />
            <result property="Telephone" column="telephone" />
            <result property="Email" column="email" />
            <result property="Linktel" column="linktel" />
            <result property="Address" column="address" />
            <result property="Content" column="content" />
            <result property="Username" column="username" />
            <result property="Password" column="password" />
            <result property="Truename" column="truename" />
            <result property="Enable" column="enable" />
            <result property="Regdate" column="regdate" />
        </resultMap>
    </resultMaps>
        
    <parameterMaps>
        <parameterMap id="swapParas" class="PlatAdmin.Model.Member">
            <parameter property="querystr" column="" />
            <parameter property="keyfield" column="" />
            <parameter property="pagesize" column="" />
            <parameter property="pagenumber" column="" />
        </parameterMap>
    </parameterMaps>
    
    <statements>
        <procedure id="GetMemberList" parameterMap="swapParas" resultMap="SelectResult">
            usp_GetRecordset
        </procedure>

        
    </statements>
</sqlMap>

 程序代码如下:
public IList GetMemberList(string querystr,int pageNo)
        {
            Hashtable ht = new Hashtable();
            ht.Add("querystr",querystr);
            ht.Add("keyfield","id");
            ht.Add("pagesize",2);
            ht.Add("pagenumber",pageNo);

            SqlMapper sqlMap = IBatisNet.DataMapper.Mapper.Instance();

            try
            {
                return sqlMap.QueryForList("GetMemberList",ht);
            }
            catch(Exception e)
            {
                throw new IBatisNetException(e.Message,e);
            }
        }


由于本人对IBatis.Net的并不是很精通,也是在边学边工作实践,所以IBatis.Net系列的文章会显的没有一定的连贯性,
这些文章应该是我平时的关于IBatis.Net的一些知识的积累吧。下面进入正题:

我们在使用IBatis.net操作数据的时候,肯定会碰到SQL参数
当我们有一个参数时,IBatis的xml映射文件如下:
<statement id="getProduct" parameterClass="System.Int32">
  select * from PRODUCT where PRD_ID = #value#
</statement>

当我们有多个参数时,xml如下:
<statement id="getProduct" parameterClass="System.Collections.IDictionary">
  select * from PRODUCT
  where PRD_CAT_ID = #catId#
  and PRD_CODE = #code#
</statement>

在代码中必须赋给他一个Hashtable,并且这个Hashtable具有catId和code两个键值,注意要区分大小写。

当我们执行存储过程的时候,xml如下:
首先定义参数定义集合
<parameterMaps>
 <parameterMap id="insertperson" class="Person">
  <parameter property="FirstName" column="PER_FIRST_NAME" />
  <parameter property="LastName" column="PER_LAST_NAME" />
 </parameterMap>
</parameterMaps>

然后定义操作
<!--使用存储过程-->
<procedure id="InsertPerson3" parameterMap="insertperson" resultMap="SelectResult">
 usp_InsertPerson
</procedure>

程序代码如下:
public void InsertPerson3()
{
 SqlMapper sqlmap = IBatisNet.DataMapper.Mapper.Instance();

 Hashtable ht = new Hashtable();
 ht.Add("FirstName","姚");
 ht.Add("LastName","明2");

 sqlmap.Insert("InsertPerson3",ht);
}

注意:Hashtable中的键值名称和参数集合众的property相对应,并且区分大小写.


最近有人问我怎么获取存储过程的output的参数值,由于我最近没有用Ibatis.net,所以就从文档中找到的param的xml,也就没有在意,但后来有人说调不通,今天早上又收到一份留言,所以我早上作了测试!也出现获取不到数据的问题,但最后还是解决了!我的测试环境是 sqlserver2005/vs2005/ibatis.net2.0
如下:
procedure:
create proc sp_output
(
    @testParam    int    output
)
as
begin
    set @testParam = 10
end
go

xml:
  <parameterMaps>
    <parameterMap id="select-params2" class="Hashtable">
      <parameter property="testParam" column="testParam" direction="Output" />
    </parameterMap>
  </parameterMaps>

  <statements>

    <procedure id="GetAccountViaSP2" parameterMap="select-params2">
      sp_output
    </procedure>
  </statements>

code:
int testid = 0;
            Hashtable map = new Hashtable();
            map.Add("testParam", testid);

            mapper.Insert("GetAccountViaSP2", map);

            Console.WriteLine(map["testParam"].ToString());

注意,在parammap定义的时候需要设置class=Hashtable,用class=int,就获取不到!

在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 )
ENDMap配置文件:
        <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);
            }
        }

iBATIS.NET多表查询方法是什么呢?让我们从实例出发逐步认识:

建两张表Account和Degree,使用Account_ID关联,需要查出两张表的所有纪录

首先:修改实体类,增加以下属性:

   1. private Degree _degree;  
   2.  public Degree Degree  
   3.  {  
   4.      get  
   5.      {  
   6.          return _degree;  
   7.      }  
   8.      set  
   9.      {  
  10.          _degree = value;  
  11.      }  
  12.  }

然后:修改配置文件,这也是最重要的地方(PS:iBATIS.NET中的配置文件真的很强)

在resultMaps节加入:

   1. ﹤resultMap id="com2result"  class="Account" ﹥  
   2.   ﹤result property="Id"           column="Account_ID"/﹥  
   3.   ﹤result property="FirstName"    column="Account_FirstName"/﹥  
   4.   ﹤result property="LastName"     column="Account_LastName"/﹥  
   5.   ﹤result property="EmailAddress" column="Account_Email" nullValue="no_email@provided.com"/﹥  
   6.   ﹤result property="Degree"  resultMapping="Account.Degree-result"/﹥  
   7. ﹤/resultMap﹥  
   8.  
   9. ﹤resultMap id="Degree-result"  class="Degree"﹥  
  10.   ﹤result property="Id"           column="Account_ID"/﹥  
  11.   ﹤result property="DegreeName"    column="DegreeName"/﹥  
  12. ﹤/resultMap﹥

这里最主要的就是使用了resultMapping属性,resultMapping="Account.Degree-result",其中 Account是当前配置文件的namespace:

   1. ﹤sqlMap namespace="Account"  ......

在statements节加入:

   1. ﹤select id="GetCom2Tables"
   2.  resultMap="com2result"﹥  
   3.   select Accounts.*, Degree.*  
   4.   from Accounts,Degree  
   5.   where Accounts.Account_ID = Degree.Account_ID  
   6. ﹤/select﹥

这样就可以随心所欲的写自己需要的sql,性能也很好,不会出现第三种方法中的1+n条的查询语句了。

那么,iBATIS.NET多表查询方法就向你介绍到这里,希望对你了解iBATIS.NET多表查询方法有所帮助。

 1using System;
 2using NUnit.Framework;
 3  
 4namespace NUnitQuickStart
 5{
 6            [TestFixture]
 7            public class NumersFixture
 8            {
 9                        [Test]
10                        public void AddTwoNumbers()
11                        {
12                                    int a=1;
13                                    int b=2;
14                                    int sum=a+b;
15                                    Assert.AreEqual(sum,3);
16                        }
17            }
18}
19

Ignore 属性 使用Ignore属性.你可以保持测试,但又不运行它们.
posted on 2011-01-12 09:46  芝麻开门  阅读(2538)  评论(0编辑  收藏  举报