ssm--mybatis使用oicle替换mysql遇到的坑,亲测总结

1、applicationContext.xml中的配置差异:
在applicationContext.xml的数据源dataSource的配置中,mysql数据库需要心跳包的配置,而oracle中不需要,否则会报错
 
2、mybatis模糊查询中sql语句的差异
mysql在使用concat拼接字符串时可以直接将三者【%、占位符、%】拼到一起,而oracle则不可以,必须两两拼接,否则就会报ORA-00909: 参数个数无效的错误
 
mysql:
   
    <select id= "selectUser" parameterType="User" resultType="User">
     
    select * from user where 1=1
     
    < if test="name != null and name != ''">
     
    and name like concat('%',#{name},'%')
     
    </if>
     
    </select>

oracle:
 
 
    <select id= "selectUser" parameterType="User" resultType="User">
     
    select * from user where 1=1
     
    < if test="name != null and name != ''">
     
    and name like concat(concat('%',#{name}),'%')
     
    </if>
     
    </select>
 

    另外需要注意几点sql的问题:

    1,oracle 用SYSDATE     mysql用 now()

    2,create表的时候 一定要注意字段和表名,如果都不加引号的话,默认都是大写(推荐,这样的话xml基本不用调整,改动量基本没有),加上引号的话,所有的sql语句都需要加上引号

     

 mysql和oracle语法有一定的差异,我们将服务由部署mysql的服务器迁移到部署oracle的服务器上时,需要修改sql语句。下面说说mybatis中由mysql转为oracle需要修改的语句。

 oricle批量插入时,需要使用查询语句,很多人说的使用selectkey方式批量插入,前提是oricle主键使用序列,或使用时创建序列,使用序列实现查询,如下:
 
 1.批量插入

    mysql:

    
         
        <insert id="insertBatch" parameterType="List">
         
        insert into black_list
         
        (uuid,type,value,delete_flag,gmt_create,gmt_modified) values
         
        <foreach collection="list" item="item" index="index"
         
        separator=",">
         
        (#{item.uuid},#{item.type},#{item.value}
         
        #{item.deleteFlag},#{item.gmtCreate},#{item.gmtModified})
         
        </foreach>
         
        </insert>
               

    oracle:
         
       
        <insert id="insertBatch">
         
        <selectKey keyProperty="id" resultType="Long" order="BEFORE">
         
        select seq_black_list.nextval as id from dual
         
        </selectKey>
         
        insert into black_list
         
        (id,uuid,type,value,delete_flag,gmt_create,gmt_modified)
         
        select seq_black_list.nextval, A.* FROM (
         
        <foreach collection="list" item="item" index="index"
         
        separator="union all">
         
        select
         
        #{item.uuid,jdbcType=VARCHAR},
         
        #{item.type,jdbcType=VARCHAR},
         
        #{item.value,jdbcType=VARCHAR},
         
        #{item.deleteFlag,jdbcType=INTEGER},
         
        #{item.gmtCreate,jdbcType=DATE},
         
        #{item.gmtModified,jdbcType=DATE}
         
        from
         
        dual
         
        </foreach>
         
        ) A
         
        </insert>

    其中,oracle在执行foreach之前,必须使用select语句。

    如果自建主键,不需要序列,需要将sql修改为:
    
    oracle:
         
       
        <insert id="insertBatch">
         
        insert into black_list
         
        (uuid,type,value,delete_flag,gmt_create,gmt_modified)
         
        <foreach collection="list" item="item" index="index"
         
        separator="union all" open="(" close=")">
         
        select
         
        #{item.uuid,jdbcType=VARCHAR},
         
        #{item.type,jdbcType=VARCHAR},
         
        #{item.value,jdbcType=VARCHAR},
         
        #{item.deleteFlag,jdbcType=INTEGER},
         
        #{item.gmtCreate,jdbcType=DATE},
         
        #{item.gmtModified,jdbcType=DATE}
         
        from
         
        dual
         
        </foreach>
         
        </insert>
    
     
    2.批量更新

    mysql:

     
         
         
         
        <update id="batchUpdate" parameterType="java.util.List">
             
        <foreach collection="list" item="item" index="index" open="" close="" separator=";">
         
        update test
         
        <set>
         
        test=${item.test}+1
         
        </set>
         
        where id = ${item.id}
         
        </foreach>
   
        </update>
         
     

    oracle:

 
        <update id="batchUpdate" parameterType="java.util.List">
            
        <foreach collection="list" item="item" index="index" open="begin" close="end;" separator=";">
         
        update test
         
        <set>
         
        test=${item.test}+1
         
        </set>
         
        where id = ${item.id}
         
        </foreach>
         
         
         
        </update>

    其中,oracle的foreach语句需要用begin和end包起来。

     
    3.limit

    mysql:


    SELECT * FROM tablename LIMIT 100,15


    oracle:

     
        select * from
         
        (select A.*,rownum rn from
         
        (
         
        原mysql的语句,注意去掉limit
         
        )A
         
        where rownum > 100
         
        )
         
        where rn <= 115


    由于oracle中没有limit,因此可以通过rownum来实现相同的效果。
    
    4.自增主键

    mysql:

     
         
        <insert id="insert" parameterType="Role" useGeneratedKeys="true" keyProperty="roleId">
         
        insert into role (name, create_time, update_time) values (#{name,jdbcType=VARCHAR}, now(), now())
         
        </insert>


    oracle:

    在执行插入之前,需要创建一个序列:

     
         
        create sequence SEQ_T_USER_ID
         
        minvalue 1
         
        maxvalue 9999999999999999999999999999
         
        start with 1
         
        increment by 1
         
        cache 20;

    序列生成后,就可以始终该序列实现主键自增的效果:

     
         
        <insert id="insert" parameterClass="ROLE">
         
        <selectKey resultType="java.lang.Long" order="AFTER" keyProperty="roleId">
         
        SELECT SEQ_T_USER_ID.currval as ROLEID from DUAL
         
         
         
        </selectKey>
         
        insert into ROLE(ID, NAME, CREATE, MODIFY) values (#{id}, #{name}, sysdate, sysdate)
         
        </insert>


    mysql可以通过设置useGeneratedKeys为true来实现主键自增,oracle的语法不支持。为解决mysql和oracle的主键自增问题,可以用另外一张表TEMP记录其他表的主键,在插入时,由TEMP获取相应表的主键值,将其插入。

     
    5.时间操作

    mysql:

     
         
        返回系统日期,输出 2009-12-25 14:38:59
         
        select now();
         
        输出 09-12-25
         
        select date_format(now(),'%y-%m-%d');
         
         
         
        获得当前 UTC 日期时间函数:utc_date(), utc_time(), utc_timestamp()
         
         
         
        当前时间减去7分钟的时间 : select date_sub(now(),interval 7 minute);
         
         
         
        获取时间戳: select unix_timestamp('2008-08-08'); -- 1218124800

     

    oracle:

     

     
             
            获取系统日期: SYSDATE()
             
            格式化日期: TO_CHAR(SYSDATE(),'YY/MM/DD HH24:MI:SS')
             
            返回系统日期,输出 25-12月-09
             
            select sysdate from dual;
             
            mi是分钟,输出 2009-12-25 14:23:31
             
            select to_char(sysdate,'yyyy-MM-dd HH24:mi:ss') from dual;
             
            当前时间减去7分钟的时间
             
            select sysdate,sysdate - interval '7' MINUTE from dual;
             
            获取时间戳: SELECT (SYSDATE - TO_DATE('1970-1-1 8','YYY-MM-DD HH24'))*86400 FROM DUAL;
             
            用当前的时间减去1970年1月1日8时,得到的天数乘以24小时乘以3600秒,得到的结果就是系统时间戳。
             
            这里用8时的原因时系统所处时区为东8区
             
             
             
            含义解释:
             
            Dual伪列
             
            Dual 是 Oracle中的一个实际存在的表,任何用户均可读取,常用在没有目标表的 select语句块中。
             
            不同系统可能返回日期的格式不一样。
             
            返回当前连接的用户: select user from dual;
             
             

            1.Oracle

            SELECT  *  FROM USER WHERE 1=1 AND NAME LIKE '%'||#{name}||'%'

            2.Mysql

            SELECT  *  FROM USER WHERE 1=1 AND NAME LIKE "%"#{name}"%"
            
            
总结:

 MySql和oracle的不同

一、语法的不同

1、oracle没有offet,limit关键字,所以在oracle中要分页的话,要换成rownum。

2、oracle建表时,没有auto_increment,所有要想让表的主键自增,要自己添加序列。

3、oracle有一个dual表,当select后没有表时,加上的。不加会报错的。select 1 这个在mysql不会报错的,oracle下会。select 1 from dual这样的话,oracle就不会报错了。

4、对空值的判断,name != ""这样在mysql下不会报错的,但是oracle下会报错。在oracle下的要换成name is not null

5、oracle下对单引号,双引号是有要求的,一般不准用双引号,用了会报错(ERROR at line 1: ORA-00904: "t": invalid identifier),而mysql就没有这样的限制。

6、oracle表的字段是number型的,如果你$post得到的参数是123456,入库的时候,你需要用to_number,to_date这样的函数来强制转换一下,不然后会被当成字符串来处理。而mysql却不会。

7、group_concat这个函数,oracle是没有的,如果要想用自已写方法。

8、mysql的用户权限管理,是放到mysql自动带的一个数据库mysql里面的,而oracle是用户权限是根着表空间走的。(这点我感觉要好好理解下)

9、在oracle下用group by的话,group by后面的字段必须在select后面出现,不然会报错的,而mysql却不会。

10、mysql存储引擎有好多,常用的mysiam,innodb等,而创建oracle表的时候,好像只有一个存储引擎。

11、oracle字段无法选择位置,alter table add column before|after,这样会报错的,即使你用sql*plus这样的工具,也没法改字段的位置。

12、oracle的表字段类型也没有mysql多,并且有很多不同,例如:mysql的int,float对应oracle的number类型等。

13、oracle查询时from 表名后面 不能加上as不然会报错的,select t.username from test as t而在mysql下是可以的。

14、oracle中是没有substring这个函数的,mysql是有的。

二、mysql移植到oracle中的表类型转换
    复制代码
    
    MYSQL                  ORACLE
    BLOB(220)             RAW(220)
    BLOB (20)             RAW(20)
    BLOG(1024)             RAW(1024)
    VARCHAR(n)             VARCHAR2(n)
    CHAR                   CHAR
    FLOAT(22,6)            NUMBER(22,6)
    DOUBLE(44,12)          NUMBER(44,12)
    TINYINT (3)            NUMBER(3)
    SMALLINT(5)            NUMBER(5)
    MEDIUMINT(8)           NUMBER(8)
    INT(10)                NUMBER(10)
    BIGINT(20)             NUMBER(20)
    DATATIME               DATA
   

 

 

下篇:解决 批量修改如果遇到多层  <foreach></foreach>如何使用的问题                                                                                                                 


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值