学习MyBatis.Net之路 (三)

时间:2022-09-23 19:48:55

11接下来我们看看我们多表联合查询,动态SQl拼接,以及SQL片段的使用,我们这里用到上面的PersonAndCour.cs这个自定义类
我们先添加PersonAndCourse.xml这个映射文件

<?xml version="1.0" encoding="utf-8" ?>
<sqlMap namespace="PratiseMyBatis" xmlns="http://ibatis.apache.org/mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">


<alias>
<!--类的别名-->
<typeAlias alias="PersonAndCourse" type="PratiseMyBatis.Models.PersonAndCourse,PratiseMyBatis" />
</alias>


<resultMaps>
<!--PersonAndCourse类和DB类的映射-->
<resultMap id="PersonAndCourseResult" class="PersonAndCourse">
<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 Course c on p.ID=c.PerID
</sql>

<select id="GetList1" resultMap="PersonAndCourseResult">
select p.Id,p.Name,p.Age,p.Sex,c.CourseName from Person p inner join Course c on p.ID=c.PerID
</select>

<!--多条件查询-->
<select id="GetList2" parameterClass="PersonAndCourse" resultMap="PersonAndCourseResult">
select p.Id,p.Name,p.Age,p.Sex,c.CourseName from Person p inner join Course c on p.ID=c.PerID
<dynamic prepend="where">
<!--姓名不能为空-->
<isNotEmpty property="Name" prepend="And">
p.Name=#Name#
</isNotEmpty>
<!--年龄大于零-->
<isGreaterThan property="Age" prepend="And" compareValue="0">
p.Age=#Age#
</isGreaterThan>
</dynamic>
</select>

<select id="GetList3" resultMap="PersonAndCourseResult">
<!--使用重复的sql语句-->
<include refid="testSql"/>
</select>


