1.Hibernate和ORM

ORM的全称是Object Relational Mapping,即对象关系映射。它的实现思想就是将关系数据库中表的数据映射成为对象,以对象的形式展现,这样开发人员就可以把对数据库的操作转化为对这些对象的操作。因此它的目的是为了方便开发人员以面向对象的思想来实现对数据库的操作。

2.Hibernate是如何实现映射的

在使用Hibernate实现ORM功能的时候,主要的文件有:映射类(*.java)、映射文件(*.hbm.xml)以及数据库配置文件(*.properties或*.cfg.xml),它们各自的作用如下:

⑴映射类:它的作用是描述数据库表的结构,表中的字段在类中被描述成属性,将来就可以实现把表中的记录映射成为该类的对象。

⑵映射文件:它的作用是指定数据库表和映射类之间的关系,包括映射类和数据库表的对应关系、表字段和类属性类型的对应关系以及表字段和类属性名称的对应关系等。

⑶数据库配置文件:它的作用是指定与数据库连接时需要的连接信息,比如连接哪中数据库、登录用户名、登录密码以及连接字符串等。

在这三种主要的文件中,映射类为普通Java源文件、映射文件为XML格式、数据库配置文件为Properties格式或者是XML格式。想理解“映射”首先我们需要知道如何解析这三种文件,即解析XML格式文件、解析Properties格式文件和解析Java类文件。

⑴如何解析XML文件
解析XML的技术可以分为两类那就是SAX和DOM,这两种方式有各自的差别和优缺点。实现解析XML文件的功能很方便,我们可以通过下载第三方的一些工具包如xml-apis.jar和xercesImpl.jar等,也可以使用JDK自带的工具类DocumentBuilderFactory、
DocumentBuilder、Document、Element等等,大家可以通过API文挡查阅这些类的说明。通过这些类我们可以把XML文件的信息读入内存并通过类中的某些方法获取指定节点的名字、值、属性名、属性值这些信息。

⑵解析Properties文件
Properties文件一般采用“属性名=属性值”的形式描述信息。
如果配置文件采用Properties文件描述,我们就需要想办法解析这种类型的文件了。想解析Properties文件需要熟悉Properties这个类了,这个类有一些常用方法比如,load()加载指定文件并读取文件中的属性信息,PropertyNames()返回所有属性名,getProperty()返回指定属性名的属性值。通过解析Properties文件我们可以得到连接数据库必要的信息,然后通过底层JDBC技术与数据库建立连接。

⑶解析Java类文件
通过解析映射文件和数据库配置文件我们可以建立数据库的连接,可以得到映射类的名字、属性名、数据库表名、字段名以及类型等信息。要把数据库中表的数据映射成为对象,首先需要把表中的记录取出,然后将每个字段值给映射类对象的每个属性,这个赋值过程要调用对象中的set方法。
我们现在通过映射文件只知道类名和属性名,如何根据类名和属性名调用相应的set和get方法,是一个关键问题。在Java中有一种机制叫反射机制,使用这种机制我们可以得到类的信息,包括类只用的修饰符、方法、属性、继承的父类以及实现接口等信息。
反射机制相关的类有Class、Field、Method以及Constructor等。通过Class的getFields()、getMethods()和getConstructors()方法得到相应的属性、方法和构造方法。
通过Field类的getName()、getType()和getModifiers()方法得到相应的属性名、属性类型、属性修饰符信息。
通过Method类getReturnType()可以获取方法的返回类型,
invoke()方法可以根据给定的方法名和参数值执行对象中对应的方法。
我们可以首先通过以上方法获取类中的属性名,然后拼写成setXXX和getXXX方法名,最后根据方法名执行对应的方法,将数据库数据加载到对象中。

整理自 Hibernate框架ORM的实现原理

3.模拟Hibernate加载配置文件并映射到实体类的过程

(1)创建实体类

/**
* 示例实体对象
* 对应学生表
*/
public class Student { private int id;
private String name;
private String score;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getScore() {
return score;
}
public void setScore(String score) {
this.score = score;
}
}

  

(2)模拟解析hbm.xml和数据库配置文件,并且创建Session

