文档章节

【译】jOOQ vs MyBatis

Landas
 Landas
发布于 2017/04/07 15:36
字数 859
阅读 900
收藏 2

        当下jOOQ和MyBatis都是热门的JPA替代品,相对于JPA来说它们也更加注重于SQL本身。它们之间最明显的区别包括:

  • jOOQ本质上是通过Java流式API使用领域专用语言(domain-specific language)来构造SQL
  • MyBatis则基于XML的SQL模板映射,它的动态SQL是通过XML-DSL生成的

        MyBatis当前的成功大部分是因为JPA本身充满争议(JPA还需要证明自己优于JDO),而MyBatis在这个时间窗提供了一个可选的、容易被SQL爱好者们接受的方案:

  • 将Java与SQL完全分离,SQL代码在一个独立文件中。便于让DBA在生产环境调整、优化SQL。
  • 能自动将结果集封装为对象。和动态sql一样,都是通过xml DSL实现。

用jOOQ实现SQL模板

        jOOQ也能做同样的事情。和MyBatis不同的是,jOOQ的SQL模板(jOOQ 3.2)并没有使用专用的模板语言。将自由选择的权利留给用户自己。目前已集成的包括:

    看一个Velocity的例子。在where查询中加入了一个ID的列表作为动态参数:

SELECT
  a.first_name,
  a.last_name,
  count(*)
FROM
  t_author a
LEFT OUTER JOIN
  t_book b ON a.id = b.author_id
WHERE
  1 = 0
#foreach ($param in $p)
  OR a.id = ?
#end
GROUP BY
  a.first_name,
  a.last_name
ORDER BY
  a.id ASC

        jOOQ的模板实现可以接受上面的模板,使用确定的输入对象来构造具体的jOOQ QueryPart。QueryPart是用于渲染SQL、绑定变量的对象:

class VelocityTemplate
implements org.jooq.Template {
 
  private final String file;
 
  public VelocityTemplate(String file) {
    this.file = file;
  }
 
  @Override
  public QueryPart transform(Object... input) {
 
    // Velocity code
    // -----------------------------------------
    URL url = this.getClass().getResource(
      "/org/jooq/test/_/templates/");
    File file = url.getFile();
 
    VelocityEngine ve = new VelocityEngine();
    ve.setProperty(RESOURCE_LOADER, "file");
    ve.setProperty(FILE_RESOURCE_LOADER_PATH,
      new File(file ).getAbsolutePath());
    ve.setProperty(FILE_RESOURCE_LOADER_CACHE,
      "true");
    ve.init();
 
    VelocityContext context = new VelocityContext();
    context.put("p", input);
 
    StringWriter writer = new StringWriter();
    ve.getTemplate(file, "UTF-8")
      .merge(context, writer);
 
    // jOOQ Code
    // -----------------------------------------
    return DSL.queryPart(writer.toString(), input);
  }
}

        就是这么简单。你可以随意控制自己的模板引擎适配器,向其中自由加入缓存、对象池等等。

        然后上面的模板可以在任何jOOQ API允许使用普通SQL的地方使用了。如一个高层query:

Template tpl = new VelocityTemplate(
    "authors-and-books.vm");
 
DSL.using(configuration)
   .resultQuery(tpl, 1, 2, 3)
   .fetch();

        或者来一个类型安全的DSL嵌套查询:

DSL.using(configuration)
   .select()
   .from(new TableSourceTemplate("my-table.vm"))
   .fetch();

        当然你可以利用jOOQ的结果映射,它允许你实现自定义的表格——对象转换算法。这通常比生硬的XML更加友好(如MyBatis):

List<MyType> result =
DSL.using(configuration)
   .select()
   .from(new TableSourceTemplate("my-table.vm"))
   .fetch(new RecordMapper<Record, MyType>() {
      public MyType map(Record record) {
        // Custom mapping logic here
      }
   });

Java 8:

