原Oracle数据库的项目同时兼容MySql步骤:

(一)修改资源配置文件applicationContext-dataSource.xml的数据库连接

Oracle数据库中加上from dual的原因:Oracle数据库中自带了一个虚拟表dual,这个的作用是测试数据库是否正常使用。

(二)添加一个类用于获取资源配置文件中当前使用的数据库类型以及该方法继承SqlMapClientDaoSupportExtend类,如果需要更多的方法,可以自行根据实际情况进行添加:

public class BaseDao extends SqlMapClientDaoSupportExtend{
@Autowired
private DruidDataSource dataSource; public Object queryForObject(String statementName){
return this.queryForObject(statementName, new HashMap());
}
/**
* 查询时并携带当前连接池数据库类型作为参数
* @param statementName
* @param parameterMap
* @return
*/
public Object queryForObject(String statementName,Map parameterMap){
setDbType(parameterMap);
return getSqlMapClientTemplate().queryForObject(statementName, parameterMap);
} public Object queryForObject(String statementName,Map parameterMap,Object resultObject){
setDbType(parameterMap);
return getSqlMapClientTemplate().queryForObject(statementName, parameterMap, resultObject);
} /**
* 查询时并携带当前连接池数据库类型作为参数
* @param statementName
* @param parameterMap
* @return
*/
public List queryForList(String statementName){
return this.queryForList(statementName, new HashMap());
} public List queryForList(String statementName,Map parameterMap){
setDbType(parameterMap);
return getSqlMapClientTemplate().queryForList(statementName, parameterMap);
} public List queryForList(String statementName, int skipResults, int maxResults){
return this.queryForList(statementName, new HashMap(), skipResults, maxResults);
} public List queryForList(
final String statementName, final Map parameterMap, final int skipResults, final int maxResults){
setDbType(parameterMap);
return getSqlMapClientTemplate().queryForList(statementName, parameterMap, skipResults, maxResults);
} public Map queryForMap(
final String statementName, final Map parameterMap, final String keyProperty){
setDbType(parameterMap);
return getSqlMapClientTemplate().queryForMap(statementName, parameterMap, keyProperty);
}
public Map queryForMap(
final String statementName, final Map parameterMap, final String keyProperty, final String valueProperty){
setDbType(parameterMap);
return getSqlMapClientTemplate().queryForMap(statementName, parameterMap, keyProperty,valueProperty);
} public int update(String statementName){
return update(statementName, new HashMap());
} public int update(final String statementName, final Map parameterMap){
setDbType(parameterMap);
return getSqlMapClientTemplate().update(statementName, parameterMap);
} public int delete(String statementName) throws DataAccessException {
return delete(statementName, new HashMap());
} public int delete(final String statementName, final Map parameterMap){
setDbType(parameterMap);
return getSqlMapClientTemplate().delete(statementName, parameterMap);
}
/**
* 获取数据库类型
* @param parameterMap
*/
private void setDbType(final Map<String, Object> parameterMap) {
String dataUrl = dataSource.getUrl();
dataUrl = dataUrl.substring(dataUrl.indexOf(":")+1);
dataUrl = dataUrl.substring(0,dataUrl.indexOf(":"));
parameterMap.put("dataBase", dataUrl);
}
}

详细说明:

(1)DruidDataSource类的自动装配

这个DruidDataSource类的来源就是要跟配置文件数据库连接池的名字一致,这个就是阿里巴巴开源的Druid连接池

(2)获取连接池里面的属性值url里面的字段,即截取出相应的数据库类型

执行过程分析:

String dataUrl = dataSource.getUrl();

获取到的值是:dataUrl="jdbc:oracle:thin:@192.168.0.153:1521:OANET"

dataUrl = dataUrl.substring(dataUrl.indexOf(":")+1);

获取到的值是:dataUrl=oracle:thin:@192.168.0.153:1521:OANET,dataUrl.indexOf(":")+1值就是5,即从下标5开始截取

dataUrl = dataUrl.substring(0,dataUrl.indexOf(":"));

获取到的值是:dataUrl=oracle,截取部分开始下标为0,结束下标为第一个冒号的下标,但不包括下标为第一个冒号的下标的那个标,左闭右开

(3)继承SqlMapClientDaoSupportExtend类,在每次写方法的时候获取当前的数据库的类型,例如:

(4)如果正常来说,Sql脚本语言如果可以同时兼容MySql和Oracle的话就可以不用调用该类了,如果不能同时兼容的话就需要调用该类,其实该类的方法和SqlMapClientDaoSupportExtend类的区别就是传递多一个dataBase参数而已,这样当我们我们发现Sql脚本语言不能兼容同时兼容MySql和Oracle时,我们的类就需要先继承我们写的BaseDao类:

