今天简单的讲讲ORM(object relation mapping 对象关系映射)。如果你对hibernate底层对象关系的映射感觉很神奇的你可以看看这篇文章。很多人接触hibernate的时候都知道这个ORM,也知道是底层对JDBC的一个封装,并提供了很多的接口供外部使用,使我们在操作数据库的时候都,感觉就像是在操作对象一样。ORM的工作正在此。
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.TYPE)
- public @interface ORM {
- String table() default "";
- boolean showSQL() default false;
- }
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.FIELD)
- public @interface Id {
- String name() default "";
- }
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.FIELD)
- public @interface Column {
- String name() default "";
- String type() default "";
- int length() default 1;
- boolean isNull() default true;
- }
好了注解定义成功,这些都是我们需要的属性,我们只需用将这些注解标注在我们的实体中去,实体标注代码如下:
- @ORM(table = "person", showSQL = true)
- public class Person {
- @Id
- private int id;
- @Column
- private String name;
- 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;
- }
- }
准备工作已经OK,接下来才是最关键的,就是如何去获取到我们标注的信息,如果去调用对应字段的get和set方法。在Hibernate中,我们通常会使用SessionFactory去过去Session,而在此我们不用接口去做这件事情,为了简化我们直接使用一个单例类来完成对实体的信息获取。
- public abstract class BaseSession {
- private static ConnectionProvider connectionProvider = ConnectionProvider
- .instanceConnectionProvider();
- /**
- * 获取表信息
- *
- * @param obj
- */
- private void getTableInfo(Object obj) {
- Annotation[] annotationClass = obj.getClass().getAnnotations();
- // 获取表名
- for (Annotation annotation : annotationClass) {
- if (annotation instanceof ORM) {
- ORM orm = (ORM) annotation;
- table = orm.table();
- if (table == null || "".equals(table)) {
- String className = obj.getClass().getSimpleName()
- .toLowerCase();
- table = className;
- }
- showSql = orm.showSQL();
- }
- }
- ...类似的方法去获取其他的注解...
- }
- // 获取实体的值
- private String getFieldValue(Object obj, String fieldName) {
- Method[] methods = obj.getClass().getDeclaredMethods();
- String value = "";
- for (Method method : methods) {
- if (method.getName().contains(
- fieldName.substring(1, fieldName.length()))
- && (method.getName().startsWith("get"))
- || method.getName().startsWith("is")) {
- Object[] objParams = new Object[0];
- Object result = method.invoke(obj, objParams);
- value = result.toString();
- }
- }
- return value;
- }
- // 设置数据库查询出来的值
- protected <T> Object loadToObject(ResultSet rs, Class<T> clazz) {
- try {
- int totalColumn = fields.length;
- while (rs.next()) {
- // 把值放到field和values中去
- for (int i = 0; i < totalColumn; i++) {
- values[i] = rs.getString(fields[i]);
- }
- }
- // 将值放入到对象中去
- return buildObject(clazz);
- } catch (SQLException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- return null;
- }
在此,我们通过getFieldValue和loadToObject去调用实体的get和set方法,以使我们在底层将这些对象与关系数据库之间建立起桥梁。以此让我们在具体的方法中直接去调用即可。
- public class Session extends BaseSession implements SessionFactory {
- /**
- * 保存对象
- */
- public boolean save(Object obj) {
- try {
- conn = super.getConnection();
- conn.setAutoCommit(true);
- String sql = super.buildSQLForSave(obj);
- PreparedStatement stmt = conn.prepareStatement(sql);
- boolean success = stmt.execute();
- return !success;
- } catch (SQLException e) {
- e.printStackTrace();
- return false;
- } finally {
- super.closeConnection(conn);
- }
- }
- public <T> Object load(Class<T> clazz, Serializable id){
- conn = super.getConnection();
- String sql = super.buildLoadSQL(clazz, id);
- ResultSet rs = null;
- PreparedStatement stmt;
- try {
- stmt = conn.prepareStatement(sql);
- rs = stmt.executeQuery();
- return super.loadToObject(rs, clazz);
- } catch (SQLException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } finally {
- super.closeConnection(conn);
- }
- return null;
- }
- }
由以上代码我们可以继承BaseSession中的一些方法,来使用继续对这些零散方法的一个封装,以使我们在外部调用的时候就只是去调用它的接口方法即可。
- public class Test {
- /**
- * @param args
- */
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- // Person person = new Person();
- // person.setId(5);
- // person.setName("Test");
- //
- SessionFactory sessionFactory = new Session();
- // boolean isSuccess = sessionFactory.save(person);
- // if(isSuccess){
- // System.out.println("保存成功");
- // } else {
- // System.out.println("保存失败");
- // }
- Person person = (Person)sessionFactory.load(Person.class, 1);
- System.out.println("===查询结果===");
- System.out.println("Id: " + person.getId());
- System.out.println("Name: " + person.getName());
- }
- }
至此,ORM的简单讲解就到此,真正的ORM远比这个复杂的多,这里只是对他实现的原理简单的做个总结,以使更多的初学者对hibernate不只是会用,还能清楚他并不是那么神秘!
转载于:https://blog.51cto.com/sgyyz/1035753