如何设计ORM架构及Bee源码分析
教你从0开始设计一个ORM框架,让你从码农进阶为软件设计高手!
1. 什么是ORM,ORM能为我们做什么
ORM是对象关系映射(Object Relational Mapping)的简称,是面向对象和关系数据库之间的一种映射,目的是为了使用面向对象的方式操作关系型的数据库,将面向对象语言程序中的对象自动持久化到关系数据库中。
在Java平台,操作数据库是通过JDBC接口,JDBC具体的实现,由各数据库厂商负责。下面我们来看下,在没有ORM工具时,是如何用JDBC直接写代码来访问数据库的。
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
Connection con = DriverManager.getConnection(dbURL, userName, userPwd);
String sql="select * from users where name=? and pw=?";
PreparedStatement stmt = con.prepareStatement(sql);
stmt.setString(1, "Bee' or '1'='1'");//防止SQL注入攻击
stmt.setString(2,"aaa");
ResultSet rs = stmt.executeQuery();
while(rs.next()){
//在此处获取结果. 手动封装成Javabean
System.out.println(rs.getString(2));
}
System.out.println("");
}catch(SQLException e){
System.out.println("have exception"+e.getMessage());
}
直接使用JDBC,存在的工作量或问题,主要有:
-
需要开发人员自己维护Connection数据库连接。
-
事务需要自己实现。
-
需要手动写sql语句,工作量大,繁琐;难于调试,经常会出现sql多一个或少一个单引号等引发的sql语法问题;且不同的sql语句需要重新调试。
-
手动编写代码设置参数,如:stmt.setString(2,"aaa");。
-
手动将查询结果拼装成Javabean对象返回。spring的JdbcTemplate也存在这个问题。
-
针对每个实体写一份dao操作文件,n个实体就要写n份。
因为存在这些问题,所以我们需要一个中间件或叫框架去完成这些类似重复、烦琐的工作。而ORM工具,正是为了满足这种需求而诞生的。
2. Bee架构(ORM框架) 目标
Bee简单易用:单表操作、多表关联操作,可以不用写sql,极少语句就可以完成SQL操作;10分钟即可学会使用。
Bee功能强大:复杂查询也支持向对象方式,分页查询性能更高,一级缓存即可支持个性化优化。高级需求,还可以方便自定义SQL语句。
名词解释:
Suid :对数据库的SQL命令查询、更新、插入与删除(select、update、insert、delete)四种操作的简称(Suid为四种操作首字母)。
编码复杂度: 为了讨论编码效率问题,采用编码复杂度来衡量。编码复杂度用于描述编码量与所解决问题的规模的关系。可以用《数据结构》里的时间复杂度和空间复杂度作类比来感受下编码复杂度。
主要设计目标
1)编码复杂度为C(n)=O(1),即不管数据库里有多少张表,都不需要写额外的Dao代码。
2)Bee设计与编码风格:Bee 是一个具有人工智能(AI)特性,省时/优雅、简易、自动( AiTea: Timesaving/Tasteful, Easy, Automatic)风格的ORM框架。
3)所有的Suid()操作都是用同样的Bee接口,不用再定义任何新的dao接口,更不用实现dao接口。
4)用户/开发者只需要关注Bee接口如何调用即可。
5)动态/任意组合查询条件,不需要提前准备dao接口,有新的查询需求也不用添加和修改接口。
6)约定优于配置:Javabean没有注解,没有xml,只是纯的Javabean即可(为什么要给Javabean那么重的负担呢??!!!)。
7)自动映射表的列与Javabean的字段。
8)支持只查询一部分字段。
9)使用PreparedStatement防止SQL注入攻击。
10)自动过滤null和空字符串(作为默认实现)。可以很方便地只插入非空的部分字段和只更新部分字段。
11)存储过程支持;批处理操作支持;自动事务支持;SQL中排序,分页。
旧的ORM工具,一般都使用一个xml文件来记录Java对象(O)与关系数据库表(R)的对应关系,后来又流行采用注解的方式,直接在Javabean文件里标注。而Bee希望只用标准的Javabean文件直接与表建立映射,采用约定优于配置的原则,DB命名与Java命名默认转换。
3. Bee架构(ORM框架) 设计
模块划分,Bee框架至少包括四个模块:面向对象方式Suid接口模块,对象转sql语句模块,底层接口操作DB及自动装配返回结果模块和上下文模块。如图1所示。
图1 Bee框架模块图
将Javabean实体对象传入Suid操作接口-->Bee ORM框架根据实体对象解析得到sql语句-->调用DB底层接口执行sql语句-->处理结果,若是更新操作返回int数据;若是查询操作,将结果集封装成实体对象相同类型的Javabean再返回。如图2所示。
图2 Bee操作DB流程图
添加缓存功能后的流程,如图3所示:
图3 Bee有缓存功能的查询流程图
4. ORM框架在整个MVC软件系统中的位置
为什么要将ORM从MVC中分出来,分出ORM层有什么好处?
因特网的雏形ARPANET网络,使用分层原理设计,将庞大而复杂的问题,转化为若干较小的局部问题。而且在TCP/IP四层协议中,IP协议是网络层的通用协议,如图4所示,其它层的协议通过网络层时一般都是使用IP协议。软件系统访问数据库也应该使用分层原理进行设计。ORM犹如TCP/IP四层协议中运输层的TCP,应该设计成通用的组件,起复用和分用的作用,如图5所示。
图4 沙漏计时器形状的TCP/IP协议族
图5 软件开发分层设计图
5. Bee源码分析
Bee的部分模块的主要接口如下表所示:
我们再来看下主要接口的方法源码:
Suid接口是我们开发使用操作数据库的。
Suid接口:
public interface Suid {
public <T> List<T> select(T entity);
public <T> int update(T entity);
public <T> int insert(T entity);
public <T> int delete(T entity);
}
ObjToSQL接口是Bee框架将Suid接口传来的对象解析成SQL语句用的。
ObjToSQL接口:
public interface ObjToSQL{
public <T> String toSelectSQL(T entity) ;
public <T> String toUpdateSQL(T entity) ;
public <T> String toInsertSQL(T entity) ;
public <T> String toDeleteSQL(T entity) ;
}
BeeSql是Bee框架访问操作DB的接口。
BeeSql接口:
public interface BeeSql {
public <T> List<T> select(String sql,T entity );
public <T> List<T> selectSomeField(String sql,T entity );
public List<String[]> select(String sql);
public String selectJson(String sql);
public int modify(String sql);
public int[] batch(String []sqls,int batchSize);
...
}
作为一般的使用者,我们只需要关注Suid,SuidRich接口的使用即可。如:
List list1 = suid.select(orders1); //select
到此, Bee架构(ORM框架) 设计及源码分析 的内容就全部讲完了。 简单易用,功能强大是我们不断追求的目标。有什么问题,欢迎咨询。
技术QQ群:992650213