<insert id="Add1" parameterClass="System.Collections.IDictionary" resultClass="Int32" >
Begin try
Begin tran
declare @id int
set @id=(select Top 1 ID from Person)
Update Person Set Name='sasa' where ID=@id
insert into Person Values(#Name#,#Age#,#Sex#)
delete Course where ID=15
<selectKey property="ID" resultClass="int" type="post">
select @@Identity as ID
</selectKey>
Commit tran
End try
Begin Catch
ROLLBACK TRAN
END CATCH
</insert>

</statements>

</sqlMap>

控制器代码

    //var list1 = BaseDA.QueryForList<PersonAndCourse>("GetList1",null); //联合查询所有数据
var list2 = BaseDA.QueryForList<PersonAndCourse>("GetList2", new PersonAndCourse() { Name = "sasa", Age = 15 }); //多条件查询
var list3 = BaseDA.QueryForList<PersonAndCourse>("GetList3", null); //使用重复使用的sql语句

A:     先说下SQL片段,我们在查询分页时的查询拼接条件或都其他查询时,可能同一段代码重复使用,这时我们就可以利用SQL片段,把重利利用的SQL代码提取出来,如PersonAndCour.xml里一样,这样我们用这一句就可以引用上面的SQL语句,这里的refid就是SQl片段中id的名字

B:     再说说多条件查询时动态拼接SQl语句,如下图
学习MyBatis.Net之路 (三)

这里我们传入的参数是PersonAndCourse,输出的参数也是这个, 这个参数我们也可以自己定义,需要几个字段就定义几个字段,但在这里时要写全名比如:parameterClass=”MyBatisNet.EntityModel.whereModel”,还有之前在博客园找到的动态SQL拼接的都是JAVA目录,进而是直接用标签嵌套标签,我在项目中也使用这种方式,但是标签的里的语句就是不执行,最后在网上找了好多,最后发现用标签之后里面的语句就可以拼接成功了,原因现在还不知道,那位大神知道可以告知下,标签里面的判断条件整理了如下几个类型:

特别声明:因为标签写不出来

在博客上<isPropertyAvailable> 这样子标签展示不出来 所以写成<>isPropertyAvailable       希望大家可以理解
所以 <标签> 改为这样子写 <>标签

一元条件元素: 一元条件元素检查属性的状态是否符合特定的条件。
属性:
prepend—-可被覆盖的SQL语句组成呢部分,添加在语句前面(可选)
property—-被比较的属性(必选)

标签 含义
<>isPropertyAvailable 检查是否存在该属性(存在parameter bear的属性)
<>isNotPropertyAvailable 检查是否不存在该属性(不存在parameter bear的属性)
<>isNull 检查属性是否Null
<>isNotNull 检查属性是否不为Null
<>isEmpty 检查Collection.size()得值。属性的String或String.valueOf()的值,是否为Null或为空
<>isNotEmpty 检查Collection.size()得值。属性的String或String.valueOf()的值,是否不为Null或为空
小例子:
<isNotEmpty prepend="And" property="firstName">
First_Name=#FirstName#
</isNotEmpty>

二元条件元素: 将一个属性值和静态值或另一个属性值比较,如果条件为真,元素将被包容在查询SQL语句中。
属性:
prepend—-可被覆盖的SQL语句组成呢部分,添加在语句前面(可选)
property—-被比较的属性(必选)
compareProerty—-另一个用于和前者比较的属性(必选或者选择compareValue)
compareValue—–用于比较的值(必选或选择compareProperty)

标签 含义
<>isEqual 比较属性值和静态值或另一个属性值是否相等
<>isNotEqual> 比较属性值和静态值或另一个属性值是否不相等
<>isGreaterThan 比较属性值是否大于静态值或另一个属性值
<>isGreaterEqual 比较属性值是否大于等于静态值或另一个属性值
<>isLessThan 比较属性值是否小于静态值或另一个属性值
<>isLessEqual 比较属性值是否小于等于静态值或另一个属性值

小例子:

<isLessEqual prepend="And" property="age" comparevalue="18">
ADOLESCENT = 'TRUE'
</isLessEqual>

其他元素条件
parameter Present: 这些元素检查参数对象是否存在
Parameter Present条件的属性
prepend - 可被覆盖的SQL语句组成部分。 添加在语句的前面(可选)

<>isParameterPresent 检查是否存在参数对象(不为Null)
<>isNotParameterPresent 例子: <isNotParameterPresent prepend="AND"> Empolyee='default' </isNotParameterPresent>

**iterate: 这属性遍历整个集合,并为List集合中的元素重复元素体的内容。
属性:**
prepend—-可被覆盖的SQL语句组成呢部分,添加在语句前面(可选)
property—-类型为Java.util.List的用于遍历的元素(必选)
open —-整个遍历内容体开始的字符串用于定义括号(可选)
close —-每次便利内容之间的字符串,用于定义AND或OR(可选)
便利类型为java.util.List的元素.
<>iterate

    <iterate prepend="And" property="userNameList" open="(" close=")" conjunction="OR">
username=#userNameList[]# </iterate>

注意:使用时,在List元素名后面包括方括号[]非常重要,方括号[]将对象标记为List,以防解析器简单的将List输出成String

12最后说一下自己尝试的事务,如果大家有更好的建议可以提出来大家一起分享

第一个方法 就是在PersonAndCourse.Xml里写的Sql语句的事务。
学习MyBatis.Net之路 (三)

第二个方法映射文件的中还是单一的条插入SQL语句,我们在控制器中使用事务,如下:

    //事务
public void Add()
{
ISqlMapper map = Mapper.Instance();
bool flag = false;
if (map != null)
{
map.BeginTransaction();
try
{
Person p1 = new Person();
p1.ID = 1;
p1.Name = "张四";
p1.Age = 15;
p1.Sex = "女";
flag = (int)map.Update("Update",p1)>0;
Person p2 = new Person();
p2.Name = "李大眼";
p2.Age = 37;
p2.Sex = "男";
flag = (int)map.Insert("Add",p2)>0;
if (flag)
{
map.CommitTransaction();
}
else
{
map.RollBackTransaction();
}
}
catch (Exception ex)
{
map.RollBackTransaction();
}
}
}

好了,到这里功能大致都可以完成了,接下来是Log4net配置的问题了。

修改web.config,主要是配置log4net,参考下面的内容:
需要加载多个DLL

学习MyBatis.Net之路 (三)

<?xml version="1.0"?>
<configuration>
<configSections>
<sectionGroup name="iBATIS">
<section name="logging" type="IBatisNet.Common.Logging.ConfigurationSectionHandler, IBatisNet.Common"/>
</sectionGroup>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
</configSections>
<system.web>
<compilation debug="true" targetFramework="4.0"/>
</system.web>
<iBATIS>
<logging>
<logFactoryAdapter type="IBatisNet.Common.Logging.Impl.Log4NetLoggerFA, IBatisNet.Common.Logging.Log4Net">
<arg key="configType" value="inline"/>
<arg key="showLogName" value="true"/>
<arg key="showDataTime" value="true"/>
<arg key="level" value="ALL"/>
<arg key="dateTimeFormat" value="yyyy/MM/dd HH:mm:ss:SSS"/>
</logFactoryAdapter>
</logging>
</iBATIS>
<log4net>
<!-- Define some output appenders -->
<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
<param name="File" value="mybatis.log"/>
<param name="AppendToFile" value="true"/>
<param name="MaxSizeRollBackups" value="2"/>
<param name="MaximumFileSize" value="100KB"/>
<param name="RollingStyle" value="Size"/>
<param name="StaticLogFileName" value="true"/>
<layout type="log4net.Layout.PatternLayout">
<param name="Header" value="[Header]\r\n"/>
<param name="Footer" value="[Footer]\r\n"/>
<param name="ConversionPattern" value="%d [%t] %-5p %c [%x] - %m%n"/>
</layout>
</appender>
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p %c [%x] &lt;%X{auth}&gt; - %m%n"/>
</layout>
</appender>
<!-- Set root logger level to ERROR and its appenders -->
<root>
<level value="DEBUG"/>
<appender-ref ref="RollingLogFileAppender"/>
<appender-ref ref="ConsoleAppender"/>
</root>
<!-- Print only messages of level DEBUG or above in the packages -->
<logger name="IBatisNet.DataMapper.Configuration.Cache.CacheModel">
<level value="DEBUG"/>
</logger>
<logger name="IBatisNet.DataMapper.Configuration.Statements.PreparedStatementFactory">
<level value="DEBUG"/>
</logger>
<logger name="IBatisNet.DataMapper.LazyLoadList">
<level value="DEBUG"/>
</logger>
<logger name="IBatisNet.DataAccess.DaoSession">
<level value="DEBUG"/>
</logger>
<logger name="IBatisNet.DataMapper.SqlMapSession">
<level value="DEBUG"/>
</logger>
<logger name="IBatisNet.Common.Transaction.TransactionScope">
<level value="DEBUG"/>
</logger>
<logger name="IBatisNet.DataAccess.Configuration.DaoProxy">
<level value="DEBUG"/>
</logger>
</log4net>
</configuration>

好了,大功告成,如果有谁还有不懂的地方,欢迎交流