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

在百度百科上找了一段定义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到数据库的桥梁,只提供了一个大致规范,所有对特定数据库的操作都需要第三方来提供实现。

时间: 2024-11-03 21:48:52

ORM framework源码分析:引言之Java JDBC的相关文章

Lavavel笔记 Eloquent ORM分页源码分析

安装了laravel-debugbar后打开一个列表页面,发现页面输出有两个 select count(*) 语句,这是一个严重的设计缺陷呀. 查看代码 $users = User::where('votes', '>', 100)->paginate(15); $count = User::where('votes', '>', 100)->count(); 之前就感觉paginate分页应该是使用了count,但是不知道怎么取总量数据所以又写了一个count(). var_du

《Java源码分析》:Java NIO 之 Buffer

<Java源码分析>:Java NIO 之 Buffer 在上篇博文中,我们介绍了Java NIO 中Channel 和Buffer的基本使用方法,这篇博文将从源码的角度来看下Buffer的内部实现. 在Java API文档中,对Buffer的说明摘入如下: Buffer:是一个用于特定基本数据类型的容器.这里的特定基本数据类型指的是:除boolean类型的其他基本上数据类型. 缓冲区是特定基本数据类型元素的线性有限序列.除内容外,缓冲区饿基本属性还包括三个重要的属性,如下: 1.capaci

Django rest framework源码分析(一) 认证

一.基础 最近正好有机会去写一些可视化的东西,就想着前后端分离,想使用django rest framework写一些,顺便复习一下django rest framework的知识,只是顺便哦,好吧.我承认我是故意的,因为我始终觉得,如果好的技术服务于企业,顺便的提高一下自己.大家都很开心不是不.再次强调一下,真的只是顺便. 安装吧 pip install djangorestframework 1.2.需要先了解的一些知识 理解下面两个知识点非常重要,django-rest-framework

Django rest framework源码分析(4)----版本

版本 新建一个工程Myproject和一个app名为api (1)api/models.py from django.db import models class UserInfo(models.Model): USER_TYPE = ( (1,'普通用户'), (2,'VIP'), (3,'SVIP') ) user_type = models.IntegerField(choices=USER_TYPE) username = models.CharField(max_length=32,u

JDK源码分析:Short.java

Short是基本数据类型short的包装类. 1)声明部: public final class Short extends Number implements Comparable<Short> extends Number,override methods: public abstract int intValue(); public abstract float floatValue(); public abstract long longValue(); public abstract

Django REST framework 源码分析

简介 Django REST framework is a powerful and flexible toolkit for building Web APIs. 文档:https://q1mi.github.io/Django-REST-framework-documentation/ 安装 pip install djangorestframework --- 原文地址:https://www.cnblogs.com/0bug/p/8515358.html

Java集合系列:-----------03ArrayList源码分析

上一章,我们学习了Collection的架构.这一章开始,我们对Collection的具体实现类进行讲解:首先,讲解List,而List中ArrayList又最为常用.因此,本章我们讲解ArrayList.先对ArrayList有个整体认识,再学习它的源码,最后再通过例子来学习如何使用它.内容包括: ArrayList简介 ArrayList 是一个数组队列,相当于 动态数组.与Java中的数组相比,它的容量能动态增长.它继承于AbstractList,实现了List, RandomAccess

Java 序列化和反序列化(二)Serializable 源码分析 - 1

目录 Java 序列化和反序列化(二)Serializable 源码分析 - 1 1. Java 序列化接口 Java 序列化和反序列化(二)Serializable 源码分析 - 1 在上一篇文章中讲解了一下 Serializable 的大致用法,本节重点关注 Java 序列化的实现,围绕 ObjectOutputStream#writeObject 方法展开. 1. Java 序列化接口 Java 为了方便开发人员将 Java 对象进行序列化及反序列化提供了一套方便的 API 来支持.其中包

quartz集群调度机制调研及源码分析---转载

quartz2.2.1集群调度机制调研及源码分析引言quartz集群架构调度器实例化调度过程触发器的获取触发trigger:Job执行过程:总结:附: 引言 quratz是目前最为成熟,使用最广泛的java任务调度框架,功能强大配置灵活.在企业应用中占重要地位.quratz在集群环境中的使用方式是每个企业级系统都要考虑的问题.早在2006年,在ITeye上就有一篇关于quratz集群方案的讨论:http://www.iteye.com/topic/40970 ITeye创始人@Robbin在8楼