重复造轮子(4) — 手写orm框架Ibernate(下)

简介: 重复造轮子(4) — 手写orm框架Ibernate(下)

3. Core核心包内容


通过一个对象,配置好相应的注解之后,如何去通过扫描识别属性,然后再自动生成sql返回对象,这个才是整个框架的核心之处。Ibernate里面涉及了一个叫做ISessionUtil的接口。它的具体实现类是org.lh.ibernate.core.impl.SessionUtil类。


首先构建SessionUtil对象的构造函数


网络异常,图片无法展示
|


至于这里面的构造参数为什么要有一个class对象,这个后边再说。


sessionUtil里面有很多有简单的函数:保存,更新,删除


网络异常,图片无法展示
|


例如说插入的实现方式主要在org.lh.ibernate.core.impl.InsertUtil


类里面进行。


主要的思路就是,通过反射获取数据表名的字段名字,然后通过相应传入对象的字段属性来进行赋值,动态创建sql语句进行插入即可。


网络异常,图片无法展示
|


为了防止sql注入,所以这里面的思路是找出需要插入的字段数量,创建足够多的占位符?,并且每个占位符映射的字段和实体类的字段顺序一致。


这个插入的实现还是比较简单的,稍微说一下里面的两个自定义函数吧:


getAttrFromFieldHasColumnAnnotation,它的功能是获取所有含有@column注解的字段的属性值,原理主要是采用反射的方式:具体实现在org.lh.ibernate.core.impl.FieldHandle里面


网络异常,图片无法展示
|


然后就是DbUtil里面的一个executeUpdate自定义函数,通过传入相应的sql语句,然后再去给sql里面的占位符赋值。但是有个前提,就是每个占位符对应的值要一一匹配好。

关于插入的功能基本也就这样了,如果读者能耐心地把这些看透,并且实现的话,可能还会发现很多有趣的部分。


同理,删除对象和更新对象的原理也基本是这样。这里就不一一介绍了。


查询操作:


查询操作比较另类,因为它需要和结果集进行动态映射,个人觉得比读操作要困难些。例如说查询操作:


网络异常,图片无法展示
|


这段代码的含义就是,当某个类如果标注了相应的缓存注解,就会先从缓存redis里面去查找,反之就是会从mysql里面查找。


关于缓存查找这个主要是用了jedis的api来进行搜索,具体代码在org.lh.ibernate.cache里面有,如果有部分api看不懂的话,百度上边找找大概就能搜索到了。


我们继续看核心部分:


网络异常,图片无法展示
|


如何能够生成sql语句,这个有了前边的插入,删除,更新经验之后,应该很快就能想到。但是如何才能动态化将ResultSet转换为相应的具体对象,这是一个难点。


慢慢来,经过思考之后,我设计了一个QueryUtil类,里面专门存放对于查询代码的封装方法,findOneObjBySql就是其中之一。


网络异常,图片无法展示
|


是的,你会发现这里面的前期部分就是动态生成sql语句,这个比较简单,后边用到了一个Dbutil的query方法,这个类在整个框架里面是进常会被用到的,而且非常核心。


网络异常,图片无法展示
|


这段源码只需要稍微了解一些jdbc基本都能读懂。


好了,返回了相应的ResultSet之后,就可以动态化的设置转换了。


这里面的ResultSetHandler实现原理可能有些复杂,需要比较耐心地去看下去才可以:


网络异常,图片无法展示
|


这里面出现了一个我在google上查到的jdk函数,叫做属性修改器PropertyDescriptor,是的,这已经是比较偏向于底层的东西了,如果你有耐心去研究下去的话,你的java能力一定会大涨的。


使用属性修改器,动态修改某个属性的值,然后再通过Method里面的invoke代理进行相应类的属性更新,这样就能创建一个新的对象了。


关于多个对象的结果集转换为List类型的函数,大概思路和上边的类似,这里就不多讲了




关于用户的自定义sql查询的底层原理又是如何的呢?


自定义sql查询方法的具体使用方式如下所示:


网络异常,图片无法展示
|


先创建一个ParameterLink对象,然后需要用这个对象add相应的占位符参数,需要一一匹配好,然后才能传入参数。


原理其实很简单,就是Dbutil里面的query方法。


