都说Hibernate框架的使用可以很容易的让你的研发平台支持多种不同类型的数据库,但实践表明,这里的“容易”,是相对的。

  想让研发平台支持多种数据库,并不是一件简单的事,也可以这么说:并不是只要使用了Hibernate框架就能实现的。

  下面记录一下我做这件事情的过程和一些感悟。

  当我接到该任务时,我先大致的理了一下思路:

  要完成迁移,总体上有2大块工作要做,分别是:数据库层面的迁移  和  平台底层代码的改造

  一、数据库层面的迁移过程:

  1、通过sqlServer Studio2008 工具将数据从Oracle导入到SqlServer数据库

  从SSMS2008开始才支持此功能,具体操作步骤(右键点击数据库-选择导入-点下一步-选择 Oracle Provider for OLE DB 数据源-点击属性-填写数据源,格式为 IP:端口/实例名),后面的步骤根据向导一步步的操作即可。需要注意的是在 选择源表和源视图的步骤中:

  (1)、要把【目标】列中的默认前缀去掉,这样导入的表才会默认关联到dbo下,否则你每次查询表都要带上schema前缀,导致你之前的应用程序中的sql无法执行,因为你之前写的那些sql肯定不会带这种前缀。

  (2)、先勾选你要导入的源,然后双击每一行记录,在弹出的对话框中检查是否所有的类型都正确绑定好了,我在检查的时候就遇到了oracle中是varchar2类型的,在该对话框显示的表结构中变成了130,只能手动的去将所有130改成varchar类型(sqlserver里没有varchar2类型)。还有原来是clob类型的,现在变成了varchar,要手动改成text类型(因为clob类型的字段比较少,所以可以通过在oracle中执行“select * from user_tab_columns c where c.data_type='CLOB';”来查看哪些表中用到了CLOB类型的字段)。

  2、增加to_date、to_char、to_number、concat等常用的函数

说明:我在编写to_date函数的时候,只提供了一种格式“yyyy-mm-dd HH:mi:ss”,这是因为在sqlserver中是没有和to_date函数的类似的函数的,只能使用convert函数实现,但是convert函数不支持传入格式化字符串,只能传入格式字符对应的整型数字,而120对应的正是之前提到的“yyyy-mm-dd HH:mi:ss”格式;另外此次是迁移到Sqlserver2005,该版本是没有内嵌concat函数的,根据官方文档的说法,是从sqlServer2012开始才有concat函数的,所以这里我要自己编写一个concat函数。

