
IBatis.net在asp.net MVC下的使用
IBatis.net 是2001年发起的开源项目,它是一个轻量级的ORM框架,现在IBatisNET已经是属于Apache下的一个子项目了,最新版本是1.6.2.
.net项目下载地址:http://code.google.com/p/mybatisnet/
DataMapper:通过配置映射关系的xml业务对象与SQL语句和存储过程进行映射.
DataAcces:简单的说就是IBatis的数据访问层.
这里通过一个简单的增删改查案例 进行学习 Ibatis.net的配置和使用
一、首先需要下载Ibatis.net 的dll.上面的官网估计下载不下来,所以这儿我自己上传了一份
下载地址:
IBatis.net1.9.2&1.6.2最新版本
本项目的 Demo:
asp.net MVC和IBatis.net整合demo程序
本项目的数据库:
asp.net MVC和IBatis.net整合demo数据库部分
二、使用VS 2013新建一个解决方案。
首先使用sqlserver2014 建立数据库表
数据库:UserDemoDb
并建立相关的架构 如图所示
IBatisDemo.Dao 提供一个统一的Mapper访问接口,
IBatisDemo.Model 数据实体
IBatisDemo.Service 数据操作
因为是做Demo没有对整体架构做过多的细节设置.
三、IBatis.net配置
web层拷贝的配置文件,这些文件在 Ibatis.net1.9.2的程序中 解压就有
providers.config 这个直接拷贝到根目录,该文件定义各种数据库的驱动,包括SqlServer, Oracle, MySQL, PostgreSQL, DB2 and OLEDB, ODBC 等。
sqlmap.config 就是非常核心的一个配置文件,主要配置了数据库访问字符串,settings设置,以及配置实体类和数据库表相关xml。
还有一个database.config 文件,它是配置一些在sqlmap中用到得参数.
添加对Ibatis dll的引用
sqlmap.config配置:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
<?xml version= "1.0" encoding= "utf-8" ?>
<sqlMapConfig <settings>
<!--启用命名空间,对于多个表的时候,进行区分-->
<setting useStatementNamespaces= "true" />
</settings>
<!--连接数据库驱动文件-->
<providers resource= "providers.config" />
<!-- Database connection information -->
<database>
<!--配置数据库连接字符串-->
<provider name= "sqlServer2.0" ></provider>
<dataSource name= "IBatisNet" connectionString= "server=WWW;database=UserDemoDb;user id=sa;password=DDD;connection reset=false;" />
</database>
<sqlMaps>
<!--引用数据库表实体xml文件-->
<sqlMap resource= "Maps/UserInfo.xml" />
</sqlMaps>
</sqlMapConfig> |
先配置网站根目录下的Maps/UserInfo.xml如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
<?xml version= "1.0" encoding= "utf-8" ?>
<sqlMap namespace = "UserInfo" xmlns= "http://ibatis.apache.org/mapping" xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" >
<alias>
<!-- alias:取别名
assembly:表示类所在的文件
type:表示该类的完整的名称
-->
<typeAlias alias= "UserInfo" assembly= "IBatisDemo.Model" type= "IBatisDemo.Model.UserInfo" />
</alias>
<statements>
< select id= "select_UserInfoAll" resultMap= "UserInfo-result" >
select Id,UserName,Age
from UserInfo
</ select >
<insert id= "insert_UserInfoOne" parameterClass= "UserInfo" >
INSERT INTO UserInfo(
[UserName],[Age]
)VALUES(
#UserName#,#Age#
)
<selectKey type= "post" resultClass= "int" property= "Id" >
SELECT CAST(@@IDENTITY as int ) as Id
</selectKey>
</insert>
<delete id= "del_UserInfoOne" parameterClass= "UserInfo" >
<![CDATA[
DELETE UserInfo
]]>
<dynamic prepend= "WHERE" >
Id = #Id#
</dynamic>
</delete>
< select id= "select_UserInfoOne" resultMap= "UserInfo-result" >
select * from UserInfo
<dynamic prepend= "where" >
<isParameterPresent property= "id" prepend= "WHERE" >
[Id] = #Id#
</isParameterPresent>
</dynamic>
</ select >
<update id= "update_UserInfoOne" parameterClass= "UserInfo" >
<![CDATA[
UPDATE UserInfo
SET
UserName = #UserName#,
Age = #Age#
]]>
<dynamic prepend= "WHERE" >
Id = #Id#
</dynamic>
</update>
</statements>
<resultMaps >
<resultMap id= "UserInfo-result" class = "UserInfo" >
<result property= "Id" column= "Id" />
<result property= "UserName" column= "UserName" />
<result property= "Age" column= "Age" />
</resultMap>
</resultMaps>
</sqlMap> |
说明:
statements 节点:
在这些容器标签中有一些常用的属性如下所示
resultMap和resultclass对比:
1、resultMap属于直接映射,可以把结果集中的数据库字段与实体类中的属性一一对应,这样通过select语句得到的结果就会准确的对上号
2、resultclass属于隐身映射,虽然你指定resultclass=“”,具体某一个类,但是select语句得到的结果是一条实力记录,但如果数据库字段与类的属性名字不一致,这个时候就会出现映射错误,有一种方式可以解决就是在写select语句时,给每个字段用as运算符取名字与属性一样:例如:select realname as name...其中realname是字段列名,name是属性字段名
3、resultmap比resultclass性能要高。尽量使用resultmap
insert标签下的selectKey 是表示返回刚插入数据的主键id,具体说明如下
<!-- 为了使insert操作能够返回插入记录的id,必须为insert写一个selectKey 建立数据库实体类:UserInfo.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IBatisDemo.Model
{ public class UserInfo
{
public int Id { get ; set ; }
public string UserName { get ; set ; }
public int Age { get ; set ; }
}
} |
Mapper.cs 获取Mapper的对象类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
using IBatisNet.Common.Utilities;
using IBatisNet.DataMapper;
using IBatisNet.DataMapper.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IBatisDemo.Dao
{ public class Mapper
{
private static volatile ISqlMapper _mapper = null ;
protected static void Configure( object obj)
{
_mapper = null ;
}
protected static void InitMapper()
{
ConfigureHandler handler = new ConfigureHandler(Configure);
DomSqlMapBuilder builder = new DomSqlMapBuilder();
_mapper = builder.ConfigureAndWatch(handler);
}
public static ISqlMapper Instance()
{
if (_mapper == null )
{
lock ( typeof (SqlMapper))
{
if (_mapper == null ) // double-check
{
InitMapper();
}
}
}
return _mapper;
}
public static ISqlMapper Get()
{
return Instance();
}
/// <summary>
/// RealMarket Mapper
/// </summary>
public static ISqlMapper GetMaper
{
get
{
if (_mapper == null )
{
lock ( typeof (ISqlMapper))
{
if (_mapper == null )
{
ConfigureHandler hander = new ConfigureHandler(Configure);
DomSqlMapBuilder builder = new DomSqlMapBuilder();
_mapper = builder.ConfigureAndWatch( "SqlMap.config" , hander);
}
}
}
return _mapper;
}
}
}
} |
然后再Service里面建立UserInfoService.cs 数据访问
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
using IBatisDemo.Dao;
using IBatisDemo.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Data.SqlClient;
namespace IBatisDemo.Service
{ public class UserInfoService
{
public int UserInfoInsertOne(UserInfo userInfo)
{
Object obj = Mapper.GetMaper.Insert( "UserInfo.insert_UserInfoOne" , userInfo);
return ( int )obj;
}
public UserInfo GetUserInfo( int id)
{
return (UserInfo)Mapper.GetMaper.QueryForObject( "UserInfo.select_UserInfoOne" , id);
}
public IList<UserInfo> GetUserInfoList()
{
//xml里面配置的格式
return Mapper.GetMaper.QueryForList<UserInfo>( "UserInfo.select_UserInfoAll" , null );
}
public int DelUserInfoOne( int id)
{
Object obj = Mapper.GetMaper.Delete( "UserInfo.del_UserInfoOne" , id);
return ( int )obj;
}
public int UpdateUserInfo(UserInfo userInfo)
{
Object obj = Mapper.GetMaper.Update( "UserInfo.update_UserInfoOne" , userInfo);
return ( int )obj;
}
}
} |
最后在web层 controller文件夹下建立 HomeController.cs 控制器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
using IBatisDemo.Service;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using IBatisDemo.Model;
namespace IBatisDemo.Controllers
{ public class HomeController : Controller
{
//
// GET: /Home/
UserInfoService service = new UserInfoService();
#region 显示员工
public ActionResult Index()
{
IList<UserInfo> userInfos = service.GetUserInfoList();
ViewData[ "list" ] = userInfos;
return View();
}
#endregion
#region 添加员工
[HttpGet]
public ActionResult UserInsert()
{
return View();
}
[HttpPost]
public ActionResult UserInsert(UserInfo userInfo)
{
userInfo.UserName = Request[ "UserName" ];
userInfo.Age = int .Parse(Request[ "Age" ]);
if (service.UserInfoInsertOne(userInfo) > 0)
{
return Redirect( "Index" );
}
else
{
return Content( "添加失败" );
}
}
#endregion
#region 删除员工
public ActionResult delUserInfo( int id)
{
id = int .Parse(Request[ "Id" ]);
if (service.DelUserInfoOne(id) > 0)
{
return Redirect( "Index" );
}
else
{
return Content( "删除失败" );
}
}
#endregion
#region 编辑员工资料
[HttpGet]
public ActionResult getUserInfo( int Id)
{
Id = int .Parse(Request[ "Id" ]);
UserInfo userInfos = service.GetUserInfo(Id);
//ViewData["user"] = userInfos;
return View(userInfos);
}
[HttpPost]
public ActionResult getUserInfo(UserInfo userInfo)
{
userInfo.Id = int .Parse(Request[ "Id" ]);
userInfo.UserName = Request[ "UserName" ];
userInfo.Age = int .Parse(Request[ "Age" ]);
if (service.UpdateUserInfo(userInfo) > 0)
{
return Redirect( "Index" );
}
else
{
return Content( "修改失败" );
}
}
#endregion
}
} |
View层 Index.cshtml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
@{ Layout = null ;
} @ using IBatisDemo.Model
<!DOCTYPE html> <html> <head> <meta name= "viewport" content= "width=device-width" />
<title>Index</title>
</head> <body> <div>
<h1>IBatis 学习Demo</h1>
@ if (ViewData[ "List" ] != null )
{
<table style= "width:100%;text-align:center;" id= "tabs" >
<tr><th>编号</th><th>姓名</th><th>年龄</th><th>详细</th><th>删除</th><th>修改</th></tr>
@ foreach ( var newInfo in (IList<UserInfo>)ViewData[ "List" ])
{
<tr>
<td>@newInfo.Id</td>
<td>@newInfo.UserName</td>
<td>@newInfo.Age</td>
<td><a href= "javascript:void(0)" class = "details" ids= "@newInfo.Id" >详细</a></td>
<td><a href= "/home/delUserInfo?Id=@newInfo.Id" class = "deletes" >删除</a></td>
<td><a href= "/home/getUserInfo?Id=@newInfo.Id" class = "edits" >修改</a></td>
</tr>
}
</table>
}
else
{
<span>暂无数据</span>
}
<a href= "/home/UserInsert" >添加</a>
</div>
</body> </html> |
编辑和添加的模板 直接在添加视图的时候生成就可以了,源码里面都有,这儿就不贴出来了
下面是运行效果: