hibernate之模拟Hibernate持久化操作

【Hibernate】之模拟Hibernate持久化操作

使用过Hibernate,大家都知道,由于其面向对象的设计,用起来非常方便,且具有很好的跨数据库性,那么Hibernate的底层是怎么实现的呢?其实也就是将对象模型转化为关系模型,最终还是得sql语句来执行。

看过Hibernate源码的同学应该发现, Hibernate底层的核心是代理和反射,那么由此这样我们就可以理解为什么使用Hibernate在效率上始终是致命的。

Ok,下面是一个简单的模拟Hibernate-ORM的save()方法,来管中窥豹,略了解一下Hibernate的底层实现。其中这里我主要演示Hibernate是如何使用反射获取数据,类型等,到这里不得不提,广大Java从业者,想在Java技术道路上有所突破,Java的反射机制,是必须掌握的。

首先模拟出新建一个Session实体类,模拟一个save()方法

为了方便,我这边就不写配置文件了,如果各位想写,可以参考Hibernate的


1

2

3

Configuration cfg=new Configuration();

cfg.configure();

sessionFactory=cfg.buildSessionFactory();

将Hiberane的源码导进去,自己看一下它如何利用dom4j解析实现的。

首先创建一个实体类:

package csg.hibernate.entity;
/**
 *
 * @author Caesar.hu
 * @Date  2014-11-28
 * @Time  上午09:32:08
 * @TODO
 */
public class Student {
    private Integer id;
    private String name;
    private Integer age;
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }

}

看代码:然后我们模拟一个Session类,里面构造一个save()方法,

下面这段代码,就是核心,每行代码的注释已经写清楚

package csg.hibernate.entity;

import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.util.HashMap;
import java.util.Map;

/**
 *
 * @author Caesar.hu
 * @Date 2014-11-27
 * @Time 下午06:02:05
 * @TODO模拟一个Session
 */
public class Session {
    // 1、写好一个表名,这个表名,理论上应该在Student.hbm.xml中读出来,或者是注解JPA映射
    // 我这里直接写出来,意思就是说,数据存到数据库的表对应的就是这个
    String tableName = "_student";
    // 2、为什么创建一个String类型的Map?
    // 这个map存放的就是实体的字段属性和数据库字段匹配,本身也是配置在文件中
    Map<String, String> cfs = new HashMap<String, String>();
    String[] methodNames;// new一个空集合主要是方便反射使用

    public Session() {
        cfs.put("_id", "id");
        cfs.put("_name", "name");
        cfs.put("_age", "age");
        methodNames = new String[cfs.size()];
    }

    public void save(Student s) throws Exception {
        // 3、创建SQL语句
        String sql = createSQL();
        String url = "jdbc:mysql://localhost/hibernate";
        String username = "root";
        String password = "root";
        Class.forName("com.mysql.jdbc.Driver");
        Connection conn = DriverManager.getConnection(url, username, password);
        PreparedStatement ps = conn.prepareStatement(sql);
        // 9,sql写好之后,这里是是不是需要设置?
        // 类似ps.setName(1,s.getId);
        // ps.setInterge(2,s.getAge)
        //怎么设置?你怎么知道传进来的是什么类型呢?所以这里最重要的是需要用到反射类型
        for (int i = 0; i < methodNames.length; i++) {
            System.out.println(methodNames[i]);// 首先取到存进到数据中的getAge getInt
            //10、 通过反射机制根据实体的方法反射出实体一系列的方法getAge,getName,getId和返回类型Integer,String,Integer
            Method m = s.getClass().getMethod(methodNames[i]);
            System.out.println(m);
            System.out.println(s.getClass() + "-------" + m + "---------"
                    + m.getName() + "-----" + m.getReturnType());
            //11、获取数组里面getAge,getInt,getName 的返回类型
            Class r = m.getReturnType();
            //12、根据返回类型判断其应该ps.setString,还是ps.setInteger
            if (r.getName().equals("java.lang.String")) {
                //13、invoke是反射里面的一个方法,其作用是通过类的返回值类型反射出属性值
                //14、getAge.invoke(s);同样也可以通过值反射出返回类型
                String returnValue = (String) m.invoke(s);
                System.out.println(returnValue);
                ps.setString(i + 1, returnValue);
            }
            //15、同样如果判断是Integer类型,就ps.setInteger
            if (r.getName().equals("java.lang.Integer")) {
                System.out.println(m.invoke(s));
                Integer returnValue = (Integer) m.invoke(s);
                // System.out.println(returnValue);
                ps.setInt(i + 1, returnValue);
            }
        }
        // ps.executeUpdate();
        ps.close();
        conn.close();
    }

