Ebean是啥
额,具体的Ebean是啥可以自己搜索下,说白了就是一个和Mybatis
、Hibernate 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 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
的数据操作方式非常多,具体可以看官方文档,而且Ebean
与ElasticSearch
也整合了,方便数据的全文搜索
另外,Ebean
和Hibernate
有一定的相似性,支持自定义的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);
}
基本代码都贴了,应该差不多没啥,配置问题网上查一下应该都能跑起来。