第一次學習Mybatis.net,在博客園也找到好多資料,但是在配置成功之后也遇到了一些問題,尤其是在動態SQl拼接時候,這里把遇到的問題還有自己寫的一個Demo貼出來,希望能幫到新手,有不適合的地方也希望大家指出,大家互相學習,共同進步。
首先我們需要下載IBatisNet程序包,這里就不多說了
一、創建一個MVC4的Web應用程序,並引用我們下載的IBatisNet程序包中的IBatisNet.DataMapper.dll,這里我只引用了這一個,log4net我沒有引用也沒有配置使用,全部程序結構如下
二、添加Providers.config,並復制到項目根目錄下
把下載的IBatisNet程序包打開,就能找到providers.config文件,里面定義了MyBatis.Net支持的各種數據庫驅動,這里我以sqlServer為例,把其他不用的全部刪除,只留下sqlServer的並且把版本號全部改為4.0,同時把enabled屬性設置成true,如下:

<?xml version="1.0" encoding="utf-8"?> <providers xmlns="http://ibatis.apache.org/providers" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <clear/> <!--設置enabled=true--> <provider name="sqlServer4.0" enabled="true" description="Microsoft SQL Server, provider V4.0.0.0 in framework .NET V4.0" assemblyName="System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" connectionClass="System.Data.SqlClient.SqlConnection" commandClass="System.Data.SqlClient.SqlCommand" parameterClass="System.Data.SqlClient.SqlParameter" parameterDbTypeClass="System.Data.SqlDbType" parameterDbTypeProperty="SqlDbType" dataAdapterClass="System.Data.SqlClient.SqlDataAdapter" commandBuilderClass=" System.Data.SqlClient.SqlCommandBuilder" usePositionalParameters = "false" useParameterPrefixInSql = "true" useParameterPrefixInParameter = "true" parameterPrefix="@" allowMARS="false" /> </providers>
三、在項目目錄下添加SqlMap.config,它的作用主要是指定db連接串,告訴系統providers.config在哪? 以及db與entity的映射文件在哪?如下:

<?xml version="1.0" encoding="utf-8"?> <sqlMapConfig xmlns="http://ibatis.apache.org/dataMapper" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <settings> <setting useStatementNamespaces="false"/> <!--true表示statementName要使用Namespace--> <setting cacheModelsEnabled="true"/> </settings> <providers resource="providers.config"/><!--指定providers.config文件的路徑--> <!-- Database connection information --> <database> <provider name="sqlServer4.0"/><!--設置數據庫連接字符串--> <dataSource name="DB" connectionString="Data Source=.;Initial Catalog=DemoDB;uid=sa;pwd=123"/> </database> <!--db與Entity的映射文件--> <sqlMaps> <sqlMap resource="Maps/PersonAndCour.xml"/> <sqlMap resource="Maps/PersonMap.xml"/> </sqlMaps> </sqlMapConfig>
四、這里在數據庫建兩張表一個是個人信息還有一個是課程表,如下:
第一張表是Person表,第二張表為Cour課程表,課程表名字是錯的只敲一半,大家略過,第一張表的ID和第二張表的PerID關聯,建兩張表是為了后面的聯合查詢,這里先不多說
五、接下來我們在EntityModel文件夾下建立兩個實體類一個是Person類和一個定義實體類PersonAndCour,而自定義實體類就比Person類多一個字段,就是課程名稱,這里就只貼這一個代碼 ,如下:

using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace MyBatisNet.EntityModel { public class PersonAndCour { public int ID { get; set; } public string Name { get; set; } public int Age { get; set; } public string Sex { get; set; } public string CourseName { get; set; } } }
六、我們在項目根目錄下建Maps文件夾,並在文件夾中創建PersonMap.xml映射文件,如下