不能同时兼容,需先继承我们写好的BaseDao:

同时可以兼容,直接继承SqlMapClientDaoSupportExtend类即可:

(5)Sql脚本语言不能同时兼容MySql和Oracle的时,修改Sql的文件如下:

(6)Sql脚本语言出现不兼容问题例子

第一步:修改该方法相应类的继承,改成继承BaseDao

第二步:修改BaseDao里面的方法,由于BaseDao里面的queryForObject方法里不能传String参数过去,所以就用一个Map对象将String的值传过去

未改前:

public ReserveInfoVO findOuternetReserveInfoByReserveSeq(String reserveSeq) {
Object obj = this.getSqlMapClientTemplate().queryForObject("outernetReserveInfo.findOuternetReserveInfoByReserveSeq", reserveSeq);
if(obj != null && obj instanceof ReserveInfoVO){
return (ReserveInfoVO)obj;
}
return null;
}

修改后:

public ReserveInfoVO findOuternetReserveInfoByReserveSeq(String reserveSeq) {
Map param=new HashMap();
param.put("reserveSeq", reserveSeq);
Object obj=queryForObject("outernetReserveInfo.findOuternetReserveInfoByReserveSeq", param);
if(obj != null && obj instanceof ReserveInfoVO){
return (ReserveInfoVO)obj;
}
return null;
}

第三步:修改完后,由于传递的参数由String变成了Map类型,所以Sql语句那边接收的参数要修改成Map,因为之前接受参数是用String的

Sql脚本语言兼容Oracle和MySql需要的注意点:

功能 Oracle MySql
转换成字符串类型 TO_CHAR DATE_FORMAT
转换成数值类型 TO_NUMBER CAST
转换成日期类型 TO_DATE STR_TO_DATE
字符拼接 || CONCAT
判断字段是否为空,为空则返回0,反之返回本身 NVL IFNULL
Desc做字段 C."DESC" C.DESC
数据库合并行记录 WMSYS.WM_CONCAT GROUP_CONCAT
条件判断 DECODE(NVL(1, 0), 0, 5, 1) CASE IFNULL(1, 0) WHEN 0 THEN 5 ELSE 1 END
BLOB数据转换成字符串 UTL_RAW.CAST_TO_VARCHAR2 CAST
将字符串类型转换为blob类型 TO_BLOB CAST
递归函数 START WITH......CONNECT BY 自定义函数再调用
通过表名获取表的主键

WHERE CU.CONSTRAINT_NAME = AU.CONSTRAINT_NAME

AND AU.CONSTRAINT_TYPE = 'P'

AND  AU.TABLE_NAME = #tableName#

WHERE table_name=#tableName#

AND COLUMN_KEY='PRI'

获取系统当前时间 SYSDATE NOW()
获取一条数据 rownum limit
删除表数据 delete(可用可不用表别名) delete(不能用表别名)

1、To_char:转换成字符串类型

MySql中的date_format(date,'%Y-%m-%d')    -------------->oracle中的to_char();

例子1:获取当前系统时间

Mysql:SELECT DATE_FORMAT(NOW(),'%Y-%m-%d %H:%i:%S');

Oracle: SELECT TO_CHAR(SYSDATE,'YYYY-MM-DD HH24:MI:SS') FROM DUAL

2、To_date:转换成日期类型

MySql中的str_to_date(date,'%Y-%m-%d')     -------------->oracle中的to_date();

例1:

Mysql:select str_to_date('2004-05-07 13:23:44','%Y-%m-%d %H:%i:%s')

Oracle:select to_date('2004-05-07 13:23:44','YYYY-MM-DD HH24:MI:SS') from dual

3、To_number:转换成数值类型如:To_number('1234.5'),结果:1234.5

例1:数字字符转换成整型:

MySql:CAST(a.sort AS SIGNED)

Oracle:to_number(a.sort)

4、字符拼接

MySql中concat('%','abc','%')------------------------>oracle中的'%' || 'abc' || '%'

例1:

MySql:CONCAT('%','不公示','%')

Oracle:'%'|| '不公示' ||'%'

5、判断字段是否为空,为空则返回0,反之返回本身:

MySql:select IFNULL('',0) from dual

Oracle:select nvl('',0) from dual

6、Desc做字段的区别:

desc字段---------------------->oracle中'desc'

MySql:

SELECT C.KEY, C.VALUE, C.DESC

FROM LZCITY_APPROVE_CONFIG C

WHERE C.KEY ='SEQ_TYPE'

Oracle:

SELECT C.KEY, C.VALUE, C."DESC"

FROM LZCITY_APPROVE_CONFIG C

WHERE C.KEY = 'SEQ_TYPE'

