Ibatis+MVC 3.0 开发手记
Ibatis+MVC 3.0 开发手记
近期公司需要开发网吧区域促销活动业绩统计系统,系统数据来源基于万象网管数据库,借这个机会运用一下学习的Ibatis与MVC3.0。
网站ORM层采用Ibatis,展示采用MVC 3.0的Razor
Ibatis引入程序集:
IBatisNet.Common
IBatisNet.Common.Logging.Log4Net
IbatisNet.DataMapper
Log4net
网吧各分层如下:
对于二个数据库采用sqlmap_mps.config与sqlmap_wx2006DB.config不同的配置文件实现。下面是其中sqlmap_mps.config的配置文件:
1 <?xml version="1.0" encoding="utf-8" ?>
3 <settings>
4 <setting cacheModelsEnabled="true"/>
5 <setting useStatementNamespaces="false" />
6 </settings>
7 <providers resource="providers.config" />
8 <database>
9 <provider name="sqlServer2005"></provider>
10 <!--<dataSource name="IBatisNet" connectionString="server=sql.develop.itour.com.cn,3433;database=tempdb;user id=ncc2008;password=ncc2008;connection reset=false;"/>-->
11 <dataSource name="DBMPS" connectionString="server=localhost;database=DBMPS;user id=sa;password=123;connection reset=false;"/>
12 </database>
13 <sqlMaps>
14 <sqlMap resource="Po/Maps/User.xml" />
15 <sqlMap resource="Po/Maps/Admin.xml"/>
16 <sqlMap resource="Po/Maps/Promotion.xml"/>
17 <sqlMap resource="Po/Maps/IncomeLog.xml" />
18 </sqlMaps>
19 </sqlMapConfig>
其中resource="Po/Maps/User.xml" /> 配置方式在根目录加载,方便修改。
embedded="${root}xmlname.xml,${assembly}" />配置方式文件将在程序集资源文件加载
url是通过绝对路径进行加载(不建议)
MapperUtil类 Ibatis的通用类,对Ibatis方法进行封装。
1 private ISqlMapper mySqlMapper = null;
3 public const String WX2006DB_MAPPER = "sqlmap_wx2006DB.config";
4 private String ConnectionString = null;
5 public MapperUtil()
6 {
7 mySqlMapper = this.Instance(MPSDB_MAPPER);
8 this.ConnectionString = mySqlMapper.DataSource.ConnectionString;
9 }
10 public MapperUtil(String sqlMapName)
11 {
12 mySqlMapper = this.Instance(sqlMapName);
13 this.ConnectionString = mySqlMapper.DataSource.ConnectionString;
14 }
15 //double check
16 public ISqlMapper Instance(string sqlMapName)
17 {
18 if (mySqlMapper == null)
19 {
20 lock (typeof(SqlMapper))
21 {
22 if (mySqlMapper == null)
23 {
24 InitMapper(sqlMapName);
25 }
26 }
27 }
28 return mySqlMapper;
29 }
30 protected void InitMapper(String sqlMapName)
31 {
32 DomSqlMapBuilder builder = new DomSqlMapBuilder();
33 mySqlMapper = builder.Configure(sqlMapName);
34 }
上面定义了MapperUtil默认构造函数创建sqlmap_mps.config ,为了阻止并发时多次创建DomSqlMapBuilder 采用Double Check确保每次只有一个实现。
MapperFactory类采用简单工厂模式:
1 /// <summary>
3 /// </summary>
4 public class MapperFactory
5 {
6 public static MapperUtil InstanceMps()
7 {
8 return new MapperUtil(MapperUtil.MPSDB_MAPPER);
9 }
10 public static MapperUtil InstanceWX2006DB()
11 {
12 return new MapperUtil(MapperUtil.WX2006DB_MAPPER);
13 }
14 }
其后在实现时直接调用相关的方法进行实例化:
如ComputerDao类:
2 {
3 MapperUtil mapper = MapperFactory.InstanceWX2006DB();
4 public IList<Computer> ShowAllComputer()
5 {
6 return mapper.ExecuteQueryForList<Computer>("Computer.ShowAllComputer",null) ;
7 }
8 public IList<Computer> ShowPagerComputer(Int32 offset,Int32 pagesize)
9 {
10 Hashtable ht = new Hashtable();
11 ht.Add("offset", offset);
12 ht.Add("pagesize", pagesize);
13 return mapper.ExecuteQueryForList<Computer>("Computer.ShowPagerComputer", ht);
14 }
15 }
在sqlMap映射文件中有一部分需要注意的:
一、Insert 添加后返回该新增行主键
1 <insert id="Admin.Insert" parameterClass="Admin">
3 <selectKey resultClass="int" property="Id" type="post" >
4 <![CDATA[SELECT @@IDENTITY AS Id]]>
5 </selectKey>
6 </insert>
二、映射中的传入参数如果不是实体类可以通过Hashtable方式传入,分页就是最好的例子
2 SELECT TOP $pagesize$ sCom FROM ( SELECT ROW_NUMBER() OVER (ORDER BY t.sCom ) AS RowNumber,* FROM tStat AS t) A WHERE RowNumber > $pagesize$*($offset$-1)
3 </select>
4 <parameterMaps>
5 <parameterMap id="QueryConditionParameter" class="HashTable">
6 <parameter property="pagesize" column="pagesize" direction="Input"/>
7 <parameter property="offset" column="offset" direction="Input"/>
8 </parameterMap>
9 </parameterMaps>
三、在遇到需要转义的符号时可以通过采用<![CDATA[]]>避免错误
如查找时的小于号处理方式:
2 <![CDATA[
3 SELECT SUM(cEffect) AS sum, sCom FROM tLogs WHERE dtTime2< '$endtime$' AND dtTime1 > '$starttime$' AND sCom='$pcNumber$' GROUP BY sCom
4 ]]>
5 </select>
四、在映射SQL SERVER 里面的money(不被提倡)时可以采用Decimal来作为dbType
Service通过调用Dao并实现业务逻辑:
如 FormsAuthentication.SetAuthCookie(name,createPersistentCookie); 识别访问用户角色的信息也在此设置。
MVC3.0 可以通过自定义AuthorizeAttribute来识别访问网站的角色。这一点作得相对比较好,原来的WebForm的用户权限一般都定义BasePage继承 Page 然后重写 protected override void OnInit(EventArgs e) 进行设置。
因为项目Authorize已经足够,下面写的是大概的实现方式,多个角色,可以在AuthorizeCore实现。
1 public class AuthAttribute:AuthorizeAttribute
3 protected override bool AuthorizeCore(HttpContextBase httpContext)
4 {
5 if (httpContext == null)
6 throw new ArgumentNullException("httpContext");
7 if (!httpContext.User.Identity.IsAuthenticated)
8 return false;
9 if (httpContext.User.Identity.Name!=null)
10 return true;
11 return false;
12 }
13 }
Razor 方面在尝试使用遇到了不少学习中不到位的,也是常见到的问题:
1、一个cshtml页面在如果不需要母版的时候需要在页头加上:
@{
Layout = null;
}
2、需要在母版扩展一个区别写JavaScript与CSS
@RenderSection("Head",required:true)
这样每个页面可以通过在其页面加入
@section Head{
}
来添加内容。
3、JavaScript与CSS的引入采用
<script src="@Url.Content("~/Content/datetimepicker.js")" type="text/javascript"></script>
<link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />