Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java中通过JDBC实现的数据库独立性_Java_Sql_Jdbc - Fatal编程技术网

java中通过JDBC实现的数据库独立性

java中通过JDBC实现的数据库独立性,java,sql,jdbc,Java,Sql,Jdbc,使用JDBC有一些局限性,数据库依赖性就是其中之一 JDBC中是否有实现数据库独立性的模式或方法(不使用任何其他ORM框架或工具) 我试图通过动态多态性(为不同的DBMS创建特定的类,并根据特定的SQL语法重写常见的CRUD操作)来实现这一点 例如,有没有一种方法可以编写通用SQL语句,以便它们可以在几乎所有与SQL相关的DBMS中执行?在我看来,您实际上试图通过创建一个库来构建通用SQL语句,该库允许您通用地访问数据库,这与许多ORM已经完成的工作非常类似 你试过jOOQ吗?它与其他的ORM有

使用JDBC有一些局限性,数据库依赖性就是其中之一

JDBC中是否有实现数据库独立性的模式或方法(不使用任何其他ORM框架或工具)

我试图通过动态多态性(为不同的DBMS创建特定的类,并根据特定的SQL语法重写常见的CRUD操作)来实现这一点


例如,有没有一种方法可以编写通用SQL语句,以便它们可以在几乎所有与SQL相关的DBMS中执行?

在我看来,您实际上试图通过创建一个库来构建通用SQL语句,该库允许您通用地访问数据库,这与许多ORM已经完成的工作非常类似

你试过jOOQ吗?它与其他的ORM有很大的不同,可以满足您的需求。你可以把它称为“工具”,但我也可以把你试图构建的东西称为“工具”

jOOQ致力于成为一种java本地语言,用于进行可移植的DB调用,因此听起来它正是您想要的


首先,数据库独立性很难。真的,真的很难;要在不使用ORM或其他工具的情况下实现它,您必须权衡解决方案设计的其他方面。简单性和可维护性将受到影响,实施解决方案的努力也将受到影响

所以,我要确保这是一个高优先级的要求——我认为假设的“如果我们想从Oracle切换到SQL Server怎么办”的问题是——没有足够的理由承担额外的成本

如果必须提供此功能,那么ORM是目前为止最简单的方法。ORM框架是专门为数据库独立性而设计的(它们的复杂性至少部分是由于这一需求)。他们通过将数据库实现抽象到更高的级别来实现这一点;我们鼓励您考虑域对象,而不是使用SQL语句

说了这么多

我已经提供了一个解决方案(不是Java,而是原则),它允许数据库独立性。我们将SQL语句存储为资源,并通过资源文件加载它们。默认的是ANSI SQL,它可以在任何与SQL兼容的现代数据库上工作

对于我们支持的每种数据库风格(在我们的例子中是MySQL和Oracle),我们都有资源文件,并使用覆盖来加载特定于数据库的SQL语句(如果它们存在的话)

这与大多数语言中的国际化类似——首先查找特定于语言环境的字符串,如果找不到,则返回默认值


Java的资源包将使这变得非常简单。不在应用程序中硬编码SQL还有其他好处-在不更改应用程序代码的情况下修复数据库问题要容易得多,您可以将修复部署为“资源”更新,而不是发布新的二进制文件等。

我想我有资格回答,作为的作者,这一点在中已经提出。正如我所展示的,完全有可能实现你想要做的事情,但是如果你想自己实现的话,你还有很长的路要走

让我们来谈谈JDBC JDBC是一种优秀的网络协议抽象,因此它是一个很好的起点。但是,当您继续在API内部解决更复杂的问题时,有很多注意事项,比如您正在尝试构建的API。例如:

  • 获取生成的密钥非常困难。很少有JDBC驱动程序能做到这一点
  • 您确定正确处理LOB吗?提示:你不是
  • 什么比高球更糟糕?Oracle对象类型内部的LOB
  • 我提到过Oracle对象类型吗?它们可以放在数组中(和数组中的数组),这时东西会变得很毛茸茸的
  • 但是与PostgreSQL的类型相比,Oracle的对象类型非常好,JDBC驱动程序根本帮不了你
  • 尝试绑定DB2
    NULL
    值。有时有效,有时无效
  • 想要支持
    java.sql.Date
    java.time.LocalDate
    ?祝你好运
  • 说到日期,你知道有多少种不同的时间戳和时区数据类型的解释吗
  • 想支持
    INTERVAL
    类型吗?真的吗
  • 如果数据库抛出多个异常怎么办
  • 如果数据库通过与异常不同的API引发错误(hello SQL Server),该怎么办
  • 如果在获取异常之前需要收集警告,该怎么办
  • 您知道吗,某些数据库首先向您发送更新计数,然后才发送实际结果集(例如,当触发器触发时)
  • 你想过处理多个结果集吗
  • 现在将上述参数与正式的
    OUT
    参数结合起来
  • 让我们讨论一下
    布尔类型
  • …我可以坚持几个小时
  • 您知道吗,当
    autoCommit
    设置为true时,某些PostgreSQL语句不起作用
  • 并非所有人都支持保存点
  • 想要使用JDBC
    DatabaseMetaData
    对模式进行反向工程吗?算了吧
  • 要使用
    ResultSetMetaData
    查找限定的列名吗?嗯
正如您所看到的,即使JDBC对大多数人来说都做得很好(而且上面的每一项都有一个适用于单个数据库的黑客解决方案。但是您希望编写一个适用于所有数据库的API,所以您必须修复/解决上述所有问题。相信我,这会让您忙上一段时间

让我们来谈谈SQL 但到目前为止,我们只讨论了绑定到JDBC有多难。我们还没有讨论标准化SQL有多难。所以让我们先讨论一下:

  • LIMIT n OFFSET m
    很好,呃?或者它是
    LIMIT m,n
    ?或者
    TOP n从m开始
    ?或者
    OFFSET m行
    
    declare
      t0 dbms_sql.number_table;
      t1 dbms_sql.date_table;
      c0 sys_refcursor;
      c1 sys_refcursor;
    begin
      update "TEST"."T_2155"
      set "TEST"."T_2155"."D1" = date '2003-03-03'
      returning 
        "TEST"."T_2155"."ID", 
        "TEST"."T_2155"."D1"
      bulk collect into t0, t1;
      ? := sql%rowcount; // Don't forget to fetch the row count
      open c0 for select * from table(t0);
      open c1 for select * from table(t1);
      ? := c0; // These need to be bound as OracleTypes.CURSOR OUT params
      ? := c1; // These need to be bound as OracleTypes.CURSOR OUT params
    end;