import java.io.IOException;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.xpath.XPath; /**
* 模拟Session类实现
*/
public class Session { /**
* 模拟Stument.hbm.xml文件的内容
* 这里没有解析hbm.xml
*/
private Map<String ,String > hbmInfo = new HashMap<String ,String >(); //存放数据库连接配置
private Map<String, String> conConfig = new HashMap<String, String>(); //实体的get方法集合
String methodNames[]; public Session(){
/**
* 初始化实体,具体的实现应该是读取hbm.xml文件解析字段
*/
hbmInfo.put("id", "id");
hbmInfo.put("name", "name");
hbmInfo.put("password", "password");
methodNames = new String[hbmInfo.size()];
} /**
* 创建数据库连接
* @return
* @throws IOException
* @throws JDOMException
*/
public Connection initConn() throws Exception{
SAXBuilder sb = new SAXBuilder();
Document doc = sb.build(this.getClass().getClassLoader().getResourceAsStream("hibernate.cfg.xml"));
Element root = doc.getRootElement();
List list = XPath.selectNodes(root, "/hibernate-configuration/property"); for (int i = 0; i < list.size(); i++) {
Element property = (Element) list.get(i);
String name = property.getAttributeValue("name");
String value = property.getText();
conConfig.put(name, value);
} //根据配置文件获得数据库连接
Class.forName(conConfig.get("driver"));
Connection con = DriverManager.getConnection(conConfig.get("url"),conConfig.get("username"),conConfig.get("password"));
return con;
} /**
* 持久化对象
* @param student
*/
public void save(Student student) { String sql = getSaveStatement();
System.out.println(sql); try {
//获得连接
Connection con = initConn();
//创建jdbc执行语句
PreparedStatement state = (PreparedStatement) con.prepareStatement(sql); for(int i=0;i<methodNames.length;i++) { //得到每一个方法的对象
Method method = student.getClass().getMethod(methodNames[i]); //得到他的返回类型
Class cla = method.getReturnType(); //根据返回类型来设置插入数据库中的每个属性值。
if(cla.getName().equals("java.lang.String")) {
String returnValue = (String)method.invoke(student);
state.setString(i+1, returnValue);
}
else if(cla.getName().equals("int")) {
Integer returnValue = (Integer) method.invoke(student);
state.setInt(i+1, returnValue);
}
} state.executeUpdate();
state.close();
con.close();
} catch (Exception e) {
e.printStackTrace();
}
} private String getSaveStatement(){
//strColumn代表数据库中表中的属性列。并将其连接起来。
String strColumn = "";
int index=0;
for(String key :hbmInfo.keySet())
{
strColumn +=key+",";
String v = hbmInfo.get(key); //获得属性的get方法,需要将属性第一个字母大写如:getId()
v = "get" + Character.toUpperCase(v.charAt(0)) + v.substring(1);
methodNames[index] = v;
index++;
}
strColumn = strColumn.substring(0, strColumn.length()-1); //拼接参数占位符,即:(?, ?, ?)
String strValue = "";
for(int i=0;i<hbmInfo.size();i++)
strValue +="?,";
strValue = strValue.substring(0,strValue.length()-1); String sql = "insert into " + hbmInfo.get("tableName") +"(" + strColumn + ")" + " values (" + strValue + ")";
return sql;
} }

(3)测试持久化

public class Test {

	/**
* 测试持久化
* 数据库语句:
* DROP TABLE IF EXISTS `tb_student`;
* CREATE TABLE tb_student (
* `id` int(10) NOT NULL DEFAULT 0 ,
* `name` varchar(50) DEFAULT NULL ,
* `score` int(11) DEFAULT 0 ,
* PRIMARY KEY (`id`)
* )ENGINE=MyISAM DEFAULT CHARSET=utf8;
*/
public void main(){
Student student=new Student();
student.setId(100);
student.setName("Tom");
student.setScore("99");
//获得Session对象
Session session=new Session();
//执行持久化操作
session.save(student);
} }

  

参考 菜鸟学SSH(十五)——简单模拟Hibernate实现原理

