hsweb的系列学习——hsweb-easy-orm分析 中
三,curd的逻辑
从sql语句里可以看出,查,删,改,都是伴随着条件进行的,首先对条件进行设计,然后再具体事情具体办
1,设计一个统一的条件类型的支持接口来统一接收
一个是根据输入条件TermTypeConditionalSupport
:
1 | package org.hsweb.ezorm.core; |
另外一个根据实例化的po bean TermTypeConditionalFromBeanSupport
:
1 | package org.hsweb.ezorm.core; |
接下来就搞定条件的设置接口:Conditional
对于Java8
Consumer接口
的知识预备,请查看 Predicate和Consumer接口– Java 8中java.util.function包下的接口
对于嵌套条件的设置,请查看org.hsweb.ezorm.core.NestConditional
,
源码最后关于Supplier接口
和BiConsumer<T, U>接口
,不懂的请看Java 8之Stream的强大工具Collector
先把各种条件关键字用方法给设定出来,如,and(),or(),where(),以及最后条件追加,根据条件判断然后再确定追加与否这些情况进行设定等,同样支持直接拼接sql,代码如下:
1 | /* |
因为之前有设计针对sql的直接封装,那么相应的增加SqlConditionSupport<T>
1 | package org.hsweb.ezorm.core; |
2,对删,改,查的设计与实现
对改的接口设计Update
:
具体不需要解释了,英文已经很清晰明白了
1 | package org.hsweb.ezorm.core; |
实现类:
1 | package org.hsweb.ezorm.rdb.simple; |
最关键的地方也就在于exec()
,
boolean supportBefore = !triggerSkip && table.getMeta().triggerIsSupport(Trigger.update_before);
在触发条件不忽略,然后此table的元数据触发条件支持Trigger.update_before
,返回true,调用过程如下图:
同理,supportDone
就不再解释了,
Map<String, Object> context = table.getDatabase().getTriggerContextRoot();
其实就是产生一个map
,具体源码如下:
1 | public Map<String, Object> getTriggerContextRoot() { |
符合supportBefore || supportDone
条件,添加table,database,param信息
当符合supportBefore
条件时,table.getMeta().on(Trigger.update_before, context);
这里只看到了这一个脚本实现类,就顺带贴下
对后面代码:
1 | SqlRender<UpdateParam> render = table.getMeta().getDatabaseMetaData().getRenderer(SqlRender.TYPE.UPDATE); |
下图RDBDatabaseMetaData
下面被掩盖的标记代码为public abstract SqlRender getRenderer(SqlRender.TYPE type);
AbstractRDBDatabaseMetaData
对RDBDatabaseMetaData
进行抽象实现
在getRenderer()
内得到相应数据库类型的render,在init()
放入相应数据库类型的render
1 | package org.hsweb.ezorm.rdb.render.dialect; |
最后再看具体实现类,此处拿MysqlRDBDatabaseMetaData
为例
在此MysqlRDBDatabaseMetaData
实例进行初始化时,设置MysqL数据库方言并会调用init()
方法放入MysqL数据库类型的render
1 | package org.hsweb.ezorm.rdb.render.dialect; |
对update sql
语句的组合渲染:
首先设计一个其他类型语句共有的语句特性,比如指定了exclude 字段,没有指定include 字段
CommonSqlRender
:具体逻辑如下,不仔细解释了
1 | package org.hsweb.ezorm.rdb.render.support.simple; |
拼接sql准备:
1 | package org.hsweb.ezorm.rdb.render; |
where语句的共同部分进行抽象
首先是Dialect
的设定:
接口:
1 | package org.hsweb.ezorm.rdb.render.dialect; |
默认实现DefaultDialect
其中TableMetaParser
默认使用OracleTableMetaParser
1 | package org.hsweb.ezorm.rdb.render.dialect; |
具体到相应数据库,这里拿MysqlDialect
为例:
其实主要还是设置对应的数据类型
1 | package org.hsweb.ezorm.rdb.render.dialect; |
这里漏说了一个表元素的解析:
先设计个接口
1 | package org.hsweb.ezorm.rdb.meta.parser; |
抽出抽象部分:
1 | package org.hsweb.ezorm.rdb.meta.parser; |
具体数据库完成具体部分MysqlTableMetaParser
为例:
1 | package org.hsweb.ezorm.rdb.meta.parser; |
其次是SimpleWhereSqlBuilder
:
1 | package org.hsweb.ezorm.rdb.render.support.simple; |
拼接出的sql封装:
关联查询sql:
1 | package org.hsweb.ezorm.rdb.executor; |
定义SQL
封装接口:
1 | package org.hsweb.ezorm.rdb.executor; |
具体实现:
1 | package org.hsweb.ezorm.rdb.render.support.simple; |
回到SimpleUpdateSqlRender
实现:
1 | package org.hsweb.ezorm.rdb.render.support.simple; |
终于得到 了sql,最后,验证之后执行sql语句:
设定执行器接口SqlExecutor
:
1 | /* |
JDBC 通用sql执行器
1 | /* |
至此,关于改终于分析完毕