之前写了Spring的实现原理,今天我们接着聊聊Hibernate的实现原理,这篇文章只是简单的模拟一下Hibernate的原理,主要是模拟了一下Hibernate的Session类。好了,废话不多说,先看看我们的代码:

package com.tgb.hibernate;import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import org.jdom.xpath.XPath;import com.tgb.hibernate.model.User;public class Session {//表名String tableName = "user";  //存放数据库连接配置private Map<String, String> conConfig = new HashMap<String, String>();//存放实体属性private Map<String ,String > columns = new HashMap<String ,String >();  //实体的get方法集合
    String methodNames[];  public Session () {  //初始化实体,这里就不用读取配置文件的方式了,有点麻烦。 columns.put("id", "id");  columns.put("name", "name");  columns.put("password", "password");  methodNames = new String[columns.size()];  }  /*** 创建数据库连接* @return* @throws Exception*/public Connection createConnection() throws Exception {//解析xml文件,读取数据库连接配置      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;}/*** save方法,持久化对象* @param user*/public void save(User user) {  String sql = createSql();  System.out.println(sql);  try {  Connection con = createConnection();  PreparedStatement state =  (PreparedStatement) con.prepareStatement(sql);  for(int i=0;i<methodNames.length;i++) {  //得到每一个方法的对象  Method method = user.getClass().getMethod(methodNames[i]);  //得到他的返回类型  Class cla = method.getReturnType();  //根据返回类型来设置插入数据库中的每个属性值。  if(cla.getName().equals("java.lang.String")) {  String returnValue = (String)method.invoke(user);  state.setString(i+1, returnValue);  }  else if(cla.getName().equals("int")) {  Integer returnValue = (Integer) method.invoke(user);  state.setInt(i+1, returnValue);  }                        }  state.executeUpdate();  state.close();  con.close();  } catch (ClassNotFoundException e) {      e.printStackTrace();  } catch (SQLException e) {  e.printStackTrace();  } catch (Exception e) {  e.printStackTrace();  }   }  /** * 得到sql语句 * @return 返回sql语句 */  private String createSql() {  //strColumn代表数据库中表中的属性列。并将其连接起来。  String strColumn = "";  int index=0;  for(String key :columns.keySet())  {  strColumn +=key+",";  String v = columns.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<columns.size();i++)  strValue +="?,";  strValue = strValue.substring(0,strValue.length()-1);  String sql = "insert into " + tableName +"(" + strColumn + ")" + " values (" + strValue + ")";   return sql;  }
}

以上代码主要是完成了Hibernate的save()方法,该类有一个构造方法,一个构建sql语句的方法,一个获得数据库连接的方法。最后通过save()方法结合前面几个方法获得结果,将实体对象持久化到数据库。

基本原理就是:首先,获得数据库连接的基本信息;然后,获得实体的映射信息;接着,也是最关键的步骤,根据前面获得的信息,组装出各种sql语句(本例只有简单的insert),将实体按照不同的要求查找或更新(增、删、改)到数据库。

当然Hibernate的具体实现远没有这么简单,Hibernate中大量运用了cglib的动态代理,其中load()方法就是一个例子。大家都知道,调用load()方法是Hibernate不会向数据库发sql语句,load()方法得到的是目标实体的一个代理类,等到真正用到实体对象的时候才会去数据库查询。这也是Hibernate的一种懒加载的实现方式。

总结一句话,这些框架之所以能够做到灵活,就是因为它们都很好的利用了懒加载机制,在运行期在确定实例化谁,需要谁实例化谁,什么时候需要,什么时候实例化。这样设计出来能不灵活吗?这些思想值得我们好好研究,并运用到我们的设计中去。

菜鸟学SSH(十五)——简单模拟Hibernate实现原理相关推荐

  1. E-捡贝壳 2021年广东工业大学第十五届文远知行杯程序设计竞赛(同步赛)

    E-捡贝壳 2021年广东工业大学第十五届文远知行杯程序设计竞赛(同步赛) 小明来到一片海滩上,他很喜欢捡贝壳,但他只喜欢质量为x的倍数的贝壳. 贝壳被排列成一条直线,下标从1到n编号,小明打算从编号 ...

  2. G-分割 2021年广东工业大学第十五届文远知行杯程序设计竞赛(同步赛)

    G-分割 2021年广东工业大学第十五届文远知行杯程序设计竞赛(同步赛) 在一个二维平面, 有n条平行于y轴的直线, 他们的x坐标是x[i], m条平行于x轴的直线y[i],他们的y坐标是y[i]. ...

  3. JavaWeb学习总结(四十九)——简单模拟Sping MVC

    在Spring MVC中,将一个普通的java类标注上Controller注解之后,再将类中的方法使用RequestMapping注解标注,那么这个普通的java类就够处理Web请求,示例代码如下: ...

  4. 菜鸟学SSH(十二)——Hibernate与Spring配合生成表结构

    前几天向大家介绍了一种用工具类生成数据表的方法,不过之前的方法需要使用一个跟项目关系不大的工具类.不免让人觉得有些多余,所以呢,今天再向大家介绍一种方法.即Hibernate与Spring配合生成表结 ...

  5. 菜鸟学SSH(八)——Hibernate对象的三种状态

    前面写了几篇关于SSH的博客,但不是Struts就是Spring,Hibernate还从来没写过呢.说好是SSH的,怎么可以光写那两个,而不写Hibernate呢对吧.今天就先说说Hibernate对 ...

  6. 菜鸟学SSH——Spring容器AOP的实现原理——动态代理

    之前写了一篇关于IOC的博客--<Spring容器IOC解析及简单实现>,今天再来聊聊AOP.大家都知道Spring的两大特性是IOC和AOP. IOC负责将对象动态的注入到容器,从而达到 ...

  7. Java从零开始学四十五(Socket编程基础)

    一.网络编程中两个主要的问题 一个是如何准确的定位网络上一台或多台主机,另一个就是找到主机后如何可靠高效的进行数据传输. 在TCP/IP协议中IP层主要负责网络主机的定位,数据传输的路由,由IP地址可 ...

  8. 2021年广东工业大学第十五届文远知行杯程序设计竞赛(同步赛)

    A题M型字符串 链接:https://ac.nowcoder.com/acm/contest/13504/A 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144 ...

  9. 菜鸟学SQL注入 --- 一个简单的教学案例

    ***的SQL***演示: 指的是***或恶意用户在应用程序不知道的情况下通过应用程序来对SQL 数据库执行恶意的代码,一旦***成功,可以做任何事情,如查看数据表中的信息,删除数据表的数据,到获得网 ...

最新文章

  1. 如何设计一个本地缓存
  2. 安装java时,配置环境变量classpath的作用
  3. SSO CAS 探究
  4. 【⚡小丑竟然是我自己⚡】安防三年,今天才知道什么是ONVIF
  5. python 任务调度 celery_python任务调度模块celery(二)
  6. java zero copy 实现,关于Zero Copy
  7. PS Raw增效工具:Adobe Camera Raw13 for mac
  8. 关于Debug.exe
  9. jq写的项目如何部署到静态服务器_如何在阿里云服务器上部署一个Web项目
  10. rmi 反序列化漏洞_写一个rmi反序列化工具
  11. redis(版本redis-5.0.2)的安装步骤
  12. 文件大小转换(b,kb,M,GB/TB)
  13. 如何在Tungsten Fabric上整合裸金属服务器(附配置验证过程)
  14. Linux 返回根目录
  15. svn conflict linux,解决svn update 产生Node remains in conflict的问题
  16. 【Matlab三维路径规划】狼群算法算法三维路径规划【含源码 167期】
  17. HWDB1.1数据集 | 手写汉字数据集 |.gnt 转换 .png格式图片| 【❤️有效转换❤️】
  18. 2021-12-15 股票模拟交易心得10
  19. 让人感到心灵平静,阳光温暖的图片
  20. 安卓 类微信界面开发(一)

热门文章

  1. mysql 8安装_mysql安装过程详解
  2. 微型计算机控制技术黄勤期末,微型计算机控制技术作者黄勤第4章__工控机的抗干扰课案.ppt...
  3. 电机编码器调零步骤_编码器原理、霍尔应用原理、调整步骤三个方面进行解读编码器调试...
  4. java table集合_Java集合类汇总记录--guava篇
  5. 日志分类存放_博特智能|文本智能聚类——千万日志一览无余
  6. android webview 截图,Android获取webView快照与屏幕截屏的方法 -电脑资料
  7. java写入简介_Java关于IO流的介绍
  8. 前端JavaScripts
  9. Java Web中的中文编码问题分析
  10. 做为产品经理如何判断一个创业项目是否靠谱?