利用java的反射机制模拟hibernate
模拟hibernate背后的处理机制
通过配置文件比如Teacher.hbm.xml可以拿到对应的字段和表名
那么在session中只需要创建一个Map类型的变量,讲拿到配置文件的名字存到map
name作为map的key name的值作为map的value
下一步就是写save方法
先创建sql语句 例如 insert into teacher(id,name,title) values(?,?,?);
表名和id name title可以通过map拿到
这样sql语句就建好了,下一步就是创建connection,preparedStatement
pstmt如何设值
比如如果id是int类型 就应该pstmt.setInt(1,这里是teacher.getId的值);
所以这里第一是要知道是int类型,第二要知道是什么方法名
所以就需要用到反射
Session类的实现
package com.hibernate.simulation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class Session {
//HashMap没有顺序,所以这里要用--LinkedHashMap,反向TreeMap
Map<String,String> m = new LinkedHashMap<String,String>();
List<String> methodNames = new ArrayList<String>();
public Session(){
}
public void save(Object o) throws ClassNotFoundException, SQLException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
Field[]fields = o.getClass().getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
Field field = fields[i];
//获取成员变量的名称
String memberName = field.getName();
System.out.println(memberName);
//第一个参数是字段名,也就是方法名作为key,第二个是属性名
m.put(memberName,memberName);
//获取成员变量的类型
//建立方法名
String methodName = "get" + Character.toUpperCase(memberName.charAt(0)) + memberName.substring(1,memberName.length());
methodNames.add(methodName);
}
String sql = createSQL(o);
System.out.println(sql);
//存值
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost/hibernate";
String username = "root";
String password = "123456";
Connection conn = DriverManager.getConnection(url,username,password);
PreparedStatement pstmt = conn.prepareStatement(sql);
for(int i=0;i<methodNames.size();i++){
Method m = o.getClass().getMethod(methodNames.get(i));
if(m.getReturnType().getName().equals("java.lang.String")){
String returnValue = (String)m.invoke(o);
pstmt.setString(i+1,returnValue);
}
if(m.getReturnType().getName().equals("int")){
int returnValue = (Integer)m.invoke(o);
pstmt.setInt(i+1, returnValue);
}
}
pstmt.executeUpdate();
pstmt.close();
conn.close();
}
public String createSQL(Object o){
String objectName = o.getClass().getName();
String[] strArr= objectName.split("@");
String[] pstrArr = strArr[0].split("\\.");
String oName = pstrArr[pstrArr.length -1];
String str1 = "";
String str2 ="";
for(String s : m.keySet()){
str1 += s + ",";
str2 += "?,";
}
str1 = str1.substring(0,str1.length() - 1);
str2 = str2.substring(0,str2.length() - 1);
String sql = "insert into " + oName + "(" + str1 + ") values(" + str2 + ")";
return sql;
}
}
model的Student类的实现
package com.hibernate.simulation;
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;
}
}
Junity测试代码的实现
package com.hibernate.simulation;
import java.lang.reflect.InvocationTargetException;
import java.sql.SQLException;
public class StudentTest {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, SQLException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Student s = new Student();
s.setId(6);
s.setName("a");
s.setAge(6);
Session session = new Session();
session.save(s);
}
}
调用session的save方法,得到结果