<?xml version="1.0" encoding="utf-8" ?> <sqlMap namespace="MyBatisNet" xmlns="http://ibatis.apache.org/mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <alias> <!--類的別名--> <typeAlias alias="Person" type="MyBatisNet.EntityModel.Person,MyBatisNet"/> </alias> <resultMaps> <!--Person類與db表的映射--> <resultMap id="PersonResult" class="Person"> <result property="ID" column="ID"/> <result property="Name" column="Name"/> <result property="Age" column="Age" /> <result property="Sex" column="Sex" /> </resultMap> </resultMaps> <statements> <!--插入Sql語句--> <insert id="Add" parameterClass="Person" resultClass="Int32"> insert into Person(Name,Age,Sex)values(#Name#,#Age#,#Sex#) <selectKey property="ID" resultClass="int" type="post" > SELECT @@identity AS ID </selectKey> </insert> <!--修改Sql語句--> <update id="Update" parameterClass="Person"> update Person set Name=#Name#,Age=#Age#,Sex=#Sex# where ID=#ID# </update> <!--根據主鍵刪除單條記錄--> <delete id="Delete" parameterClass="Int32"> delete Person where ID=#ID# </delete> <!--查詢單個實體Sql語句--> <select id="Get" parameterClass="Int32" resultMap="PersonResult"> select * from Person where ID=#ID# </select> <!--查詢所有記錄--> <select id="GetList" resultMap="PersonResult"> <![CDATA[select * from Person where ID<4]]> </select> </statements> </sqlMap>
我們可以看到這段代碼里有一個命名空間,如下:
這個命名空間與此文件中的 statements標簽中配置的SQL語句的id有關,在大型項目中,可能存在大量的 SQL 語句,這時候,為每個SQL 語句起一個唯一的標識id 就變得並不容易了。為了解決這個問題,在 mybatis 中,可以為每個映射文件起一個唯一的命名空間,這樣,定義在這個映射文件中的每個 SQL 語句就成了定義在這個命名空間中的一個 id。只要我們能夠保證每個命名空間是唯一的,即使在不同映射文件中的語句的 id 相同,也就不會沖突了。(這段是網上復制的),這個是在SqlMap.config配置文件中控制的,就是這個標簽 <setting useStatementNamespaces="false"/>。
七、接下來我們就要在SqlMap.config文件中配置這個映射文件的路徑了,上面的代碼里面我們已經配好了,
八、在XML映射文件中我們已經寫好的基礎的增、刪、改、查SQL語句,接下來我們在項目中建一個Common文件夾,里面寫一個通用的BaseDA類,里面進行ISqlMapper的實例化,以及對MyBatis.Net做些基本的封裝(這個是網上復制的)

using IBatisNet.DataMapper; using IBatisNet.DataMapper.Configuration; using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace MyBatisNet.Common { public class BaseDA { public static int Insert<T>(string statementName, T t) { ISqlMapper iSqlMapper = Mapper.Instance(); if (iSqlMapper != null) { return (int)iSqlMapper.Insert(statementName, t); } return 0; } public static int Update<T>(string statementName, T t) { ISqlMapper iSqlMapper = Mapper.Instance(); if (iSqlMapper != null) { return iSqlMapper.Update(statementName, t); } return 0; } public static int Delete(string statementName, int primaryKeyId) { ISqlMapper iSqlMapper = Mapper.Instance(); if (iSqlMapper != null) { return iSqlMapper.Delete(statementName, primaryKeyId); } return 0; } public static T Get<T>(string statementName, int primaryKeyId) where T : class { ISqlMapper iSqlMapper = Mapper.Instance(); if (iSqlMapper != null) { return iSqlMapper.QueryForObject<T>(statementName, primaryKeyId); } return null; } public static IList<T> QueryForList<T>(string statementName, object parameterObject = null) { ISqlMapper iSqlMapper = Mapper.Instance(); if (iSqlMapper != null) { return iSqlMapper.QueryForList<T>(statementName, parameterObject); } return null; } } }
九、現在我們就可以控制器中進行操作了
這樣我們就可以查詢到Person類的全部信息了,這里方法中的第一個參數就是我們映射文件中SQL語句標簽中的id名稱,其他的增、刪、改都一樣,就不多說了
十,接下來我們看看我們多表聯合查詢,動態SQl拼接,以及SQL片段的使用,我們這里用到上面的PersonAndCour.cs這個自定義類
我們先添加PersonAndCour.xml這個映射文件