7、数据库合并行记录

Oracle:WMSYS.WM_CONCAT(需要合并字段)

MySql:GROUP_CONCAT(需要合并字段)

8、条件判断:

Oracle:decode(nvl(1, 0), 0, 5, 1) from dual

MySql:case IFNULL(1, 0) when 0 then 5 else 1 end

原理:如果为1,则为0;如果为0,则为5;如果都不是则为1

9、BLOB数据转换成字符串(Oracle自带系统包utlraw将RAW转为VARCHAR2)

Oracle:UTL_RAW.CAST_TO_VARCHAR2(H.IMG_BODY)

MySql:CAST(H.IMG_BODY AS CHAR)

10、将字符串类型转换为blob类型

Oracle:to_blob(字段)

MySql:CAST(字段 AS BINARY)

11、递归函数例子,通过父节点找到所有的节点

因为MySql没有start with......connect by,所以要自己写一个自定义函数

MySql:

delimiter $$
CREATE FUNCTION appr_index_tree_test(menu_root VARCHAR(200))
RETURNS VARCHAR(1000)
BEGIN
DECLARE sTemp VARCHAR(1000);
DECLARE sTempChd VARCHAR(1000);
SET sTemp='$';
SET sTempChd=menu_root;
WHILE sTempChd IS NOT NULL DO
SET sTemp=CONCAT(sTemp,',',sTempChd);
SELECT GROUP_CONCAT(seq_code) INTO sTempChd FROM appr_index_tree WHERE FIND_IN_SET(parent_seq_code,sTempChd)>0;
END WHILE;
RETURN sTemp;
END $$
delimiter;
SELECT appr_index_tree_test(父节点)

Oracle:

start with seq_code= 父节点
connect by prior seq_code = parent_seq_code

12、通过表名获取表的主键

MySql:

SELECT DISTINCT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name=#tableName#
AND COLUMN_KEY='PRI'

Oracle:

SELECT CU.COLUMN_NAME FROM USER_CONS_COLUMNS CU, USER_CONSTRAINTS AU
WHERE CU.CONSTRAINT_NAME = AU.CONSTRAINT_NAME
AND AU.CONSTRAINT_TYPE = 'P'
AND AU.TABLE_NAME = #tableName#

注意:其他相似例子

(1)往前一天:

Mysql:(Mysql则需要调用DATE_SUB函数,反之往后一天DATE_ADD)

select STR_TO_DATE(CONCAT(DATE_FORMAT(DATE_SUB(NOW(),INTERVAL 1 DAY), '%Y-%m-%d'),' 00:00:01'),'%Y-%m-%d %H:%i:%s')

Oracle:(Oracle直接在当前系统时间减一,反之往后一天加一)

select TO_DATE(TO_CHAR((SYSDATE-1), 'YYYY-MM-DD') || ' 00:00:01','YYYY-MM-DD HH24:MI:SS') FROM dual

(2)往前一个月:

Mysql:select DATE_SUB(NOW(),INTERVAL 1 MONTH)

Oracle:select ADD_MONTHS(SYSDATE, -1) FROM dual

(3)上一个月最后一天:

Mysql:select LAST_DAY(DATE_SUB(NOW(),INTERVAL 1 MONTH))

Oracle:select LAST_DAY(ADD_MONTHS(SYSDATE, -1)) FROM dual

(4)上一个月最后一天再加一天:

Mysql:select DATE_ADD(LAST_DAY(DATE_SUB(NOW(),INTERVAL 1 MONTH)),INTERVAL 1 DAY)

Oracle:select LAST_DAY(ADD_MONTHS(SYSDATE, -1))+1 FROM dual

(5)MySql中,两个显示当天时间的区别:

(1)select CURDATE()

(2)select NOW()

结果:(1)2017-02-15

(2)2017-02-15 22:10:36

(13)获取查询结果的一条数据

MySql:

select * from temp where LIMIT 1

Oracle:

select * from temp where rownum=1

(14)删除表中的数据

MySql:

delete from temp where ...

Oracle:

delete from temp where ...
delete from temp p where ...

