ORM framework源码分析:引言之Java JDBC

来源:互联网 发布:199it大数据工具导航 编辑:程序博客网 时间:2024/06/05 15:14

    在百度百科上找了一段定义ORM的话:对象关系映射(英语Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。从效果上说,它其实是创建了一个可在编程语言里使用的“虚拟对象数据库”。那么ORM Framework就是提供对象到数据库关系映射的一套编程模型。现在流行的MyBaits、Hibernate都是这种框架。本章开始我们就来分析下这两种框架源码的分析,从而更深入的理解什么事ORM。

    在开始分析MyBaits3,Hibernate4这些当前比较流行的ORM框架的源码之前我们先来看看JDBC,它是所有这些框架的基础。说到JDBC,我们首先来看看java.sql包下有哪些类。



    我们再来看一下一次jdbc访问数据的完整过程。

   Connection con = null;   Statement stmt = null;   ResultSet rs = null;   try{       Class.forName("com.mysql.jdbc.Driver");       con = DriverManager.getConnection("jdbc:mysql://localhost:3306/database", "root", "123456");       stmt = con.createStatement();              String sql = "select * from `table`";       rs = stmt.executeQuery(sql);               ResultSetMetaData rsmd = rs.getMetaData();       int j = 0;       j = rsmd.getColumnCount();       for(int k = 0; k<j; k++){           System.out.print(rsmd.getCatalogName(k+1));           System.out.print("\t");       }       while(rs.next())       {           for(int i=0;i<j;i++)           {               System.out.print(rs.getString(i+1));               System.out.print("\t");           }       }   }   catch(Exception e1)   {       System.out.println(e1.toString());   }   finally{           try       {           if(rs != null) rs.close();           if(stmt != null) stmt.close();           if(con != null) con.close();       }       catch(SQLException e)       {           System.out.println(e.toString());       }               }
     Class.forName(String)是java reflection中用来加载类的,这里加载了一个驱动,然后DriverManager.getConnection()获取数据库连接,我们来看看DriverManager类。

    DriverManager做为驱动管理器,有个内部类DriverInfo用于存取驱动程序的信息,维护着一个Driver对象。在加载了驱动程序后就需要从DriverManager中获取数据库连接。

public static Connection getConnection(String url,        String user, String password) throws SQLException {        java.util.Properties info = new java.util.Properties();        if (user != null) {            info.put("user", user);        }        if (password != null) {            info.put("password", password);        }        return (getConnection(url, info, Reflection.getCallerClass()));    }
private static Connection getConnection(        String url, java.util.Properties info, Class<?> caller) throws SQLException {        /*         * 如果callerCl是空,我们就得检查应用的类加载器,这样就能加载rt.jar以外的JDBC驱动         */        ClassLoader callerCL = caller != null ? caller.getClassLoader() : null;        synchronized (DriverManager.class) {            // synchronize loading of the correct classloader.            if (callerCL == null) {                callerCL = Thread.currentThread().getContextClassLoader();            }        }        if(url == null) {            throw new SQLException("The url cannot be null", "08001");        }        println("DriverManager.getConnection(\"" + url + "\")");        SQLException reason = null;        for(DriverInfo aDriver : registeredDrivers) {            //如果该类加载器无加载该驱动的权限则跳过            if(isDriverAllowed(aDriver.driver, callerCL)) {                try {                    println("    trying " + aDriver.driver.getClass().getName());                    //利用驱动尝试连接数据库                    Connection con = aDriver.driver.connect(url, info);                    if (con != null) {                        println("getConnection returning " + aDriver.driver.getClass().getName());                        return (con);                    }                } catch (SQLException ex) {                    if (reason == null) {                        reason = ex;                    }                }            } else {                println("    skipping: " + aDriver.getClass().getName());            }        }      //省略部分代码...    }
     DriverManager会在类载入时调用静态代码块初始化加载数据库驱动,当用户用getConnection时Driver会尝试去连接数据库,一旦有一种Driver能连接当前数据库就返回这个连接。以Mysql的mysql-connector-java为例如果希望自己的数据库能被JDBC数据库连接必须实现Connection接口。Connection不仅能提供事务操作还有个抽象方法createStatement能创建一个sql声明,这里就讲到了JDBC的第二个比较重要的类Statement。同样这个也是一个接口,需要不同数据库的开发商自己提供实现,这个对象主要的作用就是执行sql返回ResultSet,同样这个ResultSet也是一个接口需要提供第三方实现,它类似一个Table数据结构,每次调用next()它就指向下一条数据库记录,针对不同类型字段调用不同的getXXX(String columnName)就能获取该条记录对应字段的值。除了以上的这些主要接口,JDBC还提供了描述数据库属性的DatabaseMetaData接口和一些Date之类类型类和异常类。

   从以上这些分析我们就可以看出,实际上JDBC API很简单,它只是一个java到数据库的桥梁,只提供了一个大致规范,所有对特定数据库的操作都需要第三方来提供实现。





0 0
原创粉丝点击