如何在不使用Hibernate的情况下在JDBC中提供数据库独立性。

时间:2018-04-18 06:08:02

标签: java mysql jdbc

我试图在属性文件的帮助下解决这个问题,但是在属性文件中,我们只能处理数据库驱动程序问题。如果我想将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

3 个答案:

答案 0 :(得分:1)

  

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

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

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

答案 1 :(得分:0)

如果你切换到hibernate或任何orm框架,我都不这么认为。在hibernate的情况下,您可以使用hql以这种方式编写查询,无论您切换什么数据库,hibernate都会照顾它。你甚至可以看一下Spring CrudRepository。我非常怀疑您是否可以使用JDBC实现与数据库无关的查询。从长远来看,开始使用JDBC是件好事,你应该考虑使用orm框架。

答案 2 :(得分:0)

您可以编写一个可以处理任何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),但是你不能 甚至不得不使用所有这些。