Ebean是啥
額诸狭,具體的Ebean是啥可以自己搜索下院塞,說白了就是一個和Mybatis
、Hibernate Jpa
差不多的數(shù)據(jù)庫操作框架辆憔,但是用了之后還是發(fā)現(xiàn)挺好用的,以下復(fù)制了一段贊揚Ebean
的框架的臺詞
Hibernate/JPA
反正比 Hibernate/JPA 好
MyBatis
優(yōu)點
- 在 XML 映射文件里寫 SQL 語句很爽
缺點
- 實現(xiàn)一個 DAO报嵌、倉儲要寫很多文件(DAO/Repository虱咧、XXXMapper、XXXMapper.xml)锚国,方法多了比較繁瑣
- 無法在一個方法里做批處理腕巡,無法級聯(lián)加載
- 即時是簡單的 CRUD,都顯得繁瑣血筑,導(dǎo)致存在各種彌補 mybatis 這一缺陷的第三方封裝框架
- 無法面向?qū)ο蠡娉粒瑹o法實現(xiàn) DDD
EBean
優(yōu)點
- 所有場景都實現(xiàn)非常完美煎楣,代碼可讀性高
- 實現(xiàn)批處理超級簡單
- ORM 查詢、sql 查詢车伞、DTO 查詢都非常簡單
缺點
- DTO 查詢功能較新择懂,有待增加 XML mapping 對 DTO 的支持
Ebean自動創(chuàng)建數(shù)據(jù)表
首先介紹幾個ebean
的方法
config.setDdlRun(true);
config.setDdlGenerate(true);
config.setDdlCreateOnly(true);
在EbeanServer
的配置文件中加上以上配置就可以實現(xiàn)根據(jù)entity
自動創(chuàng)建數(shù)據(jù)表,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
會在一開始的時候困曙,創(chuàng)建所有的數(shù)據(jù)表。但是如果只用這個配置谦去,那么每次啟動都會先執(zhí)行drop all ddl
赂弓,即,每次啟動是先刪除所有的表哪轿,再創(chuàng)建需要的表盈魁。
那如果需要達到不刪除已有數(shù)據(jù)表的效果,就需要加上isDdlCreateOnly
窃诉,他會跳過drop all ddl
這個語句
那么新的問題就來了杨耙,如果寫成
//是否執(zhí)行建表SQL
config.setDdlRun(true);
//是否生成建表SQL
config.setDdlGenerate(true);
//是否跳過刪表SQL
config.setDdlCreateOnly(true);
第一次創(chuàng)建的時候,是沒問題的飘痛,第二次創(chuàng)建的時候珊膜,就會報相應(yīng)的數(shù)據(jù)表already exist
的錯誤
解決這個問題呢也非常的簡單,加一個判斷就可以宣脉,判斷是否已經(jīng)存在數(shù)據(jù)表车柠,如果不存在就進行創(chuàng)建,如果已經(jīng)存在就不創(chuàng)建塑猖,也就是下面這樣
@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;
}
但是這樣竹祷。就結(jié)束了嗎?上述實現(xiàn)方式羊苟,并不能達到修改某一字段自動檢測并更新的效果塑陵。
在很多ebean
源代碼的分享者那里,都使用DbMigration來進行數(shù)據(jù)庫的遷移蜡励,更新等操作令花。那為什么不用上面的一些方法呢。因為create-all / drop-all
這兩個簡單的腳本凉倚,本身就是為了測試而創(chuàng)建的兼都,不是為了實際的編碼使用的
不過話說回來,如果不是頻繁修改稽寒,好像上面的簡單實現(xiàn)也不錯的樣子
除了上面的DdlCreate之外扮碧,Ebean還提供了其他的數(shù)據(jù)初始化方案。比如
config.setDdlInitSql("beforeCreateSql.sql"); //在CreateSql前執(zhí)行
config.setDdlSeedSql("afterCreateSql.sql"); //在CreateSql后執(zhí)行
其中setDdlInitSql
是在CreateSql
前執(zhí)行的瓦胎,所以無論建表Sql是否執(zhí)行芬萍,都會執(zhí)行這個sql文件(該文件放在resources
目錄下)尤揣。而如果數(shù)據(jù)表已存在而跳過了建表SQL,則也會相應(yīng)的跳過setDdlSeedSql
這個方法
在這個基礎(chǔ)之上柬祠,我們就能進行數(shù)據(jù)的擴展操作北戏,比如在創(chuàng)建表之后,插入測試數(shù)據(jù)漫蛔,或者直接運行在本地導(dǎo)出的SQL批處理腳本等等
DB Migration
DB Migration 是根據(jù)實體類來生成數(shù)據(jù)庫的當前情況嗜愈,每一次數(shù)據(jù)庫的修改,都可以記錄下來莽龟,并以增量記錄的方式記錄下來
如果在配置文件中蠕嫁,設(shè)置了運行DB遷移文件,也可以達到修改數(shù)據(jù)表的效果毯盈,具體配置如下:
config.setRunMigration(true);
當然生成DB的遷移文件不是自動的剃毒,需要每次在你修改完實體類之后启摄,手動生成桅锄,一般是通過一個main
方法執(zhí)行的
package com.example.demo;
import io.ebean.annotation.Platform;
import io.ebean.dbmigration.DbMigration;
import java.io.IOException;
public class GenerateDbMigration {
/**
* 生成下一個不同版本的數(shù)據(jù)庫表
*/
public static void main(String[] args) throws IOException {
DbMigration dbMigration = DbMigration.create();
dbMigration.setPlatform(Platform.POSTGRES);
dbMigration.generateMigration();
}
}
在運行之后,就能在resources
目錄下生成DB遷移文件扑眉,相應(yīng)的版本號也會通過文件名來標識
在運行時脑奠,會額外生成一個運行情況的記錄表基公,記錄運行成功的DB遷移數(shù)據(jù)的版本,和相關(guān)的數(shù)據(jù)宋欺,如下圖
通過DB Migration
也可以完成數(shù)據(jù)表的創(chuàng)建和更新工作轰豆,相比較之下,比直接全部創(chuàng)建數(shù)據(jù)表精確度更高齿诞,也比執(zhí)行本地導(dǎo)出的SQL批處理文件更加方便酸休,但是DB Migration
只更新增加的數(shù)據(jù)表或者增加的字段,如果有數(shù)據(jù)表刪除掌挚,或者某一個字段的刪除雨席,并不會進行相應(yīng)的更新
<changeSet type="pendingDrops">
<dropColumn columnName="txt" tableName="user_vole"/>
</changeSet>
會顯示pendingDrops
,即等待刪除
當然這個操作在一定程度上體現(xiàn)了安全性吠式,畢竟可能會刪除一些數(shù)據(jù),而不是一個空字段或者空表抽米。那如果這些數(shù)據(jù)真的需要刪除呢特占?只要在DB遷移文件生成類中,配置需要執(zhí)行刪除操作的遷移文件版本號即可
public static void main(String[] args) throws IOException {
//執(zhí)行1.1版本下的刪除操作
System.setProperty("ddl.migration.pendingDropsFor", "1.1");
DbMigration dbMigration = DbMigration.create();
……
}
重新生成DB遷移文件之后云茸,就會顯示該等待刪除的字段或者表已經(jīng)生成了相應(yīng)的刪除的SQL語句和新的版本號
相比之下是目,DB Migration
比批量的createSql
要好不少,而且可以自己制作相應(yīng)版本的DB遷移數(shù)據(jù)标捺,將自己需要的批處理Sql文件導(dǎo)入其中
Hello Ebean
還是要說下Ebean的簡單使用懊纳,畢竟是給很多沒用過Ebean
的人看的揉抵。舉個查詢的例子,對某一個field
進行升序或者降序排序后嗤疯,分頁查找其中的某一頁數(shù)據(jù)
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
的數(shù)據(jù)操作方式非常多,具體可以看官方文檔茂缚,而且Ebean
與ElasticSearch
也整合了戏罢,方便數(shù)據(jù)的全文搜索
另外,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);
}
基本代碼都貼了龟糕,應(yīng)該差不多沒啥,配置問題網(wǎng)上查一下應(yīng)該都能跑起來悔耘。