SpringBoot Ebean使用指南

Ebean是啥

额,具体的Ebean是啥可以自己搜索下,说白了就是一个和MybatisHibernate Jpa差不多的数据库操作框架,但是用了之后还是发现挺好用的,以下复制了一段赞扬Ebean的框架的台词

Hibernate/JPA

反正比 Hibernate/JPA 好

MyBatis

优点

  • 在 XML 映射文件里写 SQL 语句很爽

缺点

  • 实现一个 DAO、仓储要写很多文件(DAO/Repository、XXXMapper、XXXMapper.xml),方法多了比较繁琐
  • 无法在一个方法里做批处理,无法级联加载
  • 即时是简单的 CRUD,都显得繁琐,导致存在各种弥补 mybatis 这一缺陷的第三方封装框架
  • 无法面向对象,无法实现 DDD
EBean

优点

  • 所有场景都实现非常完美,代码可读性高
  • 实现批处理超级简单
  • ORM 查询、sql 查询、DTO 查询都非常简单

缺点

  • DTO 查询功能较新,有待增加 XML mapping 对 DTO 的支持

Ebean自动创建数据表

首先介绍几个ebean的方法

config.setDdlRun(true);
config.setDdlGenerate(true);
config.setDdlCreateOnly(true);

EbeanServer的配置文件中加上以上配置就可以实现根据entity自动创建数据表,entity的写法就和jpa的一样

我看了下文档的介绍

# setDdlGenerate
public void setDdlGenerate(boolean ddlGenerate)
Set to true to generate the "create all" DDL on startup.
Typically we want this on when we are running tests locally (and often using H2) and we want to create the full DB schema from scratch to run tests.

# setDdlRun
public void setDdlRun(boolean ddlRun)
Set to true to run the generated "create all DDL" on startup.
Typically we want this on when we are running tests locally (and often using H2) and we want to create the full DB schema from scratch to run tests.

# isDdlCreateOnly
public boolean isDdlCreateOnly()
Return true if the "drop all ddl" should be skipped.
Typically we want to do this when using H2 (in memory) as our test database and the drop statements are not required so skipping the drop table statements etc makes it faster with less noise in the logs.

我理解的意思就是,setDdlRun会在一开始的时候,创建所有的数据表。但是如果只用这个配置,那么每次启动都会先执行drop all ddl,即,每次启动是先删除所有的表,再创建需要的表。

那如果需要达到不删除已有数据表的效果,就需要加上isDdlCreateOnly,他会跳过drop all ddl这个语句

那么新的问题就来了,如果写成

//是否执行建表SQL
config.setDdlRun(true);
//是否生成建表SQL
config.setDdlGenerate(true);
//是否跳过删表SQL
config.setDdlCreateOnly(true);

第一次创建的时候,是没问题的,第二次创建的时候,就会报相应的数据表already exist的错误

解决这个问题呢也非常的简单,加一个判断就可以,判断是否已经存在数据表,如果不存在就进行创建,如果已经存在就不创建,也就是下面这样

@Override
public EbeanServer getObject() throws Exception {
    EbeanServer server = null;
    ServerConfig config = new ServerConfig();
    config.setName("db");
    config.loadFromProperties();
    config.setDefaultServer(true);
    config.setDdlRun(true)   
    config.setDdlCreateOnly(true);
    //省略了生成建表的SQL
    try {
        server = EbeanServerFactory.create(config);
    } catch (Exception e) {
        config.setDdlRun(false);
        server = EbeanServerFactory.create(config);
    }
    return server;
}

但是这样。就结束了吗?上述实现方式,并不能达到修改某一字段自动检测并更新的效果。

在很多ebean源代码的分享者那里,都使用DbMigration来进行数据库的迁移,更新等操作。那为什么不用上面的一些方法呢。因为create-all / drop-all这两个简单的脚本,本身就是为了测试而创建的,不是为了实际的编码使用的

不过话说回来,如果不是频繁修改,好像上面的简单实现也不错的样子

除了上面的DdlCreate之外,Ebean还提供了其他的数据初始化方案。比如

config.setDdlInitSql("beforeCreateSql.sql");  //在CreateSql前执行
config.setDdlSeedSql("afterCreateSql.sql");  //在CreateSql后执行