Hibernate的ORM原理和实现的更多相关文章

  1. Hibernate框架ORM的实现原理

    1. 什么是ORM ORM的全称是Object Relational Mapping,即对象关系映射.它的实现思想就是将关系数据库中表的数据映射成为对象,以对象的形式展现,这样开发人员就可以把对数据库 ...

  2. Hibernate(2)——Hibernate的实现原理总结和对其模仿的demo

    俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习!涉及的知识点总结如下: 开源框架的学习思路(个人总结) Hibernate的运行原理总结 Hibernate实现原理中的两个主要技术 ...

  3. hibernate的工作原理

    hibernate的工作原理1.Hibernate 的初始化.读取Hibernate 的配置信息-〉创建Session Factory1)创建Configeration类的实例.它的构造方法:将配置信 ...

  4. hibernate的实现原理以及延迟加载

    Hibernate是怎样实现呢?主要是依据反射机制. 现在以一次数据库查询操作分析Hibernate实现原理. 假设有一个用户表(tbl_user),表中字段有id,name,sex.同时有一个实体类 ...

  5. 同一个数据库实例,不同用户下多表创建视图,Hibernate完毕ORM映射,Spring整合,后台实现

    1.同一个数据库实例.同用户,多表创建视图 2.同一个数据库实例,不同用户下.多表创建视图 3.同一个数据库,不同数据库实例,多表创建视图 4.不同类型数据库,多表创建视图 1.同一个数据库实例.同用 ...

  6. Gora是一个类似Hibernate的ORM框架

    Gora是一个类似Hibernate的ORM框架,但是不只是支持关系数据库,更重要支持NoSQL之类大数据的存储. 支持NoSQL之类大数据的存储 Apache Gora是一个开源的ORM(Objec ...

  7. 2018.10.7 理解Hibernate的工作原理及其中的ORM详解

    复习 hibernate框架 简介j及其搭建: hibernate是一个开源框架,它是对象关联关系映射的框架,它对JDBC做了轻量级的封装,而我们java程序员可以使用面向对象的思想来操纵数据库. 1 ...

  8. Hibernate的工作原理及使用的原因

    一.工作原理: 1.读取并解析配置 2.读取并解析映射信息,创建Session Factory 3.打开Session 4.创建事务Transation 5.持久化操作 6.提交事务 7.关闭Sess ...

  9. ORM原理

    原理: 1.实现JavaBean的属性到数据库表的字段的映射:        --通过配置文件将JavaBean的属性与数据库表的字段的关联起来 2.映射关系:   一对多,多对一等 持久层(Pers ...

随机推荐

  1. 面向对象的 CSS (OOCSS)

    原文链接:来自smashing magazine 译文 你是否听说过一个词语叫“内容就是王道”?作为一个 Web 开发者,我们的工作与内容创作有着频繁的联系.这是一条经常被引用,并且正确地解释了什么因 ...

  2. js 判断鼠标进去方向

    function fx(id){ var obj= document.getElementById(id); var fun=function(e){ var w=obj.offsetWidth; v ...

  3. c++ 字符串流 sstream(常用于格式转换) 【转载】

    使用stringstream对象简化类型转换C++标准库中的<sstream>提供了比ANSI C的<stdio.h>更高级的一些功能,即单纯性.类型安全和可扩展性.在本文中, ...

  4. linux——基本配置

    环境:Ubuntu 12.04.2 LTS (GNU/Linux 3.5.0-23-generic i686) 网络配置 #临时改变 #修改IP和子网掩码 sudo ifconfig eth0 192 ...

  5. 【Networking】go get 失败,代理配置

    推荐VPN: https://vpnso.com/   如果还是有问题,比如: 重新编译Git,使用openssl替换gnutls,方法如下: http://askubuntu.com/questio ...

  6. Nunit-Writing Tests

    Nunit 测试可以被任意支持attributes的.net语言使用 Attributes被用于去标识测试类和测试方法,然后通过不同的方式修改他们的行为 Assertions针对一个或多个约束,测试一 ...

  7. 在asp.net mvc中上传大文件

    在asp.net mvc 页面里上传大文件到服务器端,需要如下步骤: 1. 在Control类里添加get 和 post 方法 // get method public ActionResult Up ...

  8. 【leetcode】Dungeon Game

    Dungeon Game The demons had captured the princess (P) and imprisoned her in the bottom-right corner ...

  9. ios UIButton 选中后背景图片变化发灰问题

    UIButton的类型如果选择了System类型,那么设置背景图后,点击的效果是图片发灰,而不是默认的那种图片变淡黑色效果,需要用customer类型就好了.

  10. pom.xml中引入局域网仓库

    <repositories> <repository> <id>nexus</id> <name>my-nexus-repository&l ...