<?xml version="1.0" encoding="utf-8" ?> <sqlMap namespace="MyBatisNet" xmlns="http://ibatis.apache.org/mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <alias> <!--類的別名--> <typeAlias alias="PersonAndCour" type="MyBatisNet.EntityModel.PersonAndCour,MyBatisNet"/> </alias> <resultMaps> <!--Product類與db表的映射--> <resultMap id="PersonAndCourResult" class="PersonAndCour"> <result property="ID" column="ID"/> <result property="Name" column="Name"/> <result property="Age" column="Age" /> <result property="Sex" column="Sex" /> <result property="CourseName" column="CourseName" /> </resultMap> </resultMaps> <statements> <!--sql片段,重復使用--> <sql id="testSql"> select p.ID,p.Name,p.Age,p.Sex,c.CourseName from Person p inner join cour c on p.ID= c.PerID </sql> <!--查詢所有記錄--> <select id="GetList1" resultMap="PersonAndCourResult"> select p.ID,p.Name,p.Age,p.Sex,c.CourseName from Person p inner join cour c on p.ID= c.PerID </select> <!--多條件查詢--> <select id="GetList2" parameterClass="PersonAndCour" resultMap="PersonAndCourResult"> select p.ID,p.Name,p.Age,p.Sex,c.CourseName from Person p inner join cour c on p.ID= c.PerID <dynamic perpend="where"> <!--姓名不為NUll--> <isNotEmpty property="Name" prepend="And" > p.Name=#Name# </isNotEmpty> <!--年齡大於0--> <isGreaterThan prepend="and" property="Age" compareValue="0"> p.Age = #Age# </isGreaterThan> </dynamic> </select> <select id="GetList3" resultMap="PersonAndCourResult"> <!--<include refid="sql片段" />--> <include refid="testSql" /> </select> </statements> </sqlMap>
這里面已經把SQL寫好了,現在我們在控制器里執行,如下:
a.先說下SQL片段,我們在查詢分頁時的查詢拼接條件或都其他查詢時,可能同一段代碼重復使用,這時我們就可以利用SQL片段,把重利利用的SQL代碼提取出來,如PersonAndCour.xml里一樣,這樣我們用<include refid="testSql" />這一句就可以引用上面的SQL語句,這里的refid就是SQl片段中id的名字
b.再說說多條件查詢時動態拼接SQl語句,如下圖
這里我們傳入的參數是PersonAndCour,輸出的參數也是這個, 這個參數我們也可以自己定義,需要幾個字段就定義幾個字段,但在這里時要寫全名比如:parameterClass="MyBatisNet.EntityModel.whereModel",還有之前在博客園找到的動態SQL拼接的都是JAVA目錄,進而是直接用<where>標簽嵌套<if>標簽,我在項目中也使用這種方式,但是<where>標簽的里的語句就是不執行,最后在網上找了好多,最后發現用<dynamic>標簽之后里面的語句就可以拼接成功了,原因現在還不知道,那位大神知道可以告知下,<dynamic>標簽里面的判斷條件整理了如下幾個類型:
(1)、一元條件
(2)、二元條件
(3)其他
十一、最后說一下自己嘗試的事務,如果大家有更好的建議可以提出來大家一起分享
(1)、直接把事務寫在SQL語句里面,如下
(1)映射文件的中還是單一的條插入SQL語句,我們在控制器中使用事務,如下:
好了,到這里基本上已經全部寫完了,好多是在網上找的資料,有些是自己嘗試的,文章也是在做完DEMO后才寫的,所以有遺漏的地方還望見諒,有錯誤的地方,或需要改進的地方望大家提出來一起分享,共同成長。