上节中讲到了代理模式,众所周知,Java大量的框架,例如Spring,hibernate,mybatis等,都是通过反射、代理模式等实现的,本文将通过反射与代理实现简易的ORM框架。
现在我们有一个类似这样的学生表,在数据库需要建立相应映射类,首先我们需要一些表、列、主键的注解,后续可以关联映射关系,直接用hibernate的注解稍加修改。
表征实体
表名
主键
列
这样我们可以通过注解获取到表名、列名、主键。
我们针对所有父类,需要创建一个抽象类,和获取代理对象的类,抽象类中需要包含表名、列的集合、主键的信息,以及获取代理对象的方法。
抽象父类:
在默认构造器中,我们通过反射初始化了表名、列的集合以及主键信息,实际上这个效率是比价低的,这些信息只需要在程序启动时初始化到缓存中即可,此处不再做重构。
获取代理对象的代理类:
代理类在拦截方法中,拦截了所有set方法,并且记录下变更的集合,方便后续使用。
如此,我们生成一个子类用于测试:
子类同前面图中,有三个属性id、name和age,并且分别通过注解做了数据库表字段映射。
接下来我们需要构建一个数据库访问基础类,这个类中应当包含基本的select、insert、update、delete方法,当然我们可以通过接口定义这些方法,再通过基础类实现,本文直接使用类定义方法。
在其中我们定义了一个SqlDto,用于存放操作类型、预编译sql以及参数列表。
无论JDBC、还是JDBCTemplate等何种方式访问数据库,最终都是要生成SQL访问数据库的,所以我们只需要做到生成SQL即可,后续的可以根据需要实现。
在数据库操作基础类中,其中select方法是比较简单的,只需要通过反射获取表名,字段,然后拼装sql和参数即可,见代码,insert类似,而delete更简单,不在详细实现。
在update中,我们要求必须传输对象的代理对象,好处是在我们获取对象后,生成代理对象,再对代理对象操作时,可以准确记录代理对象的操作过程(变化的列)。
建立测试类:
可以在SqlDto类中增加toString()方法,这样可以打印出sqlDto的明细,也可以通过debug方法。测试结果如下:
成功生成了预期的SQL,参数列表以及更新类型。
以上便是通过反射和代理实现的简易ORM框架,实体类继承于BaseEntity并且添加相关注解,便可以通过数据库访问基础类生成SQL相关信息,再添加JDBC或JDBCTemplate的支持,即可实现数据操作。
本文有诸多改造点:
数据库实体抽象父类BaseEntity的构造器可以不实现,在程序初始化时,将数据库表相关信息初始化到缓存中,不必每次通过反射获取。
数据访问基础类BaseRepository外可以再封装一层,添加JDBCTemplate或jdbc,直接返回数据实体或实体集合,可以添加泛型,较为符合ORM的思想。
领取专属 10元无门槛券
私享最新 技术干货