List<MyType> result =
DSL.using(configuration)
   .select()
   .from(new TableSourceTemplate("my-table.vm"))
   .fetch((Record) -> new MyType().init(record));

可能性是最好的东西

        SQL模板是一个强大的工具。如果你喜欢简单的,基于字符串的SQL,它可以随时调整,比如插入一个小循环或if语句,注入一些动态SQL子句。下面有一些这样的SQL引擎:

        在所有这些工具中,只有jOOQ鼓励用户使用自己的模板引擎,从而为模板扩展性提供无限可能。

© 著作权归作者所有

Landas
粉丝 5
博文 36
码字总数 63365
作品 0
深圳
程序员
私信 提问
ORM “杀器”之 JOOQ

摘要: 介绍JOOQ简单实用,以及相对于传统ORM框架的不同点。 (图片来自http://www.jooq.org/) 正文: JOOQ是啥? JOOQ 是基于Java访问关系型数据库的工具包,轻量,简单,并且足够灵活,可...

力谱宿云
2016/08/30
3.6K
16
jOOQ 3.2.4/3.3.1 发布,Java 的 ORM 框架

jOOQ 3.2.4 发布,此版本是 jOOQ 3.2 系列的 bug 修复版本。 jOOQ 3.3.1 发布,此版本是 jOOQ 3.3 系列的 bug 修复版本。 jOOQ 高效的合并了复杂SQL、类型安全、源码生成、Active Records、存...

oschina
2014/03/08
891
0
jOOQ 2.1.0 发布,小型 ORM 框架

jOOQ 2.1.0 发布,在该版本中,jOOQ 试图通过语义版本(http://semver.org/)来实现版本化规则。接下来 jOOQ 将每个月进行一次小版本发布,该版本同时还带来了自定义类型的支持,自定义 SQL 风...

红薯
2012/03/19
551
0
jOOQ 2.0 发布,轻量级Java的ORM框架

jOOQ 2.0 是 jOOQ 的一个全新开始,主要定位一些长期以来用户强烈要求的需求开发。 jOOQ 高效的合并了复杂SQL、类型安全、源码生成、Active Records、存储过程以及高级数据类型的 Java 类库。...

红薯
2011/11/28
949
0
jOOQ 3.11:新增支持四款数据库以及 implicit joins

jOOQ 3.11 已发布,新增支持 4 个新的数据库、implicit joins、诊断等等。 新增支持的数据库 jOOQ 专业版 Aurora MySQL Edition Aurora PostgreSQL Edition Azure SQL Data Warehouse jOOQ 企...

局长
06/08
1K
10

没有更多内容

加载失败,请刷新页面

加载更多

rabbitmq学习

使用docker安装rabbit docker run -d --hostname my-rabbit --name rabbit -p 8080:15672 rabbitmq:management--hostname:指定容器主机名称--name:指定容器名称-p:将mq端口号映射到本地...

元谷
19分钟前
0
0
想知道谁是你的最佳用户?基于Redis实现排行榜周期榜与最近N期榜

本文由云+社区发表 前言 业务已基于Redis实现了一个高可用的排行榜服务,长期以来相安无事。有一天,产品说:我要一个按周排名的排行榜,以反映本周内用户的活跃情况。于是周榜(按周重置更新...

腾讯云加社区
21分钟前
1
0
函数计算性能福利篇(二) —— 业务冷启动优化

继前一篇《函数计算性能福利篇——系统冷启动优化》,我们再来看看近期函数计算推出的 Initializer 功能之后,带来的一波高能性能优化成果。 背景 函数计算是一个事件驱动的全托管 serverle...

阿里云官方博客
27分钟前
1
0
开源版本说明

1527
28分钟前
2
0
Mysql经验-------持续更新

单表行数超过 500 万行或者单表容量超过 2GB,才推荐进行分库分表。 说明:如果预计三年后的数据量根本达不到这个级别,请不要在创建表时就分库分表。

DoLo-lty
31分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部