其中setDdlInitSql是在CreateSql前执行的,所以无论建表Sql是否执行,都会执行这个sql文件(该文件放在resources目录下)。而如果数据表已存在而跳过了建表SQL,则也会相应的跳过setDdlSeedSql这个方法

在这个基础之上,我们就能进行数据的扩展操作,比如在创建表之后,插入测试数据,或者直接运行在本地导出的SQL批处理脚本等等

DB Migration

DB Migration 是根据实体类来生成数据库的当前情况,每一次数据库的修改,都可以记录下来,并以增量记录的方式记录下来

如果在配置文件中,设置了运行DB迁移文件,也可以达到修改数据表的效果,具体配置如下:

config.setRunMigration(true);

当然生成DB的迁移文件不是自动的,需要每次在你修改完实体类之后,手动生成,一般是通过一个main方法执行的

package com.example.demo;
import io.ebean.annotation.Platform;
import io.ebean.dbmigration.DbMigration;
import java.io.IOException;

public class GenerateDbMigration {
    /**
     * 生成下一个不同版本的数据库表
     */
    public static void main(String[] args) throws IOException {
        DbMigration dbMigration = DbMigration.create();
        dbMigration.setPlatform(Platform.POSTGRES);
        dbMigration.generateMigration();
    }
}

在运行之后,就能在resources目录下生成DB迁移文件,相应的版本号也会通过文件名来标识

DB迁移文件

在运行时,会额外生成一个运行情况的记录表,记录运行成功的DB迁移数据的版本,和相关的数据,如下图


DB迁移运行记录表

通过DB Migration也可以完成数据表的创建和更新工作,相比较之下,比直接全部创建数据表精确度更高,也比执行本地导出的SQL批处理文件更加方便,但是DB Migration只更新增加的数据表或者增加的字段,如果有数据表删除,或者某一个字段的删除,并不会进行相应的更新

<changeSet type="pendingDrops">
    <dropColumn columnName="txt" tableName="user_vole"/>
</changeSet>

会显示pendingDrops,即等待删除

当然这个操作在一定程度上体现了安全性,毕竟可能会删除一些数据,而不是一个空字段或者空表。那如果这些数据真的需要删除呢?只要在DB迁移文件生成类中,配置需要执行删除操作的迁移文件版本号即可

public static void main(String[] args) throws IOException {
        //执行1.1版本下的删除操作
        System.setProperty("ddl.migration.pendingDropsFor", "1.1");
        DbMigration dbMigration = DbMigration.create();
        ……
 }

重新生成DB迁移文件之后,就会显示该等待删除的字段或者表已经生成了相应的删除的SQL语句和新的版本号

相比之下,DB Migration比批量的createSql要好不少,而且可以自己制作相应版本的DB迁移数据,将自己需要的批处理Sql文件导入其中

Hello Ebean

还是要说下Ebean的简单使用,毕竟是给很多没用过Ebean的人看的。举个查询的例子,对某一个field进行升序或者降序排序后,分页查找其中的某一页数据

public List<UserLogin> findByPage(String field, String type, int start, int size) {
     return ebeanServer.find(UserLogin.class)
           .orderBy(field+" "+type)
           .setFirstRow(start)
           .setMaxRows(size)
           .findList();
}

其中,排序的字段和排序的方式是传入的

Ebean的数据操作方式非常多,具体可以看官方文档,而且EbeanElasticSearch也整合了,方便数据的全文搜索

另外,EbeanHibernate有一定的相似性,支持自定义的SQL

public int exeUpdate(String f1, Object v1, String f2, Object v2) {
     String s = "UPDATE user_login set "+f2+" = :v2 where "+f1+" = :v1";
     SqlUpdate update = ebeanServer.createSqlUpdate(s);
     update.setParameter("v1", v1);
     update.setParameter("v2", v2);
     return ebeanServer.execute(update);
 }

基本代码都贴了,应该差不多没啥,配置问题网上查一下应该都能跑起来。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,905评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,140评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,791评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,483评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,476评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,516评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,905评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,560评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,778评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,557评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,635评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,338评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,925评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,898评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,142评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,818评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,347评论 2 342

推荐阅读更多精彩内容