转自:http://www.2cto.com/database/201312/265514.html
最近完成了一个(IBatis.Net+MVC)项目的数据库+代码迁移工作,可把我折腾得~~~
IBatis.Net是一个ORM框架,具体介绍可以问度娘。我之前没用ORM框架使用经验,所以这一路我不是走来的,而是爬出一个坑又掉入另外一个坑~~~
项目原来用的是Sqlserver2008,现在要转到Oracle,所以我先完成数据迁移,然后是代码迁移。
数据库迁移
1、数据库安装与配置
略过。
2、表结构迁移
1)用PowerDesigner创建一个PhysicalDataModel,DBMS选择Sqlserver2008;
2)选择DataBase->Connect… ,连上Sqlserver数据库;
3)选择DataBase->Update Model from DataBase…,获取Sqlserver数据库的表结构和视图,不获取约束关系等(会影响数据导入);
4)选择DataBase->Change Current DBMS…,选择new DBMS为Oracle10gR2 ;
5)修改用户,将原始dbo,修改成我们oracle的方案名(用户名)。
90%的工作PowerDesigner已经为我完成了,剩下来就是修改字段类型和长度工作了。
修改字段类型和长度的部分,主要包括:
1)将转换后的NUMBER和INTEGER类型都改成NUMBER(10)。sqlserver自增序列转化后默认是NUMBER(6),这个肯定是不够的;
2)将转化后的FLOAT类型改为NUMBER(12,2);
3)将VARCHAR2长度都增加1倍,如sqlserver中的varchar(50),在oracle中就设置为varchar2(100)(注意:varchar(50)与varchar2(50)是有区别的)。
表字段类型和长度都修改完毕后,就是表的批量创建了。
3、数据导入
通过Sqlserver2008的DTS进行数据导入,数据导入失败一般有以下几种情况:
1)目标表中字段类型长度不够;
2)表之间存在约束关系,如先在子表中导入数据,而主表又没数据。
DTS导入完毕后,没有返回到上一步功能,除非导入出错。这个太不人性化了,太不厚道了~~~
4、主要工作已经完成,剩下就是创建序列和存储过程的事情了。数据库这部分基本搞定。在类型字段长度上,我返工了1次-_-有100多张表,坑啊~~~
项目的代码迁移
1、IBatis的配置文件修改
providers.config文件中加入
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<provider
name
=
"oracleClient1.0"
description=
"Oracle, Microsoft provider V1.0.5000.0"
enabled=
"true"
assemblyName=
"System.Data.OracleClient, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
connectionClass=
"System.Data.OracleClient.OracleConnection"
commandClass=
"System.Data.OracleClient.OracleCommand"
parameterClass=
"System.Data.OracleClient.OracleParameter"
parameterDbTypeClass=
"System.Data.OracleClient.OracleType"
parameterDbTypeProperty=
"OracleType"
dataAdapterClass=
"System.Data.OracleClient.OracleDataAdapter"
commandBuilderClass=
"System.Data.OracleClient.OracleCommandBuilder"
usePositionalParameters=
"false"
useParameterPrefixInSql=
"true"
useParameterPrefixInParameter=
"false"
parameterPrefix=
":"
allowMARS=
"false"
/>
|
注意enable="true",并设置其余的provider节点 enable=“false”。
SqlMap.config文件中的连接字符串设置
1
2
3
4
|
<
database
>
<provider
name
=
"oracleClient1.0"
/>
<dataSource
name
=
"ORCL"
connectionString=
"Data Source=ORCL;user=用户名;password=密码"
/>
</
database
>
|
这个oracleClient1.0的连接字符串找了很久,开始一直以为是USER ID=用户名。
2、Oracle客户端的安装
开始一直以为Oracle9i精简版客户端就可以搞定,结果老提示:Unable to open connection to "Oracle, Microsoft provider V1.0.5000.0"。于是下载并安装了oracle10gR2的客户端,还是不行。于是我在网上找了个ibatis.net+oracle的winform版demo,测试正常,可以确认不是配置文件和连接字符串的问题了。可将代码移植到web项目上就不行了,即使部署到IIS上并模拟32位运行(开发机是win7x64系统)也是出错。32位模式运行的时候会提示要求更高的客户端版本。难道是新安装的客户端的时候在环境变量中新增加的Path没生效?于是抱抱试试看的心态,重启了电脑,终于老天是眷顾程序猿的~~~搞定。
3、SQL语句代码修改
1)dbType=Int 都换成dbType=Number
2)遇到<等会破坏XML文件格式的符号,将其放在<![CDATA[……]]>中
3)Oracle的自增序列
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
<
insert
id=
"Insert"
parameterClass=
"Account"
>
<selectKey property=
"UserID"
resultClass=
"int"
type=
"pre"
>
SELECT
SEQ_ACCOUNT_ID.NEXTVAL
AS
VALUE
FROM
DUAL
</selectKey>
INSERT
INTO
Account (
USERID
,
Name
, AccountNo
, MobileNo
,
Password
)
VALUES
(
#UserID#
,#
Name
,dbType=
VarChar
#
, #AccountNo,dbType=
VarChar
#
, #MobileNo,dbType=
VarChar
#
, #
Password
,dbType=
VarChar
#
)
</
insert
>
|
注意:自增序列的值,上面代码段中我用的是UserId,这个要与XML中向对应,我之前都用了ID,结果踩到坑了。
1
2
3
|
<resultMaps>
<resultMap id=
"FullResultMap"
class=
"Account"
>
<result property=
"UserID"
column
=
"UserID"
dbType=
"Int"
/>
|
4)select top的实现
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<
select
id=
"XXXXXXXX"
parameterClass=
"Hashtable"
resultMap=
"NonLobResultMap"
>
SELECT
*
FROM
(
SELECT
rownum
as
rn
,ID
, Title
FROM
Article
WHERE
(OwnerID = #OwnerID,dbType=Number#)
ORDER
BY
CreateTime
DESC
) tb
<![CDATA[
where
rn <= $ReturnCount$
]]>
</
select
>
|
5)分页的实现
1
2
3
4
5
6
7
8
9
10
11
|
<
select
id=
"Search"
parameterClass=
"Hashtable"
resultMap=
"FullResultMap"
>
SELECT
*
From
(
SELECT
rownum
as
RowNumber,Article.*
FROM
Article
<include refid=
"SearchWhere"
></include>
<![CDATA[
order
by
ID
DESC
) tb
where
RowNumber >=( ($PageIndex$ - 1) * $PageSize$ + 1)
and
RowNumber<=( $PageIndex$ * $PageSize$)
]]>
</
select
>
|
6)like模糊查询
1
2
3
|
<
select
id=
"XXX"
parameterClass=
"Citys"
resultMap=
"FullResultMap"
extends=
"FindAll"
>
where
(Namelike
'%'
|| #
Name
,dbType=
VarChar
#||
'%'
)
</
select
>
|
7)存储过程返回游标
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<parameterMaps>
<!
-- 存储过程参数 -->
<parameterMap id=
"parm_sp_XXXXXX"
class=
"Hashtable"
>
<parameter property=
"AAAAAA"
column
=
"IN_AAAAAA"
direction=
"Input"
/>
<parameter property=
"BBBBBB"
column
=
"IN_BBBBBB"
direction=
"Input"
/>
<parameter property=
"Result"
column
=
"OUT_REF_CUR"
dbType=
"Cursor"
direction=
"Output"
/>
</parameterMap>
</parameterMaps>
<statements>
<!
-- 存储过程 -->
<
procedure
id=
"GetXXXXXXXXXXXX"
parameterMap=
"parm_sp_XXXXXX"
resultMap=
"YYYYYYYYYYYYY"
>
proc_存储过程名称
</
procedure
>
</statements>
|
8)Oracle对字段取别名可以用as,但是对表就不能用as
9)select * ,然后增加其他字段,就需要在*前面加上表名,如t.*
10)然后把一些SQL命令改成Oracle的命令
11)SQL语句的脚本文件中,建议将存储过程、参数、序列等都用大写表示。
总结
初次接触Ibatis.Net,通过代码生成器为我们完成大部分工程,开发上确实很方便,在后期做数据库迁移的时候,工作量比传统的工厂模式或IOC少很多,修改的时候直接在对应的XML上修改,非常直观方便。