关于Dbutil里面的query方法而言,里面包含有一个ParameterLink对象,这个对象的位置在org.lh.ibernate.core.tools里面,这个类主要是采用了一种链式编程的思想,有点像设计模式里面的责任链模式,所以在添加参数的时候会处理的比较灵活。这里需要注意一下,ParameterLink里面添加的内容需要和条件字段一一匹配。


关于ParameterLink的截图:


网络异常,图片无法展示
|


4.自定义接口创建Dao的具体实现


在Ibernate的1.3版本当中,最主要是添加了invoker这个包


网络异常,图片无法展示
|


这里面的到设计有点借鉴了mybatis和springdata的思想,通过开发者定义接口,然后在实际生产环境中动态化的生成实例类,从而完成相应的crud操作。


网络异常,图片无法展示
|


在IbernateBaseDao里面,有多个已经预定义好的crud函数,由于最近事情有点多,还有些许功能未有添加,希望各位开发者谅解。


网络异常,图片无法展示
|


开发中遇到的困难:


如何动态化地在jvm中通过接口来创建类实例;


使用asm字节码框架来获取某个函数参数名称;


如何更加高效和有用地封装繁琐的函数和类….


如果你对于我的源码表示看不懂,没关系,只要在看完之后,对框架有了更深的认识,小编我也就知足了。


可能各位读者会疑惑,为什么


如果对于源码有兴趣的朋友,可以到我的gitee上边去下载:

gitee.com/IdeaHome_ad…


目录
相关文章
|
Oracle Java 关系型数据库
想要造轮子,你知道反射机制吗?
平时写代码的过程中,我们使用不同的工具框架来提升开发效率,除了基础框架之外,我们自己也想造轮子,封装各种业务平台功能; 一旦需造轮子的时候,那么就需要使用Java造轮子利器:反射; 一些项目中常见的反射应用场景: • 泛化调用: 提前不知道目标RPC的接口和方法,而是开发在后台输入值,根据输入的配置动态请求。 这也是提升效率的一部分,因为不可能所以得RPC接口都要亲自对接的,总要有一部分可以灵活的调用不同接口。
60 0
|
8月前
|
存储 JSON 缓存
前端面试必须掌握的手写题:基础篇
前端面试必须掌握的手写题:基础篇
|
数据库
Basedao工具类:数据库操作利器,让你事半功倍!挥别繁琐,轻松驾驭数据世界!
Basedao工具类:数据库操作利器,让你事半功倍!挥别繁琐,轻松驾驭数据世界!
83 0
|
Java Spring
再也不用重复造轮子了 一个Spring注解轻松解决
再也不用重复造轮子了 一个Spring注解轻松解决
73 0
|
Java 数据库连接 数据库
返璞归真,学了那么多技术栈,那些 [Mybatis-plus] 之 CRUD操作你还熟悉吗
返璞归真,学了那么多技术栈,那些 [Mybatis-plus] 之 CRUD操作你还熟悉吗
89 0
|
SQL 缓存 Oracle
MyBatis 别再乱用 foreach 批量插入了,5000 数据用了 14 分钟,实力劝退。。
MyBatis 别再乱用 foreach 批量插入了,5000 数据用了 14 分钟,实力劝退。。
435 0
MyBatis 别再乱用 foreach 批量插入了,5000 数据用了 14 分钟,实力劝退。。
|
SQL 设计模式 存储
Mybatis 使用的 9 种设计模式,真是太有用了(二)
Mybatis 使用的 9 种设计模式,真是太有用了(二)
Mybatis 使用的 9 种设计模式,真是太有用了(二)
|
SQL 设计模式 JavaScript
Mybatis 使用的 9 种设计模式,真是太有用了(一)
Mybatis 使用的 9 种设计模式,真是太有用了
Mybatis 使用的 9 种设计模式,真是太有用了(一)
|
SQL 缓存 Oracle
重复造轮子(4) — 手写orm框架Ibernate(上)
重复造轮子(4) — 手写orm框架Ibernate(上)
128 0
FluentMybatis 项目工程化、常规操作(增删改查)(二) | FluentMybatis实践
FluentMybatis 项目工程化、常规操作(增删改查)(二) | FluentMybatis实践
FluentMybatis 项目工程化、常规操作(增删改查)(二) | FluentMybatis实践