    private String createSQL() {
        String str1 = "";
        int index = 0;
        for (String s : cfs.keySet()) {
            // 4、通过Map中的key得到Value
            String v = cfs.get(s);
            // 5、根据get,set方法我们可以知道字段首字母是需要大写的,
            // 6、这段代码就是将取出来的value首字母大写加上get
            v = Character.toUpperCase(v.charAt(0)) + v.substring(1);
            // 7、这样new出来的空集合里面就放上了getId,getName,getAge
            methodNames[index] = "get" + v;
            str1 += s + ",";
            index++;
        }
        str1 = str1.substring(0, str1.length() - 1);
        String str2 = "";
        for (int i = 0; i < cfs.size(); i++) {
            str2 += "?,";
        }
        str2 = str2.substring(0, str2.length() - 1);
        String sql = "insert into " + tableName + "(" + str1 + ")" + "values("
                + str2 + ")";
        // 8、这段sql==
        // insert into _table(id,name,age)values(?,?,?);
        return sql;
    }

}

最后测试代码:

package JunitTest;

import csg.hibernate.entity.Session;
import csg.hibernate.entity.Student;
/**
 *
 * @author Caesar.hu
 * @Date  2014-11-28
 * @Time  上午09:32:15
 * @TODO
 */
public class Test {
    public static void main(String[] args) throws Exception{
        Student student=new Student();
        Session s=new Session();
        student.setId(1);
        student.setAge(12);
        student.setName("张三");
        s.save(student);
    }

}

Ok,到这里,大家应该能明白,为什么说Hibernate是JDBC的封装?尤其是在考虑web性能的问题上为什么Hibernate不能满足开发需求,反射机制对于Java是多么重要!

其实Hibernate的源码写法也莫不于此,只不过其在底层进行大量的封装,同时为了性能Hibernate也有采用直接将数据生成二进制流进行操作。对于配置文件大家可以看Hibernate 源码是如何利用dom4j解析Hibernate.cfg.xml这个文件,写的尤其经典,Ok?

Java从业者,想在技术上突破,反射机制是必须掌握的!

【Hibernate】之模拟Hibernate持久化操作

使用过Hibernate,大家都知道,由于其面向对象的设计,用起来非常方便,且具有很好的跨数据库性,那么Hibernate的底层是怎么实现的呢?其实也就是将对象模型转化为关系模型,最终还是得sql语句来执行。

看过Hibernate源码的同学应该发现, Hibernate底层的核心是代理和反射,那么由此这样我们就可以理解为什么使用Hibernate在效率上始终是致命的。

Ok,下面是一个简单的模拟Hibernate-ORM的save()方法,来管中窥豹,略了解一下Hibernate的底层实现。其中这里我主要演示Hibernate是如何使用反射获取数据,类型等,到这里不得不提,广大Java从业者,想在Java技术道路上有所突破,Java的反射机制,是必须掌握的。

首先模拟出新建一个Session实体类,模拟一个save()方法

为了方便,我这边就不写配置文件了,如果各位想写,可以参考Hibernate的


1

2

3

Configuration cfg=new Configuration();

cfg.configure();

sessionFactory=cfg.buildSessionFactory();

将Hiberane的源码导进去,自己看一下它如何利用dom4j解析实现的。

首先创建一个实体类:

时间: 2024-08-01 06:31:08

hibernate之模拟Hibernate持久化操作的相关文章

Mysql对空间数据库的支持及使用Hibernate Spatial对空间数据的持久化操作

1.空间数据:如果做地图方面的开发,那么对空间数据肯定不会陌生,也就是地图元素即,点,线,图形,它们有x,y坐标的信息 2.MySQL对于空间数据库本身就是支持的,只是支持的不太全面,实际上专业空间数据库非postgis莫属,之所以使用Mysql是因为项目中的数据库已经使用了它,而且对于地图方面的功能并不是很高,所以才有了这样的应该场景:使用MySQL做空间数据库,对于MySQL的空间数据库的操作,参见MySQL使用手册第19章中有详细的说明使用各空间函数的使用sql语句 3.Hibernate

