zoukankan      html  css  js  c++  java
  • 【转】IBatis.Net项目数据库SqlServer迁移至Oracle

    转自: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上修改,非常直观方便。

  • 相关阅读:
    CacheHelper
    DynamicQueryable
    这则招聘,看的我笑尿了!!!
    垃圾JSON
    Socket模拟Ping
    DataReaderGetterGenerator
    保存指定品质的图片
    [翻译]XNA 3.0 Game Programming Recipes之twentyseven
    [翻译]XNA 3.0 Game Programming Recipes之twentyfive
    [翻译]XNA 3.0 Game Programming Recipes之thirty
  • 原文地址:https://www.cnblogs.com/wdw31210/p/4637156.html
Copyright © 2011-2022 走看看