java中通过JDBC实现的数据库独立性
使用JDBC有一些局限性,数据库依赖性就是其中之一 JDBC中是否有实现数据库独立性的模式或方法(不使用任何其他ORM框架或工具) 我试图通过动态多态性(为不同的DBMS创建特定的类,并根据特定的SQL语法重写常见的CRUD操作)来实现这一点java中通过JDBC实现的数据库独立性,java,sql,jdbc,Java,Sql,Jdbc,使用JDBC有一些局限性,数据库依赖性就是其中之一 JDBC中是否有实现数据库独立性的模式或方法(不使用任何其他ORM框架或工具) 我试图通过动态多态性(为不同的DBMS创建特定的类,并根据特定的SQL语法重写常见的CRUD操作)来实现这一点 例如,有没有一种方法可以编写通用SQL语句,以便它们可以在几乎所有与SQL相关的DBMS中执行?在我看来,您实际上试图通过创建一个库来构建通用SQL语句,该库允许您通用地访问数据库,这与许多ORM已经完成的工作非常类似 你试过jOOQ吗?它与其他的ORM有
例如,有没有一种方法可以编写通用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
- 让我们讨论一下
布尔类型
- …我可以坚持几个小时
- 您知道吗,当
设置为true时,某些PostgreSQL语句不起作用autoCommit
- 并非所有人都支持保存点
- 想要使用JDBC
对模式进行反向工程吗?算了吧DatabaseMetaData
- 要使用
查找限定的列名吗?嗯ResultSetMetaData
很好,呃?或者它是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;