Hibernate学习02---Hibernate原理分析和模拟其实现

来源:互联网 发布:淘宝主宝贝图片尺寸 编辑:程序博客网 时间:2024/06/05 16:46


Hibernate实现原理

1、Configuration加载hibernate.cfg.xml

2、生成SessionFactory

3、加载对象关系映射文件*.hbm.xml

4、创建Session对象

5、调用Session API保存对象

6、根据Dialect生成和底层数据库平台相关的sql代码

7、对JDBC封装,执行sql脚本

从本质上讲,Hibernate还是最终还是通过JDBC进行数据库的访问,只是对JDBC进行了封装。

Hibernate实现的关键技术

1、DOM(解析XML文档)DOM/SAX------dom4j

2、反射机制

 

 

模拟Hibernate实现

新建java项目,把需要的jar导入(dom4j.jar,还有mysql驱动包)

1.pojo类Student.java

package com.demo.pojo;public class Students {private int sid;private String sname;public int getSid() {return sid;}public void setSid(int sid) {this.sid = sid;}public String getSname() {return sname;}public void setSname(String sname) {this.sname = sname;}}


2.对象关系映射文件 Student.hbm.xml

<?xml version="1.0"?><hibernate-mapping package="com.demo.pojo"><class name="Students" table="students"><property name="sid" column="sid" type="int" /><property name="sname" column="sname" type="string"  /></class></hibernate-mapping>

 

3.创建自己的Session类

这个类有三个属性(用来存放pojo中的属性与数据库字段对应的maps,存放表名的tableName,存放getter方法的methodNames)

有三个方法(构造方法,createSQL,Save)

构造方法对Students.hbm.xml进行解析,初始化maps,tableName还有methodName的大小

createSQL方法就是根据maps中的属性-字段来拼接sql字符串了

save方法利用反射和jdbc操作对数据进行操作

 

package com.demo.dao;import java.io.File;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.dom4j.Document;import org.dom4j.Element;import org.dom4j.io.SAXReader;import com.demo.pojo.Students;public class Session {//属性--字段 O-R mapping的映射关系private Map<String,String> maps = new HashMap<String, String>();//表名private String tableName;//保存实体类中的方法(只保存getter方法),后面会用反射得到方法的返回类型 ,从而在preparedStatement.setXXX方法中用private String[] methodNames;public Session()throws Exception{SAXReader reader = new SAXReader();//生成reader对象File f = new File("Students.hbm.xml");Document doc = (Document)reader.read(f);//生成文档对象Element root = doc.getRootElement();//获取根节点List list1 = (List) root.elements();for(int i=0;i<list1.size();i++)//遍历root下的子节点{Element node1 = (Element) list1.get(i);tableName = node1.attributeValue("table");//得到属性为table的值List list2 = node1.elements();//得到node1下的子节点for(int j=0;j<list2.size();j++)//遍历node1下的子节点{Element node2 = (Element)list2.get(j);maps.put(node2.attributeValue("name"), node2.attributeValue("column"));}methodNames = new String[maps.size()];//初始化methodNames的大小}}public void save(Students s) throws Exception{String sql = createSQL();System.out.println(sql);Connection conn = null;PreparedStatement pstate = null;Class.forName("com.mysql.jdbc.Driver");conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root","");pstate = conn.prepareStatement(sql);//遍历方法数组,利用反射得到方法的返回类型for(int i=0;i<methodNames.length;i++){//利用反射,根据方法的字符串名字,得到一个方法对象Method m = s.getClass().getMethod(methodNames[i]);//利用反射,根据方法对象,得到方法的返回类型Class c = m.getReturnType();//如果返回类型是intif(c.getName().equals("java.lang.Integer")||c.getName().equals("int")){int value = (Integer) m.invoke(s);pstate.setInt(i+1,value);//则设置int}//如果返回类型是Stringif(c.getName().equals("java.lang.String")){String value = (String) m.invoke(s);pstate.setString(i+1,value);//则设置String}}pstate.executeUpdate();//最后执行pstate.close();//关闭连接conn.close();}//拼接sql语句private String createSQL(){int index=0;//问号的拼接字符串String qutoes="";//得到表的字段名,中间加逗号拼接起来String columns = "";for(String key:maps.keySet()){String value = maps.get(key);columns +=value+",";//同时把getXXX方法存入到数组中methodNames[index++]="get"+Character.toUpperCase(key.charAt(0))+key.substring(1);}for(int i=0;i<maps.size();i++){qutoes +="? ,";}columns = columns.substring(0,columns.length()-1);qutoes = qutoes.substring(0, qutoes.length()-1);return "insert into "+tableName+" ("+columns+") values ("+qutoes+")";}}


4、最后就是一个测试类了


 

package com.demo.dao;import com.demo.pojo.Students;public class Client {public static void main(String[] args)throws Exception {Session sessoin = new Session();Students student = new Students();student.setSid(1);student.setSname("wangwu");sessoin.save(student);}}


 

原创粉丝点击