模拟hibernate读配置文件生成sql

今天温习了下尚学堂马士兵老师的hibernate视频,其中讲解模拟hibernate读取配置文件并生成sql部分内容。以前自己不用框架的时候也去模拟过持久层的处理,但最终效果总是不理想。而且现在想想,一些细节部分并没有能够很好的处理。其实这个模拟用的关键知识点不多,就两个:

  • 读取并解析xml配置文件
  • 使用反射机制根据属性名得到获取属性getProperty()的方法,根据方法的返回值类型设置PreparedStatement参数类型setXXX

简单模拟,学生类以及配置文件如下,模拟目标是要完成学生入库持久化这样的操作。

<?xml version="1.0"?>
<hibernate-mapping package="com.hibernate.model">
    <class name="Student" table="_Student">
        <id column="_id" name="id" />
        <property column="_name" name="name" />
        <property column="_age" name="age" />
    </class>
</hibernate-mapping>
public class Student {
    private int id;
    private String name;
    private int age;

    // getXXX( )
    // setXXX(..)
}

下面是模拟关键类,其中解决了以下难点:

  • 插入的数据顺序不知道
  • 插入数据读取的方法不知道,调用的getXXX不知道
  • 插入数据的类型不知道,ps.setXXX不知道
package com.hibernate.simulation;

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

import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.input.SAXBuilder;

import com.google.gson.Gson;
import com.hibernate.model.Student;

public class Session {
    String tableName ;
    Map<String,String> config = new HashMap<String,String>();
    
    private Session() throws Exception{
        SAXBuilder sb = new SAXBuilder();
        Document doc = sb.build("bin/com/hibernate/model/Student.hbm.xml");
        Element clazz = doc.getRootElement().getChild("class");
        tableName = clazz.getAttributeValue("table");
        List<Element> list = (List<Element>)clazz.getChildren();
        for(int i=0; i<list.size(); i++){
            Element e = list.get(i);
            config.put(e.getAttributeValue("column"), e.getAttributeValue("name"));
        }
    }
    
    public static void main(String[] args) throws Exception{
        Session session = new Session();
        String sql = session.createSql();
        System.out.println(sql);
        Student s = new Student();
        s.setId(2);
        s.setAge(2);
        s.setName("2");
        session.save(s);
    }

    private void save(Student student) throws Exception {
        String sql = createSql();
        Class.forName("com.mysql.jdbc.Driver");
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/hibernate","root","1");
        PreparedStatement ps = conn.prepareStatement(sql);
        //
        String[] methodName = new String[config.size()];
        int i=0;
        Iterator<String> itr = config.keySet().iterator();
        while(itr.hasNext()){
            String propertyName = config.get(itr.next());
            methodName[i] = "get" + propertyName.substring(0,1).toUpperCase() + propertyName.substring(1);
            i++;
        }
        System.out.println(new Gson().toJson(methodName).toString());
        for(int j=0; j<methodName.length; j++){
            Method method = student.getClass().getMethod(methodName[j]);
            Class clazz = method.getReturnType();
            if(clazz.getName().equals("int")){
                Integer propertyValue = (Integer)method.invoke(student);
                ps.setInt(j+1, propertyValue);
            }
            if(clazz.getName().equals("java.lang.String")){
                ps.setString(j+1, (String)method.invoke(student));
            }
        }
        ps.executeUpdate();
        ps.close();
        conn.close();
    }
    
    private String createSql(){
        StringBuffer sql = new StringBuffer();
        
        String str1="";
        for(String column : config.keySet()){
            str1 += column + ",";
        }
        str1 = str1.substring(0, str1.length() - 1);
        
        String str2 ="";
        for(int i=0; i<config.size(); i++){
            str2 += "?,";
        }
        str2 = str2.substring(0, str2.length() - 1);
        
        sql.append("insert into ").append(tableName)
            .append("(").append(str1).append(")")
            .append(" values (").append(str2).append(")");
        
        return sql.toString();
    }
}

以上代码是草草而就,缺陷不少,空了再改,但关键核心思路值得参考学习,备忘!

原文地址:https://www.cnblogs.com/huntdream/p/2991186.html