------------------------------------------------------------------concat函数
USE [skyplatform]
GO
/****** Object: UserDefinedFunction [dbo].[concat] Script Date: 03/10/2015 17:11:31 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[concat]
(
@param1 varchar(500),
@param2 varchar(500)
)
returns varchar(1000)
as
begin
DECLARE @returntext varchar(1000)
if (@param1 is null)
SELECT @returntext= @param2;
else if (@param2 is null)
SELECT @returntext= @param1;
else
SELECT @returntext= @param1 + @param2;
return @returntext;
end --------------------------------------------------------------------to_char函数
USE [skyplatform]
GO
/****** Object: UserDefinedFunction [dbo].[to_char] Script Date: 03/10/2015 17:12:09 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[to_char]
(
@param1 datetime,
@param2 varchar(20)
)
returns varchar(20)
as
begin return convert(varchar(20),@param1,120) end --------------------------------------------------------------------to_date函数
USE [skyplatform]
GO
/****** Object: UserDefinedFunction [dbo].[to_date] Script Date: 03/10/2015 17:12:58 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[to_date]
(
@param1 varchar(20),
@param2 varchar(20)
)
returns datetime
as
begin return convert(datetime,@param1,120)--120 means that yyyy-mm-dd hh:mi:ss(24h) end
--------------------------------------------------------------------to_number函数
USE [skyplatform]
GO
/****** Object: UserDefinedFunction [dbo].[to_number] Script Date: 03/10/2015 17:13:09 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[to_number]
(
@param1 varchar
)
returns numeric
as
begin return convert(numeric,@param1) end

  二、平台底层代码的改造

  1、引入SqlServer的jar包:sqljdbc4-4.0.jar

<groupId>com.microsoft.sqlserver</groupId>
<artifactId>sqljdbc4</artifactId>
<version>4.0</version>

  2、修改db.properties中关于数据库连接信息的配置

jdbc.dialect=org.hibernate.dialect.SQLServerDialect
jdbc.driver=com.microsoft.sqlserver.jdbc.SQLServerDriver
jdbc.url=jdbc:sqlserver://xx.xx.xx.xx:1433;DatabaseName=xxx
jdbc.default_schema=dbo
jdbc.username=xxx
jdbc.password=xxx

  3、修改平台中使用的一些非sql标准的语法

  在使用delete insert update这些dml语句的时候,切记不要使用别名,因为在oracle和sqlserver中,这些dml语句使用别名的语法是不一样的。

  4、各实体类主键策略的改造

  最好都使用string类型的主键,但是因为之前的代码中都用的sequence做主键策略,现在改成string类型工作量势必很大,所以决定使用table策略来兼容各种数据库。

  5、dao层对sql的处理

  由于sqlserver中调用自定义标量值函数,必须在函数名前加上dbo.的前缀,但是这样写势必会导致不能兼容其它的关系型数据库,所以只能从dao实现层,对sql进行统一的处理,处理规则就是:如果当前数据库是sqlserver,并且sql中出现了concat、to_date、to_char、to_number等函数,就为这些函数名加上dbo.的前缀。

  以上做完,基本就可以让平台在sqlserver数据库上跑了,同时也可以通过改配置文件切换到Oracle数据库。

  以上的做法可能并不是最优的方式,如果有更好的方案,希望各位大牛能给予指点。

采用Hibernate框架的研发平台如何能够真正兼容Oracle和sqlServer数据库的更多相关文章

  1. Hibernate(一)——采用Hibernate框架开发环境搭建

    Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员充分使用对象编程思维来操作数据库.HIbernate的移植性很好,它可以应用于任何JDB ...

  2. SNF平台从sql server兼容oracle的处理方式和开发方式

    前几天有这样一个需求,就是让SNF平台BS版的基础程序全面支持Oracle数据库. 初一看这是一个很大的工程,因为大家都知道 Sql和Oracle的语法有很多的不一样,如 top .日期获取.类型之间 ...

  3. Hibernate框架基础

    Hibernate框架基础 Hibernate框架 ORM概念 O, Object 对象 R, Realtion 关系 (关系型数据库: MySQL, Oracle…) M,Mapping 映射 OR ...

  4. Hibernate框架:CRM练习--保存客户

    crm:customer ralation manager 客户关系管理系统 一.准备 1.创建web项目 2.导包 最终为: 3.引入静态页面 将文件复制放入项目的WebContent目录下面: 4 ...

  5. GPS部标平台的架构设计(三) 基于struts+spring+hibernate+ibatis+quartz+mina框架开发GPS平台

    注意,此版本是2014年研发的基于Spring2.5和Struts2的版本,此版本的源码仍然销售,但已不再提供源码升级的服务,因为目前我们开发的主流新版本是2015-2016年近一年推出的基于spri ...

  6. Hibernate框架--配置,映射,主键

    SSH框架: Struts框架, 基于mvc模式的应用层框架技术! Hibernate,    基于持久层的框架(数据访问层使用)! Spring,   创建对象处理对象的依赖关系以及框架整合! Da ...

  7. [ SSH框架 ] Hibernate框架学习之二

    一.Hibernate持久化类的编写规范 1.什么是持久化类 Hibernate是持久层的ORM影射框架,专注于数据的持久化工作.所谓持久化,就是将内存中的数据永久存储到关系型数据库中.那么知道了什么 ...

  8. (转)Hibernate框架基础——Java对象持久化概述

    http://blog.csdn.net/yerenyuan_pku/article/details/52732990 Java对象持久化概述 应用程序的分层体系结构 基于B/S的典型三层架构  说明 ...

  9. Struts2+Spring+Hibernate框架整合总结详细教程

    一.SSH三大框架知识总结 Struts 2是Struts的下一代产品,是在 struts 1和WebWork的技术基础上进行了合并的全新的Struts 2框架.其全新的Struts 2的体系结构与S ...

随机推荐

  1. 近实时运算的利器---presto在公司实践

    1.起因 公司hadoop集群里的datanonde和tasktracker节点负载主要集中于晚上到凌晨,平日工作时间负载不是很高.但在工作时间内,公司业务人员有实时查询需求,现在主要 借助于hive ...

  2. 【POI xls Java map】使用POI处理xls 抽取出异常信息 --java1.8Group by ---map迭代 -- 设置单元格高度

    代码处理逻辑: 代码流程: 1.首先需要创建一个实体 用来存储 相关信息 package com.sxd.test.unusualName; public class NameEntity { pri ...

  3. mysql数据库备份与还原命令

    还原一个数据库:mysql -h localhost -u root -p123456 www 备份一个数据库:mysqldump -h localhost -u root -p123456 www ...

  4. js小例子(标签页)

    运用js写的一个小例子,实现点击不同的标签出现不同的内容: <!DOCTYPE html> <html> <head> <meta chaset=" ...

  5. 我的c++学习(7)引用和复制构造函数

    一.引用 什么是引用? 引用又称别名(alias),是一种非常特殊的数据类型.它不是定义一个新的变量,而是给一个已经定义的变量重新起一个别名,也就是 C++系统不为引用类型变量分配内存空间.引用主要用 ...

  6. [bzoj4424]Fairy

    很久之前想写这题.结果还是把握不住CF的E,太神了啊....... 首先考虑的是二分图的性质,这个so easy,图中不存在奇数环. 然后分三种情况考虑: 1.只有一个奇数环,随便删除哪条 2.多个奇 ...

  7. Dijkstra(变形) POJ 1797 Heavy Transportation

    题目传送门 题意:求1到n的最大载重量 分析:那么就是最大路上的最小的边权值,改变优先规则. #include <cstdio> #include <algorithm> #i ...

  8. MapReduce 作业调试

    1. 最经典的方法通过打印语句来调试程序 System.err.println("Bad Data"+value.toString()); 这些输出错误都会记录到一个标准错误中,可 ...

  9. ArrayList和Vector以及synchronizedList

    ArrayList和Vector都是使用数组方式存储数据 区别大概就是Vector本身所有方法都是用synchronized修饰的,所以线程安全,而ArrayList没有 还有一个区别就是新增元素的时 ...

  10. DrawingContext.Pop Method

    The following example shows the effect of the Pop command. using System; using System.Windows; using ...