Hibernate学习笔记(二)
标签(空格分隔): hibernate
本课提纲
Hibernate原理模拟
O/R Mapping
本文模拟了Hibernate如何对数据库进行操作,但是真实的Hibernate并不是通过此模拟,而是直接编译成二进制码进行操作。本文表明了一种实现的方式。
环境配置
myeclipse2014,加入mysql-connector-java-5.1.33-bin.jar,jdom.jar两个jar包。
OR Mapping Simulation
对MySQL
数据库进行操作,直接看java代码:
首先新建model包,将我们自己写的类写入其中
Student.java:
package com.han.hibernate.model;
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;
}
}
与上节课一样,Student.java的属性有id,name,age
建立test的source folder用于存储我们的测试类:
- 首先先写一个properties文件存储我们的数据库信息,以便java代码中提取数据库信息
myinit.properties:
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/select_test
user=root
pass=xuanzhi1
- 重点!!!Session类!!!
Session.java:
package com.han.test;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.PseudoColumnUsage;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import com.han.hibernate.model.Student;
public class Session {
//假设已经读到类的名字了
String tableName="student";
//为什么用Map,因为我们的属性名和类名一一对应
Map<String, String> cfs=new HashMap<String,String>();
String[] methodNames;
private static String driver;
private static String url;
private static String user;
private static String pass;
public Session() throws Exception{
//使用Properties类来加载属性文件
Properties props=new Properties();
InputStream fis = Session.class.getResourceAsStream("myinit.properties");
props.load(fis);
driver=props.getProperty("driver");
url=props.getProperty("url");
user=props.getProperty("user");
pass=props.getProperty("pass");
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(driver);
try(
//获取数据库连接
Connection conn=DriverManager.getConnection(url,user,pass);
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); //对Student s中的m方法进行调用调用
//?是从1开始的
ps.setString(i+1, returnValue);
}
//System.out.println(m.getName()+" | "+r.getName());
if(r.getName().equals("int")){
Integer returnValue=(Integer)m.invoke(s);
ps.setInt(i+1, returnValue);
}
}
ps.executeUpdate();
}
}
private String createSQL() { //构造sql语句
String str1="";
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; //getxxx,xxx的首字母大写,比如getId;
index++;
str1+=s+",";
}
str1=str1.substring(0,str1.length()-1);
String str2="";
// TODO Auto-generated method stub
for(int i=0;i<cfs.size();i++){
str2+="?,";
}
str2=str2.substring(0,str2.length()-1); //去掉最后一个,
String sql="insert into "+tableName+"(" + str1 + ")"+" values("+str2+")";
System.out.println("sql : "+sql); //本例输出sql : insert into student(id,age,name) values(?,?,?)
return sql;
}
}
代码解释:
1. **Session()**
driver,url,user,pass代表数据库的驱动,url,用户名及密码,使用InputStream读myinit.properties文件再通过Properties.load的方法提取出用户名密码等信,最后将属性放入cfs键值对中。
2. **createSQL()**
创建sql语句,从cfs的关键字中提取出方法名。由于get方法是如下形式:
getId()
可以看出方法是由get加上属性第一个字母大写再加上其余字符串而形成,所以我们的toUpperCase(v.chatAt(0))+v.substring(1)是构造方法字符串。
遍历出所有构造方法,由于构造的字符串最后有一个逗号,所以要去掉最后的逗号即str1=str1.substring(0,str1.length()-1)
str2字符串为属性同等个数的?字符串,同理遍历后要去掉尾部的逗号。
```
for(int i=0;i<cfs.size();i++){
str2+="?,";
}
str2=str2.substring(0,str2.length()-1); //去掉最后一个,
```
String sql="insert into "+tableName+"(" + str1 + ")"+" values("+str2+")";
此例最后输出的SQL语句应该为 **insert into student(id,age,name) values(?,?,?)**,构造字符串完成。
3. **save(Student s)**
创建字符串,打开数据库连接,然后使用java的反射机制通过getClass().getMethod()获取方法名,getReturnType()获取返回类型。根据不同的返回类型进行不同的处理,具体内容参见代码,最后executeUpdate()提交。
最后写一个测试类
StudentTest.java:
package com.han.test;
import org.junit.Test;
import com.han.hibernate.model.Student;
public class StudentTest {
@Test
public void test() throws Exception {
Student s=new Student();
s.setId(9);
s.setName("s9");
s.setAge(9);
Session session=new Session();
session.save(s);
}
}
运行后执行情况如下:
可以看出数据正确的插入到了数据库中
下一节我将会讲解关于hibernate的基本配置