ORM框架-发展历史

贴一段最常见的传统Jdbc数据访问代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class JdbcDemo {
public static void main(String[] args) {
ResultSet re = null;
try {
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
try {
Connection connection = DriverManager.getConnection(
"jdbc:mysql://10.0.12.72:3306/mybatis-demo","root","C!Fr0ShoW9Nu");
Statement statement = connection.createStatement();
String sql = "SELECT * FROM blog";
re = statement.executeQuery(sql);
while(re.next()){
Blog blog = new Blog();
blog.setBid(re.getInt("bid"));
blog.setName(re.getString("name"));
blog.setAuthorId(re.getInt("author_id"));
System.out.println(blog);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}

分析这段代码能发现这种连接数据库获取对象的方式有四大弊端:

1、 造成代码重复

2、 资源管理问题,像Connection、StateMent、ResultSet这些资源需要用户去管理,很可能造成资源泄露

3、 结果集的处理,执行结果ResultSet需要用户代码转换成java对象

4、Sql耦合,查询语句耦合在业务代码中,不好管理。

那么解决思路是什么?写一个工具类,将重复操作和资源管理代码封装进去,查询时只要传入sql语句就行了。

于是 Apache在2003年发布了一个叫Commons DbUtils工具类,可以简化对数据库的操作。

DbUtils使用核心类QueryRunner进行操作。

此外,spring也对原生的JDBC做了封装

1、对于代码重复问题—-sping提供了一个模板方法JdbcTemplate,里面封装了各种各样的exectue、query、update方法

注释:

它是JDBC的核心包的中心类。简化了jdbc的使用,可以避免常见的异常。它封装了jdbc的核心流程,应用只需要提供sql,提取结果集就行了,它是线程安全的。初始话的时候可以设置数据源,所以资源管理的问题也可以解决

2、对于结果集转换

根据不同dto类型实现RowMapper接口,同一类型的对象数据集转换代码只需要写一份

可以使用反射的方式进行优化,这样就只要写一份数据映射代码。

DbUtils和JdbcTemplate,这两个工具类对jdbc做了轻量级的封装,帮我们解决的问题有:

  • 对操作数据的增删改查方法进行了封装
  • 无论是QueryRunner 还是JdbcTemplate 都可以传入一个数据源进行时初始化,也就是资源管理这一部分的事情可以交给专门的数据源组件去做
  • 可以帮助我们映射结果集,无论是映射成List、Map还是POJO

这种轻量化的工具类已经帮助我们解决了很大的问题,但还是存在以下几点不足

  1. Sql语句是写死在代码里的,依旧存在硬编码问题
  2. 参数只能按照固定位置的顺序传入,它是通过占位符去替换的,不能传入对象和Map,没有自动映射
  3. 在方法里,可以把结果集映射成实体类,但是不能直接把实体类映射成数据库记录,没有自动生成Sql功能
  4. 查询没有缓存,性能还不够好

面对这些新的需求,轻量化的工具类是不够用了,ORM框架应运而生。

1、Hibernate

Hibernate是一个很流行的ORM框架,2001年的时候就出现了第一个版本,在使用Hibernate时,我们需要为实体类建立一些hbm的xml映射文件

然后通过Hibernate提供的session的增删改查方法来操作对象。

使用Hibernate操作对象就像是操作数据库的数据一样,Hibernate会自动帮我们生成sql语句,可以屏蔽数据库的差异。自动进行映射。这样业务代码变得更加简洁。程序的可读性更高

映射的配置文件也可以使用注解代替。

session方法也可以通过继承JpaRepository获得,无需手动创建

总结Hibernate特性:

  • 根据数据库方言生成sql语句,代码移植性好
  • 自动管理连接资源
  • 实现了对象和关系型数据库的完全映射,操作对象就像在操作数据库
  • 提供缓存机制

存在的一些问题:

  1. 使用get、update、save,操作是所有字段,没有办法指定部分字段,不够灵活
  2. 自动生成sql方式,如果要基于sql做一些优化的话,是很困难的,可能会存在性能问题
  3. 不支持动态sql

总结起来就是:操作真的很方便,可是还不够灵活,我们需要一个更灵活的框架

2、mybatis

与Hibernate相比,mybatis是半自动的Orm框架,恰恰是半自动化解决了Hibernate遗留的问题。mybatis的封装成本没有Hibernate那么高,不会自动生成全部的sql语句,它主要解决的是sql和对象的映射问题。

两种方式使用:

  • 通过传入statementId的方式调用,但这种方式存在硬编码,且id错误在编译时不能发现
  • 通过定义mapper接口,调用接口方法的方式。

总结出mybatis的核心特性:

  1. 使用连接池管理连接
  2. Sql与代码分离集中管理
  3. 结果集映射
  4. 参数映射和动态sql
  5. 彩虹昂福sql的提取
  6. 缓存(虽然已不常用了)
  7. 插件机制(很强大很灵活)