Hibernate——Java 领域的持久化ORM框架

Hibernate教程 https://www.w3cschool.cn/hibernate/skzl1idz.html Hibernate是一个开源,轻量级的ORM(对象关系映射)工具.Hibernate框架简化了java应用程序与数据库交互的开发. ORM工具简化了数据创建,数据处理和数据访问.它是将对象映射到数据库中存储的数据(表)的编程技术. 狭义的理解,“持久化”仅仅指把对象永久保存到数据库中 广义的理解,“持久化”包括和数据库相关的各种操作: 保存:把对象永久保存到数据库中. 更新:

Hibernate (面向对象的数据库操作)

JPA,java persistance api,java持久层接口,即与数据库打交道的一些接口.实现交给各个厂商去实现. ORM,Object/Relation Mapping,对象/关系数据库映射.面向对象的数据库操作,底层仍是sql语句. 获得 hibernate的maven依赖. <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactI

(六)Hibernate的增删改查操作(2)

一.在Hibernate中使用原生SQL语句 sql语句面向的是数据库,所以sql语句中对应的不再是bean了,比如sql="select * from user"   在hql中*是无效的,但是在sql中可以使用,且user指的是数据库中的user表. 案例一: package action; import java.util.List; import org.hibernate.SQLQuery; import org.hibernate.Session; import org.h

用反射模拟Hibernate保存JavaBean

1 用反射模拟Hibernate保存JavaBean 2 首先要说一下思想.就是要接收一个JavaBean实例对象,然后根据字段信息.类名信息,自己组组织成sql语句最后保存到数据库中. 3 组件说明: 4 需要一个@Table注解,自己声明,以便于用户声明的表名与数据库的表名不致的情况. 5 此注解应该包含一个属性,以便于指定表名. 6 需要声明一个@Column注解,自己声明以便于用户声明的字段名与JavaBean的列名不一致的情况. 7 此注解也应该包含一个属性,以便于指定字段名.如果需要

Hibernate——以面向对象的思维操作关系数据库(一)

Hibernate是一个轻量级的ORM开源框架.Hibernate解脱了面对繁琐的JDBC的开发者,使得变成更加面向对象化,将之前的连接语句,增删改查等语句进行了很好的封装,使得业务逻辑等的编写更加的容易:使移植数据库也变得十分的容易,即根据不同的数据库配置configuration.cfg.xml就可以轻松改变数据库:下面以一个代码段稍作解释: 一 :每个相对应的实体都会有相对应的映射文件,映射文件的作用主要是维护实体间的关系. 实体类User: package com.bjpowernode

Spring执行持久化操作

Spring整合Hibernate后,为Hibernate的DAO提供了两个工具类:HibernateTemplate和HibernateDaoSupport      HibernateTemplateHibernateTemplate是Spring提供的一个就Hibernate访问持久层技术而言.支持Dao组件的一个工具.HibernateTemplate提供持久层访问模板,应用HibernateTemplate无须实现特定的接口,它只需要提供一个sessionFactory的引用就可以执行

Hibernate学习之——Hibernate环境搭建

之前在写关于安卓闹钟的教程,写了一半就没后一半了,其实自己也没做好,在校外实习,校内毕业实习又有任务,只能先放放了,等毕业实习结束之后,在继续安卓闹钟开发之旅,相信这个时间不会很久的.现在毕业实习用到的SSH框架(Struts+Spring+Hibernate),自己没有多少时间去好好学习,但是还是想把学到的东西记录下来. 一.Hibernate简介 1.什么是Hibernate? Hibernate是数据持久层的一个轻量级框架.数据持久层的框架有很多比如:iBATIS,myBatis,Nhib

Hibernate SQL方言 (hibernate.dialect) Spring配置文件applicationContext.xml

转自:http://www.cnblogs.com/wj-wangjun/archive/2009/10/21/1587624.html Hibernate SQL方言 (hibernate.dialect) 数据库 hibernate方言 DB2 org.hibernate.dialect.DB2Dialect DB2 AS/400 org.hibernate.dialect.DB2400Dialect DB2 OS390 org.hibernate.dialect.DB2390Dialect