Hibernate O/R Mapping模拟

时间:2021-09-08 22:27:15

作为SSH中的重要一环,有必要理解一下Hibernate对 O/R Mapping的实现。

主要利用java的反射机制来得到完整的SQL语句。

准备工作:

1. Object

Student实体类:

public class Student {
private int id;
private String name;
private int age; public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} }

2. Relationship

_student表:

-- database: hibernate
create table _student(_id int primary key auto_increment,_age int,_name varchar(20));

3. 模拟O/R Mapping:

针对Student实体类的SessionStu (完成Student对象的持久化):

public class SessionStu {

    private String tableName;
private Map<String, String> field2Column = new HashMap<String,String>();
private String[] fields; public SessionStu() {
// 以下内容应当通过解析xml的方式build出来
// 该示例仅仅演示Hibernate的核心部分:O/R Mapping (利用反射得到完整sql)
tableName = "_student";
field2Column.put("id","_id");
field2Column.put("name","_name");
field2Column.put("age","_age");
fields = new String[field2Column.size()];
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} public void save(Student student) throws Exception {
// TODO Auto-generated method stub
String sql = createSQL();
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/hibernate","root","");
PreparedStatement ps = conn.prepareStatement(sql);
ps = setParameters(ps,student);
ps.executeUpdate();
ps.close();
conn.close();
} //important
private PreparedStatement setParameters(PreparedStatement ps, Student student) throws Exception{
for (int i = 0; i < fields.length; i++) {
String get_method = "get"+(char)(fields[i].charAt(0)-32)+fields[i].substring(1);
Method m = student.getClass().getMethod(get_method);
String type =
m.getReturnType().getName();
String te = type.substring(type.lastIndexOf(".")+1);
switch (te) {
case "int":
ps.setInt(i+1, (int) m.invoke(student));
break;
case "String":
ps.setString(i+1, (String) m.invoke(student));
default:
break;
}
}
return ps;
} private String createSQL(){
String columnsStr = "";
int index = 0;
for (String key : field2Column.keySet()) {
fields[index] = key;
columnsStr += (field2Column.get(key) + ",");
index++;
}
columnsStr = columnsStr.substring(0, columnsStr.length()-1);
String unknow = "";
for (int i = 0; i < field2Column.size(); i++) {
unknow += "?,";
}
unknow = unknow.substring(0,unknow.length()-1);
String sql = "insert into " + this.tableName + " (" + columnsStr +") values (" + unknow +")";
System.out.println(sql);
return sql;
} }

4. Test:

public class TestSessionSave {

    public static void main(String[] args) throws Exception {
Student student = new Student();
student.setAge(20);
student.setId(5);
student.setName("hibernate");
SessionStu ss = new SessionStu();
ss.save(student);
}
}

5. Done