【问题标题】:How To Provide Database Independency in JDBC Without Using Hibernate.?如何在不使用 Hibernate 的情况下在 JDBC 中提供数据库独立性。?
【发布时间】:2018-04-18 06:08:01
【问题描述】:

我试图借助属性文件来解决这个问题,但在属性文件中,我们只能处理数据库驱动程序问题。如果我想将我的 MySQL 切换到 Oracle 数据库,我需要更改我的所有查询。问题是如何让JDBC中的查询独立?

import java.io.FileInputStream;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Properties;

public class DBIndependencyExample {
    public static void main(String[] args) {
        try {
            Properties pros = new Properties();
            InputStream fis = new FileInputStream(
                    "D:\\Programs\\Eclipse\\DBIndependecyByPropertiesFile\\src\\connectdb.properties");
            pros.load(fis);
            String Drivername = pros.getProperty("k1");
            //System.out.println(Drivername);
            String url = pros.getProperty("k2");
            String un = pros.getProperty("k3");
            String pw = pros.getProperty("k4");
            Class.forName(Drivername);
            Connection con = DriverManager.getConnection(url, un, pw);
            System.out.println("Driver Is Loaded With" + Drivername);
            System.out.println("Connection is Opened");
            Statement smt = con.createStatement();
            String sql = pros.getProperty("k5");
            //System.out.println(sql);
            ResultSet rs = smt.executeQuery(sql);
            while (rs.next()) {
                System.out.println("username is:" + rs.getString(1) + " password is:" + rs.getString(2));
            }
            con.close();
            System.out.println("Connection is closed");
            fis.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

属性文件:

//Mysql Connectivity 
//Start Properties File Code
k1=com.mysql.jdbc.Driver
k2=jdbc:mysql://localhost:3306/practice
k3=root
k4=root
k5=select * from student

//Oracle  Connectivity

k1=oracle.jdbc.driver.OracleDriver
k2=jdbc:oracle:thin:@localhost:1521/orcla
k3=scott
k4=manish       
k5=select * from dept

【问题讨论】:

  • select * from studentselect * from dept 应该适用于 Oracle 和 MySQL;您是否有更复杂的查询不适用于两种 RDBMS?
  • 有一些基于 mysql 和 oracle 的特定查询。假设我的应用程序基于 mysql db,我想将我的 db 更改为任何其他 db。在这种情况下,我必须更改整个查询什么我们在我们的应用程序中申请了。我需要可以在我的应用程序中接受任何数据库查询的东西。谢谢
  • 我不认为有一个实用程序可以自动将专有语法从​​一个供应商翻译到另一个供应商。正如其他人指出的那样,您要么需要坚持 ANSI SQL 语法,要么需要针对不同的数据库进行单独的查询。

标签: java mysql jdbc


【解决方案1】:

如果我想将我的 mysql 切换到 oracle 数据库,我需要更改我的 所有查询。

如果您的 SQL 查询仅依赖于 ANSI SQL 而从不依赖专有特性(函数、关键字和...),那么您应该能够从 DBMS 切换到另一个 DBMS,而无需对查询进行任何更改。
请注意,Hibernate 不会将 DBMS 特性转换为另一个,例如将用 Oracle 编写的 DUAL 表上的查询转换为 MySQL 方式。
Hibernate 确保您的 SQL 查询是可移植的,而您不创建本机查询,Hibernate 仍然提供这种可能性。

Here 是原始 SQL ANSI 草案,here 是最新版本信息技术 -- 数据库语言 -- SQL -- 第 1 部分:框架(SQL/框架)的下载链接

【讨论】:

  • 先生,我还有其他方法可以执行mysql和oracle的所有查询。
  • @Manish 没有奇迹,抱歉。
  • 感谢您宝贵的时间。
  • 问题是:来自 LAMP 黄金年代的普通 MySQL 程序员的普通 MySQL 代码完全不可移植。 SQL 查询必须严格遵守 SQL ANSI
【解决方案2】:

如果您切换到休眠或任何 orm 框架,我不这么认为。在休眠的情况下,您可以使用 hql 以独立于数据库的方式编写查询,无论您切换休眠状态的数据库都会处理。您甚至可以查看 Spring CrudRepository。我非常怀疑您是否可以仅使用 JDBC 来实现与数据库无关的查询。从长远来看,最好从 JDBC 开始,您应该考虑 orm 框架。

【讨论】:

  • 尊敬的先生,我知道我们可以借助休眠 ORM 工具实现数据库独立,但我的要求是我想借助 JDBC 实现数据库独立。
  • 如果没有第三方 API,那么您必须编写实现以在执行您的 statement.executeQuery 之前根据您的属性文件更改转换查询,您可以根据您的数据库更改您的查询。如果这只是一种方法,那很好,但你想为整个应用程序做建议你的团队转向 orm。这是他们引入 orm 的主要原因之一。
【解决方案3】:

您可以编写一个通用方法来处理任何 sql 查询(无论使用什么数据库)。这里的技巧是使用数据库元数据自动 填充包含查询结果的哈希映射(哈希映射很方便,因为我们可以使用列名作为键)。对于参数化查询,您需要一个更复杂的方法,可以在下面提供的链接 (DBSelect.getRecordsForCustomQuery) 中找到。如果针对不同数据库的所有查询都相同,那么您甚至不必使用元数据,只需对列名进行硬编码即可。

public Map<String, Object> getQueryResults(String query, Connection conn){

    ResultSet rs=null; 
    PreparedStatement stmt=null; 
    Map<String, Object> objMap = new HashMap<>();

    stmt = conn.prepareStatement(sqlQuery); 
    rs = stmt.executeQuery();
    while(rs.next()){
    for (int i=1;i<=rs.getMetaData().getColumnCount();i++) { 
                objMap.put( rs.getMetaData().getColumnName(i), rs.getObject(i)); 
    }
 }
    return mapObj;

}

当然,您可以修改此方法以满足您的需要。

可以在此处找到使用反射和泛型的稍微复杂的解决方案 (https://github.com/IvanGH2/EasyORM),但您没有 甚至必须使用所有这些。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-26
    • 1970-01-01
    • 2010-10-18
    • 1970-01-01
    • 2013-12-03
    相关资源
    最近更新 更多