当前位置:编程学习 > JAVA >>

Hibernate过程模拟——Hibernate学习笔记02

学习了一下Hibernate模拟,我们现在我们不用HIbernate的lib,自己来模拟一下hibernate工作过程,其实就是把java里面save()方法传进来的数据自己拼成SQL语句。再执行sql。
  那我们现在开始研究一下,首先我们把之前的项目复制一下,然后命名为Hibernate_0200_OR_Mapping_Simulation,首先来解释下OR Mapping吧,对象数据映射(ORM
ORM-Object/Relational Mapper,即“对象-关系型数据映射组件”。对于O/R,即 Object(对象)和 Relational(关系型数据),表示必须同时使用面向对象和关系型数据进行开发。 
  我们去掉其中的hibernate lib,去掉Teacher部分。我们现在要写自己的Session。创建Session类在里面建立save()方法。
 
StudentTest.java
 
package com.tfj.test;  
  
import com.tfj.hibernate.model.Student;  
  
public class StudentTest {  
    public static void main(String args[]) {  
        Student s = new Student();  
        s.setId(4);  
        s.setName("s1");  
        s.setAge(1);  
  
        Session session = new Session();  
  
        session.save(s);  
  
    }  
}  

 

 
关于Session部分
 
package com.tfj.test;  
  
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.Map;  
  
import com.tfj.hibernate.model.Student;  
  
public class Session {  
    String tableName = "student";  
    Map<String, String> cfs = new HashMap<String, String>();  
    String[] methodNames;  
  
    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 {  
        String sql = createSQL();  
  
        Class.forName("com.mysql.jdbc.Driver");  
        Connection conn = DriverManager.getConnection(  
                "jdbc:mysql://localhost:3306/hibernate", "root", "111111");  
        PreparedStatement ps = conn.prepareStatement(sql);  
        for (int i = 0; i < methodNames.length; i++) {  
            Method m = s.getClass().getMethod(methodNames[i]);  
            Class r = m.getReturnType();  
            if (r.getName().equals("java.lang.String")) {  
                String returnValue = (String) m.invoke(s);  
                ps.setString(i + 1, returnValue);  
            }  
            if (r.getName().equals("int")) {  
                Integer returnValue = (Integer) m.invoke(s);  
                ps.setInt(i + 1, returnValue);  
            }  
            System.out.println(m.getName() + "|" + r.getName());  
        }  
  
        ps.executeUpdate();  
  
        ps.close();  
        conn.close();  
  
    }  
  
    private String createSQL() {  
        String str1 = "";  
        String str2 = "";  
        int index = 0;  
        for (String s : cfs.keySet()) {  
  
            String v = cfs.get(s);  
            v = Character.toUpperCase(v.charAt(0)) + v.substring(1);  
            methodNames[index] = "get" + v;  
            str1 += s + ",";  
            index++;  
        }  
        str1 = str1.substring(0, str1.length() - 1);  
        System.out.println(str1);  
        for (int i = 0; i < cfs.size(); i++) {  
            str2 += "?,";  
        }  
        str2 = str2.substring(0, str2.length() - 1);  
        System.out.println(str2);  
        String sql = "insert into " + tableName + "(" + str1 + ")"  
                + " values (" + str2 + ")";  
        System.out.println(sql);  
        return sql;  
    }  
}  

 

 
 
  我们来分析一下代码,在Session里有一个save()方法,那么我们先想到要构建出来sql语句,建立createSQL()方法。需要得到的sql语句是insert into student (_id,_name,_age) values (?,?,?);那么要把表和程序关联起来,想到用一个Map来存储,对应的键和值,键是数据库中表的键名,值是java中student属性名。
  下来就是得到_id,_name,_student,循环从map里拿到,再截取一下字符串,(得到?,?,?)同理。这样我们的sql就构造好了。
  然后是把得到的sql中的?,?,?替换掉,(要用到ps.setXXX(i+1,getXXX()))接下来我们遇到的问题就是,由于有各种数据类型,我们要确定就是数据类型和方法名。这里就用到了反射,通过s(s是一个student)拿到class再拿到方法。通过字符串组合就可以得到各种get方法(如getName(),getAge(),getId()),也是用反射拿到方法返回的数据类型来确定用setXXX()(如setString(i+1,getId()),setInt(i+1,getId()))。
补充:软件开发 , Java ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,