Web项目--------原Oracle数据库的项目同时兼容MySql
原Oracle数据库的项目同时兼容MySql步骤:
(一)修改资源配置文件applicationContext-dataSource.xml的数据库连接
Oracle数据库中加上from dual的原因:Oracle数据库中自带了一个虚拟表dual,这个的作用是测试数据库是否正常使用。
(二)添加一个类用于获取资源配置文件中当前使用的数据库类型以及该方法继承SqlMapClientDaoSupportExtend类,如果需要更多的方法,可以自行根据实际情况进行添加:
public class BaseDao extends SqlMapClientDaoSupportExtend{@Autowiredprivate 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.DESCFROM LZCITY_APPROVE_CONFIG CWHERE C.KEY ='SEQ_TYPE'
Oracle:
SELECT C.KEY, C.VALUE, C."DESC"FROM LZCITY_APPROVE_CONFIG CWHERE 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 DOSET 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 ...
转载于:https://www.cnblogs.com/xuegu/p/6431425.html
Web项目--------原Oracle数据库的项目同时兼容MySql相关推荐
- oracle数据库报错09275,项目连接Oracle数据库报错
要连的数据库是oracle 11.2 项目是从SVN上check out的.我检查了class12.jar和ojdbc6.jar都已经添加到项目的引用里了,但是连接数据库时还是提示NullPointe ...
- 物流项目中Oracle 数据库的使用及OGG是如何同步
文章目录 业务服务器之Oracle 数据库 06-[掌握]-OGG 数据同步之功能概述 07-[掌握]-OGG 数据同步之基本原理及架构 08-[理解]-OGG 数据同步之拓扑结构及支持环境 09-[ ...
- Springboot项目配置oracle数据库
前段时间的一个项目需要使用oracle数据库,之前使用的都是Spingboot+Mybatis+Druid+Mysql,没有配置Oracle的经验,现在记录一下 1.使用Navicat Premium ...
- javaweb分页查询oracle,JavaWeb项目 利用Oracle数据库实现分页查看细讲
一.了解数据库指令 Oracle数据库相对于MySQL数据库来说,要实现分页查看,Oracle中没有像MySQL里的limit命令,使用的Oracle语句也比较复杂 select * from (se ...
- 关于springboot项目连接oracle数据库报错 ORA01017的改正
拉取的项目本身用的是mysql数据库,改用orcl数据库,引入 驱动,连接时报ORA01017 ,确认用户名和密码是正确的.查看报错,之前有druid驱动,注释了就不报错了.
- war项目连接linux数据库,springboot项目war包部署到Linux
1.修改springboot启动类 2.移除springboot嵌入式tomcat 3.以上两步就可以了,如果还不行,就看tomcat日志catalina.log是否报错 1)jmx.mbean.dr ...
- mysql 数据库中数据去重,oracle数据库中如何达到像mysql数据库中group by 那种去重的效果..求大神解答...
满意答案 oracle和mysql,group by是由区别的. oracle的gruop by 后跟的必须是select查询出的字段 而且group by语句中select指定的字段必须是" ...
- Abp项目模板使用Oracle数据库包括系统权限管理
Abp项目模板使用Oracle数据库包括系统权限管理 by dacong 参考:Abp项目的创建以及Oracle的支持 aspnet-zero-core 使用MySql数据库 http://www.s ...
- oracle复制数据库文件,史上最简单的方法复制或迁移Oracle数据库
在DBA的日常工作中,经常需要重装或在新机器上安装Oracle,但每次安装所浪费的时间.精力以及失败的挫折都在考验着DBA的承受能力,本文着重介绍了一个简单的复制和迁移Oracle数据库的方法,详细内 ...
最新文章
- 光纤熔接盒盘线方法_【图文教程】光纤熔接技术的操作与技巧分享!
- c 结构体在声明时赋值_C/C++编程笔记:C++入门知识,C++多态性和虚函数解析
- 今天写了一个含配置文件的 文件分割 及 合并 的java程序。
- 高通骁龙855刚捂热 骁龙865就现身:三星代工 7nm EUV制程
- org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
- 自定义ZXing二维码扫描界面并解决取景框拉伸等问题
- 【转】opengl的一些小问题
- php 中访问常量,php 中的常量
- Win10 利用快捷键,快速新建TXT文档
- kali android命令大全,让你的安卓设备跑起kali——kali for android
- html中背景色优先级,CSS背景颜色优先级
- 黑人是晒黑的吗_当您是互联网上的黑人时,无处可逃
- [NOI2004]郁闷的出纳员 Treap
- javascript随机抽签程序
- 二进制部署 单Master Kubernetes-v1.14.1集群
- 西电通院随机信号实验(FPGA实现2ASK键控、RC低通滤波器、Matlab实现SSB调制)
- [luogu] P4735 最大异或和
- 【uniapp 动态设置 起始页 默认展示页面 】
- Tailwind教程1 - 开始使用
- 机器学习实战2.2. k-近邻算法例子-优化约会网站的配对效果
热门文章
- python字典数据的特点_Python核心数据类型之字典15
- cholesky分解_Time Series Analysis-1.2 LDL分解
- 北京大学生物信息学学习(6)隐含马尔可夫模型
- 数据挖掘、数据分析、人工智能及机器学习课程资源
- 应用数据挖掘进行客户关系管理
- 麦亡9什么时候能装鸿蒙系统,距断供不到10天 麒麟9000即将绝版 华为大招来了:不止鸿蒙2.0...
- 蓝牙学习笔记(五)——AC692x_BLE工具make_gatt_services
- spark.network.timeout参数入门
- Kafka 副本leader选举
- 理解RDD的Partition