做WEB开发不可避免和数据库打交道, 初学java也必定会了解jdbc, 而ORM技术则是必不可少的. 这里通过一些基本的需要对几个orm框架进行了尝试. 只涉及使用方面的尝试, 没进行性能等高级功能的测试. 项目代码在 https://gitee.com/tianzhipeng/ormtest

Object/Relational Mapping

目前包含orm框架:

  • Spring JdbcTemplate
  • Mybatis
  • Ebean-ORM
  • JPA-Hibernate

打算从几个方面测试各orm框架, 按需求从强到弱(演示这些功能的demo方法见BaseDemo):

  • 基本的单表crud
  • 结果映射成对象
  • 条件查询
  • 多表联合查询
    • 自动oneToMany
    • 手动join, 结果映射. dto/entity.
  • 执行原生sql语句
  • 分页
  • lazy loading/projection
  • 多租户分schema设计
  • db migrations
  • 其他高级功能
    • 缓存
    • 事务
    • 批量
    • audit

multi-tenancy, 多租户

是指在SaaS项目中, 一个程序服务多个租户, 数据上要进行隔离. 简单看有三个级别的隔离

  • 分库
  • 分schema. (database下面是schema, schema下面是表. mysql里没有这一层)
  • 分表
  • 表内分区

调查结论. hibernate和ebean提供的多租户支持, 都是上述1,2,4三种方式, 分表的需求可能很奇怪?


database migration/evolution

是指虽迭代开发, 数据库的schema要随着版本不断变化, 如何自动管理这种变化, 防止手动打patch出现问题.

在Django/Rails这些框架的ORM中, 由于使用了ActiveRecord的机制, 不用自己维护ddl语句, 直接用”类” 来映射 “数据库表”, 这样的话, 升级的时候比较容易追踪, 所以那些框架自己提供了非常easy的db migration功能.

这个工作分为两步, 谁来生成diff的sql, 谁来管理和执行sql更新.

执行更新动作也有多种可能的方式:

  • mvn插件的goal
  • command line执行
  • 随程序启动执行
  • 在jar包里加一个main入口

手写sql手动打patch很崩的, 我们期待的比较好的方式是:

在开发的时候用工具自动生成diff的sql, 在部署的时候用工具管理sql更新, 启动的时候有validate一下是最好的.

  • Hibernate中有个hbm2ddl工具: hbm2ddl: 随程序启动, 开发的时候用来生成sql, 上线的时候用来validate不错, 用来执行有点崩, 好像没有版本的概念.

  • ebean也加了自己的migration工具: 可以生成sql,

  • 独立的三方migration工具有两个, 用于管理和执行sql更新, 他们不能生成diff sql. 见src/main/resources/dbmigrate/

    • flyway
    • liquibase

参考链接

  • http://ebean-orm.github.io/docs/
  • docs.jboss.org/hibernate/orm/current/userguide/html_single/Hibernate_User_Guide.html
  • https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.custom-implementations
  • http://www.mybatis.org/mybatis-3/

总结

一下总结纯属个人一家之言.

  • Mybatis: 完全是纯写sql, 这既是他的有点也是他的缺点, 其他方面没什么特点. 简单, 适合各种比较随意就能起步的中小型团队.
  • Hibernate: 成熟, 功能全, 也就意味着复杂上手难度高. 没有好的规范容易些的乱, 需要有大神hold住, 适合比较成熟规范的团队.
  • Spring-JPA: 根据jpa规范对hibernate进行的封装, 根据函数名自动实现查询很鬼畜, 向repository里mixin自定的方法很别扭. 不知道到底用jpa的entityManger接口做还是hibernate的接口做了.
  • Ebean: 模仿我个人很喜欢的ActiveRecord风格的api, 而且比较做到了DRY. 类似lombok需要在编译器修改class进行enhance, 所以需要maven插件和idea插件, 项目版本乱对新学者不友好. 但坑就是机会, 项目整体代码量简单, 大神可以轻松入手, 小项目或者自己搞着玩, 有bug可以提pr.

对比

数据库migration工具就选liquibase了.

另外发现一个好玩的项目 querydsl TODO

UPDATE0: 最终采用的是Mybatis Plus… UPDATE1: liquibase结合SpringBoot在启动时执行migrate