简单模拟Hibernate的主要功能实现
在学习期间接触到Hibernate框架,这是一款非常优秀的O/R映射框架,大大简化了在开发web项目过程中对数据库的操作。
这里就简单模拟其底层的实现。
/*******代码部分,及其主要注解**********************/
1、实体类User:
1 public class User { 2 private int id; 3 private String username; 4 private String password; 5 6 public int getId() { 7 return id; 8 } 9 10 public void setId(int id) { 11 this.id = id; 12 } 13 14 public String getUsername() { 15 return username; 16 } 17 18 public void setUsername(String username) { 19 this.username = username; 20 } 21 22 public String getPassword() { 23 return password; 24 } 25 26 public void setPassword(String password) { 27 this.password = password; 28 } 29 }
2、主体测试代码:
1 public class TestHibernate { 2 public static void main(String[] args) throws Exception{ 3 User user = new User(); 4 user.setId(123); 5 user.setUsername("admin"); 6 user.setPassword("admin"); 7 8 //Configuration configuration = new Configuration(); 9 //SessionFactory sessionFactory = configuration.configure().buildSessionFactory(); 10 11 //Session session = sessionFactory.openSession(); 12 //session.beginTransaction(); 13 //其他的过程均省略,利用自定义的Seesion进行存储 14 Session session = new Session(); 15 session.save(user); 16 //session.getTransaction().commit(); 17 //session.close(); 18 //sessionFactory.close(); 19 20 21 } 22 23 }
3、自定义的Seesion类:
1 public class Session { 2 3 //假设通过配置文件读出实体类对应的表 4 String tableName = "_user"; 5 //模拟表属性与类属性的一一对应关系 6 Map<String,String> map = new HashMap<String, String>(); 7 8 9 //每个属性对应一个get方法,methodNames存放所有方法名 10 String[] methodNames ; 11 //初始化 12 public Session(){ 13 map.put("_id","id"); 14 map.put("_username","username"); 15 map.put("_password","password"); 16 17 methodNames = new String[map.size()]; 18 } 19 20 public void save(User user)throws Exception{ 21 String sql = createSQL(); 22 23 Class.forName("com.mysql.jdbc.Driver"); 24 Connection cnn = DriverManager.getConnection("jdbc:mysql://localhost/digtalheaven","root","7890"); 25 PreparedStatement preparedStatement = cnn.prepareStatement(sql); 26 for(int i = 0; i < methodNames.length;i++){ 27 28 //利用java的反射机制获取实体类属性的get方法 29 Method method = user.getClass().getMethod(methodNames[i]); 30 //获取返回类型 31 Class c = method.getReturnType(); 32 33 //由于调用get方法返回值可能是"java.lang.String" "int "等不同的属性,所以要进行判断,再调用不同的jdbc语句执行方法 34 if(c.getName().equals("java.lang.String")){ 35 String returnValue = (String)method.invoke(user);//执行方法,获得返回值 36 preparedStatement.setString(i+1,returnValue); 37 } 38 else if(c.getName().equals("int")){ 39 Integer returnValue = (Integer)method.invoke(user); 40 preparedStatement.setInt(i+1,returnValue); 41 } 42 43 } 44 45 preparedStatement.executeUpdate(); 46 preparedStatement.close(); 47 cnn.close(); 48 49 } 50 51 //创建save方法对应的sql 语句: insert into _user(_id,_username,_password) values (?,?,?); 52 public String createSQL(){ 53 54 String str2 = ""; 55 for(int i = 0; i < map.size(); i++){ 56 str2 += "?,"; 57 } 58 str2 = str2.substring(0,str2.length()-1); //截掉最后一个逗号 59 60 String str1 = ""; 61 int index = 0; 62 for(String i : map.keySet()){ 63 //获取表属性对应的类的属性,然后拼出该属性的get对应的方法名字 64 //例如 getUsername(); 65 String str = map.get(i); //例如获得表属性名 _username 对应的实体类属性名 username ; 66 str = "get" + Character.toUpperCase(str.charAt(0)) + str.substring(1,str.length()); 67 methodNames[index++] = str; 68 str1 += i+","; 69 } 70 str1 = str1.substring(0,str1.length()-1); 71 72 String sql = "insert into "+ tableName + "(" + str1 + ") values (" + str2 + ")"; 73 74 return sql; 75 76 } 77 }
4、在navicat查询数据库结果: