转战Oracle,在线避坑目录
前言
Oracle的使用与MySQl相似,但也存在很多细节上的差异,以下记录一下MySQL过渡Oracle时遇到的一些坑及解决措施,欢迎留言区补充,相互学习
Oracle注意点
- Oracle的SQL语句要用单引号,不能用双引号(在Oracle中 双引号 被当做一个普通的字符串来处理)
- SQL Developer 默认是不会自动提交事务的,执行DML语句后记得commit
- mybatis里面的sql末尾是不能以分号(;)结尾(MySQL均可,Oracle会报错:java.sql.SQLSyntaxErrorException: ORA-00911: 无效字符)
- Oracle字段默认采用大写,当与实体类对应时,实体类不支持驼峰命名法
使用Mybatis时,
法一:mapper映射文件使用resultMap将实体类字段与数据库表字段一一对应
<resultMap id="指定resultMap名" type="实体类全类名" >
<!--id标签为主键列-->
<id column="DB表字段" property="实体类字段" jdbcType="DECIMAL(jdbcType类型)" />
<!--result标签为非主键列-->
<result column="USER_NAME" property="userName" jdbcType="VARCHAR(jdbcType类型)" />
<result column="PASSWORD" property="password" jdbcType="VARCHAR" />
</resultMap>
法二:配置文件开启驼峰功能
#配置mybatis
mybatis:
#自动扫描包下的实体类
type-aliases-package: 实体类全类名
#映射文件所在的位置
mapper-locations: classpath:mapper/*.xml
configuration:
#开启驼峰功能
map-underscore-to-camel-case: true
关于varchar和varchar2的区别
- varchar是标准sql里面的。 varchar2是oracle提供的独有的数据类型。
- varchar对于汉字占两个字节,对于数字,英文字符是一个字节,占的内存小,varchar2一般情况下把所有字符都占两字节处理。具体要看数据库使用的字符集,比如GBK,汉字就会占两个字节,英文1个,如果是UTF-8,汉字一般占3个字节,英文还是1个。
- varchar对空串不处理,varchar2将空串当做null来处理。
- varchar存放固定长度的字符串,最大长度是2000,varchar2是存放可变长度的字符串,最大长度是4000.
- 如果是要更换不同的数据库,例如mysql,那么就用varchar,如果就用oracle,那么用varchar2比较好一点。
来源:https://www.cnblogs.com/anningkang/p/oracle.html
关于number类型
- Oracle只用NUMBER(m,n)就可以表示任何复杂的数字数据
- 为了兼容,Oracle将decimal,numeric,int(只能存储整数)等数据类型引入,但实际上在Oracle内部还是以NUMBER的形式将其存入。
- Java实体类映射时使用BigDecimal,不要使用String,否则会出现部分显示缺失问题。例如:“0.5” -> “.5”
来源:https://www.cnblogs.com/jiangfeilong/p/10923899.html
关于date时间显示类型
- Oracle的date字段显示为"24-5月 -20",表示2020年5月24日
- 使用时需要用TO_DATE()函数进行转换
TO_DATE(#{startTime},‘YYYY-MM-DD HH24:MI:SS’) - Oracle的日期格式也略有不同:月-MM、24小时制-HH24、12小时制-HH12,分-MI
- Java操作Mybatis插入date字段时可不用传参,而是使用sysdate
SELECT SYSDATE FROM DUAL;
sysdate内容可参考:https://www.cnblogs.com/forever-love-zjl/p/9717413.html
关于limit
oracle数据库不支持mysql中limit功能,但可以通过rownum来限制返回的结果集的行数,rownum是oracle系统自动添加的
- 使查询结果最多返回前10行
select * from XXXTABLE where rownum<=10;
- 使查询结果返回中间的10到100行
select * from XXXTABLE where rownum<101 minus select * from XXXTABLE where rownum<10
minus:减法操作,按列比较,对查询结果集的减法。A minus B将只去除A跟B的交集部分,对于B中存在而A中不存在的记录不会做任何操作,也不会抛出异常。
注:select * from XXXTABLE where rownum>9 and rownum<101是错误的,oracle会认为条件不成立,不存在大于>
关于CRUD的返回值(MySQl与Oracle相同)
select
- true:实体类或其集合
- false:null或空集合
增删改返回值自定义:void/int,传参的List集合多条数据用for遍历,DB执行时还是一条一条执行,故返回值为1
insert
- true:N条数据返回N
- false:(主键冲突)异常
Oracle实例:
INSERT ALL
INTO table (t_id, t_name) VALUES (1, 'sy')
INTO score (t_id, t_name) VALUES (2, 'zhan')
SELECT * FROM dual;
delete
- true:无数据返回0,N条数据返回N
- false:(外键)异常
update
- true:无数据返回0,N条数据返回N
- false:(外键)异常
关于自增主键
MySQL直接一个AUTO_INCREMENT即可,但Oracle没有这玩样,一般Oracle设置自增主键分三步走:
- 建表设置主键(primary key)
- 建序列
- 建触发器
案例:数据库名DB_NAME,表名TEST_TABLE,表字段TABLE_ID(主键),USER_NAME,序列名TEST_TABLE_SEQUENCE,触发器名TEST_TABLE_TRIGGER
1.建表设置主键(primary key):
CREATE TABLE TEST_TABLE (
"TABLE_ID" NUMBER primary key,
"USER_NAME" VARCHAR2(20 BYTE)
);
COMMENT ON COLUMN "DB_NAME"."TEST_TABLE"."TABLE_ID" IS '主键ID';
COMMENT ON COLUMN "数据库名"."表名"."表字段" IS '备注';
2.建序列:
CREATE SEQUENCE TEST_TABLE_SEQUENCE INCREMENT BY 1 MAXVALUE 9999999999999999999999999999 MINVALUE 1 NOCACHE;
//CREATE 序列 序列名 INCREMENT BY 自增值 MAXVALUE 自增最终值 MINVALUE 自增开始值 NOCACHE;
3.建触发器:
create or replace TRIGGER DB_NAME.TEST_TABLE_TRIGGER
BEFORE INSERT ON DB_NAME.TEST_TABLE FOR EACH ROW
begin
select TEST_TABLE_SEQUENCE.nextval into :new.TABLE_ID from dual;
end;
/**
create or replace TRIGGER 触发器名(一般为:数据库名_表名_TRIGGER)
BEFORE INSERT ON 数据库名.表名 FOR EACH ROW
begin
select 序列名.nextval into :new.主键字段 from dual;
end;
*/
当一个值必须返回,且只返回一次,可以从dual表选择返回:
SELECT 1 FROM DUAL
DUAL是一个随着Oracle数据库创建数据字典时自动创建的很小的表有一列,名叫DUMMY,定义为VARCHAR2(1),包含一行数据,值为X