Web项目--------原Oracle数据库的项目同时兼容MySql的更多相关文章

  1. FineReport - 项目连接Oracle数据库

    FineReport项目连接Oracle数据库 1:打开模板设计器,单击[服务器],选择[定义数据连接]: 2:单击[+],选择[JDBC]; 3:数据库选择[Oracle],驱动器选择[oracle ...

  2. JavaWeb项目连接Oracle数据库

    参考网址:http://jingyan.baidu.com/article/0320e2c1d4dd0b1b87507b38.html 既然你要链接oracle数据库 ,那么首先就是先打开我们的ora ...

  3. MVC项目使用Oracle数据库运行提示:找不到请求的 .Net Framework Data Provider。可能没有安装

    MVC项目使用Entity Framework针对Oracle数据库进行开发时,由于Oracle官方网站一般建议开发者在64位操作系统中使用32位ODP.Net进行开发.在进行程序编码的时候不会有问题 ...

  4. JDBC(Java项目使用Oracle数据库)

    Java项目中使用Oracle数据库(Eclipse) 前言 这学期选了Oracle数据库这门课,于是自己下载了Oracle11gR2版本的数据库.在这之前我一直用的是MySQL.虽然两者教程差不多, ...

  5. 解决使用Oracle数据库,项目启动由于表原因无法成功启动问题

    1.仔细看异常信息,如果出现一个  翻译过来是 不仅仅这一张表,那就说明,在连接数据库,定位到表的时候有多张表,不知道连哪一张. 原因: 有多个用户,这两个用户下有相同的表. 就算是在不同的表空间也不 ...

  6. Java电商项目-1.构建数据库,搭建项目环境

    目录 到Github获取源码请点击此处 一. 数据库还原 二. Mybatis逆向生成工具的使用 三. 搭建项目环境 四. 在linux虚拟机上部署zookeeper, 搭建Dubbo服务. linu ...

  7. 因为NLS_LANG 造成 Oracle数据库丢失 中文字符集兼容问题的处理.

    接着上一封blog. 因为sqlplus的 乱码问题 我修改了 注册表里面 NLS_LANG 的 value值.主要改动为: NLS_LANG source: SIMPLIFIED CHINESE_C ...

  8. C#:Oracle数据库带参PLSQL语句的正确性验证

    在有Oracle数据库C#项目中,有一个这样的需求:在界面上配置了带参数的PLSQL语句,但是要通过程序验证其正确性,那么该如何实现?这就是本文要探讨的内容. 一:通过OracleCommand对象的 ...

  9. Django连接oracle数据库的那些问题

    环境: windows 7 64位 python 3.6.5 32位 oracle客户端11.2 32位 django1.11.20 (django2.x版本不支持oracle客户端11g了) cx_ ...

随机推荐

  1. jquery1.9 下检测浏览器类型和版本的方法

    Jquery1.9版本中$.browser已被剔除: 判断浏览器类型: 复制代码 代码如下: $.browser.mozilla = /firefox/.test(navigator.userAgen ...

  2. JAVA反射机制_获取字节码文件对象

    是在运行状态中,对于任意一个类 (class文件),都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性: 这种动态获取的信息以及动态调用对象的方法的功能称为java语 ...

  3. Swift: Associated Types--为什么协议使用关联类型而不是泛型

    关联类型的形式为类型的引用进而进行约束提供了条件: 同时能够简化语法形式. Swift: Associated Types http://www.russbishop.net/swift-associ ...

  4. 谈谈HTTP

    HTTP又称超文本传输协议,在互联网上广为流传和应用. 今天主要讲这么几个? a.针对HTTP下细分为: HTTP概念.Request和Response详解.Request中GET和POST的区别.说 ...

  5. android camera 摄像头预览画面变形

    问题:最近在处理一下camera的问题,发现在竖屏时预览图像会变形,而横屏时正常.但有的手机则是横竖屏都会变形. 结果:解决了预览变形的问题,同时支持前后摄像头,预览无变形,拍照生成的jpg照片方向正 ...

  6. 在AspNetCore 中 使用Redis实现分布式缓存 (转载)

    文章概念描述 分布式缓存描述:分布式缓存重点是在分布式上,相信大家接触过的分布式有很多中,像分布式开发,分布式部署,分布式锁.事物.系统 等有很多.使我们对分布式本身就有一个很明确的认识,分布式就是有 ...

  7. Junit测试中找不到junit.framework.testcase

    在使用Junit进行测试时,出现如下问题: 找不到junit.framework.testcase 解决方法: 选中项目->属性->Java构建路径->库->添加外部jar 在 ...

  8. Python3入门(十)——调试与测试

    一.异常处理 1.try...except...finally... 这个也就是Java里的try...cath..finally...了,直接看经典代码: try: print("开始执行 ...

  9. 20155232《网络对抗》 Exp1 PC平台逆向破解(5)M

    20155232<网络对抗> Exp1 PC平台逆向破解(5)M 实验内容 (1).掌握NOP, JNE, JE, JMP, CMP汇编指令的机器码(1分) (2)掌握反汇编与十六进制编程 ...

  10. Python、pywin32&pycharm安装记录

    未完待续-- Python 下载安装 1.百度搜索Python,进入官网,download,下载相应版本 [因为我们需要用到的是Windows下的解释器,所以在Operating System中可以选 ...